From 1a8aacdff601e90ec47daf1c54c47815062ae4ce Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 26 Jun 2025 19:51:18 +0200 Subject: [PATCH 01/33] fix(Spotify): Add `Spoof client` patch to fix various issues by using a web platform access token (#5173) Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Co-authored-by: brosssh Co-authored-by: Dawid Krajcarz <80264606+drobotk@users.noreply.github.com> Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> --- build.gradle.kts | 3 + .../boostforreddit/stub/build.gradle.kts | 2 +- extensions/nunl/stub/build.gradle.kts | 2 +- extensions/primevideo/stub/build.gradle.kts | 2 +- extensions/reddit/stub/build.gradle.kts | 2 +- extensions/shared/library/build.gradle.kts | 2 +- extensions/spotify/build.gradle.kts | 24 ++ .../misc/fix/LoginRequestListener.java | 153 ++++++++++ .../extension/spotify/misc/fix/Session.java | 124 ++++++++ .../spotify/misc/fix/SpoofClientPatch.java | 42 +++ .../extension/spotify/misc/fix/WebApp.java | 267 ++++++++++++++++++ .../spotify/src/main/proto/login5.proto | 43 +++ extensions/spotify/stub/build.gradle.kts | 2 +- extensions/spotify/utils/build.gradle.kts | 19 ++ .../revanced/extension/spotify/UserAgent.g4 | 35 +++ .../revanced/extension/spotify/UserAgent.java | 60 ++++ .../syncforreddit/stub/build.gradle.kts | 2 +- extensions/tiktok/stub/build.gradle.kts | 2 +- extensions/tumblr/stub/build.gradle.kts | 2 +- extensions/twitch/stub/build.gradle.kts | 2 +- extensions/youtube/stub/build.gradle.kts | 2 +- gradle/libs.versions.toml | 12 +- gradle/wrapper/gradle-wrapper.properties | 6 +- patches/api/patches.api | 40 ++- .../revanced/patches/all/misc/hex/HexPatch.kt | 44 ++- .../patches/shared/misc/hex/HexPatch.kt | 123 -------- .../shared/misc/hex/HexPatchBuilder.kt | 154 ++++++++++ .../patches/spotify/misc/fix/Fingerprints.kt | 12 + .../spotify/misc/fix/SpoofClientPatch.kt | 122 ++++++++ .../spotify/misc/fix/SpoofPackageInfoPatch.kt | 56 +--- .../spotify/misc/fix/SpoofSignaturePatch.kt | 4 +- 31 files changed, 1140 insertions(+), 225 deletions(-) create mode 100644 build.gradle.kts create mode 100644 extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/LoginRequestListener.java create mode 100644 extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/Session.java create mode 100644 extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java create mode 100644 extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java create mode 100644 extensions/spotify/src/main/proto/login5.proto create mode 100644 extensions/spotify/utils/build.gradle.kts create mode 100644 extensions/spotify/utils/src/main/antlr/app/revanced/extension/spotify/UserAgent.g4 create mode 100644 extensions/spotify/utils/src/main/java/app/revanced/extension/spotify/UserAgent.java delete mode 100644 patches/src/main/kotlin/app/revanced/patches/shared/misc/hex/HexPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/shared/misc/hex/HexPatchBuilder.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..fcaeeb54c --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + alias(libs.plugins.android.library) apply false +} diff --git a/extensions/boostforreddit/stub/build.gradle.kts b/extensions/boostforreddit/stub/build.gradle.kts index b0bb6f027..b4bee8809 100644 --- a/extensions/boostforreddit/stub/build.gradle.kts +++ b/extensions/boostforreddit/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/nunl/stub/build.gradle.kts b/extensions/nunl/stub/build.gradle.kts index a8da923ed..7905271b2 100644 --- a/extensions/nunl/stub/build.gradle.kts +++ b/extensions/nunl/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/primevideo/stub/build.gradle.kts b/extensions/primevideo/stub/build.gradle.kts index 2d9865785..7744c0eaa 100644 --- a/extensions/primevideo/stub/build.gradle.kts +++ b/extensions/primevideo/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/reddit/stub/build.gradle.kts b/extensions/reddit/stub/build.gradle.kts index b0bb6f027..b4bee8809 100644 --- a/extensions/reddit/stub/build.gradle.kts +++ b/extensions/reddit/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/shared/library/build.gradle.kts b/extensions/shared/library/build.gradle.kts index 3cbb56069..95969234f 100644 --- a/extensions/shared/library/build.gradle.kts +++ b/extensions/shared/library/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.android.library") + alias(libs.plugins.android.library) } android { diff --git a/extensions/spotify/build.gradle.kts b/extensions/spotify/build.gradle.kts index 39d58a022..eb963a007 100644 --- a/extensions/spotify/build.gradle.kts +++ b/extensions/spotify/build.gradle.kts @@ -1,7 +1,15 @@ +plugins { + alias(libs.plugins.protobuf) +} + dependencies { compileOnly(project(":extensions:shared:library")) compileOnly(project(":extensions:spotify:stub")) compileOnly(libs.annotation) + + implementation(project(":extensions:spotify:utils")) + implementation(libs.nanohttpd) + implementation(libs.protobuf.javalite) } android { @@ -14,3 +22,19 @@ android { targetCompatibility = JavaVersion.VERSION_1_8 } } + +protobuf { + protoc { + artifact = libs.protobuf.protoc.get().toString() + } + + generateProtoTasks { + all().forEach { task -> + task.builtins { + create("java") { + option("lite") + } + } + } + } +} diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/LoginRequestListener.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/LoginRequestListener.java new file mode 100644 index 000000000..613d82bbb --- /dev/null +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/LoginRequestListener.java @@ -0,0 +1,153 @@ +package app.revanced.extension.spotify.misc.fix; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import app.revanced.extension.shared.Logger; +import app.revanced.extension.spotify.login5.v4.proto.Login5.*; +import com.google.protobuf.ByteString; +import com.google.protobuf.MessageLite; +import fi.iki.elonen.NanoHTTPD; + +import java.io.ByteArrayInputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; + +import static fi.iki.elonen.NanoHTTPD.Response.Status.INTERNAL_ERROR; + +class LoginRequestListener extends NanoHTTPD { + LoginRequestListener(int port) { + super(port); + } + + @NonNull + @Override + public Response serve(IHTTPSession request) { + Logger.printInfo(() -> "Serving request for URI: " + request.getUri()); + + InputStream requestBodyInputStream = getRequestBodyInputStream(request); + + LoginRequest loginRequest; + try { + loginRequest = LoginRequest.parseFrom(requestBodyInputStream); + } catch (IOException e) { + Logger.printException(() -> "Failed to parse LoginRequest", e); + return newResponse(INTERNAL_ERROR); + } + + MessageLite loginResponse; + + // A request may be made concurrently by Spotify, + // however a webview can only handle one request at a time due to singleton cookie manager. + // Therefore, synchronize to ensure that only one webview handles the request at a time. + synchronized (this) { + loginResponse = getLoginResponse(loginRequest); + } + + if (loginResponse != null) { + return newResponse(Response.Status.OK, loginResponse); + } + + return newResponse(INTERNAL_ERROR); + } + + + @Nullable + private static LoginResponse getLoginResponse(@NonNull LoginRequest loginRequest) { + Session session; + + boolean isInitialLogin = !loginRequest.hasStoredCredential(); + if (isInitialLogin) { + Logger.printInfo(() -> "Received request for initial login"); + session = WebApp.currentSession; // Session obtained from WebApp.login. + } else { + Logger.printInfo(() -> "Received request to restore saved session"); + session = Session.read(loginRequest.getStoredCredential().getUsername()); + } + + return toLoginResponse(session, isInitialLogin); + } + + + private static LoginResponse toLoginResponse(Session session, boolean isInitialLogin) { + LoginResponse.Builder builder = LoginResponse.newBuilder(); + + if (session == null) { + if (isInitialLogin) { + Logger.printInfo(() -> "Session is null, returning try again later error for initial login"); + builder.setError(LoginError.TRY_AGAIN_LATER); + } else { + Logger.printInfo(() -> "Session is null, returning invalid credentials error for stored credential login"); + builder.setError(LoginError.INVALID_CREDENTIALS); + } + } else if (session.username == null) { + Logger.printInfo(() -> "Session username is null, returning invalid credentials error"); + builder.setError(LoginError.INVALID_CREDENTIALS); + } else if (session.accessTokenExpired()) { + Logger.printInfo(() -> "Access token has expired, renewing session"); + WebApp.renewSession(session.cookies); + return toLoginResponse(WebApp.currentSession, isInitialLogin); + } else { + session.save(); + Logger.printInfo(() -> "Returning session for username: " + session.username); + builder.setOk(LoginOk.newBuilder() + .setUsername(session.username) + .setAccessToken(session.accessToken) + .setStoredCredential(ByteString.fromHex("00")) // Placeholder, as it cannot be null or empty. + .setAccessTokenExpiresIn(session.accessTokenExpiresInSeconds()) + .build()); + } + + return builder.build(); + } + + @NonNull + private static InputStream limitedInputStream(InputStream inputStream, long contentLength) { + return new FilterInputStream(inputStream) { + private long remaining = contentLength; + + @Override + public int read() throws IOException { + if (remaining <= 0) return -1; + int result = super.read(); + if (result != -1) remaining--; + return result; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (remaining <= 0) return -1; + len = (int) Math.min(len, remaining); + int result = super.read(b, off, len); + if (result != -1) remaining -= result; + return result; + } + }; + } + + @NonNull + private static InputStream getRequestBodyInputStream(@NonNull IHTTPSession request) { + long requestContentLength = + Long.parseLong(Objects.requireNonNull(request.getHeaders().get("content-length"))); + return limitedInputStream(request.getInputStream(), requestContentLength); + } + + + @SuppressWarnings("SameParameterValue") + @NonNull + private static Response newResponse(Response.Status status) { + return newResponse(status, null); + } + + @NonNull + private static Response newResponse(Response.IStatus status, MessageLite messageLite) { + if (messageLite == null) { + return newFixedLengthResponse(status, "application/x-protobuf", null); + } + + byte[] messageBytes = messageLite.toByteArray(); + InputStream stream = new ByteArrayInputStream(messageBytes); + return newFixedLengthResponse(status, "application/x-protobuf", stream, messageBytes.length); + } +} diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/Session.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/Session.java new file mode 100644 index 000000000..6e7f38cde --- /dev/null +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/Session.java @@ -0,0 +1,124 @@ +package app.revanced.extension.spotify.misc.fix; + +import android.content.SharedPreferences; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import org.json.JSONException; +import org.json.JSONObject; + +import static android.content.Context.MODE_PRIVATE; + +class Session { + /** + * Username of the account. Null if this session does not have an authenticated user. + */ + @Nullable + final String username; + /** + * Access token for this session. + */ + final String accessToken; + /** + * Session expiration timestamp in milliseconds. + */ + final Long expirationTime; + /** + * Authentication cookies for this session. + */ + final String cookies; + + /** + * @param username Username of the account. Empty if this session does not have an authenticated user. + * @param accessToken Access token for this session. + * @param cookies Authentication cookies for this session. + */ + Session(@Nullable String username, String accessToken, String cookies) { + this(username, accessToken, System.currentTimeMillis() + 60 * 60 * 1000, cookies); + } + + private Session(@Nullable String username, String accessToken, long expirationTime, String cookies) { + this.username = username; + this.accessToken = accessToken; + this.expirationTime = expirationTime; + this.cookies = cookies; + } + + /** + * @return The number of milliseconds until the access token expires. + */ + long accessTokenExpiresInMillis() { + long currentTime = System.currentTimeMillis(); + return expirationTime - currentTime; + } + + /** + * @return The number of seconds until the access token expires. + */ + int accessTokenExpiresInSeconds() { + return (int) accessTokenExpiresInMillis() / 1000; + } + + /** + * @return True if the access token has expired, false otherwise. + */ + boolean accessTokenExpired() { + return accessTokenExpiresInMillis() <= 0; + } + + void save() { + Logger.printInfo(() -> "Saving session: " + this); + + SharedPreferences.Editor editor = Utils.getContext().getSharedPreferences("revanced", MODE_PRIVATE).edit(); + + String json; + try { + json = new JSONObject() + .put("accessToken", accessToken) + .put("expirationTime", expirationTime) + .put("cookies", cookies).toString(); + } catch (JSONException ex) { + Logger.printException(() -> "Failed to convert session to stored credential", ex); + return; + } + + editor.putString("session_" + username, json); + editor.apply(); + } + + @Nullable + static Session read(String username) { + Logger.printInfo(() -> "Reading saved session for username: " + username); + + SharedPreferences sharedPreferences = Utils.getContext().getSharedPreferences("revanced", MODE_PRIVATE); + String savedJson = sharedPreferences.getString("session_" + username, null); + if (savedJson == null) { + Logger.printInfo(() -> "No session found in shared preferences"); + return null; + } + + try { + JSONObject json = new JSONObject(savedJson); + String accessToken = json.getString("accessToken"); + long expirationTime = json.getLong("expirationTime"); + String cookies = json.getString("cookies"); + + return new Session(username, accessToken, expirationTime, cookies); + } catch (JSONException ex) { + Logger.printException(() -> "Failed to read session from shared preferences", ex); + return null; + } + } + + @NonNull + @Override + public String toString() { + return "Session(" + + "username=" + username + + ", accessToken=" + accessToken + + ", expirationTime=" + expirationTime + + ", cookies=" + cookies + + ')'; + } +} diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java new file mode 100644 index 000000000..8d01edaf7 --- /dev/null +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java @@ -0,0 +1,42 @@ +package app.revanced.extension.spotify.misc.fix; + +import android.view.LayoutInflater; +import app.revanced.extension.shared.Logger; + +@SuppressWarnings("unused") +public class SpoofClientPatch { + private static LoginRequestListener listener; + + /** + * Injection point. + *
+ * Start login server. + */ + public static void listen(int port) { + if (listener != null) { + Logger.printInfo(() -> "Listener already running on port " + port); + return; + } + + try { + listener = new LoginRequestListener(port); + listener.start(); + Logger.printInfo(() -> "Listener running on port " + port); + } catch (Exception ex) { + Logger.printException(() -> "listen failure", ex); + } + } + + /** + * Injection point. + *
+ * Launch login web view. + */ + public static void login(LayoutInflater inflater) { + try { + WebApp.login(inflater.getContext()); + } catch (Exception ex) { + Logger.printException(() -> "login failure", ex); + } + } +} diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java new file mode 100644 index 000000000..082c7833f --- /dev/null +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java @@ -0,0 +1,267 @@ +package app.revanced.extension.spotify.misc.fix; + +import android.annotation.SuppressLint; +import android.app.Dialog; +import android.content.Context; +import android.graphics.Bitmap; +import android.os.Build; +import android.view.*; +import android.webkit.*; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import app.revanced.extension.spotify.UserAgent; + +class WebApp { + private static final String OPEN_SPOTIFY_COM = "open.spotify.com"; + private static final String OPEN_SPOTIFY_COM_URL = "https://" + OPEN_SPOTIFY_COM; + private static final String OPEN_SPOTIFY_COM_PREFERENCES_URL = OPEN_SPOTIFY_COM_URL + "/preferences"; + private static final String ACCOUNTS_SPOTIFY_COM_LOGIN_URL = "https://accounts.spotify.com/login?continue=" + + "https%3A%2F%2Fopen.spotify.com%2Fpreferences"; + + private static final int GET_SESSION_TIMEOUT_SECONDS = 10; + private static final String JAVASCRIPT_INTERFACE_NAME = "androidInterface"; + private static final String USER_AGENT = getWebUserAgent(); + + /** + * Current webview in use. Any use of the object must be done on the main thread. + */ + @SuppressLint("StaticFieldLeak") + private static volatile WebView currentWebView; + + /** + * A session obtained from the webview after logging in or renewing the session. + */ + @Nullable + static volatile Session currentSession; + + static void login(Context context) { + Logger.printInfo(() -> "Starting login"); + + Dialog dialog = new Dialog(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen); + + // Ensure that the keyboard does not cover the webview content. + Window window = dialog.getWindow(); + //noinspection StatementWithEmptyBody + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + window.getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { + v.setPadding(0, 0, 0, insets.getInsets(WindowInsets.Type.ime()).bottom); + + return WindowInsets.CONSUMED; + }); + } else { + // TODO: Implement for lower Android versions. + } + + newWebView( + // Can't use Utils.getContext() here, because autofill won't work. + // See https://stackoverflow.com/a/79182053/11213244. + context, + new WebViewCallback() { + @Override + void onInitialized(WebView webView) { + // Ensure that cookies are cleared before loading the login page. + CookieManager.getInstance().removeAllCookies((anyRemoved) -> { + Logger.printInfo(() -> "Loading URL: " + ACCOUNTS_SPOTIFY_COM_LOGIN_URL); + webView.loadUrl(ACCOUNTS_SPOTIFY_COM_LOGIN_URL); + }); + + dialog.setCancelable(false); + dialog.setContentView(webView); + dialog.show(); + } + + @Override + void onLoggedIn(String cookies) { + dialog.dismiss(); + } + + @Override + void onReceivedSession(WebView webView, Session session) { + Logger.printInfo(() -> "Received session from login: " + session); + currentSession = session; + currentWebView = null; + webView.stopLoading(); + webView.destroy(); + } + } + ); + } + + static void renewSession(String cookies) { + Logger.printInfo(() -> "Renewing session with cookies: " + cookies); + + CountDownLatch getSessionLatch = new CountDownLatch(1); + + newWebView( + Utils.getContext(), + new WebViewCallback() { + @Override + public void onInitialized(WebView webView) { + Logger.printInfo(() -> "Loading URL: " + OPEN_SPOTIFY_COM_PREFERENCES_URL + + " with cookies: " + cookies); + setCookies(cookies); + webView.loadUrl(OPEN_SPOTIFY_COM_PREFERENCES_URL); + } + + @Override + public void onReceivedSession(WebView webView, Session session) { + Logger.printInfo(() -> "Received session: " + session); + currentSession = session; + getSessionLatch.countDown(); + currentWebView = null; + webView.stopLoading(); + webView.destroy(); + } + } + ); + + try { + final boolean isAcquired = getSessionLatch.await(GET_SESSION_TIMEOUT_SECONDS, TimeUnit.SECONDS); + if (!isAcquired) { + Logger.printException(() -> "Failed to retrieve session within " + GET_SESSION_TIMEOUT_SECONDS + " seconds"); + } + } catch (InterruptedException e) { + Logger.printException(() -> "Interrupted while waiting to retrieve session", e); + Thread.currentThread().interrupt(); + } + + // Cleanup. + currentWebView = null; + } + + /** + * All methods are called on the main thread. + */ + abstract static class WebViewCallback { + void onInitialized(WebView webView) { + } + + void onLoggedIn(String cookies) { + } + + void onReceivedSession(WebView webView, Session session) { + } + } + + @SuppressLint("SetJavaScriptEnabled") + private static void newWebView( + Context context, + WebViewCallback webViewCallback + ) { + Utils.runOnMainThreadNowOrLater(() -> { + WebView webView = currentWebView; + if (webView != null) { + // Old webview is still hanging around. + // Could happen if the network request failed and thus no callback is made. + // But in practice this never happens. + Logger.printException(() -> "Cleaning up prior webview"); + webView.stopLoading(); + webView.destroy(); + } + + webView = new WebView(context); + WebSettings settings = webView.getSettings(); + settings.setDomStorageEnabled(true); + settings.setJavaScriptEnabled(true); + settings.setUserAgentString(USER_AGENT); + // WebViewClient is always called off the main thread, + // but callback interface methods are called on the main thread. + webView.setWebViewClient(new WebViewClient() { + @Override + public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { + if (OPEN_SPOTIFY_COM.equals(request.getUrl().getHost())) { + Utils.runOnMainThread(() -> webViewCallback.onLoggedIn(getCurrentCookies())); + } + + return super.shouldInterceptRequest(view, request); + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + Logger.printInfo(() -> "Page started loading: " + url); + + if (!url.startsWith(OPEN_SPOTIFY_COM_URL)) { + return; + } + + Logger.printInfo(() -> "Evaluating script to get session on url: " + url); + String getSessionScript = "Object.defineProperty(Object.prototype, \"_username\", {" + + " configurable: true," + + " set(username) {" + + " accessToken = this._builder?.accessToken;" + + " if (accessToken) {" + + " " + JAVASCRIPT_INTERFACE_NAME + ".getSession(username, accessToken);" + + " delete Object.prototype._username;" + + " }" + + " " + + " Object.defineProperty(this, \"_username\", {" + + " configurable: true," + + " enumerable: true," + + " writable: true," + + " value: username" + + " })" + + " " + + " }" + + "});"; + + view.evaluateJavascript(getSessionScript, null); + } + }); + + final WebView callbackWebView = webView; + webView.addJavascriptInterface(new Object() { + @SuppressWarnings("unused") + @JavascriptInterface + public void getSession(String username, String accessToken) { + Session session = new Session(username, accessToken, getCurrentCookies()); + Utils.runOnMainThread(() -> webViewCallback.onReceivedSession(callbackWebView, session)); + } + }, JAVASCRIPT_INTERFACE_NAME); + + currentWebView = webView; + + CookieManager.getInstance().removeAllCookies((anyRemoved) -> { + Logger.printInfo(() -> "WebView initialized with user agent: " + USER_AGENT); + webViewCallback.onInitialized(currentWebView); + }); + }); + } + + private static String getWebUserAgent() { + String userAgentString = WebSettings.getDefaultUserAgent(Utils.getContext()); + try { + return new UserAgent(userAgentString) + .withCommentReplaced("Android", "Windows NT 10.0; Win64; x64") + .withoutProduct("Mobile") + .toString(); + } catch (IllegalArgumentException e) { + userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edge/137.0.0.0"; + String fallback = userAgentString; + Logger.printException(() -> "Failed to get user agent, falling back to " + fallback, e); + } + + return userAgentString; + } + + private static String getCurrentCookies() { + CookieManager cookieManager = CookieManager.getInstance(); + return cookieManager.getCookie(OPEN_SPOTIFY_COM_URL); + } + + private static void setCookies(@NonNull String cookies) { + CookieManager cookieManager = CookieManager.getInstance(); + + String[] cookiesList = cookies.split(";"); + for (String cookie : cookiesList) { + cookieManager.setCookie(OPEN_SPOTIFY_COM_URL, cookie); + } + } +} diff --git a/extensions/spotify/src/main/proto/login5.proto b/extensions/spotify/src/main/proto/login5.proto new file mode 100644 index 000000000..7d8e38d24 --- /dev/null +++ b/extensions/spotify/src/main/proto/login5.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package spotify.login5.v4; + +option optimize_for = LITE_RUNTIME; +option java_package = "app.revanced.extension.spotify.login5.v4.proto"; + +message StoredCredential { + string username = 1; + bytes data = 2; +} + +message LoginRequest { + oneof login_method { + StoredCredential stored_credential = 100; + } +} + +message LoginOk { + string username = 1; + string access_token = 2; + bytes stored_credential = 3; + int32 access_token_expires_in = 4; +} + +message LoginResponse { + oneof response { + LoginOk ok = 1; + LoginError error = 2; + } +} + +enum LoginError { + UNKNOWN_ERROR = 0; + INVALID_CREDENTIALS = 1; + BAD_REQUEST = 2; + UNSUPPORTED_LOGIN_PROTOCOL = 3; + TIMEOUT = 4; + UNKNOWN_IDENTIFIER = 5; + TOO_MANY_ATTEMPTS = 6; + INVALID_PHONENUMBER = 7; + TRY_AGAIN_LATER = 8; +} diff --git a/extensions/spotify/stub/build.gradle.kts b/extensions/spotify/stub/build.gradle.kts index 489664c26..e31f1e322 100644 --- a/extensions/spotify/stub/build.gradle.kts +++ b/extensions/spotify/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/spotify/utils/build.gradle.kts b/extensions/spotify/utils/build.gradle.kts new file mode 100644 index 000000000..3cdce1cc0 --- /dev/null +++ b/extensions/spotify/utils/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + java + antlr +} + +dependencies { + antlr(libs.antlr4) +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +tasks { + generateGrammarSource { + arguments = listOf("-visitor") + } +} diff --git a/extensions/spotify/utils/src/main/antlr/app/revanced/extension/spotify/UserAgent.g4 b/extensions/spotify/utils/src/main/antlr/app/revanced/extension/spotify/UserAgent.g4 new file mode 100644 index 000000000..afd3ba3f9 --- /dev/null +++ b/extensions/spotify/utils/src/main/antlr/app/revanced/extension/spotify/UserAgent.g4 @@ -0,0 +1,35 @@ +grammar UserAgent; + +@header { package app.revanced.extension.spotify; } + +userAgent + : product (WS product)* EOF + ; + +product + : name ('/' version)? (WS comment)? + ; + +name + : STRING + ; + +version + : STRING ('.' STRING)* + ; + +comment + : COMMENT + ; + +COMMENT + : '(' ~ ')'* ')' + ; + +STRING + : [a-zA-Z0-9]+ + ; + +WS + : [ \r\n]+ + ; \ No newline at end of file diff --git a/extensions/spotify/utils/src/main/java/app/revanced/extension/spotify/UserAgent.java b/extensions/spotify/utils/src/main/java/app/revanced/extension/spotify/UserAgent.java new file mode 100644 index 000000000..e25912f86 --- /dev/null +++ b/extensions/spotify/utils/src/main/java/app/revanced/extension/spotify/UserAgent.java @@ -0,0 +1,60 @@ +package app.revanced.extension.spotify; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.TokenStreamRewriter; +import org.antlr.v4.runtime.tree.ParseTreeWalker; + +public class UserAgent { + private final UserAgentParser.UserAgentContext tree; + private final TokenStreamRewriter rewriter; + private final ParseTreeWalker walker; + + public UserAgent(String userAgentString) { + CharStream input = CharStreams.fromString(userAgentString); + UserAgentLexer lexer = new UserAgentLexer(input); + CommonTokenStream tokens = new CommonTokenStream(lexer); + + tree = new UserAgentParser(tokens).userAgent(); + walker = new ParseTreeWalker(); + rewriter = new TokenStreamRewriter(tokens); + } + + public UserAgent withoutProduct(String name) { + walker.walk(new UserAgentBaseListener() { + @Override + public void exitProduct(UserAgentParser.ProductContext ctx) { + if (!ctx.name().getText().contains(name)) return; + + int startIndex = ctx.getStart().getTokenIndex(); + if (startIndex != 0) startIndex -= 1; // Also remove the preceding whitespace. + + int stopIndex = ctx.getStop().getTokenIndex(); + + + rewriter.delete(startIndex, stopIndex); + } + }, tree); + + return new UserAgent(rewriter.getText().trim()); + } + + public UserAgent withCommentReplaced(String containing, String replacement) { + walker.walk(new UserAgentBaseListener() { + @Override + public void exitComment(UserAgentParser.CommentContext ctx) { + if (ctx.getText().contains(containing)) { + rewriter.replace(ctx.getStart(), ctx.getStop(), "(" + replacement + ")"); + } + } + }, tree); + + return new UserAgent(rewriter.getText()); + } + + @Override + public String toString() { + return rewriter.getText(); + } +} diff --git a/extensions/syncforreddit/stub/build.gradle.kts b/extensions/syncforreddit/stub/build.gradle.kts index b0bb6f027..b4bee8809 100644 --- a/extensions/syncforreddit/stub/build.gradle.kts +++ b/extensions/syncforreddit/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/tiktok/stub/build.gradle.kts b/extensions/tiktok/stub/build.gradle.kts index 798b5a681..de3358345 100644 --- a/extensions/tiktok/stub/build.gradle.kts +++ b/extensions/tiktok/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/tumblr/stub/build.gradle.kts b/extensions/tumblr/stub/build.gradle.kts index 3b8616f8e..c1e0b1722 100644 --- a/extensions/tumblr/stub/build.gradle.kts +++ b/extensions/tumblr/stub/build.gradle.kts @@ -1,7 +1,7 @@ android.namespace = "app.revanced.extension" plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/twitch/stub/build.gradle.kts b/extensions/twitch/stub/build.gradle.kts index 42cf7d038..ffdfac5a6 100644 --- a/extensions/twitch/stub/build.gradle.kts +++ b/extensions/twitch/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/extensions/youtube/stub/build.gradle.kts b/extensions/youtube/stub/build.gradle.kts index 3ec9f09a8..318046019 100644 --- a/extensions/youtube/stub/build.gradle.kts +++ b/extensions/youtube/stub/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id(libs.plugins.android.library.get().pluginId) + alias(libs.plugins.android.library) } android { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bac3e0dd9..6af604481 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,15 +11,25 @@ appcompat = "1.7.0" okhttp = "5.0.0-alpha.14" retrofit = "2.11.0" guava = "33.4.0-jre" +protobuf-javalite = "4.31.1" +protoc = "4.31.1" +protobuf = "0.9.5" +antlr4 = "4.13.2" +nanohttpd = "2.3.1" apksig = "8.10.1" [libraries] annotation = { module = "androidx.annotation:annotation", version.ref = "annotation" } +antlr4 = { module = "org.antlr:antlr4", version.ref = "antlr4" } appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +nanohttpd = { module = "org.nanohttpd:nanohttpd", version.ref = "nanohttpd" } okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } +protobuf-javalite = { module = "com.google.protobuf:protobuf-javalite", version.ref = "protobuf-javalite" } +protobuf-protoc = { module = "com.google.protobuf:protoc", version.ref = "protoc" } retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } guava = { module = "com.google.guava:guava", version.ref = "guava" } apksig = { group = "com.android.tools.build", name = "apksig", version.ref = "apksig" } [plugins] -android-library = { id = "com.android.library", version.ref = "agp" } +android-library = { id = "com.android.library" } +protobuf = { id = "com.google.protobuf", version.ref = "protobuf" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 68e8816d7..5205bd795 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,8 +1,6 @@ +#Mon Jun 16 14:39:32 CEST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip -networkTimeout=10000 -validateDistributionUrl=true +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/patches/api/patches.api b/patches/api/patches.api index 69981ad6c..bbb98099c 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -668,17 +668,39 @@ public final class app/revanced/patches/shared/misc/gms/GmsCoreSupportPatchKt { public static synthetic fun gmsCoreSupportResourcePatch$default (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/patch/Option;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch; } -public final class app/revanced/patches/shared/misc/hex/HexPatchKt { - public static final fun hexPatch (Lkotlin/jvm/functions/Function0;)Lapp/revanced/patcher/patch/RawResourcePatch; +public final class app/revanced/patches/shared/misc/hex/HexPatchBuilder : java/util/Set, kotlin/jvm/internal/markers/KMappedMarker { + public fun ()V + public fun add (Lapp/revanced/patches/shared/misc/hex/Replacement;)Z + public synthetic fun add (Ljava/lang/Object;)Z + public fun addAll (Ljava/util/Collection;)Z + public final fun asPatternTo (Ljava/lang/String;Ljava/lang/String;)Lkotlin/Pair; + public fun clear ()V + public fun contains (Lapp/revanced/patches/shared/misc/hex/Replacement;)Z + public final fun contains (Ljava/lang/Object;)Z + public fun containsAll (Ljava/util/Collection;)Z + public fun getSize ()I + public final fun inFile (Lkotlin/Pair;Ljava/lang/String;)V + public fun isEmpty ()Z + public fun iterator ()Ljava/util/Iterator; + public fun remove (Ljava/lang/Object;)Z + public fun removeAll (Ljava/util/Collection;)Z + public fun retainAll (Ljava/util/Collection;)Z + public final fun size ()I + public fun toArray ()[Ljava/lang/Object; + public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; +} + +public final class app/revanced/patches/shared/misc/hex/HexPatchBuilderKt { + public static final fun hexPatch (ZLkotlin/jvm/functions/Function0;)Lapp/revanced/patcher/patch/RawResourcePatch; + public static final fun hexPatch (ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/RawResourcePatch; + public static synthetic fun hexPatch$default (ZLkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lapp/revanced/patcher/patch/RawResourcePatch; + public static synthetic fun hexPatch$default (ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/RawResourcePatch; } public final class app/revanced/patches/shared/misc/hex/Replacement { - public static final field Companion Lapp/revanced/patches/shared/misc/hex/Replacement$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - public final fun replacePattern ([B)V -} - -public final class app/revanced/patches/shared/misc/hex/Replacement$Companion { + public fun ([B[BLjava/lang/String;)V + public final fun getReplacementBytesPadded ()[B } public final class app/revanced/patches/shared/misc/mapping/ResourceElement { @@ -922,6 +944,10 @@ public final class app/revanced/patches/spotify/misc/extension/ExtensionPatchKt public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/spotify/misc/fix/SpoofClientPatchKt { + public static final fun getSpoofClientPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatchKt { public static final fun getSpoofPackageInfoPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/hex/HexPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/hex/HexPatch.kt index a8bb80517..9a9e427ec 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/hex/HexPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/hex/HexPatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.all.misc.hex import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.rawResourcePatch import app.revanced.patcher.patch.stringsOption -import app.revanced.patches.shared.misc.hex.Replacement +import app.revanced.patches.shared.misc.hex.HexPatchBuilder import app.revanced.patches.shared.misc.hex.hexPatch import app.revanced.util.Utils.trimIndentMultiline @@ -13,44 +13,42 @@ val hexPatch = rawResourcePatch( description = "Replaces a hexadecimal patterns of bytes of files in an APK.", use = false, ) { - // TODO: Instead of stringArrayOption, use a custom option type to work around - // https://github.com/ReVanced/revanced-library/issues/48. - // Replace the custom option type with a stringArrayOption once the issue is resolved. val replacements by stringsOption( key = "replacements", title = "Replacements", description = """ Hexadecimal patterns to search for and replace with another in a target file. - + A pattern is a sequence of case insensitive strings, each representing hexadecimal bytes, separated by spaces. An example pattern is 'aa 01 02 FF'. Every pattern must be followed by a pipe ('|'), the replacement pattern, another pipe ('|'), and the path to the file to make the changes in relative to the APK root. - The replacement pattern must have the same length as the original pattern. + The replacement pattern must be shorter or equal in length to the pattern. - Full example of a valid input: - 'aa 01 02 FF|00 00 00 00|path/to/file' + Full example of a valid replacement: + '01 02 aa FF|03 04|path/to/file' """.trimIndentMultiline(), required = true, ) dependsOn( - hexPatch { - replacements!!.map { from -> - val (pattern, replacementPattern, targetFilePath) = try { - from.split("|", limit = 3) - } catch (e: Exception) { - throw PatchException( - "Invalid input: $from.\n" + - "Every pattern must be followed by a pipe ('|'), " + - "the replacement pattern, another pipe ('|'), " + - "and the path to the file to make the changes in relative to the APK root. ", - ) + hexPatch( + block = fun HexPatchBuilder.() { + replacements!!.forEach { replacement -> + try { + val (pattern, replacementPattern, targetFilePath) = replacement.split("|", limit = 3) + pattern asPatternTo replacementPattern inFile targetFilePath + } catch (e: Exception) { + throw PatchException( + "Invalid replacement: $replacement.\n" + + "Every pattern must be followed by a pipe ('|'), " + + "the replacement pattern, another pipe ('|'), " + + "and the path to the file to make the changes in relative to the APK root. ", + ) + } } - - Replacement(pattern, replacementPattern, targetFilePath) - }.toSet() - }, + }, + ) ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/hex/HexPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/hex/HexPatch.kt deleted file mode 100644 index d361a5571..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/hex/HexPatch.kt +++ /dev/null @@ -1,123 +0,0 @@ -package app.revanced.patches.shared.misc.hex - -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.patch.rawResourcePatch -import kotlin.math.max - -// The replacements being passed using a function is intended. -// Previously the replacements were a property of the patch. Getter were being delegated to that property. -// This late evaluation was being leveraged in app.revanced.patches.all.misc.hex.HexPatch. -// Without the function, the replacements would be evaluated at the time of patch creation. -// This isn't possible because the delegated property is not accessible at that time. -fun hexPatch(replacementsSupplier: () -> Set) = rawResourcePatch { - execute { - replacementsSupplier().groupBy { it.targetFilePath }.forEach { (targetFilePath, replacements) -> - val targetFile = try { - get(targetFilePath, true) - } catch (e: Exception) { - throw PatchException("Could not find target file: $targetFilePath") - } - - // TODO: Use a file channel to read and write the file instead of reading the whole file into memory, - // in order to reduce memory usage. - val targetFileBytes = targetFile.readBytes() - - replacements.forEach { replacement -> - replacement.replacePattern(targetFileBytes) - } - - targetFile.writeBytes(targetFileBytes) - } - } -} - -/** - * Represents a pattern to search for and its replacement pattern. - * - * @property pattern The pattern to search for. - * @property replacementPattern The pattern to replace the [pattern] with. - * @property targetFilePath The path to the file to make the changes in relative to the APK root. - */ -class Replacement( - private val pattern: String, - replacementPattern: String, - internal val targetFilePath: String, -) { - private val patternBytes = pattern.toByteArrayPattern() - private val replacementPattern = replacementPattern.toByteArrayPattern() - - init { - if (this.patternBytes.size != this.replacementPattern.size) { - throw PatchException("Pattern and replacement pattern must have the same length: $pattern") - } - } - - /** - * Replaces the [patternBytes] with the [replacementPattern] in the [targetFileBytes]. - * - * @param targetFileBytes The bytes of the file to make the changes in. - */ - fun replacePattern(targetFileBytes: ByteArray) { - val startIndex = indexOfPatternIn(targetFileBytes) - - if (startIndex == -1) { - throw PatchException("Pattern not found in target file: $pattern") - } - - replacementPattern.copyInto(targetFileBytes, startIndex) - } - - // TODO: Allow searching in a file channel instead of a byte array to reduce memory usage. - /** - * Returns the index of the first occurrence of [patternBytes] in the haystack - * using the Boyer-Moore algorithm. - * - * @param haystack The array to search in. - * - * @return The index of the first occurrence of the [patternBytes] in the haystack or -1 - * if the [patternBytes] is not found. - */ - private fun indexOfPatternIn(haystack: ByteArray): Int { - val needle = patternBytes - - val haystackLength = haystack.size - 1 - val needleLength = needle.size - 1 - val right = IntArray(256) { -1 } - - for (i in 0 until needleLength) right[needle[i].toInt().and(0xFF)] = i - - var skip: Int - for (i in 0..haystackLength - needleLength) { - skip = 0 - - for (j in needleLength - 1 downTo 0) { - if (needle[j] != haystack[i + j]) { - skip = max(1, j - right[haystack[i + j].toInt().and(0xFF)]) - - break - } - } - - if (skip == 0) return i - } - return -1 - } - - companion object { - /** - * Convert a string representing a pattern of hexadecimal bytes to a byte array. - * - * @return The byte array representing the pattern. - * @throws PatchException If the pattern is invalid. - */ - private fun String.toByteArrayPattern() = try { - split(" ").map { it.toInt(16).toByte() }.toByteArray() - } catch (e: NumberFormatException) { - throw PatchException( - "Could not parse pattern: $this. A pattern is a sequence of case insensitive strings " + - "representing hexadecimal bytes separated by spaces", - e, - ) - } - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/hex/HexPatchBuilder.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/hex/HexPatchBuilder.kt new file mode 100644 index 000000000..8b6bc4dc2 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/hex/HexPatchBuilder.kt @@ -0,0 +1,154 @@ +package app.revanced.patches.shared.misc.hex + +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.rawResourcePatch +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.math.max + +fun hexPatch(ignoreMissingTargetFiles: Boolean = false, block: HexPatchBuilder.() -> Unit) = + hexPatch(ignoreMissingTargetFiles, fun(): Set = HexPatchBuilder().apply(block)) + +@Suppress("JavaDefaultMethodsNotOverriddenByDelegation") +class HexPatchBuilder internal constructor( + private val replacements: MutableSet = mutableSetOf(), +) : Set by replacements { + infix fun String.asPatternTo(replacementPattern: String) = byteArrayOf(this) to byteArrayOf(replacementPattern) + + infix fun Pair.inFile(filePath: String) { + if (first is String && second is String) { + val first = first as String + val second = second as String + + replacements += Replacement( + first.toByteArray(), second.toByteArray(), + filePath + ) + } else if (first is ByteArray && second is ByteArray) { + val first = first as ByteArray + val second = second as ByteArray + + replacements += Replacement(first, second, filePath) + } else { + throw PatchException("Unsupported types for pattern and replacement: $first, $second") + } + } +} + +// The replacements being passed using a function is intended. +// Previously the replacements were a property of the patch. Getter were being delegated to that property. +// This late evaluation was being leveraged in app.revanced.patches.all.misc.hex.HexPatch. +// Without the function, the replacements would be evaluated at the time of patch creation. +// This isn't possible because the delegated property is not accessible at that time. +@Deprecated("Use the hexPatch function with the builder parameter instead.") +fun hexPatch(ignoreMissingTargetFiles: Boolean = false, replacementsSupplier: () -> Set) = + rawResourcePatch { + execute { + replacementsSupplier().groupBy { it.targetFilePath }.forEach { (targetFilePath, replacements) -> + val targetFile = get(targetFilePath, true) + if (ignoreMissingTargetFiles && !targetFile.exists()) return@forEach + + // TODO: Use a file channel to read and write the file instead of reading the whole file into memory, + // in order to reduce memory usage. + val targetFileBytes = targetFile.readBytes() + replacements.forEach { it.replacePattern(targetFileBytes) } + targetFile.writeBytes(targetFileBytes) + } + } + } + +/** + * Represents a pattern to search for and its replacement pattern in a file. + * + * @property bytes The bytes to search for. + * @property replacementBytes The bytes to replace the [bytes] with. + * @property targetFilePath The path to the file to make the changes in relative to the APK root. + */ +class Replacement( + private val bytes: ByteArray, + replacementBytes: ByteArray, + internal val targetFilePath: String, +) { + val replacementBytesPadded = replacementBytes + ByteArray(bytes.size - replacementBytes.size) + + @Deprecated("Use the constructor with ByteArray parameters instead.") + constructor( + pattern: String, + replacementPattern: String, + targetFilePath: String, + ) : this( + byteArrayOf(pattern), + byteArrayOf(replacementPattern), + targetFilePath + ) + + /** + * Replaces the [bytes] with the [replacementBytes] in the [targetFileBytes]. + * + * @param targetFileBytes The bytes of the file to make the changes in. + */ + internal fun replacePattern(targetFileBytes: ByteArray) { + val startIndex = indexOfPatternIn(targetFileBytes) + + if (startIndex == -1) { + throw PatchException( + "Pattern not found in target file: " + + bytes.joinToString(" ") { "%02x".format(it) } + ) + } + + replacementBytesPadded.copyInto(targetFileBytes, startIndex) + } + + // TODO: Allow searching in a file channel instead of a byte array to reduce memory usage. + /** + * Returns the index of the first occurrence of [bytes] in the haystack + * using the Boyer-Moore algorithm. + * + * @param haystack The array to search in. + * + * @return The index of the first occurrence of the [bytes] in the haystack or -1 + * if the [bytes] is not found. + */ + private fun indexOfPatternIn(haystack: ByteArray): Int { + val needle = bytes + + val haystackLength = haystack.size - 1 + val needleLength = needle.size - 1 + val right = IntArray(256) { -1 } + + for (i in 0 until needleLength) right[needle[i].toInt().and(0xFF)] = i + + var skip: Int + for (i in 0..haystackLength - needleLength) { + skip = 0 + + for (j in needleLength - 1 downTo 0) { + if (needle[j] != haystack[i + j]) { + skip = max(1, j - right[haystack[i + j].toInt().and(0xFF)]) + + break + } + } + + if (skip == 0) return i + } + return -1 + } +} + +/** + * Convert a string representing a pattern of hexadecimal bytes to a byte array. + * + * @return The byte array representing the pattern. + * @throws PatchException If the pattern is invalid. + */ +private fun byteArrayOf(pattern: String) = try { + pattern.split(" ").map { it.toInt(16).toByte() }.toByteArray() +} catch (e: NumberFormatException) { + throw PatchException( + "Could not parse pattern: $pattern. A pattern is a sequence of case insensitive strings " + + "representing hexadecimal bytes separated by spaces", + e, + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt index 6b25bc630..f1600861a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt @@ -1,9 +1,21 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags internal val getPackageInfoFingerprint = fingerprint { strings( "Failed to get the application signatures" ) } + +internal val startLiborbitFingerprint = fingerprint { + strings("/liborbit-jni-spotify.so") +} + +internal val startupPageLayoutInflateFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("Landroid/view/View;") + parameters("Landroid/view/LayoutInflater;", "Landroid/view/ViewGroup;", "Landroid/os/Bundle;") + strings("blueprintContainer", "gradient", "valuePropositionTextView") +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt new file mode 100644 index 000000000..70339813d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt @@ -0,0 +1,122 @@ +package app.revanced.patches.spotify.misc.fix + +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.intOption +import app.revanced.patches.shared.misc.hex.HexPatchBuilder +import app.revanced.patches.shared.misc.hex.hexPatch +import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch +import app.revanced.util.findInstructionIndicesReversedOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/spotify/misc/fix/SpoofClientPatch;" + +@Suppress("unused") +val spoofClientPatch = bytecodePatch( + name = "Spoof client", + description = "Spoofs the client to fix various functions of the app.", +) { + val port by intOption( + key = "port", + default = 4345, + title = " Login request listener port", + description = "The port to use for the listener that intercepts and handles login requests. " + + "Port must be between 0 and 65535.", + required = true, + validator = { + it!! + !(it < 0 || it > 65535) + } + ) + + dependsOn( + sharedExtensionPatch, + hexPatch(ignoreMissingTargetFiles = true, block = fun HexPatchBuilder.() { + listOf( + "arm64-v8a", + "armeabi-v7a", + "x86", + "x86_64" + ).forEach { architecture -> + "https://login5.spotify.com/v3/login" to "http://127.0.0.1:$port/v3/login" inFile + "lib/$architecture/liborbit-jni-spotify.so" + + "https://login5.spotify.com/v4/login" to "http://127.0.0.1:$port/v4/login" inFile + "lib/$architecture/liborbit-jni-spotify.so" + } + }) + ) + + compatibleWith("com.spotify.music") + + execute { + getPackageInfoFingerprint.method.apply { + // region Spoof signature. + + val failedToGetSignaturesStringIndex = + getPackageInfoFingerprint.stringMatches!!.first().index + + val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow( + failedToGetSignaturesStringIndex, + Opcode.MOVE_RESULT_OBJECT, + ) + + val signatureRegister = getInstruction(concatSignaturesIndex).registerA + val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32" + + replaceInstruction(concatSignaturesIndex, "const-string v$signatureRegister, \"$expectedSignature\"") + + // endregion + + // region Spoof installer name. + + val expectedInstallerName = "com.android.vending" + + findInstructionIndicesReversedOrThrow { + val reference = getReference() + reference?.name == "getInstallerPackageName" || reference?.name == "getInstallingPackageName" + }.forEach { index -> + val returnObjectIndex = index + 1 + + val installerPackageNameRegister = getInstruction( + returnObjectIndex + ).registerA + + addInstruction( + returnObjectIndex + 1, + "const-string v$installerPackageNameRegister, \"$expectedInstallerName\"" + ) + } + + // endregion + } + + startLiborbitFingerprint.method.addInstructions( + 0, + """ + const/16 v0, $port + invoke-static { v0 }, $EXTENSION_CLASS_DESCRIPTOR->listen(I)V + """ + ) + + startupPageLayoutInflateFingerprint.method.apply { + val openLoginWebViewDescriptor = + "$EXTENSION_CLASS_DESCRIPTOR->login(Landroid/view/LayoutInflater;)V" + + addInstructions( + 0, + """ + move-object/from16 v3, p1 + invoke-static { v3 }, $openLoginWebViewDescriptor + """ + ) + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt index 58606777d..20f9b3b4e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt @@ -1,63 +1,11 @@ package app.revanced.patches.spotify.misc.fix -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.util.findInstructionIndicesReversedOrThrow -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionReversedOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference +@Deprecated("Superseded by spoofClientPatch", ReplaceWith("spoofClientPatch")) @Suppress("unused") val spoofPackageInfoPatch = bytecodePatch( - name = "Spoof package info", description = "Spoofs the package info of the app to fix various functions of the app.", ) { - compatibleWith("com.spotify.music") - - execute { - getPackageInfoFingerprint.method.apply { - // region Spoof signature. - - val failedToGetSignaturesStringIndex = - getPackageInfoFingerprint.stringMatches!!.first().index - - val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow( - failedToGetSignaturesStringIndex, - Opcode.MOVE_RESULT_OBJECT, - ) - - val signatureRegister = getInstruction(concatSignaturesIndex).registerA - val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32" - - replaceInstruction(concatSignaturesIndex, "const-string v$signatureRegister, \"$expectedSignature\"") - - // endregion - - // region Spoof installer name. - - val expectedInstallerName = "com.android.vending" - - findInstructionIndicesReversedOrThrow { - val reference = getReference() - reference?.name == "getInstallerPackageName" || reference?.name == "getInstallingPackageName" - }.forEach { index -> - val returnObjectIndex = index + 1 - - val installerPackageNameRegister = getInstruction( - returnObjectIndex - ).registerA - - addInstruction( - returnObjectIndex + 1, - "const-string v$installerPackageNameRegister, \"$expectedInstallerName\"" - ) - } - - // endregion - } - } + dependsOn(spoofClientPatch) } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofSignaturePatch.kt index d59969c6c..238da0f41 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofSignaturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofSignaturePatch.kt @@ -2,10 +2,10 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.patch.bytecodePatch -@Deprecated("Superseded by spoofPackageInfoPatch", ReplaceWith("spoofPackageInfoPatch")) +@Deprecated("Superseded by spoofClientPatch", ReplaceWith("spoofClientPatch")) @Suppress("unused") val spoofSignaturePatch = bytecodePatch( description = "Spoofs the signature of the app fix various functions of the app.", ) { - dependsOn(spoofPackageInfoPatch) + dependsOn(spoofClientPatch) } From 5d2c21540c57cb8e5129becc04b079e95b5544b5 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 26 Jun 2025 17:56:10 +0000 Subject: [PATCH 02/33] chore: Release v5.29.1-dev.1 [skip ci] ## [5.29.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.29.0...v5.29.1-dev.1) (2025-06-26) ### Bug Fixes * **Spotify:** Add `Spoof client` patch to fix various issues by using a web platform access token ([#5173](https://github.com/ReVanced/revanced-patches/issues/5173)) ([1a8aacd](https://github.com/ReVanced/revanced-patches/commit/1a8aacdff601e90ec47daf1c54c47815062ae4ce)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48d35373a..ae7400c73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.29.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.29.0...v5.29.1-dev.1) (2025-06-26) + + +### Bug Fixes + +* **Spotify:** Add `Spoof client` patch to fix various issues by using a web platform access token ([#5173](https://github.com/ReVanced/revanced-patches/issues/5173)) ([b7b75bb](https://github.com/ReVanced/revanced-patches/commit/b7b75bb9d8d5fd505121e752b8a20e61ff28d1b2)) + # [5.29.0](https://github.com/ReVanced/revanced-patches/compare/v5.28.0...v5.29.0) (2025-06-26) diff --git a/gradle.properties b/gradle.properties index b1d4f9c17..d0c6652ab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.29.0 +version = 5.29.1-dev.1 From 9fa89d48c0c442c34f7cb2ccf50a6b889d680356 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 15:32:34 +0400 Subject: [PATCH 03/33] chore: Sync translations (#5272) --- .../addresources/values-fi-rFI/strings.xml | 8 +- .../addresources/values-ja-rJP/strings.xml | 54 ++++---- .../addresources/values-ko-rKR/strings.xml | 10 +- .../addresources/values-sv-rSE/strings.xml | 116 +++++++++--------- .../addresources/values-tr-rTR/strings.xml | 2 +- .../addresources/values-vi-rVN/strings.xml | 8 +- .../addresources/values-zh-rTW/strings.xml | 2 + 7 files changed, 104 insertions(+), 96 deletions(-) diff --git a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml index 15d5a154a..d87229191 100644 --- a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml +++ b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml @@ -561,6 +561,9 @@ Säädä äänenvoimakkuutta pyyhkäisemällä pystysuoraan näytön oikealta pu Klippi-painike on piilotettu Klippi-painike näytetään + Piilota Tallenna + Tallenna-painike on piilotettu + Tallenna-painike näytetään Navigointipainikkeet @@ -767,6 +770,9 @@ Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi" Piilota Tulossa-painike Tulossa-painike on piilotettu Tulossa-painike näytetään + Piilota Tehoste-painike + Tehoste-painike on piilotettu + Tehoste-painike näytetään Piilota Vihertausta-painike Vihertausta-painike on piilotettu Vihertausta-painike näytetään @@ -1259,7 +1265,7 @@ Minisoitin voidaan vetää pois näytöltä vasemmalle tai oikealle" Latausruudulla on yksivärinen tausta Aloitussivun tyyli Väri - Musta ja valkoinen + Mustavalkoinen Ota mukautettu etenemispalkin väri käyttöön Mukautettu etenemispalkin väri näytetään Alkuperäinen etenemispalkin väri näytetään diff --git a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml index d6edf9b4a..5be0e73ad 100644 --- a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml +++ b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml @@ -24,12 +24,12 @@ Second \"item\" text" チェックに失敗しました 公式サイトを開く 無視 - <h5>このアプリはあなたによってパッチが適用されていないようです。</h5><br>このアプリは正しく機能しない可能性があり、<b>使用すると有害または危険になる可能性があります</b>。<br><br>これらのチェックは、このアプリが事前にパッチが適用されているか、または他の誰かから取得されたことを意味します:<br><br><small>%1$s</small><br>検証済みで安全なアプリを使用していることを確認するために、<b>このアプリをアンインストールして自分でパッチを適用する</b>ことを強くお勧めします。<p><br>無視した場合、この警告は 2 回のみ表示されます。 - 別のデバイスでパッチが適用されています - ReVanced Manager によってインストールされていません - 10 分以上前にパッチが適用されています - %s 日前にパッチが適用されています - APK の作成日時データが破損しています + <h5>このアプリはあなたによってパッチが適用されていないようです。</h5><br>このアプリは正しく機能しない可能性があり、<b>使用すると有害または危険になる可能性があります</b>。<br><br>これらのチェックは、このアプリが事前にパッチが適用されているか、または他の誰かから取得されたことを意味します:<br><br><small>%1$s</small><br>検証済みで安全なアプリを使用していることを確認するために、<b>このアプリをアンインストールして自分でパッチを適用する</b>ことを強くおすすめします。<p><br>無視した場合、この警告は 2 回のみ表示されます。 + 別のデバイス上でパッチが適用されている + ReVanced Manager によってインストールされていない + 10 分以上前にパッチが適用されている + %s 日前にパッチが適用されている + APK の作成日時データが破損している 設定 @@ -95,7 +95,7 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に プレーヤー ショート シークバー - スワイプコントロール + スワイプ コントロール その他 動画 古い設定メニューを復元 @@ -188,8 +188,8 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 「もっと見る」ボタンを非表示にします 「もっと見る」ボタンを非表示にします チケット欄を非表示 - チケット欄は表示されません - チケット欄は表示されます + チケット欄を非表示にします + チケット欄を非表示にします Timed Reaction を非表示 Timed Reaction とチャット欄のハートマーク アイコンは表示されません Timed Reaction とチャット欄のハートマー ク アイコンは表示されます @@ -536,8 +536,8 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 共有ボタンは表示されます 「広告を停止」を非表示 - 「広告を停止」ボタンは表示されません - 「広告を停止」ボタンは表示されます + 「広告を停止」ボタンを非表示にします + 「広告を停止」ボタンを非表示にします 報告ボタンを非表示 @@ -766,11 +766,11 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 「音楽を保存」ボタンは表示されません 「音楽を保存」ボタンは表示されます 「このサウンドを使用する」ボタンを非表示 - 「このサウンドを使用する」ボタンは表示されません - 「このサウンドを使用する」ボタンは表示されます + 「このサウンドを使用する」ボタンを非表示にします + 「このサウンドを使用する」ボタンを非表示にします 「このテンプレートを使用する」ボタンを非表示 - 「このテンプレートを使用する」ボタンは表示されません - 「このテンプレートを使用する」ボタンは表示されます + 「このテンプレートを使用する」ボタンを非表示にします + 「このテンプレートを使用する」ボタンを非表示にします 今後の動画ボタンを非表示 今後の動画ボタンは表示されません 今後の動画ボタンは表示されます @@ -1399,9 +1399,9 @@ Automotive レイアウト 画質の変更を保存する 画質の変更はすべての動画に適用されます 画質の変更は現在の動画にのみ適用されます - 画質変更時にトーストを表示する - デフォルトの動画品質が変更されると、トースト ポップアップが表示されます - デフォルトの動画品質が変更されても、トースト ポップアップは表示されません + 画質の変更時にトーストを表示 + デフォルトの画質が変更された際に、トースト ポップアップを表示します + デフォルトの画質が変更された際に、トースト ポップアップを表示します デフォルトの画質(Wi-Fi) デフォルトの画質(携帯回線) ショートの画質の変更を保存する @@ -1435,9 +1435,9 @@ Automotive レイアウト 再生速度の変更を保存する 再生速度の変更はすべての動画に適用されます 再生速度の変更は現在の動画にのみ適用されます - 再生速度変更時にトーストを表示 - デフォルトの再生速度が変更されると、トースト ポップアップが表示されます - デフォルトの再生速度が変更されても、トースト ポップアップは表示されません + 再生速度の変更時にトーストを表示 + デフォルトの再生速度が変更された際に、トースト ポップアップを表示します + デフォルトの再生速度が変更された際に、トースト ポップアップを表示します デフォルトの再生速度 デフォルトの再生速度: %s @@ -1535,13 +1535,13 @@ AVC は、最大解像度が 1080p であり、Opus オーディオ コーデッ チャットの設定 その他 その他の設定 - 一般設定 + 全般設定 その他の設定 - クライアントサイド広告 - サーバー側サレストリーム広告 - デバッグログ - デバッグログは有効です - デバッグログは無効です + クライアント側広告 + サーバー側 SureStream 広告 + デバッグログを有効化 + デバッグログを有効にします + デバッグログを有効にします diff --git a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml index 9107593f4..bf292b350 100644 --- a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml +++ b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml @@ -62,7 +62,7 @@ Second \"item\" text" ReVanced Patches <i>%s</i><br>버전을 사용 중입니다 알림 - Pre-Release 버전이므로<br>알려지지 않은 문제점이<br>발생할 수 있습니다 + Pre-release 버전이므로<br>알려지지 않은 문제점이<br>발생할 수 있습니다 공식 링크 @@ -1409,8 +1409,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요" 동영상 화질 값이 변경될 때마다 기본 동영상 화질으로 저장합니다 동영상 화질 값이 변경될 때마다 기본 동영상 화질으로 저장하지 않습니다 동영상 화질 변경 메시지 표시하기 - 기본 동영상 화질 값이 변경되었을 때, 팝업 메시지를 표시합니다 - 기본 동영상 화질 값이 변경되었을 때, 팝업 메시지를 표시하지 않습니다 + 기본 동영상 화질 값이 변경될 때마다 팝업 메시지를 표시합니다 + 기본 동영상 화질 값이 변경될 때마다 팝업 메시지를 표시하지 않습니다 Wi-Fi 이용 시 기본 동영상 화질 모바일 네트워크 이용 시 기본 동영상 화질 Shorts 화질 저장 활성화하기 @@ -1445,8 +1445,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요" 동영상 재생 속도 값이 변경될 때마다 기본 동영상 재생 속도로 저장합니다 동영상 재생 속도 값이 변경될 때마다 기본 동영상 재생 속도로 저장하지 않습니다 동영상 재생 속도 변경 메시지 표시하기 - 기본 동영상 재생 속도 값이 변경되었을 때, 팝업 메시지를 표시합니다 - 기본 동영상 재생 속도 값이 변경되었을 때, 팝업 메시지를 표시하지 않습니다 + 기본 동영상 재생 속도 값이 변경될 때마다 팝업 메시지를 표시합니다 + 기본 동영상 재생 속도 값이 변경될 때마다 팝업 메시지를 표시하지 않습니다 기본 동영상 재생 속도 기본 동영상 재생 속도 값을 %s 로 변경하였습니다 diff --git a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml index 7947cc62f..e045f9984 100644 --- a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml +++ b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml @@ -127,9 +127,9 @@ Men om du aktiverar detta kommer även vissa användardata, t.ex. din IP-adress, Felsökningsloggar inkluderar stackspår Felsökningsloggar inkluderar inte stackspår Visa ett meddelande om ett fel uppstår med ReVanced - Toast visas om fel uppstår - Toast visas inte om fel uppstår - "Att stänga av felmeddelanden döljer alla ReVanced-felmeddelanden. + Meddelande visas om fel uppstår + Meddelande visas inte om fel uppstår + "Om du stänger av felmeddelanden döljs alla ReVanced-felmeddelanden. Du kommer inte att bli meddelad om oväntade händelser." Exportera felsökningsloggar @@ -316,8 +316,8 @@ Du kommer inte att bli meddelad om oväntade händelser." Tidsstämpelknappen är dold Tidsstämpelknappen är synlig Dölj förhandsgranskningskommentar - Förhandsgranska kommentaren är dold - Förhandsgranska kommentar är synlig + Förhandsgranskningskommentaren är dold + Förhandsgranskningskommentaren visas Dölj knappen \"Tack\" Tack-knappen är dold Tackknappen är synlig @@ -759,8 +759,8 @@ För att visa ljudspårsmenyn, ändra \"Spoof video streams\" till iOS TV"Platsetiketten är dold Platsetikett är synlig Dölj förhandsgranskningskommentar - Förhandsgranskningskommentar är dold - Förhandsvisningskommentaren visas + Förhandsgranskningskommentaren är dold + Förhandsgranskningskommentaren visas Dölj knapp \'Spara musik\' Spara musikknappen är dold Spara musikknappen visas @@ -901,8 +901,8 @@ Begränsning: Ogillanden kanske inte visas i inkognitoläge" Videor med inaktiverade gillanden visar ett uppskattat antal gillanden Uppskattade gillanden visas inte Visa ett meddelande om API inte är tillgängligt - Visa ett meddelande om Return YouTube Dislike inte är tillgängligt - Visa inget meddelande om Return YouTube Dislike inte är tillgängligt + Meddelande visas om Return YouTube Dislike inte är tillgängligt + Meddelande visas inte om Return YouTube Dislike inte är tillgängligt Data tillhandahålls av Return YouTube Tycker inte om API. Tryck här för att läsa mer ReturnYouTubeDislike API-statistik för denna enhet @@ -942,11 +942,11 @@ Den här funktionen fungerar bäst med en videokvalitet på 720p eller lägre oc Aktivera SponsorBlock - SponsorBlock är ett crowdsourcat system för att hoppa över irriterande delar av YouTube-videor + SponsorBlock är ett crowdsourcing-baserat system för att hoppa över irriterande delar av YouTube-videor Utseende - Visa röstknapp - Segmentets röstknapp är synligt - Segmentets röstknapp visas inte + Visa röstningsknapp + Röstningsknappen för segment visas + Röstningsknappen för segment visas inte Använd fyrkantig layout Knappar och kontroller är fyrkantiga Knappar och kontroller är rundade @@ -954,21 +954,21 @@ Den här funktionen fungerar bäst med en videokvalitet på 720p eller lägre oc Använd kompakt Hoppa över-knapp Skippa knappen stylad för minsta bredd Skippa knappen stylad för bästa utseende - Dölj automatiskt Hoppa över-knappen - Hoppa över knappen döljer efter några sekunder + Dölj Hoppa över-knappen automatiskt + Hoppa över-knappen döljs efter några sekunder Hoppa över-knappen visas för hela segmentet - Visa en toast när du hoppar över - Visa ett meddelande när ett segment hoppas över automatiskt. Tryck här för att se ett exempel + Visa ett meddelande vid överhoppning + Meddelande visas när ett segment hoppas över automatiskt. Tryck här för att se ett exempel Meddelande visas inte. Tryck här för att se ett exempel Visa videons längd utan segment Videolängd minus alla segment, som visas i parentes bredvid den fullständiga videolängden Hela videons längd visas Skapa nya segment Visa knappen Skapa nytt segment - Skapa ny knapp för segmentet visas - Skapa ny segmentknapp visas inte - Justera nytt steg för segment - Antal millisekunder knapparna för tidsjustering rör sig när nya segment skapas + Knappen Skapa nytt segment visas + Knappen Skapa nytt segment visas inte + Justera steg för nytt segment + Antal millisekunder som tidsjusteringsknapparna hoppar framåt/bakåt när nya segment skapas Värdet måste vara ett positivt tal Visa riktlinjer Riktlinjer innehåller regler och tips för att skapa nya segment @@ -978,11 +978,11 @@ Den här funktionen fungerar bäst med en videokvalitet på 720p eller lägre oc Visa mig Allmänt Visa ett meddelande om API inte är tillgängligt - Visa ett meddelande om SponsorBlock inte är tillgängligt - Visa inte ett meddelande inte om SponsorBlock inte är tillgängligt - Aktivera spårning av hoppa över antalet - Låt SponsorBlock leaderboarden veta hur mycket tid som sparas. Ett meddelande skickas till leaderboarden varje gång ett segment hoppas över - Tracking av Skip count är inte aktiverat + Meddelande visas om SponsorBlock inte är tillgängligt + Meddelande visas inte om SponsorBlock inte är tillgängligt + Aktivera spårning av antalet överhoppningar + Låter SponsorBlock-topplistan veta hur mycket tid som sparas. Ett meddelande skickas till topplistan varje gång ett segment hoppas över + Spårning av antalet överhoppningar är inte aktiverat Minsta segmentlängd Segment kortare än detta värde (i sekunder) kommer inte att visas eller hoppas över Ogiltig tidslängd @@ -1007,52 +1007,52 @@ Ditt användar-ID är som ett lösenord och det bör aldrig delas." Visa inte igen Ändra segmentbeteende Sponsor - Betald marknadsföring, betalda hänvisningar och direktannonser. Inte för självmarknadsföring eller gratis rop till orsaker/skapare/hemsidor/produkter som de gillar - Obetald/självbefodran - Liknande sponsor men för obetald eller egen marknadsföring. Inkluderar avsnitt om varor, donationer eller information om vem de samarbetade med - Interaktionspåminnelse (Prenumerera) - En kort påminnelse om att gilla, prenumerera eller följa dem mitt i innehållet. Om den är lång eller om något specifikt, bör den istället vara under självfrämjande + Betald marknadsföring, betalda hänvisningar och direktannonser. Inte för egenreklam eller gratis reklam för saker/kreatörer/webbplatser/produkter som de gillar + Obetald reklam/egenreklam + Som Sponsor men för obetald reklam eller egenreklam. Inkluderar avsnitt om varor, donationer eller information om vem de samarbetade med + Interaktionspåminnelse (prenumerera) + En kort påminnelse om att gilla, prenumerera eller följa dem mitt i innehållet. Om den är lång eller om något specifikt, bör den istället vara under egenreklam Höjdpunkt Den del av videon som de flesta letar efter - Paus/introduktionsanimation + Uppehåll/introanimation Ett intervall utan faktiskt innehåll. Kan vara en paus, statisk ram eller upprepande animation. Inkluderar inte övergångar som innehåller information - Slutkort/krediter - Krediter eller när YouTube slutkort visas. Inte för slutsatser med information - Förhandsgranska/återskapa/krok - Samling av klipp som visar vad som kommer upp eller vad som hände i videon eller i andra videor i en serie, där all information upprepas någon annanstans - Ämnesavvikelse/Skämt - Tangentiella scener läggs endast till för fyllmedel eller humor som inte krävs för att förstå det huvudsakliga innehållet i videon. Inkluderar inte segment som tillhandahåller kontext eller bakgrundsinformation - Musik: Icke-musiksektionen + Slutkort/eftertexter + Eftertexter eller när YouTube-slutkort visas. Inte för slut med information + Förhandstitt/sammanfattning/hook + Samling av klipp som visar vad som kommer eller vad som hände i videon eller i andra videor i en serie, där all information upprepas någon annanstans + Ämnesavvikelse/skämt + Ämnesavvikande scener som endast läggs till som utfyllnad eller för humor som inte krävs för att förstå det huvudsakliga innehållet i videon. Inkluderar inte segment som tillhandahåller kontext eller bakgrundsinformation + Musik: Icke-musiksektion Endast för användning i musikvideor. Sektioner av musikvideor utan musik, som inte redan omfattas av en annan kategori Hoppa Höjdpunkt Hoppa över sponsor - Hoppa över kampanjerbjudande + Hoppa över reklam Hoppa över interagera Hoppa till höjdpunkten Hoppa över intro - Hoppa över paus - Hoppa över paus + Hoppa över uppehåll + Hoppa över uppehåll Hoppa över outro - Hoppa över förhandsgranskning - Hoppa över förhandsgranskning + Hoppa över förhandstitt + Hoppa över förhandstitt Hoppa över sammanfattning Hoppa över fyllmedel Hoppa över icke-musik Hoppa över segment Hoppade över sponsor - Hoppade över självmarknadsföring - Överhoppad irriterande påminnelse + Hoppade över egenreklam + Hoppade över irriterande påminnelse Hoppade till höjdpunkten Hoppade över intro - Överhoppad paus - Överhoppad paus + Hoppade över uppehåll + Hoppade över uppehåll Hoppade över outro - Hoppade över förhandsgranskning - Hoppade över förhandsgranskning - Överhoppad sammanfattning + Hoppade över förhandstitt + Hoppade över förhandstitt + Hoppade över sammanfattning Hoppade över ämnesavvikelse - Hoppade över icke-musik segment + Hoppade över en icke-musiksektion Hoppade över oinskickat segment Hoppade över flera segment Hoppa över automatiskt @@ -1251,9 +1251,9 @@ Minispelare kan dras av skärmen till vänster eller höger" Dölj undertexter Undertexter är dolda Undertexter visas - Dölj hoppa över framåt- och bakknapparna - Hoppa framåt och tillbaka är dolda - Hoppa framåt och tillbaka visas + Dölj knapparna för att hoppa framåt och bakåt + Hoppa framåt och bakåt är dolda + Hoppa framåt och bakåt visas Ursprunglig storlek Inledande på skärmstorlek, i pixlar Pixelstorlek måste vara mellan %1$s och %2$s @@ -1303,8 +1303,8 @@ Om detta är aktiverat skickas video-URL:er till API-servern och inga andra data Klicka här för att lära dig mer om DeArrow" Visa ett meddelande om API inte är tillgängligt - Visa ett meddelande om DeArrow inte är tillgängligt - Visa inte ett meddelande om DeArrow inte är tillgängligt + Meddelande visas om DeArrow inte är tillgängligt + Meddelande visas inte om DeArrow inte är tillgängligt DeArrow API-slutpunkt URL till DeArrow miniatyrbilds slutpunkt Fortfarande videoinspelningar @@ -1437,7 +1437,7 @@ Att aktivera detta kan låsa upp högre videokvalitet" Ändring av uppspelningshastighet gäller endast för den aktuella videon Visa meddelande vid ändringar av uppspelningshastighet Ett meddelande visas när standarduppspelningshastigheten ändras - En toast visas inte när standarduppspelningshastigheten ändras + Ett meddelande visas inte när standarduppspelningshastigheten ändras Standarduppspelningshastighet Ändrade standardhastigheten till: %s diff --git a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml index 9a3619b28..c38ec5c48 100644 --- a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml +++ b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml @@ -21,7 +21,7 @@ Second \"item\" text" - Kontroller başarısız + Denetimler başarısız Resmî web sitesini aç Yok say <h5>Bu uygulama sizin tarafınızdan yamalanmış gibi görünmüyor.</h5><br>Bu uygulama düzgün çalışmayabilir, <b>kullanması zararlı veya tehlikeli bile olabilir</b>.<br><br>Şu kontroller, bu uygulamanın hali hazırda yamalanmış olduğunu veya başka birinden edinildiğini gösteriyor:<br><br><small>%1$s</small><br>Doğrulanmış ve güvenli bir uygulama kullandığınızdan emin olmak için, <b>bu uygulamayı kaldırmanız ve kendiniz yamalamanız</b> şiddetle tavsiye edilir.<p><br>Bu uyarı yok sayıldığında sadece iki kez gösterilecektir. diff --git a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml index a5588df9e..e288acd6c 100644 --- a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml +++ b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml @@ -100,7 +100,7 @@ Nhấn nút tiếp tục và cho phép thay đổi lựa chọn tối ưu hóa." Khôi phục trình đơn cài đặt cũ Các trình đơn cài đặt cũ được hiển thị Các trình đơn cài đặt cũ không được hiển thị - Hiển thị lịch sử tìm kiếm trong cài đặt + Hiện lịch sử tìm kiếm trong cài đặt Đã hiển thị lịch sử tìm kiếm trong cài đặt Không hiển thị lịch sử tìm kiếm trong phần cài đặt @@ -414,9 +414,9 @@ Tính năng này chỉ khả dụng trên các thiết bị cũ" Ẩn QC toàn màn hình chỉ hoạt động trên thiết bị cũ - Ẩn quảng cáo khuyến mãi YouTube Premium - Quảng cáo Youtube Premium bên dưới trình phát video đã bị ẩn - Quảng cáo Youtube Premium bên dưới trình phát video được hiển thị + Ẩn quảng cáo YouTube Premium + Quảng cáo khuyến mãi Youtube Premium bên dưới trình phát video đã bị ẩn + Quảng cáo khuyến mãi Youtube Premium bên dưới trình phát video được hiển thị Ẩn quảng cáo trên video diff --git a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml index 27e30598e..7d7334493 100644 --- a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml @@ -1210,6 +1210,8 @@ Second \"item\" text" 啟用漸層載入畫面 載入畫面將具有漸層背景 載入畫面將具有純色背景 + 顏色 + 黑白 啟用自訂跳轉列顏色 已顯示自訂跳轉列顏色 已顯示原版跳轉列顏色 From b6bf1e026cf72813a8c9fd63620a8b1b0834f488 Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:03:02 +0530 Subject: [PATCH 04/33] fix(YouTube - Hide Shorts components): Fix hiding of untoggled components (#5266) --- .../patches/components/ShortsFilter.java | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java index 73b144b52..f38959a19 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java @@ -44,6 +44,8 @@ public final class ShortsFilter extends Filter { private final ByteArrayFilterGroup shortsCompactFeedVideoBuffer; private final StringFilterGroup useSoundButton; private final ByteArrayFilterGroup useSoundButtonBuffer; + private final StringFilterGroup useTemplateButton; + private final ByteArrayFilterGroup useTemplateButtonBuffer; private final StringFilterGroup subscribeButton; private final StringFilterGroup joinButton; @@ -178,7 +180,10 @@ public final class ShortsFilter extends Filter { useSoundButton = new StringFilterGroup( Settings.HIDE_SHORTS_USE_SOUND_BUTTON, + // First filter needed for "Use this sound" that can appear when viewing Shorts + // through the "Short remixing this video" section. "floating_action_button.eml", + // Second filter needed for "Use this sound" that can appear below the video title. REEL_METAPANEL_PATH ); @@ -187,6 +192,17 @@ public final class ShortsFilter extends Filter { "yt_outline_camera_" ); + useTemplateButton = new StringFilterGroup( + Settings.HIDE_SHORTS_USE_TEMPLATE_BUTTON, + // Second filter needed for "Use this template" that can appear below the video title. + REEL_METAPANEL_PATH + ); + + useTemplateButtonBuffer = new ByteArrayFilterGroup( + null, + "yt_outline_template_add_" + ); + videoActionButton = new StringFilterGroup( null, // Can be simply 'button.eml', 'shorts_video_action_button.eml' or 'reel_action_button.eml' @@ -195,8 +211,7 @@ public final class ShortsFilter extends Filter { suggestedAction = new StringFilterGroup( null, - "suggested_action.eml", - REEL_METAPANEL_PATH + "suggested_action.eml" ); addPathCallbacks( @@ -268,6 +283,7 @@ public final class ShortsFilter extends Filter { ), new ByteArrayFilterGroup( Settings.HIDE_SHORTS_USE_TEMPLATE_BUTTON, + // "Use this template" can appear in two different places. "yt_outline_template_add_" ), new ByteArrayFilterGroup( @@ -317,6 +333,10 @@ public final class ShortsFilter extends Filter { return useSoundButtonBuffer.check(protobufBufferArray).isFiltered(); } + if (matchedGroup == useTemplateButton) { + return useTemplateButtonBuffer.check(protobufBufferArray).isFiltered(); + } + if (matchedGroup == shortsCompactFeedVideo) { return shouldHideShortsFeedItems() && shortsCompactFeedVideoBuffer.check(protobufBufferArray).isFiltered(); } @@ -402,17 +422,6 @@ public final class ShortsFilter extends Filter { }; } - /** - * Injection point. Only used if patching older than 19.03. - * This hook may be obsolete even for old versions - * as they now use a litho layout like newer versions. - */ - public static void hideShortsShelf(final View shortsShelfView) { - if (shouldHideShortsFeedItems()) { - Utils.hideViewByLayoutParams(shortsShelfView); - } - } - public static int getSoundButtonSize(int original) { if (Settings.HIDE_SHORTS_SOUND_BUTTON.get()) { return 0; From e169056b70222f7a0c8e2ef307d0d839c1805158 Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:03:21 +0530 Subject: [PATCH 05/33] fix(YouTube - Hide ads): Fix "Hide shopping links" (#5267) --- .../extension/youtube/patches/components/AdsFilter.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java index 8c7669ad6..51903793c 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java @@ -116,18 +116,17 @@ public final class AdsFilter extends Filter { shoppingLinks = new StringFilterGroup( Settings.HIDE_SHOPPING_LINKS, - "expandable_list" + "expandable_list", + "shopping_description_shelf.eml" ); playerShoppingShelf = new StringFilterGroup( Settings.HIDE_PLAYER_STORE_SHELF, - "expandable_list.eml", "horizontal_shelf.eml" ); playerShoppingShelfBuffer = new ByteArrayFilterGroup( null, - "shopping_link_item", "shopping_item_card_list" ); From ca694c78d2f7d93f8e5c4b1621d27bd06ab50cdd Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:03:37 +0530 Subject: [PATCH 06/33] fix(YouTube - Hide layout components): Fix "Hide AI-generated video summary" in video description (#5269) --- .../components/DescriptionComponentsFilter.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/DescriptionComponentsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/DescriptionComponentsFilter.java index 8c402b78d..873fc9a96 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/DescriptionComponentsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/DescriptionComponentsFilter.java @@ -4,6 +4,7 @@ import androidx.annotation.Nullable; import app.revanced.extension.youtube.StringTrieSearch; import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.shared.PlayerType; @SuppressWarnings("unused") final class DescriptionComponentsFilter extends Filter { @@ -17,6 +18,8 @@ final class DescriptionComponentsFilter extends Filter { private final StringFilterGroup horizontalShelf; private final ByteArrayFilterGroup cellVideoAttribute; + private final StringFilterGroup aiGeneratedVideoSummarySection; + public DescriptionComponentsFilter() { exceptions.addPatterns( "compact_channel", @@ -26,7 +29,7 @@ final class DescriptionComponentsFilter extends Filter { "metadata" ); - final StringFilterGroup aiGeneratedVideoSummarySection = new StringFilterGroup( + aiGeneratedVideoSummarySection = new StringFilterGroup( Settings.HIDE_AI_GENERATED_VIDEO_SUMMARY_SECTION, "cell_expandable_metadata.eml" ); @@ -104,6 +107,12 @@ final class DescriptionComponentsFilter extends Filter { @Override boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray, StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) { + + if (matchedGroup == aiGeneratedVideoSummarySection) { + // Only hide if player is open, in case this component is used somewhere else. + return PlayerType.getCurrent().isMaximizedOrFullscreen(); + } + if (exceptions.matches(path)) return false; if (matchedGroup == macroMarkersCarousel) { From da20e565cda0871f693fef5485431b4bb1618e81 Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:03:53 +0530 Subject: [PATCH 07/33] feat(YouTube - Hide layout components): Add `Hide in history` option to filter bar (#5271) --- .../patches/components/LayoutComponentsFilter.java | 13 ++++++++++++- .../extension/youtube/settings/Settings.java | 1 + .../hide/general/HideLayoutComponentsPatch.kt | 1 + .../main/resources/addresources/values/strings.xml | 11 +++++++---- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java index 347491a46..30244b361 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java @@ -39,6 +39,7 @@ public final class LayoutComponentsFilter extends Filter { private final ByteArrayFilterGroup joinMembershipButton; private final StringFilterGroup horizontalShelves; private final ByteArrayFilterGroup ticketShelf; + private final StringFilterGroup chipBar; public LayoutComponentsFilter() { exceptions.addPatterns( @@ -105,6 +106,11 @@ public final class LayoutComponentsFilter extends Filter { "subscriptions_chip_bar" ); + chipBar = new StringFilterGroup( + Settings.HIDE_FILTER_BAR_FEED_IN_HISTORY, + "chip_bar" + ); + inFeedSurvey = new StringFilterGroup( Settings.HIDE_FEED_SURVEY, "in_feed_survey", @@ -272,6 +278,7 @@ public final class LayoutComponentsFilter extends Filter { emergencyBox, subscribersCommunityGuidelines, subscriptionsChipBar, + chipBar, channelGuidelines, audioTrackButton, artistCard, @@ -314,6 +321,10 @@ public final class LayoutComponentsFilter extends Filter { return contentIndex == 0 && (hideShelves() || ticketShelf.check(protobufBufferArray).isFiltered()); } + if (matchedGroup == chipBar) { + return contentIndex == 0 && NavigationButton.getSelectedNavigationButton() == NavigationButton.LIBRARY; + } + return true; } @@ -448,7 +459,7 @@ public final class LayoutComponentsFilter extends Filter { } // Do not hide if the navigation back button is visible, - // otherwise the content shelves in the explore/music/courses pages are hidde. + // otherwise the content shelves in the explore/music/courses pages are hidden. if (NavigationBar.isBackButtonVisible()) { return false; } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 8f6e080b0..cdf86fd75 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -98,6 +98,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_EXPANDABLE_CHIP = new BooleanSetting("revanced_hide_expandable_chip", TRUE); public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE); public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_FEED = new BooleanSetting("revanced_hide_filter_bar_feed_in_feed", FALSE, true); + public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_HISTORY = new BooleanSetting("revanced_hide_filter_bar_feed_in_history", FALSE); public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS = new BooleanSetting("revanced_hide_filter_bar_feed_in_related_videos", FALSE, true); public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_SEARCH = new BooleanSetting("revanced_hide_filter_bar_feed_in_search", FALSE, true); public static final BooleanSetting HIDE_FLOATING_MICROPHONE_BUTTON = new BooleanSetting("revanced_hide_floating_microphone_button", TRUE, true); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt index 711d5af3e..34925d565 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt @@ -201,6 +201,7 @@ val hideLayoutComponentsPatch = bytecodePatch( key = "revanced_hide_filter_bar_screen", preferences = setOf( SwitchPreference("revanced_hide_filter_bar_feed_in_feed"), + SwitchPreference("revanced_hide_filter_bar_feed_in_history"), SwitchPreference("revanced_hide_filter_bar_feed_in_search"), SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"), ), diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index f5418f8f2..f72851cd4 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -344,10 +344,13 @@ You will not be notified of any unexpected events." Hide or show video description components Filter bar - Hide or show the filter bar in the feed, search results, and related videos - Hide in feed - Hidden in feed - Shown in feed + Hide or show the filter bar in the feeds, history, search results, and related videos + Hide in feeds + Hidden in feeds + Shown in feeds + Hide in history + Hidden in history + Shown in history Hide in search results Hidden in search results Shown in search results From 92b588c866ed94d5d74d55aeb60cd44736be33c0 Mon Sep 17 00:00:00 2001 From: brosssh <44944126+brosssh@users.noreply.github.com> Date: Fri, 27 Jun 2025 13:34:13 +0200 Subject: [PATCH 08/33] feat(Spotify): Remove ads section from browse (#5193) --- .../spotify/browsita/v1/resolved/Section.java | 6 +++++ .../patches/spotify/misc/Fingerprints.kt | 22 ++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 extensions/spotify/stub/src/main/java/com/spotify/browsita/v1/resolved/Section.java diff --git a/extensions/spotify/stub/src/main/java/com/spotify/browsita/v1/resolved/Section.java b/extensions/spotify/stub/src/main/java/com/spotify/browsita/v1/resolved/Section.java new file mode 100644 index 000000000..af3fd9aa3 --- /dev/null +++ b/extensions/spotify/stub/src/main/java/com/spotify/browsita/v1/resolved/Section.java @@ -0,0 +1,6 @@ +package com.spotify.browsita.v1.resolved; + +public final class Section { + public static final int BRAND_ADS_FIELD_NUMBER = 6; + public int sectionTypeCase_; +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt index a797763a0..3ac589fc8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt @@ -93,18 +93,28 @@ internal val abstractProtobufListEnsureIsMutableFingerprint = fingerprint { } } -internal val homeSectionFingerprint = fingerprint { - custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") } -} - -internal val homeStructureGetSectionsFingerprint = fingerprint { +private fun structureGetSectionsFingerprint(className: String) = fingerprint { custom { method, classDef -> - classDef.endsWith("homeapi/proto/HomeStructure;") && method.indexOfFirstInstruction { + classDef.endsWith(className) && method.indexOfFirstInstruction { opcode == Opcode.IGET_OBJECT && getReference()?.name == "sections_" } >= 0 } } +internal val homeSectionFingerprint = fingerprint { + custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") } +} + +internal val homeStructureGetSectionsFingerprint = + structureGetSectionsFingerprint("homeapi/proto/HomeStructure;") + +internal val browseSectionFingerprint = fingerprint { + custom { _, classDef -> classDef.endsWith("browsita/v1/resolved/Section;") } +} + +internal val browseStructureGetSectionsFingerprint = + structureGetSectionsFingerprint("browsita/v1/resolved/BrowseStructure;") + internal fun reactivexFunctionApplyWithClassInitFingerprint(className: String) = fingerprint { returns("Ljava/lang/Object;") parameters("Ljava/lang/Object;") From 5dba77612bb4f53d6a78f8e72a5c7e0467563ad5 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 27 Jun 2025 11:38:02 +0000 Subject: [PATCH 09/33] chore: Release v5.30.0-dev.1 [skip ci] # [5.30.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.29.1-dev.1...v5.30.0-dev.1) (2025-06-27) ### Bug Fixes * **YouTube - Hide ads:** Fix "Hide shopping links" ([#5267](https://github.com/ReVanced/revanced-patches/issues/5267)) ([e169056](https://github.com/ReVanced/revanced-patches/commit/e169056b70222f7a0c8e2ef307d0d839c1805158)) * **YouTube - Hide layout components:** Fix "Hide AI-generated video summary" in video description ([#5269](https://github.com/ReVanced/revanced-patches/issues/5269)) ([ca694c7](https://github.com/ReVanced/revanced-patches/commit/ca694c78d2f7d93f8e5c4b1621d27bd06ab50cdd)) * **YouTube - Hide Shorts components:** Fix hiding of untoggled components ([#5266](https://github.com/ReVanced/revanced-patches/issues/5266)) ([b6bf1e0](https://github.com/ReVanced/revanced-patches/commit/b6bf1e026cf72813a8c9fd63620a8b1b0834f488)) ### Features * **Spotify:** Remove ads section from browse ([#5193](https://github.com/ReVanced/revanced-patches/issues/5193)) ([92b588c](https://github.com/ReVanced/revanced-patches/commit/92b588c866ed94d5d74d55aeb60cd44736be33c0)) * **YouTube - Hide layout components:** Add `Hide in history` option to filter bar ([#5271](https://github.com/ReVanced/revanced-patches/issues/5271)) ([da20e56](https://github.com/ReVanced/revanced-patches/commit/da20e565cda0871f693fef5485431b4bb1618e81)) --- CHANGELOG.md | 15 +++++++++++++++ gradle.properties | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae7400c73..e92c43759 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +# [5.30.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.29.1-dev.1...v5.30.0-dev.1) (2025-06-27) + + +### Bug Fixes + +* **YouTube - Hide ads:** Fix "Hide shopping links" ([#5267](https://github.com/ReVanced/revanced-patches/issues/5267)) ([2fe4607](https://github.com/ReVanced/revanced-patches/commit/2fe46079d78ab98076d3a4cdf01c8bfdbdea45c0)) +* **YouTube - Hide layout components:** Fix "Hide AI-generated video summary" in video description ([#5269](https://github.com/ReVanced/revanced-patches/issues/5269)) ([5203da0](https://github.com/ReVanced/revanced-patches/commit/5203da0ae58e467657bc915ab0af5b9904c4f492)) +* **YouTube - Hide Shorts components:** Fix hiding of untoggled components ([#5266](https://github.com/ReVanced/revanced-patches/issues/5266)) ([008e192](https://github.com/ReVanced/revanced-patches/commit/008e192779a8658e894d5718baa732717bf96e40)) + + +### Features + +* **Spotify:** Remove ads section from browse ([#5193](https://github.com/ReVanced/revanced-patches/issues/5193)) ([ebd4dcc](https://github.com/ReVanced/revanced-patches/commit/ebd4dccf12a5fbd31d2d53c19a792c389a4641d7)) +* **YouTube - Hide layout components:** Add `Hide in history` option to filter bar ([#5271](https://github.com/ReVanced/revanced-patches/issues/5271)) ([ba242a3](https://github.com/ReVanced/revanced-patches/commit/ba242a36b040b82e84870e5e240734637125a472)) + ## [5.29.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.29.0...v5.29.1-dev.1) (2025-06-26) diff --git a/gradle.properties b/gradle.properties index d0c6652ab..48f63feb8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.29.1-dev.1 +version = 5.30.0-dev.1 From 69600d08a487a88ae33ba314e2109de962a9365e Mon Sep 17 00:00:00 2001 From: brosssh <44944126+brosssh@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:03:07 +0200 Subject: [PATCH 10/33] fix(Spotify - Spoof client patch): Block sending bad integrity verdicts to potentially fix account suspensions (#5274) Co-authored-by: oSumAtrIX --- .../app/revanced/patches/spotify/misc/fix/Fingerprints.kt | 8 ++++++++ .../revanced/patches/spotify/misc/fix/SpoofClientPatch.kt | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt index f1600861a..dff859cfb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt @@ -19,3 +19,11 @@ internal val startupPageLayoutInflateFingerprint = fingerprint { parameters("Landroid/view/LayoutInflater;", "Landroid/view/ViewGroup;", "Landroid/os/Bundle;") strings("blueprintContainer", "gradient", "valuePropositionTextView") } + +internal val standardIntegrityTokenProviderBuilderFingerprint = fingerprint { + strings( + "standard_pi_init", + "outcome", + "success" + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt index 70339813d..e34bcebaa 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt @@ -12,6 +12,7 @@ import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch import app.revanced.util.findInstructionIndicesReversedOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import app.revanced.util.returnEarly import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference @@ -118,5 +119,8 @@ val spoofClientPatch = bytecodePatch( """ ) } + + // Early return to block sending bad verdicts to the API. + standardIntegrityTokenProviderBuilderFingerprint.method.returnEarly() } } From 9131c50f1b36bab5a23bda35589f0780dd211053 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 27 Jun 2025 14:07:00 +0000 Subject: [PATCH 11/33] chore: Release v5.30.0-dev.2 [skip ci] # [5.30.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.1...v5.30.0-dev.2) (2025-06-27) ### Bug Fixes * **Spotify - Spoof client patch:** Block sending bad integrity verdicts to potentially fix account suspensions ([#5274](https://github.com/ReVanced/revanced-patches/issues/5274)) ([69600d0](https://github.com/ReVanced/revanced-patches/commit/69600d08a487a88ae33ba314e2109de962a9365e)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e92c43759..fd6f70c6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.1...v5.30.0-dev.2) (2025-06-27) + + +### Bug Fixes + +* **Spotify - Spoof client patch:** Block sending bad integrity verdicts to potentially fix account suspensions ([#5274](https://github.com/ReVanced/revanced-patches/issues/5274)) ([f7b574c](https://github.com/ReVanced/revanced-patches/commit/f7b574ca79c5a616cfe33a3fc75bd8cf68571f7d)) + # [5.30.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.29.1-dev.1...v5.30.0-dev.1) (2025-06-27) diff --git a/gradle.properties b/gradle.properties index 48f63feb8..8d61c9b4e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.1 +version = 5.30.0-dev.2 From ed617094eacc966a97f1dc5220820aa424a2bc4a Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 28 Jun 2025 11:51:29 +0400 Subject: [PATCH 12/33] refactor(YouTube - Litho): Use a simpler hook that does not require using a thread local (#5281) --- .../patches/components/LithoFilterPatch.java | 61 +++---- .../youtube/misc/litho/filter/Fingerprints.kt | 18 +-- .../misc/litho/filter/LithoFilterPatch.kt | 150 +++++++----------- 3 files changed, 88 insertions(+), 141 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LithoFilterPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LithoFilterPatch.java index 09117f040..4f9e4ef32 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LithoFilterPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LithoFilterPatch.java @@ -48,7 +48,7 @@ public final class LithoFilterPatch { /** * Search through a byte array for all ASCII strings. */ - private static void findAsciiStrings(StringBuilder builder, byte[] buffer) { + static void findAsciiStrings(StringBuilder builder, byte[] buffer) { // Valid ASCII values (ignore control characters). final int minimumAscii = 32; // 32 = space character final int maximumAscii = 126; // 127 = delete character @@ -96,7 +96,7 @@ public final class LithoFilterPatch { private static final class DummyFilter extends Filter { } private static final Filter[] filters = new Filter[] { - new DummyFilter() // Replaced by patch. + new DummyFilter() // Replaced patching, do not touch. }; private static final StringTrieSearch pathSearchTree = new StringTrieSearch(); @@ -108,11 +108,7 @@ public final class LithoFilterPatch { * Because litho filtering is multi-threaded and the buffer is passed in from a different injection point, * the buffer is saved to a ThreadLocal so each calling thread does not interfere with other threads. */ - private static final ThreadLocal bufferThreadLocal = new ThreadLocal<>(); - /** - * Results of calling {@link #filter(String, StringBuilder)}. - */ - private static final ThreadLocal filterResult = new ThreadLocal<>(); + private static final ThreadLocal bufferThreadLocal = new ThreadLocal<>(); static { for (Filter filter : filters) { @@ -168,57 +164,50 @@ public final class LithoFilterPatch { /** * Injection point. Called off the main thread. */ - @SuppressWarnings("unused") - public static void setProtoBuffer(@Nullable ByteBuffer protobufBuffer) { + public static void setProtoBuffer(byte[] buffer) { // Set the buffer to a thread local. The buffer will remain in memory, even after the call to #filter completes. // This is intentional, as it appears the buffer can be set once and then filtered multiple times. // The buffer will be cleared from memory after a new buffer is set by the same thread, // or when the calling thread eventually dies. - if (protobufBuffer == null) { + bufferThreadLocal.set(buffer); + } + + /** + * Injection point. Called off the main thread. + * Targets 20.21 and lower. + */ + public static void setProtoBuffer(@Nullable ByteBuffer buffer) { + // Set the buffer to a thread local. The buffer will remain in memory, even after the call to #filter completes. + // This is intentional, as it appears the buffer can be set once and then filtered multiple times. + // The buffer will be cleared from memory after a new buffer is set by the same thread, + // or when the calling thread eventually dies. + if (buffer == null || !buffer.hasArray()) { // It appears the buffer can be cleared out just before the call to #filter() // Ignore this null value and retain the last buffer that was set. - Logger.printDebug(() -> "Ignoring null protobuffer"); + Logger.printDebug(() -> "Ignoring null or empty buffer: " + buffer); } else { - bufferThreadLocal.set(protobufBuffer); + setProtoBuffer(buffer.array()); } } /** * Injection point. */ - public static boolean shouldFilter() { - Boolean shouldFilter = filterResult.get(); - return shouldFilter != null && shouldFilter; - } - - /** - * Injection point. Called off the main thread, and commonly called by multiple threads at the same time. - */ - public static void filter(@Nullable String lithoIdentifier, StringBuilder pathBuilder) { - filterResult.set(handleFiltering(lithoIdentifier, pathBuilder)); - } - - private static boolean handleFiltering(@Nullable String lithoIdentifier, StringBuilder pathBuilder) { + public static boolean shouldFilter(@Nullable String lithoIdentifier, StringBuilder pathBuilder) { try { if (pathBuilder.length() == 0) { return false; } - ByteBuffer protobufBuffer = bufferThreadLocal.get(); - final byte[] bufferArray; + byte[] buffer = bufferThreadLocal.get(); // Potentially the buffer may have been null or never set up until now. // Use an empty buffer so the litho id/path filters still work correctly. - if (protobufBuffer == null) { - bufferArray = EMPTY_BYTE_ARRAY; - } else if (!protobufBuffer.hasArray()) { - Logger.printDebug(() -> "Proto buffer does not have an array, using an empty buffer array"); - bufferArray = EMPTY_BYTE_ARRAY; - } else { - bufferArray = protobufBuffer.array(); + if (buffer == null) { + buffer = EMPTY_BYTE_ARRAY; } - LithoFilterParameters parameter = new LithoFilterParameters(lithoIdentifier, - pathBuilder.toString(), bufferArray); + LithoFilterParameters parameter = new LithoFilterParameters( + lithoIdentifier, pathBuilder.toString(), buffer); Logger.printDebug(() -> "Searching " + parameter); if (parameter.identifier != null && identifierSearchTree.matches(parameter.identifier, parameter)) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt index 8ef0161d1..497bd3c89 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt @@ -7,26 +7,18 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode internal val componentContextParserFingerprint = fingerprint { - strings( - "TreeNode result must be set.", - // String is a partial match and changed slightly in 20.03+ - "it was removed due to duplicate converter bindings." - ) + strings("Number of bits must be positive") } -/** - * Resolves to the class found in [componentContextParserFingerprint]. - * When patching 19.16 this fingerprint matches the same method as [componentContextParserFingerprint]. - */ -internal val componentContextSubParserFingerprint = fingerprint { +internal val componentCreateFingerprint = fingerprint { strings( - "Number of bits must be positive" + "Element missing correct type extension", + "Element missing type" ) } internal val lithoFilterFingerprint = fingerprint { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) - returns("V") custom { _, classDef -> classDef.endsWith("/LithoFilterPatch;") } @@ -58,7 +50,7 @@ internal val lithoThreadExecutorFingerprint = fingerprint { parameters("I", "I", "I") custom { method, classDef -> classDef.superclass == "Ljava/util/concurrent/ThreadPoolExecutor;" && - method.containsLiteralInstruction(1L) // 1L = default thread timeout. + method.containsLiteralInstruction(1L) // 1L = default thread timeout. } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt index bc17028f2..90fcbef8f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt @@ -9,13 +9,13 @@ import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch +import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_05_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.shared.conversionContextFingerprintToString import app.revanced.util.addInstructionsAtControlFlowLabel import app.revanced.util.findFreeRegister -import app.revanced.util.findInstructionIndicesReversedOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow @@ -24,7 +24,6 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.reference.MethodReference lateinit var addLithoFilter: (String) -> Unit private set @@ -66,17 +65,11 @@ val lithoFilterPatch = bytecodePatch( * } * } * - * class ComponentContextParser { - * public Component parseComponent() { + * class CreateComponentClass { + * public Component createComponent() { * ... * - * // Checks if the component should be filtered. - * // Sets a thread local with the filtering result. - * extensionClass.filter(identifier, pathBuilder); // Inserted by this patch. - * - * ... - * - * if (extensionClass.shouldFilter()) { // Inserted by this patch. + * if (extensionClass.shouldFilter(identifier, path)) { // Inserted by this patch. * return emptyComponent; * } * return originalUnpatchedComponent; // Original code. @@ -116,95 +109,68 @@ val lithoFilterPatch = bytecodePatch( // Allow the method to run to completion, and override the // return value with an empty component if it should be filtered. // It is important to allow the original code to always run to completion, - // otherwise memory leaks and poor app performance can occur. - // - // The extension filtering result needs to be saved off somewhere, but cannot - // save to a class field since the target class is called by multiple threads. - // It would be great if there was a way to change the register count of the - // method implementation and save the result to a high register to later use - // in the method, but there is no simple way to do that. - // Instead save the extension filter result to a thread local and check the - // filtering result at each method return index. - // String field for the litho identifier. - componentContextParserFingerprint.method.apply { - val conversionContextClass = conversionContextFingerprintToString.originalClassDef + // otherwise high memory usage and poor app performance can occur. - val conversionContextIdentifierField = componentContextSubParserFingerprint.match( - componentContextParserFingerprint.originalClassDef - ).let { - // Identifier field is loaded just before the string declaration. - val index = it.method.indexOfFirstInstructionReversedOrThrow( - it.stringMatches!!.first().index - ) { - val reference = getReference() - reference?.definingClass == conversionContextClass.type - && reference.type == "Ljava/lang/String;" - } - it.method.getInstruction(index).getReference() + // Find the identifier/path fields of the conversion context. + val conversionContextIdentifierField = componentContextParserFingerprint.let { + // Identifier field is loaded just before the string declaration. + val index = it.method.indexOfFirstInstructionReversedOrThrow( + it.stringMatches!!.first().index + ) { + val reference = getReference() + reference?.definingClass == conversionContextFingerprintToString.originalClassDef.type + && reference.type == "Ljava/lang/String;" } - // StringBuilder field for the litho path. - val conversionContextPathBuilderField = conversionContextClass.fields - .single { field -> field.type == "Ljava/lang/StringBuilder;" } + it.method.getInstruction(index).getReference()!! + } - val conversionContextResultIndex = indexOfFirstInstructionOrThrow { - val reference = getReference() - reference?.returnType == conversionContextClass.type - } + 1 + val conversionContextPathBuilderField = conversionContextFingerprintToString.originalClassDef + .fields.single { field -> field.type == "Ljava/lang/StringBuilder;" } - val conversionContextResultRegister = getInstruction( - conversionContextResultIndex - ).registerA - - val identifierRegister = findFreeRegister( - conversionContextResultIndex, conversionContextResultRegister - ) - val stringBuilderRegister = findFreeRegister( - conversionContextResultIndex, conversionContextResultRegister, identifierRegister - ) - - // Check if the component should be filtered, and save the result to a thread local. - addInstructionsAtControlFlowLabel( - conversionContextResultIndex + 1, - """ - iget-object v$identifierRegister, v$conversionContextResultRegister, $conversionContextIdentifierField - iget-object v$stringBuilderRegister, v$conversionContextResultRegister, $conversionContextPathBuilderField - invoke-static { v$identifierRegister, v$stringBuilderRegister }, $EXTENSION_CLASS_DESCRIPTOR->filter(Ljava/lang/String;Ljava/lang/StringBuilder;)V - """ - ) - - // Get the only static method in the class. - val builderMethodDescriptor = emptyComponentFingerprint.classDef.methods.single { + // Find class and methods to create an empty component. + val builderMethodDescriptor = emptyComponentFingerprint.classDef.methods.single { + // The only static method in the class. method -> AccessFlags.STATIC.isSet(method.accessFlags) - } - // Only one field. - val emptyComponentField = classBy { classDef -> - classDef.type == builderMethodDescriptor.returnType - }!!.immutableClass.fields.single() + } + val emptyComponentField = classBy { + // Only one field that matches. + it.type == builderMethodDescriptor.returnType + }!!.immutableClass.fields.single() - // Check at each return value if the component is filtered, - // and return an empty component if filtering is needed. - findInstructionIndicesReversedOrThrow(Opcode.RETURN_OBJECT).forEach { returnIndex -> - val freeRegister = findFreeRegister(returnIndex) - - addInstructionsAtControlFlowLabel( - returnIndex, - """ - invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->shouldFilter()Z - move-result v$freeRegister - if-eqz v$freeRegister, :unfiltered - - move-object/from16 v$freeRegister, p1 - invoke-static { v$freeRegister }, $builderMethodDescriptor - move-result-object v$freeRegister - iget-object v$freeRegister, v$freeRegister, $emptyComponentField - return-object v$freeRegister - - :unfiltered - nop - """ - ) + componentCreateFingerprint.method.apply { + val insertIndex = if (is_19_17_or_greater) { + indexOfFirstInstructionOrThrow(Opcode.RETURN_OBJECT) + } else { + // 19.16 clobbers p2 so must check at start of the method and not at the return index. + 0 } + + val freeRegister = findFreeRegister(insertIndex) + val identifierRegister = findFreeRegister(insertIndex, freeRegister) + val pathRegister = findFreeRegister(insertIndex, freeRegister, identifierRegister) + + addInstructionsAtControlFlowLabel( + insertIndex, + """ + move-object/from16 v$freeRegister, p2 + iget-object v$identifierRegister, v$freeRegister, $conversionContextIdentifierField + iget-object v$pathRegister, v$freeRegister, $conversionContextPathBuilderField + invoke-static { v$identifierRegister, v$pathRegister }, $EXTENSION_CLASS_DESCRIPTOR->shouldFilter(Ljava/lang/String;Ljava/lang/StringBuilder;)Z + move-result v$freeRegister + if-eqz v$freeRegister, :unfiltered + + # Return an empty component + move-object/from16 v$freeRegister, p1 + invoke-static { v$freeRegister }, $builderMethodDescriptor + move-result-object v$freeRegister + iget-object v$freeRegister, v$freeRegister, $emptyComponentField + return-object v$freeRegister + + :unfiltered + nop + """ + ) } // endregion From f08474369b2156ec37533d605792d0b5d6b51117 Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Sat, 28 Jun 2025 23:32:03 +0530 Subject: [PATCH 13/33] fix(YouTube - Hide layout components): Fix "Hide AI Comments summary" in Comments (#5284) --- .../extension/youtube/patches/components/CommentsFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/CommentsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/CommentsFilter.java index fa9cc5b7f..ec8b9cabe 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/CommentsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/CommentsFilter.java @@ -52,7 +52,7 @@ final class CommentsFilter extends Filter { filterChipBar = new StringFilterGroup( Settings.HIDE_COMMENTS_AI_SUMMARY, - "filter_chip_bar.eml" + "chip_bar.eml" ); aiCommentsSummary = new ByteArrayFilterGroup( From 21688201afc05e5f1e64597dcfb585300d9786a9 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 28 Jun 2025 18:05:53 +0000 Subject: [PATCH 14/33] chore: Release v5.30.0-dev.3 [skip ci] # [5.30.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.2...v5.30.0-dev.3) (2025-06-28) ### Bug Fixes * **YouTube - Hide layout components:** Fix "Hide AI Comments summary" in Comments ([#5284](https://github.com/ReVanced/revanced-patches/issues/5284)) ([f084743](https://github.com/ReVanced/revanced-patches/commit/f08474369b2156ec37533d605792d0b5d6b51117)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd6f70c6d..fb61c0e8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.2...v5.30.0-dev.3) (2025-06-28) + + +### Bug Fixes + +* **YouTube - Hide layout components:** Fix "Hide AI Comments summary" in Comments ([#5284](https://github.com/ReVanced/revanced-patches/issues/5284)) ([d42370e](https://github.com/ReVanced/revanced-patches/commit/d42370ef71f4608abc64b6ef4a3fb0c5bd5e3eb6)) + # [5.30.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.1...v5.30.0-dev.2) (2025-06-27) diff --git a/gradle.properties b/gradle.properties index 8d61c9b4e..862e96fbd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.2 +version = 5.30.0-dev.3 From 6ee94f8532a073d720f5f2cc6862c78c2e06aee6 Mon Sep 17 00:00:00 2001 From: MarcaD <152095496+MarcaDian@users.noreply.github.com> Date: Mon, 30 Jun 2025 09:50:52 +0300 Subject: [PATCH 15/33] feat(YouTube - SponsorBlock): Add "Undo automatic skip toast" (#5277) Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> --- .../app/revanced/extension/shared/Utils.java | 10 +- .../shared/settings/EnumSetting.java | 15 +- .../extension/shared/settings/Setting.java | 35 +- .../extension/youtube/settings/Settings.java | 6 + .../SegmentPlaybackController.java | 470 +++++++++++++----- .../sponsorblock/SponsorBlockUtils.java | 64 +-- .../sponsorblock/objects/SponsorSegment.java | 38 +- .../sponsorblock/requests/SBRequester.java | 46 +- .../ui/SponsorBlockPreferenceGroup.java | 91 +++- .../ui/SponsorBlockViewController.java | 2 +- .../resources/addresources/values/arrays.xml | 35 +- .../resources/addresources/values/strings.xml | 22 +- 12 files changed, 591 insertions(+), 243 deletions(-) diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java index 36d7f8d97..609d99b0b 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java @@ -311,6 +311,10 @@ public class Utils { return getContext().getResources().getDimension(getResourceIdentifier(resourceIdentifierName, "dimen")); } + public static String[] getResourceStringArray(String resourceIdentifierName) throws Resources.NotFoundException { + return getContext().getResources().getStringArray(getResourceIdentifier(resourceIdentifierName, "array")); + } + public interface MatchFilter { boolean matches(T object); } @@ -579,7 +583,7 @@ public class Utils { Context currentContext = context; if (currentContext == null) { - Logger.printException(() -> "Cannot show toast (context is null): " + messageToToast, null); + Logger.printException(() -> "Cannot show toast (context is null): " + messageToToast); } else { Logger.printDebug(() -> "Showing toast: " + messageToToast); Toast.makeText(currentContext, messageToToast, toastDuration).show(); @@ -809,7 +813,7 @@ public class Utils { // Create content container (message/EditText) inside a ScrollView only if message or editText is provided. ScrollView contentScrollView = null; - LinearLayout contentContainer = null; + LinearLayout contentContainer; if (message != null || editText != null) { contentScrollView = new ScrollView(context); contentScrollView.setVerticalScrollBarEnabled(false); // Disable the vertical scrollbar. @@ -833,7 +837,7 @@ public class Utils { contentScrollView.addView(contentContainer); // Message (if not replaced by EditText). - if (editText == null && message != null) { + if (editText == null) { TextView messageView = new TextView(context); messageView.setText(message); // Supports Spanned (HTML). messageView.setTextSize(16); diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/EnumSetting.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/EnumSetting.java index 60972f0f5..88de4029e 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/EnumSetting.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/EnumSetting.java @@ -71,15 +71,20 @@ public class EnumSetting> extends Setting { json.put(importExportKey, value.name().toLowerCase(Locale.ENGLISH)); } - @NonNull - private T getEnumFromString(String enumName) { + /** + * @param enumName Enum name. Casing does not matter. + * @return Enum of this type with the same declared name. + * @throws IllegalArgumentException if the name is not a valid enum of this type. + */ + protected T getEnumFromString(String enumName) { //noinspection ConstantConditions for (Enum value : defaultValue.getClass().getEnumConstants()) { if (value.name().equalsIgnoreCase(enumName)) { - // noinspection unchecked + //noinspection unchecked return (T) value; } } + throw new IllegalArgumentException("Unknown enum value: " + enumName); } @@ -103,7 +108,9 @@ public class EnumSetting> extends Setting { * Availability based on if this setting is currently set to any of the provided types. */ @SafeVarargs - public final Setting.Availability availability(@NonNull T... types) { + public final Setting.Availability availability(T... types) { + Objects.requireNonNull(types); + return () -> { T currentEnumType = get(); for (T enumType : types) { diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/Setting.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/Setting.java index 8294fe423..bbb590558 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/Setting.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/Setting.java @@ -28,16 +28,14 @@ public abstract class Setting { /** * Availability based on a single parent setting being enabled. */ - @NonNull - public static Availability parent(@NonNull BooleanSetting parent) { + public static Availability parent(BooleanSetting parent) { return parent::get; } /** * Availability based on all parents being enabled. */ - @NonNull - public static Availability parentsAll(@NonNull BooleanSetting... parents) { + public static Availability parentsAll(BooleanSetting... parents) { return () -> { for (BooleanSetting parent : parents) { if (!parent.get()) return false; @@ -49,8 +47,7 @@ public abstract class Setting { /** * Availability based on any parent being enabled. */ - @NonNull - public static Availability parentsAny(@NonNull BooleanSetting... parents) { + public static Availability parentsAny(BooleanSetting... parents) { return () -> { for (BooleanSetting parent : parents) { if (parent.get()) return true; @@ -79,7 +76,7 @@ public abstract class Setting { /** * Adds a callback for {@link #importFromJSON(Context, String)} and {@link #exportToJson(Context)}. */ - public static void addImportExportCallback(@NonNull ImportExportCallback callback) { + public static void addImportExportCallback(ImportExportCallback callback) { importExportCallbacks.add(Objects.requireNonNull(callback)); } @@ -100,14 +97,13 @@ public abstract class Setting { public static final SharedPrefCategory preferences = new SharedPrefCategory("revanced_prefs"); @Nullable - public static Setting getSettingFromPath(@NonNull String str) { + public static Setting getSettingFromPath(String str) { return PATH_TO_SETTINGS.get(str); } /** * @return All settings that have been created. */ - @NonNull public static List> allLoadedSettings() { return Collections.unmodifiableList(SETTINGS); } @@ -115,7 +111,6 @@ public abstract class Setting { /** * @return All settings that have been created, sorted by keys. */ - @NonNull private static List> allLoadedSettingsSorted() { Collections.sort(SETTINGS, (Setting o1, Setting o2) -> o1.key.compareTo(o2.key)); return allLoadedSettings(); @@ -124,13 +119,11 @@ public abstract class Setting { /** * The key used to store the value in the shared preferences. */ - @NonNull public final String key; /** * The default value of the setting. */ - @NonNull public final T defaultValue; /** @@ -161,7 +154,6 @@ public abstract class Setting { /** * The value of the setting. */ - @NonNull protected volatile T value; public Setting(String key, T defaultValue) { @@ -199,8 +191,8 @@ public abstract class Setting { * @param userDialogMessage Confirmation message to display, if the user tries to change the setting from the default value. * @param availability Condition that must be true, for this setting to be available to configure. */ - public Setting(@NonNull String key, - @NonNull T defaultValue, + public Setting(String key, + T defaultValue, boolean rebootApp, boolean includeWithImportExport, @Nullable String userDialogMessage, @@ -227,7 +219,7 @@ public abstract class Setting { /** * Migrate a setting value if the path is renamed but otherwise the old and new settings are identical. */ - public static void migrateOldSettingToNew(@NonNull Setting oldSetting, @NonNull Setting newSetting) { + public static void migrateOldSettingToNew(Setting oldSetting, Setting newSetting) { if (oldSetting == newSetting) throw new IllegalArgumentException(); if (!oldSetting.isSetToDefault()) { @@ -243,7 +235,7 @@ public abstract class Setting { * This method will be deleted in the future. */ @SuppressWarnings("rawtypes") - public static void migrateFromOldPreferences(@NonNull SharedPrefCategory oldPrefs, @NonNull Setting setting, String settingKey) { + public static void migrateFromOldPreferences(SharedPrefCategory oldPrefs, Setting setting, String settingKey) { if (!oldPrefs.preferences.contains(settingKey)) { return; // Nothing to do. } @@ -285,7 +277,7 @@ public abstract class Setting { * This intentionally is a static method to deter * accidental usage when {@link #save(Object)} was intended. */ - public static void privateSetValueFromString(@NonNull Setting setting, @NonNull String newValue) { + public static void privateSetValueFromString(Setting setting, String newValue) { setting.setValueFromString(newValue); // Clear the preference value since default is used, to allow changing @@ -299,7 +291,7 @@ public abstract class Setting { /** * Sets the value of {@link #value}, but do not save to {@link #preferences}. */ - protected abstract void setValueFromString(@NonNull String newValue); + protected abstract void setValueFromString(String newValue); /** * Load and set the value of {@link #value}. @@ -309,7 +301,7 @@ public abstract class Setting { /** * Persistently saves the value. */ - public final void save(@NonNull T newValue) { + public final void save(T newValue) { if (value.equals(newValue)) { return; } @@ -406,7 +398,6 @@ public abstract class Setting { json.put(importExportKey, value); } - @NonNull public static String exportToJson(@Nullable Context alertDialogContext) { try { JSONObject json = new JSONObject(); @@ -445,7 +436,7 @@ public abstract class Setting { /** * @return if any settings that require a reboot were changed. */ - public static boolean importFromJSON(@NonNull Context alertDialogContext, @NonNull String settingsJsonString) { + public static boolean importFromJSON(Context alertDialogContext, String settingsJsonString) { try { if (!settingsJsonString.matches("[\\s\\S]*\\{")) { settingsJsonString = '{' + settingsJsonString + '}'; // Restore outer JSON braces diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index cdf86fd75..f0eecb5c9 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -5,6 +5,7 @@ import static java.lang.Boolean.TRUE; import static app.revanced.extension.shared.settings.Setting.Availability; import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew; import static app.revanced.extension.shared.settings.Setting.parent; +import static app.revanced.extension.shared.settings.Setting.parentsAll; import static app.revanced.extension.shared.settings.Setting.parentsAny; import static app.revanced.extension.youtube.patches.ChangeFormFactorPatch.FormFactor; import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.ChangeStartPageTypeAvailability; @@ -22,6 +23,7 @@ import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPa import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability; import static app.revanced.extension.youtube.patches.components.PlayerFlyoutMenuItemsFilter.HideAudioFlyoutMenuAvailability; import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle; +import static app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController.SponsorBlockDuration; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; @@ -381,7 +383,11 @@ public class Settings extends BaseSettings { public static final BooleanSetting SB_SQUARE_LAYOUT = new BooleanSetting("sb_square_layout", FALSE, parent(SB_ENABLED)); public static final BooleanSetting SB_COMPACT_SKIP_BUTTON = new BooleanSetting("sb_compact_skip_button", FALSE, parent(SB_ENABLED)); public static final BooleanSetting SB_AUTO_HIDE_SKIP_BUTTON = new BooleanSetting("sb_auto_hide_skip_button", TRUE, parent(SB_ENABLED)); + public static final EnumSetting SB_AUTO_HIDE_SKIP_BUTTON_DURATION = new EnumSetting<>("sb_auto_hide_skip_button_duration", + SponsorBlockDuration.FOUR_SECONDS, parent(SB_ENABLED)); public static final BooleanSetting SB_TOAST_ON_SKIP = new BooleanSetting("sb_toast_on_skip", TRUE, parent(SB_ENABLED)); + public static final EnumSetting SB_TOAST_ON_SKIP_DURATION = new EnumSetting<>("sb_toast_on_skip_duration", + SponsorBlockDuration.FOUR_SECONDS, parentsAll(SB_ENABLED, SB_TOAST_ON_SKIP)); public static final BooleanSetting SB_TOAST_ON_CONNECTION_ERROR = new BooleanSetting("sb_toast_on_connection_error", TRUE, parent(SB_ENABLED)); public static final BooleanSetting SB_TRACK_SKIP_COUNT = new BooleanSetting("sb_track_skip_count", TRUE, parent(SB_ENABLED)); public static final FloatSetting SB_SEGMENT_MIN_DURATION = new FloatSetting("sb_min_segment_duration", 0F, parent(SB_ENABLED)); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SegmentPlaybackController.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SegmentPlaybackController.java index 22259d571..b279de71b 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SegmentPlaybackController.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SegmentPlaybackController.java @@ -1,16 +1,37 @@ package app.revanced.extension.youtube.sponsorblock; import static app.revanced.extension.shared.StringRef.str; +import static app.revanced.extension.shared.Utils.dipToPixels; +import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; +import android.app.Dialog; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Rect; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.RoundRectShape; import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.util.Range; +import android.view.Gravity; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.view.animation.Animation; +import android.widget.LinearLayout; +import android.widget.TextView; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import java.lang.ref.WeakReference; import java.lang.reflect.Field; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Objects; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; @@ -30,20 +51,37 @@ import app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockViewController * Class is not thread safe. All methods must be called on the main thread unless otherwise specified. */ public class SegmentPlaybackController { + /** - * Length of time to show a skip button for a highlight segment, - * or a regular segment if {@link Settings#SB_AUTO_HIDE_SKIP_BUTTON} is enabled. - * - * Effectively this value is rounded up to the next second. + * Enum for configurable durations (1 to 10 seconds) for skip button and toast display. */ - private static final long DURATION_TO_SHOW_SKIP_BUTTON = 3800; + public enum SponsorBlockDuration { + ONE_SECOND(1), + TWO_SECONDS(2), + THREE_SECONDS(3), + FOUR_SECONDS(4), + FIVE_SECONDS(5), + SIX_SECONDS(6), + SEVEN_SECONDS(7), + EIGHT_SECONDS(8), + NINE_SECONDS(9), + TEN_SECONDS(10); + + /** + * Duration, minus 200ms to adjust for exclusive end time checking in scheduled show/hides. + */ + private final long adjustedDuration; + + SponsorBlockDuration(int seconds) { + adjustedDuration = seconds * 1000L - 200; + } + } /* * Highlight segments have zero length as they are a point in time. * Draw them on screen using a fixed width bar. - * Value is independent of device dpi. */ - private static final int HIGHLIGHT_SEGMENT_DRAW_BAR_WIDTH = 7; + private static final int HIGHLIGHT_SEGMENT_DRAW_BAR_WIDTH = dipToPixels(7); @Nullable private static String currentVideoId; @@ -59,7 +97,7 @@ public class SegmentPlaybackController { /** * Because loading can take time, show the skip to highlight for a few seconds after the segments load. * This is the system time (in milliseconds) to no longer show the initial display skip to highlight. - * Value will be zero if no highlight segment exists, or if the system time to show the highlight has passed. + * Value is zero if no highlight segment exists, or if the system time to show the highlight has passed. */ private static long highlightSegmentInitialShowEndTime; @@ -70,7 +108,7 @@ public class SegmentPlaybackController { private static SponsorSegment segmentCurrentlyPlaying; /** * Currently playing manual skip segment that is scheduled to hide. - * This will always be NULL or equal to {@link #segmentCurrentlyPlaying}. + * This is always NULL or equal to {@link #segmentCurrentlyPlaying}. */ @Nullable private static SponsorSegment scheduledHideSegment; @@ -89,31 +127,71 @@ public class SegmentPlaybackController { */ private static final List hiddenSkipSegmentsForCurrentVideoTime = new ArrayList<>(); + /** + * Current segments that have been auto skipped. + * If field is non null then the range will always contain the current video time. + * Range is used to prevent auto-skipping after undo. + * Android Range object has inclusive end time, unlike {@link SponsorSegment}. + */ + @Nullable + private static Range undoAutoSkipRange; + /** + * Range to undo if the toast is tapped. + * Is always null or identical to the last non null value of {@link #undoAutoSkipRange}. + */ + @Nullable + private static Range undoAutoSkipRangeToast; + /** * System time (in milliseconds) of when to hide the skip button of {@link #segmentCurrentlyPlaying}. * Value is zero if playback is not inside a segment ({@link #segmentCurrentlyPlaying} is null), * or if {@link Settings#SB_AUTO_HIDE_SKIP_BUTTON} is not enabled. */ private static long skipSegmentButtonEndTime; - @Nullable private static String timeWithoutSegments; - private static int sponsorBarAbsoluteLeft; private static int sponsorAbsoluteBarRight; private static int sponsorBarThickness; + @Nullable + private static SponsorSegment lastSegmentSkipped; + private static long lastSegmentSkippedTime; + + @Nullable + private static SponsorSegment toastSegmentSkipped; + private static int toastNumberOfSegmentsSkipped; + + /** + * The last toast dialog showing on screen. + */ + private static WeakReference toastDialogRef = new WeakReference<>(null); + + /** + * @return The adjusted duration to show the skip button, in milliseconds. + */ + private static long getSkipButtonDuration() { + return Settings.SB_AUTO_HIDE_SKIP_BUTTON_DURATION.get().adjustedDuration; + } + + /** + * @return The adjusted duration to show the skipped toast, in milliseconds. + */ + private static long getToastDuration() { + return Settings.SB_TOAST_ON_SKIP_DURATION.get().adjustedDuration; + } + @Nullable static SponsorSegment[] getSegments() { return segments; } - private static void setSegments(@NonNull SponsorSegment[] videoSegments) { + private static void setSegments(SponsorSegment[] videoSegments) { Arrays.sort(videoSegments); segments = videoSegments; calculateTimeWithoutSegments(); - if (SegmentCategory.HIGHLIGHT.behaviour == CategoryBehaviour.SKIP_AUTOMATICALLY + if (SegmentCategory.HIGHLIGHT.behaviour == SKIP_AUTOMATICALLY || SegmentCategory.HIGHLIGHT.behaviour == CategoryBehaviour.MANUAL_SKIP) { for (SponsorSegment segment : videoSegments) { if (segment.category == SegmentCategory.HIGHLIGHT) { @@ -125,7 +203,7 @@ public class SegmentPlaybackController { highlightSegment = null; } - static void addUnsubmittedSegment(@NonNull SponsorSegment segment) { + static void addUnsubmittedSegment(SponsorSegment segment) { Objects.requireNonNull(segment); if (segments == null) { segments = new SponsorSegment[1]; @@ -140,6 +218,7 @@ public class SegmentPlaybackController { if (segments == null || segments.length == 0) { return; } + List replacement = new ArrayList<>(); for (SponsorSegment segment : segments) { if (segment.category != SegmentCategory.UNSUBMITTED) { @@ -156,7 +235,7 @@ public class SegmentPlaybackController { } /** - * Clears all downloaded data. + * Clear all data. */ private static void clearData() { currentVideoId = null; @@ -170,6 +249,8 @@ public class SegmentPlaybackController { skipSegmentButtonEndTime = 0; toastSegmentSkipped = null; toastNumberOfSegmentsSkipped = 0; + undoAutoSkipRange = null; + undoAutoSkipRangeToast = null; hiddenSkipSegmentsForCurrentVideoTime.clear(); } @@ -186,7 +267,7 @@ public class SegmentPlaybackController { SponsorBlockUtils.clearUnsubmittedSegmentTimes(); Logger.printDebug(() -> "Initialized SponsorBlock"); } catch (Exception ex) { - Logger.printException(() -> "Failed to initialize SponsorBlock", ex); + Logger.printException(() -> "initialize failure", ex); } } @@ -203,7 +284,7 @@ public class SegmentPlaybackController { return; } if (PlayerType.getCurrent().isNoneOrHidden()) { - Logger.printDebug(() -> "ignoring Short"); + Logger.printDebug(() -> "Ignoring Short"); return; } if (!Utils.isNetworkConnected()) { @@ -212,7 +293,7 @@ public class SegmentPlaybackController { } currentVideoId = videoId; - Logger.printDebug(() -> "setCurrentVideoId: " + videoId); + Logger.printDebug(() -> "New video ID: " + videoId); Utils.runOnBackgroundThread(() -> { try { @@ -227,42 +308,39 @@ public class SegmentPlaybackController { } /** - * Must be called off main thread + * Must be called off main thread. */ - static void executeDownloadSegments(@NonNull String videoId) { + static void executeDownloadSegments(String videoId) { Objects.requireNonNull(videoId); - try { - SponsorSegment[] segments = SBRequester.getSegments(videoId); - Utils.runOnMainThread(()-> { - if (!videoId.equals(currentVideoId)) { - // user changed videos before get segments network call could complete - Logger.printDebug(() -> "Ignoring segments for prior video: " + videoId); - return; - } - setSegments(segments); + SponsorSegment[] segments = SBRequester.getSegments(videoId); - final long videoTime = VideoInformation.getVideoTime(); - if (highlightSegment != null) { - // If the current video time is before the highlight. - final long timeUntilHighlight = highlightSegment.start - videoTime; - if (timeUntilHighlight > 0) { - if (highlightSegment.shouldAutoSkip()) { - skipSegment(highlightSegment, false); - return; - } - highlightSegmentInitialShowEndTime = System.currentTimeMillis() + Math.min( - (long) (timeUntilHighlight / VideoInformation.getPlaybackSpeed()), - DURATION_TO_SHOW_SKIP_BUTTON); + Utils.runOnMainThread(() -> { + if (!videoId.equals(currentVideoId)) { + // user changed videos before get segments network call could complete + Logger.printDebug(() -> "Ignoring segments for prior video: " + videoId); + return; + } + setSegments(segments); + + final long videoTime = VideoInformation.getVideoTime(); + if (highlightSegment != null) { + // If the current video time is before the highlight. + final long timeUntilHighlight = highlightSegment.start - videoTime; + if (timeUntilHighlight > 0) { + if (highlightSegment.shouldAutoSkip()) { + skipSegment(highlightSegment, false); + return; } + highlightSegmentInitialShowEndTime = System.currentTimeMillis() + Math.min( + (long) (timeUntilHighlight / VideoInformation.getPlaybackSpeed()), + getSkipButtonDuration()); } + } - // check for any skips now, instead of waiting for the next update to setVideoTime() - setVideoTime(videoTime); - }); - } catch (Exception ex) { - Logger.printException(() -> "executeDownloadSegments failure", ex); - } + // check for any skips now, instead of waiting for the next update to setVideoTime() + setVideoTime(videoTime); + }); } /** @@ -273,8 +351,8 @@ public class SegmentPlaybackController { public static void setVideoTime(long millis) { try { if (!Settings.SB_ENABLED.get() - || PlayerType.getCurrent().isNoneOrHidden() // Shorts playback. - || segments == null || segments.length == 0) { + || PlayerType.getCurrent().isNoneOrHidden() // Shorts playback. + || segments == null || segments.length == 0) { return; } Logger.printDebug(() -> "setVideoTime: " + millis); @@ -290,7 +368,7 @@ public class SegmentPlaybackController { // // To debug the stale skip logic, set this to a very large value (5000 or more) // then try manually seeking just before playback reaches a segment skip. - final long speedAdjustedTimeThreshold = (long)(playbackSpeed * 1200); + final long speedAdjustedTimeThreshold = (long) (playbackSpeed * 1200); final long startTimerLookAheadThreshold = millis + speedAdjustedTimeThreshold; SponsorSegment foundSegmentCurrentlyPlaying = null; @@ -298,22 +376,24 @@ public class SegmentPlaybackController { for (final SponsorSegment segment : segments) { if (segment.category.behaviour == CategoryBehaviour.SHOW_IN_SEEKBAR - || segment.category.behaviour == CategoryBehaviour.IGNORE - || segment.category == SegmentCategory.HIGHLIGHT) { + || segment.category.behaviour == CategoryBehaviour.IGNORE + || segment.category == SegmentCategory.HIGHLIGHT) { continue; } if (segment.end <= millis) { - continue; // past this segment + continue; // Past this segment. } + final boolean segmentShouldAutoSkip = shouldAutoSkipAndUndoSkipNotActive(segment, millis); + if (segment.start <= millis) { - // we are in the segment! - if (segment.shouldAutoSkip()) { + // We are in the segment! + if (segmentShouldAutoSkip) { skipSegment(segment, false); - return; // must return, as skipping causes a recursive call back into this method + return; // Must return, as skipping causes a recursive call back into this method. } - // first found segment, or it's an embedded segment and fully inside the outer segment + // First found segment, or it's an embedded segment and fully inside the outer segment. if (foundSegmentCurrentlyPlaying == null || foundSegmentCurrentlyPlaying.containsSegment(segment)) { // If the found segment is not currently displayed, then do not show if the segment is nearly over. // This check prevents the skip button text from rapidly changing when multiple segments end at nearly the same time. @@ -327,25 +407,27 @@ public class SegmentPlaybackController { } } // Keep iterating and looking. There may be an upcoming autoskip, - // or there may be another smaller segment nested inside this segment + // or there may be another smaller segment nested inside this segment. continue; } - // segment is upcoming + // Segment is upcoming. if (startTimerLookAheadThreshold < segment.start) { - break; // segment is not close enough to schedule, and no segments after this are of interest + // Segment is not close enough to schedule, and no segments after this are of interest. + break; } - if (segment.shouldAutoSkip()) { // upcoming autoskip + + if (segmentShouldAutoSkip) { foundUpcomingSegment = segment; - break; // must stop here + break; // Must stop here. } - // upcoming manual skip + // Upcoming manual skip. - // do not schedule upcoming segment, if it is not fully contained inside the current segment + // Do not schedule upcoming segment, if it is not fully contained inside the current segment. if ((foundSegmentCurrentlyPlaying == null || foundSegmentCurrentlyPlaying.containsSegment(segment)) - // use the most inner upcoming segment - && (foundUpcomingSegment == null || foundUpcomingSegment.containsSegment(segment))) { + // Use the most inner upcoming segment. + && (foundUpcomingSegment == null || foundUpcomingSegment.containsSegment(segment))) { // Only schedule, if the segment start time is not near the end time of the current segment. // This check is needed to prevent scheduled hide and show from clashing with each other. @@ -361,8 +443,8 @@ public class SegmentPlaybackController { } if (highlightSegment != null) { - if (millis < DURATION_TO_SHOW_SKIP_BUTTON || (highlightSegmentInitialShowEndTime != 0 - && System.currentTimeMillis() < highlightSegmentInitialShowEndTime)) { + if (millis < getSkipButtonDuration() || (highlightSegmentInitialShowEndTime != 0 + && System.currentTimeMillis() < highlightSegmentInitialShowEndTime)) { SponsorBlockViewController.showSkipHighlightButton(highlightSegment); } else { highlightSegmentInitialShowEndTime = 0; @@ -373,16 +455,17 @@ public class SegmentPlaybackController { if (segmentCurrentlyPlaying != foundSegmentCurrentlyPlaying) { setSegmentCurrentlyPlaying(foundSegmentCurrentlyPlaying); } else if (foundSegmentCurrentlyPlaying != null - && skipSegmentButtonEndTime != 0 && skipSegmentButtonEndTime <= System.currentTimeMillis()) { + && skipSegmentButtonEndTime != 0 + && skipSegmentButtonEndTime <= System.currentTimeMillis()) { Logger.printDebug(() -> "Auto hiding skip button for segment: " + segmentCurrentlyPlaying); skipSegmentButtonEndTime = 0; hiddenSkipSegmentsForCurrentVideoTime.add(foundSegmentCurrentlyPlaying); SponsorBlockViewController.hideSkipSegmentButton(); } - // schedule a hide, only if the segment end is near - final SponsorSegment segmentToHide = - (foundSegmentCurrentlyPlaying != null && foundSegmentCurrentlyPlaying.endIsNear(millis, speedAdjustedTimeThreshold)) + // Schedule a hide, but only if the segment end is near. + final SponsorSegment segmentToHide = (foundSegmentCurrentlyPlaying != null && + foundSegmentCurrentlyPlaying.endIsNear(millis, speedAdjustedTimeThreshold)) ? foundSegmentCurrentlyPlaying : null; @@ -407,7 +490,7 @@ public class SegmentPlaybackController { final long videoTime = VideoInformation.getVideoTime(); if (!segmentToHide.endIsNear(videoTime, speedAdjustedTimeThreshold)) { - // current video time is not what's expected. User paused playback + // Current video time is not what's expected. User paused playback. Logger.printDebug(() -> "Ignoring outdated scheduled hide: " + segmentToHide + " videoInformation time: " + videoTime); return; @@ -416,7 +499,7 @@ public class SegmentPlaybackController { // Need more than just hide the skip button, as this may have been an embedded segment // Instead call back into setVideoTime to check everything again. // Should not use VideoInformation time as it is less accurate, - // but this scheduled handler was scheduled precisely so we can just use the segment end time + // but this scheduled handler was scheduled precisely so we can just use the segment end time. setSegmentCurrentlyPlaying(null); setVideoTime(segmentToHide.end); }, delayUntilHide); @@ -446,12 +529,12 @@ public class SegmentPlaybackController { final long videoTime = VideoInformation.getVideoTime(); if (!segmentToSkip.startIsNear(videoTime, speedAdjustedTimeThreshold)) { - // current video time is not what's expected. User paused playback + // Current video time is not what's expected. User paused playback. Logger.printDebug(() -> "Ignoring outdated scheduled segment: " + segmentToSkip + " videoInformation time: " + videoTime); return; } - if (segmentToSkip.shouldAutoSkip()) { + if (shouldAutoSkipAndUndoSkipNotActive(segmentToSkip, videoTime)) { Logger.printDebug(() -> "Running scheduled skip segment: " + segmentToSkip); skipSegment(segmentToSkip, false); } else { @@ -461,6 +544,12 @@ public class SegmentPlaybackController { }, delayUntilSkip); } } + + // Clear undo range if video time is outside the segment. Must check last. + if (undoAutoSkipRange != null && !undoAutoSkipRange.contains(millis)) { + Logger.printDebug(() -> "Clearing undo range as current time is now outside range: " + undoAutoSkipRange); + undoAutoSkipRange = null; + } } catch (Exception e) { Logger.printException(() -> "setVideoTime failure", e); } @@ -470,14 +559,13 @@ public class SegmentPlaybackController { * Removes all previously hidden segments that are not longer contained in the given video time. */ private static void updateHiddenSegments(long currentVideoTime) { - Iterator i = hiddenSkipSegmentsForCurrentVideoTime.iterator(); - while (i.hasNext()) { - SponsorSegment hiddenSegment = i.next(); + hiddenSkipSegmentsForCurrentVideoTime.removeIf((hiddenSegment) -> { if (!hiddenSegment.containsTime(currentVideoTime)) { Logger.printDebug(() -> "Resetting hide skip button: " + hiddenSegment); - i.remove(); + return true; } - } + return false; + }); } private static void setSegmentCurrentlyPlaying(@Nullable SponsorSegment segment) { @@ -488,8 +576,10 @@ public class SegmentPlaybackController { SponsorBlockViewController.hideSkipSegmentButton(); return; } + segmentCurrentlyPlaying = segment; skipSegmentButtonEndTime = 0; + if (Settings.SB_AUTO_HIDE_SKIP_BUTTON.get()) { if (hiddenSkipSegmentsForCurrentVideoTime.contains(segment)) { // Playback exited a nested segment and the outer segment skip button was previously hidden. @@ -497,16 +587,13 @@ public class SegmentPlaybackController { SponsorBlockViewController.hideSkipSegmentButton(); return; } - skipSegmentButtonEndTime = System.currentTimeMillis() + DURATION_TO_SHOW_SKIP_BUTTON; + skipSegmentButtonEndTime = System.currentTimeMillis() + getSkipButtonDuration(); } Logger.printDebug(() -> "Showing segment: " + segment); SponsorBlockViewController.showSkipSegmentButton(segment); } - private static SponsorSegment lastSegmentSkipped; - private static long lastSegmentSkippedTime; - - private static void skipSegment(@NonNull SponsorSegment segmentToSkip, boolean userManuallySkipped) { + private static void skipSegment(SponsorSegment segmentToSkip, boolean userManuallySkipped) { try { SponsorBlockViewController.hideSkipHighlightButton(); SponsorBlockViewController.hideSkipSegmentButton(); @@ -525,7 +612,7 @@ public class SegmentPlaybackController { } } - Logger.printDebug(() -> "Skipping segment: " + segmentToSkip); + Logger.printDebug(() -> "Skipping segment: " + segmentToSkip + " videoState: " + VideoState.getCurrent()); lastSegmentSkipped = segmentToSkip; lastSegmentSkippedTime = now; setSegmentCurrentlyPlaying(null); @@ -535,29 +622,39 @@ public class SegmentPlaybackController { highlightSegmentInitialShowEndTime = 0; } + // Set or update undo skip range. + Range range = segmentToSkip.getUndoRange(); + if (undoAutoSkipRange == null) { + Logger.printDebug(() -> "Setting new undo range to: " + range); + undoAutoSkipRange = range; + } else { + Range extendedRange = undoAutoSkipRange.extend(range); + Logger.printDebug(() -> "Extending undo range from: " + undoAutoSkipRange + + " to: " + extendedRange); + undoAutoSkipRange = extendedRange; + } + undoAutoSkipRangeToast = undoAutoSkipRange; + // If the seek is successful, then the seek causes a recursive call back into this class. final boolean seekSuccessful = VideoInformation.seekTo(segmentToSkip.end); if (!seekSuccessful) { - // can happen when switching videos and is normal + // Can happen when switching videos and is normal. Logger.printDebug(() -> "Could not skip segment (seek unsuccessful): " + segmentToSkip); return; } - final boolean videoIsPaused = VideoState.getCurrent() == VideoState.PAUSED; if (!userManuallySkipped) { - // check for any smaller embedded segments, and count those as autoskipped + // Check for any smaller embedded segments, and count those as auto-skipped. final boolean showSkipToast = Settings.SB_TOAST_ON_SKIP.get(); - for (final SponsorSegment otherSegment : Objects.requireNonNull(segments)) { + for (SponsorSegment otherSegment : Objects.requireNonNull(segments)) { if (segmentToSkip.end < otherSegment.start) { - break; // no other segments can be contained + break; // No other segments can be contained. } + if (otherSegment == segmentToSkip || (otherSegment.category != SegmentCategory.HIGHLIGHT && segmentToSkip.containsSegment(otherSegment))) { otherSegment.didAutoSkipped = true; - // Do not show a toast if the user is scrubbing thru a paused video. - // Cannot do this video state check in setTime or earlier in this method, as the video state may not be up to date. - // So instead, only hide toasts because all other skip logic done while paused causes no harm. - if (showSkipToast && !videoIsPaused) { + if (showSkipToast) { showSkippedSegmentToast(otherSegment); } } @@ -567,7 +664,7 @@ public class SegmentPlaybackController { if (segmentToSkip.category == SegmentCategory.UNSUBMITTED) { removeUnsubmittedSegments(); SponsorBlockUtils.setNewSponsorSegmentPreviewed(); - } else if (!videoIsPaused) { + } else if (VideoState.getCurrent() != VideoState.PAUSED) { SponsorBlockUtils.sendViewRequestAsync(segmentToSkip); } } catch (Exception ex) { @@ -575,29 +672,44 @@ public class SegmentPlaybackController { } } + /** + * Checks if the segment should be auto-skipped _and_ if undo autoskip is not active. + */ + private static boolean shouldAutoSkipAndUndoSkipNotActive(SponsorSegment segment, long currentVideoTime) { + return segment.shouldAutoSkip() && (undoAutoSkipRange == null + || !undoAutoSkipRange.contains(currentVideoTime)); + } - private static int toastNumberOfSegmentsSkipped; - @Nullable - private static SponsorSegment toastSegmentSkipped; - - private static void showSkippedSegmentToast(@NonNull SponsorSegment segment) { + private static void showSkippedSegmentToast(SponsorSegment segment) { Utils.verifyOnMainThread(); - toastNumberOfSegmentsSkipped++; - if (toastNumberOfSegmentsSkipped > 1) { - return; // toast already scheduled - } toastSegmentSkipped = segment; + if (toastNumberOfSegmentsSkipped++ > 0) { + return; // Toast is already scheduled. + } - final long delayToToastMilliseconds = 250; // also the maximum time between skips to be considered skipping multiple segments + // Maximum time between skips to be considered skipping multiple segments. + final long delayToToastMilliseconds = 250; Utils.runOnMainThreadDelayed(() -> { try { - if (toastSegmentSkipped == null) { // video was changed just after skipping segment + // Do not show a toast if the user is scrubbing thru a paused video. + // Cannot do this video state check in setTime or before calling this this method, + // as the video state may not be up to date. So instead, only ignore the toast + // just before it's about to show since the video state is up to date. + if (VideoState.getCurrent() == VideoState.PAUSED) { + Logger.printDebug(() -> "Ignoring scheduled toast as video state is paused"); + return; + } + + if (toastSegmentSkipped == null || undoAutoSkipRangeToast == null) { + // Video was changed immediately after skipping segment. Logger.printDebug(() -> "Ignoring old scheduled show toast"); return; } - Utils.showToastShort(toastNumberOfSegmentsSkipped == 1 + String message = toastNumberOfSegmentsSkipped == 1 ? toastSegmentSkipped.getSkippedToastText() - : str("revanced_sb_skipped_multiple_segments")); + : str("revanced_sb_skipped_multiple_segments"); + + showToastShortWithTapAction(message, undoAutoSkipRangeToast); } catch (Exception ex) { Logger.printException(() -> "showSkippedSegmentToast failure", ex); } finally { @@ -607,13 +719,128 @@ public class SegmentPlaybackController { }, delayToToastMilliseconds); } + private static void showToastShortWithTapAction(String messageToToast, Range rangeToUndo) { + Objects.requireNonNull(messageToToast); + Utils.verifyOnMainThread(); + + Context currentContext = SponsorBlockViewController.getOverLaysViewGroupContext(); + if (currentContext == null) { + Logger.printException(() -> "Cannot show toast (context is null): " + messageToToast); + return; + } + + Logger.printDebug(() -> "Showing toast: " + messageToToast); + + Dialog dialog = new Dialog(currentContext); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + // Do not dismiss dialog if tapped outside the dialog bounds. + dialog.setCanceledOnTouchOutside(false); + + LinearLayout mainLayout = new LinearLayout(currentContext); + mainLayout.setOrientation(LinearLayout.VERTICAL); + final int dip8 = dipToPixels(8); + final int dip16 = dipToPixels(16); + mainLayout.setPadding(dip16, dip8, dip16, dip8); + mainLayout.setGravity(Gravity.CENTER); + mainLayout.setMinimumHeight(dipToPixels(48)); + + ShapeDrawable background = new ShapeDrawable(new RoundRectShape( + Utils.createCornerRadii(20), null, null)); + background.getPaint().setColor(Utils.getDialogBackgroundColor()); + mainLayout.setBackground(background); + + TextView textView = new TextView(currentContext); + textView.setText(messageToToast); + textView.setTextSize(14); + textView.setTextColor(Utils.getAppForegroundColor()); + textView.setGravity(Gravity.CENTER); + LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); + textParams.gravity = Gravity.CENTER; + textView.setLayoutParams(textParams); + mainLayout.addView(textView); + mainLayout.setAlpha(0.8f); // Opacity for the entire dialog. + + final int fadeDurationFast = Utils.getResourceInteger("fade_duration_fast"); + Animation fadeIn = Utils.getResourceAnimation("fade_in"); + Animation fadeOut = Utils.getResourceAnimation("fade_out"); + fadeIn.setDuration(fadeDurationFast); + fadeOut.setDuration(fadeDurationFast); + fadeOut.setAnimationListener(new Animation.AnimationListener() { + public void onAnimationStart(Animation animation) { } + public void onAnimationEnd(Animation animation) { + if (dialog.isShowing()) { + dialog.dismiss(); + } + } + public void onAnimationRepeat(Animation animation) { } + }); + + mainLayout.setOnClickListener(v -> { + try { + Logger.printDebug(() -> "Undoing autoskip using range: " + rangeToUndo); + // Restore undo autoskip range since it's already cleared by now. + undoAutoSkipRange = rangeToUndo; + VideoInformation.seekTo(rangeToUndo.getLower()); + + mainLayout.startAnimation(fadeOut); + } catch (Exception ex) { + Logger.printException(() -> "showToastShortWithTapAction setOnClickListener failure", ex); + dialog.dismiss(); + } + }); + mainLayout.setClickable(true); + dialog.setContentView(mainLayout); + + Window window = dialog.getWindow(); + if (window != null) { + // Remove window animations and use custom fade animation. + window.setWindowAnimations(0); + + WindowManager.LayoutParams params = window.getAttributes(); + params.gravity = Gravity.BOTTOM; + params.y = dipToPixels(72); + DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics(); + int portraitWidth = (int) (displayMetrics.widthPixels * 0.6); + + if (Resources.getSystem().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + portraitWidth = (int) Math.min(portraitWidth, displayMetrics.heightPixels * 0.6); + } + params.width = portraitWidth; + params.dimAmount = 0.0f; + window.setAttributes(params); + window.setBackgroundDrawable(null); + window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); + window.addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH); + } + + Dialog priorDialog = toastDialogRef.get(); + if (priorDialog != null && priorDialog.isShowing()) { + Logger.printDebug(() -> "Removing previous skip toast that is still on screen: " + priorDialog); + priorDialog.dismiss(); + } + toastDialogRef = new WeakReference<>(dialog); + + mainLayout.startAnimation(fadeIn); + dialog.show(); + + // Fade out and dismiss the dialog if the user does not undo the skip. + Utils.runOnMainThreadDelayed(() -> { + if (dialog.isShowing()) { + mainLayout.startAnimation(fadeOut); + } + }, getToastDuration()); + } + /** * @param segment can be either a highlight or a regular manual skip segment. */ - public static void onSkipSegmentClicked(@NonNull SponsorSegment segment) { + public static void onSkipSegmentClicked(SponsorSegment segment) { try { if (segment != highlightSegment && segment != segmentCurrentlyPlaying) { - Logger.printException(() -> "error: segment not available to skip"); // should never happen + Logger.printException(() -> "error: segment not available to skip"); // Should never happen. SponsorBlockViewController.hideSkipSegmentButton(); SponsorBlockViewController.hideSkipHighlightButton(); return; @@ -628,7 +855,7 @@ public class SegmentPlaybackController { * Injection point */ @SuppressWarnings("unused") - public static void setSponsorBarRect(final Object self) { + public static void setSponsorBarRect(Object self) { try { Field field = self.getClass().getDeclaredField("replaceMeWithsetSponsorBarRect"); field.setAccessible(true); @@ -651,7 +878,7 @@ public class SegmentPlaybackController { private static void setSponsorBarAbsoluteRight(Rect rect) { final int right = rect.right; if (sponsorAbsoluteBarRight != right) { - Logger.printDebug(() -> "setSponsorBarAbsoluteRight: " + right); + Logger.printDebug(() -> "setSponsorBarAbsoluteRight: " + right); sponsorAbsoluteBarRight = right; } } @@ -726,12 +953,6 @@ public class SegmentPlaybackController { } } - /** - * Actual screen pixel width to use for the highlight segment time bar. - */ - private static final int highlightSegmentTimeBarScreenWidth - = Utils.dipToPixels(HIGHLIGHT_SEGMENT_DRAW_BAR_WIDTH); - /** * Injection point. */ @@ -752,9 +973,9 @@ public class SegmentPlaybackController { final float left = leftPadding + segment.start * videoMillisecondsToPixels; final float right; if (segment.category == SegmentCategory.HIGHLIGHT) { - right = left + highlightSegmentTimeBarScreenWidth; + right = left + HIGHLIGHT_SEGMENT_DRAW_BAR_WIDTH; } else { - right = leftPadding + segment.end * videoMillisecondsToPixels; + right = leftPadding + segment.end * videoMillisecondsToPixels; } canvas.drawRect(left, top, right, bottom, segment.category.paint); } @@ -762,5 +983,4 @@ public class SegmentPlaybackController { Logger.printException(() -> "drawSponsorTimeBars failure", ex); } } - } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SponsorBlockUtils.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SponsorBlockUtils.java index 5edccbacd..59ee84544 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SponsorBlockUtils.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SponsorBlockUtils.java @@ -223,13 +223,18 @@ public class SponsorBlockUtils { Logger.printException(() -> "invalid parameters"); return; } + clearUnsubmittedSegmentTimes(); Utils.runOnBackgroundThread(() -> { - SBRequester.submitSegments(videoId, segmentCategory.keyValue, start, end, videoLength); - SegmentPlaybackController.executeDownloadSegments(videoId); + try { + SBRequester.submitSegments(videoId, segmentCategory.keyValue, start, end, videoLength); + SegmentPlaybackController.executeDownloadSegments(videoId); + } catch (Exception ex) { + Logger.printException(() -> "submitNewSegment failure", ex); + } }); - } catch (Exception e) { - Logger.printException(() -> "Unable to submit segment", e); + } catch (Exception ex) { + Logger.printException(() -> "submitNewSegment failure", ex); } } @@ -366,7 +371,7 @@ public class SponsorBlockUtils { } - static void sendViewRequestAsync(@NonNull SponsorSegment segment) { + static void sendViewRequestAsync(SponsorSegment segment) { if (segment.recordedAsSkipped || segment.category == SegmentCategory.UNSUBMITTED) { return; } @@ -409,7 +414,7 @@ public class SponsorBlockUtils { return statsNumberFormatter.format(viewCount); } - private static long parseSegmentTime(@NonNull String time) { + private static long parseSegmentTime(String time) { Matcher matcher = manualEditTimePattern.matcher(time); if (!matcher.matches()) { return -1; @@ -419,9 +424,12 @@ public class SponsorBlockUtils { String secondsStr = matcher.group(4); String millisecondsStr = matcher.group(6); // Milliseconds is optional. + try { final int hours = (hoursStr != null) ? Integer.parseInt(hoursStr) : 0; + //noinspection ConstantConditions final int minutes = Integer.parseInt(minutesStr); + //noinspection ConstantConditions final int seconds = Integer.parseInt(secondsStr); final int milliseconds; if (millisecondsStr != null) { @@ -468,32 +476,29 @@ public class SponsorBlockUtils { } public static String getTimeSavedString(long totalSecondsSaved) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - Duration duration = Duration.ofSeconds(totalSecondsSaved); - final long hours = duration.toHours(); - final long minutes = duration.toMinutes() % 60; + Duration duration = Duration.ofSeconds(totalSecondsSaved); + final long hours = duration.toHours(); + final long minutes = duration.toMinutes() % 60; - // Format all numbers so non-western numbers use a consistent appearance. - String minutesFormatted = statsNumberFormatter.format(minutes); - if (hours > 0) { - String hoursFormatted = statsNumberFormatter.format(hours); - return str("revanced_sb_stats_saved_hour_format", hoursFormatted, minutesFormatted); - } - - final long seconds = duration.getSeconds() % 60; - String secondsFormatted = statsNumberFormatter.format(seconds); - if (minutes > 0) { - return str("revanced_sb_stats_saved_minute_format", minutesFormatted, secondsFormatted); - } - - return str("revanced_sb_stats_saved_second_format", secondsFormatted); + // Format all numbers so non-western numbers use a consistent appearance. + String minutesFormatted = statsNumberFormatter.format(minutes); + if (hours > 0) { + String hoursFormatted = statsNumberFormatter.format(hours); + return str("revanced_sb_stats_saved_hour_format", hoursFormatted, minutesFormatted); } - return "error"; // will never be reached. YouTube requires Android O or greater + + final long seconds = duration.getSeconds() % 60; + String secondsFormatted = statsNumberFormatter.format(seconds); + if (minutes > 0) { + return str("revanced_sb_stats_saved_minute_format", minutesFormatted, secondsFormatted); + } + + return str("revanced_sb_stats_saved_second_format", secondsFormatted); } private static class EditByHandSaveDialogListener implements DialogInterface.OnClickListener { - boolean settingStart; - WeakReference editTextRef = new WeakReference<>(null); + private boolean settingStart; + private WeakReference editTextRef = new WeakReference<>(null); @Override public void onClick(DialogInterface dialog, int which) { @@ -512,10 +517,11 @@ public class SponsorBlockUtils { } } - if (settingStart) + if (settingStart) { newSponsorSegmentStartMillis = Math.max(time, 0); - else + } else { newSponsorSegmentEndMillis = time; + } if (which == DialogInterface.BUTTON_NEUTRAL) editByHandDialogListener.onClick(dialog, settingStart ? diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/objects/SponsorSegment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/objects/SponsorSegment.java index 375de16b5..4528cfae9 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/objects/SponsorSegment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/objects/SponsorSegment.java @@ -9,7 +9,10 @@ import java.util.Objects; import static app.revanced.extension.shared.StringRef.sf; +import android.util.Range; + public class SponsorSegment implements Comparable { + public enum SegmentVote { UPVOTE(sf("revanced_sb_vote_upvote"), 1,false), DOWNVOTE(sf("revanced_sb_vote_downvote"), 0, true), @@ -38,7 +41,7 @@ public class SponsorSegment implements Comparable { @NonNull public final SegmentCategory category; /** - * NULL if segment is unsubmitted + * NULL if segment is unsubmitted. */ @Nullable public final String UUID; @@ -64,33 +67,54 @@ public class SponsorSegment implements Comparable { } /** - * @param nearThreshold threshold to declare the time parameter is near this segment. Must be a positive number + * @param nearThreshold threshold to declare the time parameter is near this segment. Must be a positive number. */ public boolean startIsNear(long videoTime, long nearThreshold) { return Math.abs(start - videoTime) <= nearThreshold; } /** - * @param nearThreshold threshold to declare the time parameter is near this segment. Must be a positive number + * @param nearThreshold threshold to declare the time parameter is near this segment. Must be a positive number. */ public boolean endIsNear(long videoTime, long nearThreshold) { return Math.abs(end - videoTime) <= nearThreshold; } /** - * @return if the time parameter is within this segment + * @return if the time parameter is within this segment. */ public boolean containsTime(long videoTime) { return start <= videoTime && videoTime < end; } /** - * @return if the segment is completely contained inside this segment + * @return if the segment is completely contained inside this segment. */ public boolean containsSegment(SponsorSegment other) { return start <= other.start && other.end <= end; } + /** + * @return If the range has any overlap with this segment. + */ + public boolean intersectsRange(Range range) { + return range.getLower() < end && range.getUpper() >= start; + } + + /** + * @return The start/end time in range form. + * Range times are adjusted since it uses inclusive and Segments use exclusive. + * + * {@link SegmentCategory#HIGHLIGHT} is unique and + * returns a range from the start of the video until the highlight. + */ + public Range getUndoRange() { + final long undoStart = category == SegmentCategory.HIGHLIGHT + ? 0 + : start; + return Range.create(undoStart, end - 1); + } + /** * @return the length of this segment, in milliseconds. Always a positive number. */ @@ -99,7 +123,7 @@ public class SponsorSegment implements Comparable { } /** - * @return 'skip segment' UI overlay button text + * @return 'skip segment' UI overlay button text. */ @NonNull public String getSkipButtonText() { @@ -107,7 +131,7 @@ public class SponsorSegment implements Comparable { } /** - * @return 'skipped segment' toast message + * @return 'skipped segment' toast message. */ @NonNull public String getSkippedToastText() { diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/requests/SBRequester.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/requests/SBRequester.java index fea7664f1..dc86e1d0d 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/requests/SBRequester.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/requests/SBRequester.java @@ -53,7 +53,7 @@ public class SBRequester { private SBRequester() { } - private static void handleConnectionError(@NonNull String toastMessage, @Nullable Exception ex) { + private static void handleConnectionError(String toastMessage, @Nullable Exception ex) { if (Settings.SB_TOAST_ON_CONNECTION_ERROR.get()) { Utils.showToastShort(toastMessage); } @@ -63,7 +63,7 @@ public class SBRequester { } @NonNull - public static SponsorSegment[] getSegments(@NonNull String videoId) { + public static SponsorSegment[] getSegments(String videoId) { Utils.verifyOffMainThread(); List segments = new ArrayList<>(); try { @@ -113,10 +113,10 @@ public class SBRequester { Logger.printException(() -> "getSegments failure", ex); } - // Crude debug tests to verify random features + // Crude debug tests to verify random features. // Could benefit from: - // 1) collection of YouTube videos with test segment times (verify client skip timing matches the video, verify seekbar draws correctly) - // 2) unit tests (verify everything else) + // 1) Collection of YouTube videos with test segment times (verify client skip timing matches the video, verify seekbar draws correctly). + // 2) Unit tests (verify everything else). //noinspection ConstantValue if (false) { segments.clear(); @@ -140,10 +140,30 @@ public class SBRequester { segments.add(new SponsorSegment(SegmentCategory.SELF_PROMO, "debug", 200000, 330000, false)); } + // Test undo skip functionality. + // To test enable 'Autoskip always' for intro and self promo. + //noinspection ConstantValue + if (false) { + // Should autoskip to 12 seconds. + // Undoing skip should seek to 2 seconds. + // Skip button should show at 2 seconds, and again at 8 seconds. + // Self promo at 8 second time should not autoskip. + segments.clear(); + segments.add(new SponsorSegment(SegmentCategory.INTRO, "debug", 2000, 12000, false)); + segments.add(new SponsorSegment(SegmentCategory.SELF_PROMO, "debug", 8000, 15000, false)); + + // Test multiple autoskip dialogs rapidly showing. + // Only one toast should be shown at anytime. + segments.add(new SponsorSegment(SegmentCategory.INTRO, "debug", 16000, 17000, false)); + segments.add(new SponsorSegment(SegmentCategory.INTRO, "debug", 18000, 19000, false)); + segments.add(new SponsorSegment(SegmentCategory.INTRO, "debug", 20000, 21000, false)); + segments.add(new SponsorSegment(SegmentCategory.INTRO, "debug", 22000, 23000, false)); + } + return segments.toArray(new SponsorSegment[0]); } - public static void submitSegments(@NonNull String videoId, @NonNull String category, + public static void submitSegments(String videoId, String category, long startTime, long endTime, long videoLength) { Utils.verifyOffMainThread(); @@ -189,7 +209,7 @@ public class SBRequester { } } - public static void sendSegmentSkippedViewedRequest(@NonNull SponsorSegment segment) { + public static void sendSegmentSkippedViewedRequest(SponsorSegment segment) { Utils.verifyOffMainThread(); try { HttpURLConnection connection = getConnectionFromRoute(SBRoutes.VIEWED_SEGMENT, segment.UUID); @@ -208,13 +228,13 @@ public class SBRequester { } } - public static void voteForSegmentOnBackgroundThread(@NonNull SponsorSegment segment, @NonNull SegmentVote voteOption) { + public static void voteForSegmentOnBackgroundThread(SponsorSegment segment, SegmentVote voteOption) { voteOrRequestCategoryChange(segment, voteOption, null); } - public static void voteToChangeCategoryOnBackgroundThread(@NonNull SponsorSegment segment, @NonNull SegmentCategory categoryToVoteFor) { + public static void voteToChangeCategoryOnBackgroundThread(SponsorSegment segment, SegmentCategory categoryToVoteFor) { voteOrRequestCategoryChange(segment, SegmentVote.CATEGORY_CHANGE, categoryToVoteFor); } - private static void voteOrRequestCategoryChange(@NonNull SponsorSegment segment, @NonNull SegmentVote voteOption, SegmentCategory categoryToVoteFor) { + private static void voteOrRequestCategoryChange(SponsorSegment segment, SegmentVote voteOption, SegmentCategory categoryToVoteFor) { Utils.runOnBackgroundThread(() -> { try { String segmentUuid = segment.UUID; @@ -280,7 +300,7 @@ public class SBRequester { * @return NULL if the call was successful. If unsuccessful, an error message is returned. */ @Nullable - public static String setUsername(@NonNull String username) { + public static String setUsername(String username) { Utils.verifyOffMainThread(); try { HttpURLConnection connection = getConnectionFromRoute(SBRoutes.CHANGE_USERNAME, SponsorBlockSettings.getSBPrivateUserID(), username); @@ -320,14 +340,14 @@ public class SBRequester { // helpers - private static HttpURLConnection getConnectionFromRoute(@NonNull Route route, String... params) throws IOException { + private static HttpURLConnection getConnectionFromRoute(Route route, String... params) throws IOException { HttpURLConnection connection = Requester.getConnectionFromRoute(Settings.SB_API_URL.get(), route, params); connection.setConnectTimeout(TIMEOUT_TCP_DEFAULT_MILLISECONDS); connection.setReadTimeout(TIMEOUT_HTTP_DEFAULT_MILLISECONDS); return connection; } - private static JSONObject getJSONObject(@NonNull Route route, String... params) throws IOException, JSONException { + private static JSONObject getJSONObject(Route route, String... params) throws IOException, JSONException { return Requester.parseJSONObject(getConnectionFromRoute(route, params)); } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockPreferenceGroup.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockPreferenceGroup.java index a5d2703dc..e0149f2f6 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockPreferenceGroup.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockPreferenceGroup.java @@ -1,6 +1,7 @@ package app.revanced.extension.youtube.sponsorblock.ui; import static app.revanced.extension.shared.StringRef.str; +import static app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController.SponsorBlockDuration; import android.annotation.SuppressLint; import android.app.Dialog; @@ -28,6 +29,7 @@ import java.util.List; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; +import app.revanced.extension.shared.settings.preference.CustomDialogListPreference; import app.revanced.extension.shared.settings.preference.ResettableEditTextPreference; import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController; @@ -62,6 +64,8 @@ public class SponsorBlockPreferenceGroup extends PreferenceGroup { private SwitchPreference trackSkips; private SwitchPreference showTimeWithoutSegments; private SwitchPreference toastOnConnectionError; + private CustomDialogListPreference autoHideSkipSegmentButtonDuration; + private CustomDialogListPreference showSkipToastDuration; private ResettableEditTextPreference newSegmentStep; private ResettableEditTextPreference minSegmentDuration; @@ -69,8 +73,8 @@ public class SponsorBlockPreferenceGroup extends PreferenceGroup { private EditTextPreference importExport; private Preference apiUrl; - private final List segmentCategories = new ArrayList<>(); private PreferenceCategory segmentCategory; + private final List segmentCategories = new ArrayList<>(); public SponsorBlockPreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); @@ -114,17 +118,23 @@ public class SponsorBlockPreferenceGroup extends PreferenceGroup { votingEnabled.setChecked(Settings.SB_VOTING_BUTTON.get()); votingEnabled.setEnabled(enabled); - autoHideSkipSegmentButton.setEnabled(enabled); autoHideSkipSegmentButton.setChecked(Settings.SB_AUTO_HIDE_SKIP_BUTTON.get()); + autoHideSkipSegmentButton.setEnabled(enabled); + + autoHideSkipSegmentButtonDuration.setValue(Settings.SB_AUTO_HIDE_SKIP_BUTTON_DURATION.get().toString()); + autoHideSkipSegmentButtonDuration.setEnabled(Settings.SB_AUTO_HIDE_SKIP_BUTTON_DURATION.isAvailable()); compactSkipButton.setChecked(Settings.SB_COMPACT_SKIP_BUTTON.get()); compactSkipButton.setEnabled(enabled); + showSkipToast.setChecked(Settings.SB_TOAST_ON_SKIP.get()); + showSkipToast.setEnabled(enabled); + squareLayout.setChecked(Settings.SB_SQUARE_LAYOUT.get()); squareLayout.setEnabled(enabled); - showSkipToast.setChecked(Settings.SB_TOAST_ON_SKIP.get()); - showSkipToast.setEnabled(enabled); + showSkipToastDuration.setValue(Settings.SB_TOAST_ON_SKIP_DURATION.get().toString()); + showSkipToastDuration.setEnabled(Settings.SB_TOAST_ON_SKIP_DURATION.isAvailable()); toastOnConnectionError.setChecked(Settings.SB_TOAST_ON_CONNECTION_ERROR.get()); toastOnConnectionError.setEnabled(enabled); @@ -166,7 +176,7 @@ public class SponsorBlockPreferenceGroup extends PreferenceGroup { try { super.onAttachedToActivity(); - if (preferencesInitialized) { + if (preferencesInitialized) { if (settingsImported) { settingsImported = false; updateUI(); @@ -205,17 +215,6 @@ public class SponsorBlockPreferenceGroup extends PreferenceGroup { }); appearanceCategory.addPreference(votingEnabled); - autoHideSkipSegmentButton = new SwitchPreference(context); - autoHideSkipSegmentButton.setTitle(str("revanced_sb_enable_auto_hide_skip_segment_button")); - autoHideSkipSegmentButton.setSummaryOn(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_on")); - autoHideSkipSegmentButton.setSummaryOff(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_off")); - autoHideSkipSegmentButton.setOnPreferenceChangeListener((preference1, newValue) -> { - Settings.SB_AUTO_HIDE_SKIP_BUTTON.save((Boolean) newValue); - updateUI(); - return true; - }); - appearanceCategory.addPreference(autoHideSkipSegmentButton); - compactSkipButton = new SwitchPreference(context); compactSkipButton.setTitle(str("revanced_sb_enable_compact_skip_button")); compactSkipButton.setSummaryOn(str("revanced_sb_enable_compact_skip_button_sum_on")); @@ -227,25 +226,38 @@ public class SponsorBlockPreferenceGroup extends PreferenceGroup { }); appearanceCategory.addPreference(compactSkipButton); - squareLayout = new SwitchPreference(context); - squareLayout.setTitle(str("revanced_sb_square_layout")); - squareLayout.setSummaryOn(str("revanced_sb_square_layout_sum_on")); - squareLayout.setSummaryOff(str("revanced_sb_square_layout_sum_off")); - squareLayout.setOnPreferenceChangeListener((preference1, newValue) -> { - Settings.SB_SQUARE_LAYOUT.save((Boolean) newValue); + autoHideSkipSegmentButton = new SwitchPreference(context); + autoHideSkipSegmentButton.setTitle(str("revanced_sb_enable_auto_hide_skip_segment_button")); + autoHideSkipSegmentButton.setSummaryOn(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_on")); + autoHideSkipSegmentButton.setSummaryOff(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_off")); + autoHideSkipSegmentButton.setOnPreferenceChangeListener((preference1, newValue) -> { + Settings.SB_AUTO_HIDE_SKIP_BUTTON.save((Boolean) newValue); updateUI(); return true; }); - appearanceCategory.addPreference(squareLayout); + appearanceCategory.addPreference(autoHideSkipSegmentButton); + + String[] durationEntries = Utils.getResourceStringArray("revanced_sb_duration_entries"); + String[] durationEntryValues = Utils.getResourceStringArray("revanced_sb_duration_entry_values"); + + autoHideSkipSegmentButtonDuration = new CustomDialogListPreference(context); + autoHideSkipSegmentButtonDuration.setTitle(str("revanced_sb_auto_hide_skip_button_duration")); + autoHideSkipSegmentButtonDuration.setSummary(str("revanced_sb_auto_hide_skip_button_duration_sum")); + autoHideSkipSegmentButtonDuration.setEntries(durationEntries); + autoHideSkipSegmentButtonDuration.setEntryValues(durationEntryValues); + autoHideSkipSegmentButtonDuration.setOnPreferenceChangeListener((preference1, newValue) -> { + Settings.SB_AUTO_HIDE_SKIP_BUTTON_DURATION.save( + SponsorBlockDuration.valueOf((String) newValue) + ); + updateUI(); + return true; + }); + appearanceCategory.addPreference(autoHideSkipSegmentButtonDuration); showSkipToast = new SwitchPreference(context); showSkipToast.setTitle(str("revanced_sb_general_skiptoast")); showSkipToast.setSummaryOn(str("revanced_sb_general_skiptoast_sum_on")); showSkipToast.setSummaryOff(str("revanced_sb_general_skiptoast_sum_off")); - showSkipToast.setOnPreferenceClickListener(preference1 -> { - Utils.showToastShort(str("revanced_sb_skipped_sponsor")); - return false; - }); showSkipToast.setOnPreferenceChangeListener((preference1, newValue) -> { Settings.SB_TOAST_ON_SKIP.save((Boolean) newValue); updateUI(); @@ -253,6 +265,20 @@ public class SponsorBlockPreferenceGroup extends PreferenceGroup { }); appearanceCategory.addPreference(showSkipToast); + showSkipToastDuration = new CustomDialogListPreference(context); + showSkipToastDuration.setTitle(str("revanced_sb_toast_on_skip_duration")); + showSkipToastDuration.setSummary(str("revanced_sb_toast_on_skip_duration_sum")); + showSkipToastDuration.setEntries(durationEntries); + showSkipToastDuration.setEntryValues(durationEntryValues); + showSkipToastDuration.setOnPreferenceChangeListener((preference1, newValue) -> { + Settings.SB_TOAST_ON_SKIP_DURATION.save( + SponsorBlockDuration.valueOf((String) newValue) + ); + updateUI(); + return true; + }); + appearanceCategory.addPreference(showSkipToastDuration); + showTimeWithoutSegments = new SwitchPreference(context); showTimeWithoutSegments.setTitle(str("revanced_sb_general_time_without")); showTimeWithoutSegments.setSummaryOn(str("revanced_sb_general_time_without_sum_on")); @@ -264,6 +290,17 @@ public class SponsorBlockPreferenceGroup extends PreferenceGroup { }); appearanceCategory.addPreference(showTimeWithoutSegments); + squareLayout = new SwitchPreference(context); + squareLayout.setTitle(str("revanced_sb_square_layout")); + squareLayout.setSummaryOn(str("revanced_sb_square_layout_sum_on")); + squareLayout.setSummaryOff(str("revanced_sb_square_layout_sum_off")); + squareLayout.setOnPreferenceChangeListener((preference1, newValue) -> { + Settings.SB_SQUARE_LAYOUT.save((Boolean) newValue); + updateUI(); + return true; + }); + appearanceCategory.addPreference(squareLayout); + segmentCategory = new PreferenceCategory(context); segmentCategory.setTitle(str("revanced_sb_diff_segments")); addPreference(segmentCategory); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java index a16ffdd32..4749c6930 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java @@ -203,7 +203,7 @@ public class SponsorBlockViewController { setSkipButtonMargins(skipSponsorButton, isWatchFullScreen); setViewVisibility(skipSponsorButton, skipSegment != null); } catch (Exception ex) { - Logger.printException(() -> "Player type changed failure", ex); + Logger.printException(() -> "playerTypeChanged failure", ex); } } diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index 6e5c17dea..41a90c129 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -61,6 +61,7 @@ @string/revanced_language_ZH + DEFAULT AM AR @@ -129,7 +130,6 @@ iOS TV - ANDROID_UNPLUGGED ANDROID_VR_NO_AUTH IOS_UNPLUGGED @@ -146,7 +146,6 @@ @string/revanced_swipe_overlay_style_entry_7 - HORIZONTAL HORIZONTAL_MINIMAL_TOP HORIZONTAL_MINIMAL_CENTER @@ -180,7 +179,6 @@ @string/revanced_change_form_factor_entry_4 - DEFAULT SMALL LARGE @@ -210,7 +208,6 @@ @string/revanced_exit_fullscreen_entry_4 - DISABLED PORTRAIT LANDSCAPE @@ -229,7 +226,6 @@ @string/revanced_miniplayer_type_entry_7 - DISABLED DEFAULT MINIMAL @@ -330,13 +326,38 @@ YOUR_CLIPS + + + @string/revanced_sb_duration_1s + @string/revanced_sb_duration_2s + @string/revanced_sb_duration_3s + @string/revanced_sb_duration_4s + @string/revanced_sb_duration_5s + @string/revanced_sb_duration_6s + @string/revanced_sb_duration_7s + @string/revanced_sb_duration_8s + @string/revanced_sb_duration_9s + @string/revanced_sb_duration_10s + + + ONE_SECOND + TWO_SECONDS + THREE_SECONDS + FOUR_SECONDS + FIVE_SECONDS + SIX_SECONDS + SEVEN_SECONDS + EIGHT_SECONDS + NINE_SECONDS + TEN_SECONDS + + @string/revanced_shorts_player_type_shorts @string/revanced_shorts_player_type_regular_player - SHORTS_PLAYER REGULAR_PLAYER @@ -346,7 +367,6 @@ @string/revanced_shorts_player_type_regular_player_fullscreen - SHORTS_PLAYER REGULAR_PLAYER REGULAR_PLAYER_FULLSCREEN @@ -360,7 +380,6 @@ @string/revanced_alt_thumbnail_options_entry_4 - ORIGINAL DEARROW DEARROW_STILL_IMAGES diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index f72851cd4..bec6c8537 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1027,11 +1027,25 @@ This feature works best with a video quality of 720p or lower and when using a v Automatically hide Skip button Skip button hides after a few seconds Skip button is shown for the entire segment - Show a toast when skipping - Toast is shown when a segment is automatically skipped. Tap here to see an example - Toast is not shown. Tap here to see an example + Skip button duration + How long the auto hide skip and skip to highlight buttons are shown + Show undo skip toast + Toast is shown when a segment is automatically skipped. Tap the toast notification to undo the skip + Toast is not shown + Skip toast duration + How long the skip toast notification is shown + 1 second + 2 seconds + 3 seconds + 4 seconds + 5 seconds + 6 seconds + 7 seconds + 8 seconds + 9 seconds + 10 seconds Show video length without segments - Video length minus all segments, shown in parentheses next to the full video length + Video length minus all segments is shown on the seekbar Full video length shown Creating new segments Show Create new segment button From e52ee41222eeca9dcd6d4fcc1151908230e39cb3 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 30 Jun 2025 06:54:53 +0000 Subject: [PATCH 16/33] chore: Release v5.30.0-dev.4 [skip ci] # [5.30.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.3...v5.30.0-dev.4) (2025-06-30) ### Features * **YouTube - SponsorBlock:** Add "Undo automatic skip toast" ([#5277](https://github.com/ReVanced/revanced-patches/issues/5277)) ([6ee94f8](https://github.com/ReVanced/revanced-patches/commit/6ee94f8532a073d720f5f2cc6862c78c2e06aee6)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb61c0e8d..f17acaf1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.3...v5.30.0-dev.4) (2025-06-30) + + +### Features + +* **YouTube - SponsorBlock:** Add "Undo automatic skip toast" ([#5277](https://github.com/ReVanced/revanced-patches/issues/5277)) ([7fa169a](https://github.com/ReVanced/revanced-patches/commit/7fa169ae262c880019c5a069a2d6bdc7f94885f1)) + # [5.30.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.2...v5.30.0-dev.3) (2025-06-28) diff --git a/gradle.properties b/gradle.properties index 862e96fbd..5a3d70d23 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.3 +version = 5.30.0-dev.4 From 14dc593eba6008ee979899af6612982eaae4cf62 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:57:44 +0400 Subject: [PATCH 17/33] chore: Sync translations (#5294) --- .../addresources/values-ar-rSA/strings.xml | 29 +- .../addresources/values-az-rAZ/strings.xml | 8 - .../addresources/values-be-rBY/strings.xml | 33 +- .../addresources/values-bg-rBG/strings.xml | 33 +- .../addresources/values-bn-rBD/strings.xml | 31 +- .../addresources/values-cs-rCZ/strings.xml | 33 +- .../addresources/values-da-rDK/strings.xml | 33 +- .../addresources/values-de-rDE/strings.xml | 33 +- .../addresources/values-el-rGR/strings.xml | 29 +- .../addresources/values-es-rES/strings.xml | 33 +- .../addresources/values-et-rEE/strings.xml | 33 +- .../addresources/values-fi-rFI/strings.xml | 8 - .../addresources/values-fil-rPH/strings.xml | 33 +- .../addresources/values-fr-rFR/strings.xml | 33 +- .../addresources/values-ga-rIE/strings.xml | 33 +- .../addresources/values-hu-rHU/strings.xml | 33 +- .../addresources/values-hy-rAM/strings.xml | 33 +- .../addresources/values-in-rID/strings.xml | 33 +- .../addresources/values-it-rIT/strings.xml | 33 +- .../addresources/values-iw-rIL/strings.xml | 33 +- .../addresources/values-ja-rJP/strings.xml | 93 +++--- .../addresources/values-ko-rKR/strings.xml | 43 ++- .../addresources/values-lt-rLT/strings.xml | 33 +- .../addresources/values-lv-rLV/strings.xml | 33 +- .../addresources/values-nl-rNL/strings.xml | 33 +- .../addresources/values-pl-rPL/strings.xml | 33 +- .../addresources/values-pt-rBR/strings.xml | 33 +- .../addresources/values-pt-rPT/strings.xml | 33 +- .../addresources/values-ro-rRO/strings.xml | 33 +- .../addresources/values-ru-rRU/strings.xml | 49 ++- .../addresources/values-sk-rSK/strings.xml | 33 +- .../addresources/values-sl-rSI/strings.xml | 33 +- .../addresources/values-sq-rAL/strings.xml | 33 +- .../addresources/values-sr-rCS/strings.xml | 33 +- .../addresources/values-sr-rSP/strings.xml | 33 +- .../addresources/values-sv-rSE/strings.xml | 249 +++++++------- .../addresources/values-th-rTH/strings.xml | 29 +- .../addresources/values-tr-rTR/strings.xml | 33 +- .../addresources/values-uk-rUA/strings.xml | 37 ++- .../addresources/values-vi-rVN/strings.xml | 43 ++- .../addresources/values-zh-rCN/strings.xml | 33 +- .../addresources/values-zh-rTW/strings.xml | 98 +++++- .../addresources/values-zu-rZA/strings.xml | 308 +++++++++--------- 43 files changed, 1370 insertions(+), 641 deletions(-) diff --git a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml index e8f6a994f..afea1a33f 100644 --- a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml +++ b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml @@ -285,10 +285,13 @@ Second \"item\" text" وصف الفيديو إخفاء أو عرض مكونات وصف الفيديو شريط التصفية - إخفاء أو عرض شريط الفلتر في الموجز ونتائج البحث والفيديوهات ذات الصلة + إخفاء أو إظهار شريط الفلترة في الخلاصات، السجل، نتائج البحث، والفيديوهات ذات الصلة إخفاء في الموجز مخفي في الموجز - يُعرض في الموجز + معروض في الموجز + إخفاء في السجل + مخفي في السجل + معروض في السجل إخفاء في نتائج البحث مخفي في نتائج البحث يُعرض في نتائج البحث @@ -957,11 +960,25 @@ Second \"item\" text" إخفاء زر التخطي تلقائيًا إخفاء زر التخطي بعد بضع ثوانٍ يتم عرض زر التخطي للمقطع بأكمله - عرض ملاحظة عند التخطي - يتم عرض ملاحظة عندما يتم تخطي مقطع تلقائيًا. انقر هنا لمشاهدة مثال - لن يتم عرض الملاحظة. انقر هنا لمشاهدة مثال + مدة زر التخطي + المدة التي تظهر فيها أزرار التخطي والتخطي إلى التمييز المخفية تلقائيًا + إظهار إشعار التراجع عن التخطي + يظهر إشعار عند تخطي مقطع تلقائيًا. انقر على الإشعار للتراجع عن التخطي. + لا يتم عرض التوست + مدة توست التخطي + المدة التي يظهر فيها إشعار التخطي + ثانية واحدة + ثانيتان + 3 ثوانٍ + 4 ثوانٍ + 5 ثوانٍ + 6 ثوانٍ + 7 ثوانٍ + 8 ثوانٍ + 9 ثوانٍ + 10 ثوانٍ عرض مدة الفيديو بدون المقاطع - يعرض مدة الفيديو ناقصًا منه جميع المقاطع بين قوسين بجوار مدة الفيديو الكاملة + يتم عرض طول الفيديو مطروحًا منه جميع المقاطع على شريط التقدم يتم عرض مدة الفيديو كاملةً إنشاء مقاطع جديدة عرض زر إنشاء مقطع جديد diff --git a/patches/src/main/resources/addresources/values-az-rAZ/strings.xml b/patches/src/main/resources/addresources/values-az-rAZ/strings.xml index 0271d8db4..b95bd8e4f 100644 --- a/patches/src/main/resources/addresources/values-az-rAZ/strings.xml +++ b/patches/src/main/resources/addresources/values-az-rAZ/strings.xml @@ -285,10 +285,6 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız." Video təsviri Video təsviri elementlərini gizlət və ya göstər Filtr çubuğu - Axında, axtarış nəticələrində və əlaqəli videolarda filtr cərgəsin gizlət və ya göstər - Axında gizlət - Axında gizlidir - Axında göstərilir Axtarış nəticələrində gizlət Axtarış nəticələrində gizlədilib Axtarış nəticələrində göstərilir @@ -956,11 +952,7 @@ Bu funksiya 720p və ya daha aşağı video keyfiyyəti ilə və çox sürətli Ötürmə düyməsini avtomatik gizlət Ötürmə düyməsi bir neçə saniyə sonra gizlənir Ötürmə düyməsi bütün bölüm ərzində göstərilir - Ötürüləndə ani bildiriş göstər - Bölüm avto-ötürüləndə bildiriş göstərilir. Nümunə görmək üçün bura toxun - Bildiriş göstərilmir. Nümunə görmək üçün bura toxun Bölümsüz video uzunluğun göstər - Video uzunluğu bütün bölümləri silir, tam video uzunluğu yanaşı mötərizədə göstərilir Tam video uzunluğu göstərilir Yeni bölümlər yaradılır Yeni Bölüm Yarat Düyməsini Göstər diff --git a/patches/src/main/resources/addresources/values-be-rBY/strings.xml b/patches/src/main/resources/addresources/values-be-rBY/strings.xml index 5388cac7b..8cb2733ef 100644 --- a/patches/src/main/resources/addresources/values-be-rBY/strings.xml +++ b/patches/src/main/resources/addresources/values-be-rBY/strings.xml @@ -285,10 +285,13 @@ Second \"item\" text" Апісанне відэа Схаваць або паказаць кампаненты апісання відэа Панэль фільтраў - Схаваць ці паказаць панэль фільтраў у стужцы, выніках пошуку і звязаных відэа - Схаваць у карме - Схаваны ў стужцы - Паказваецца ў стужцы + Схаваць ці паказаць панэль фільтраў у стужках, гісторыі, выніках пошуку і звязаных відэа + Схаваць у стужках + Схавана ў стужках + Паказана ў стужках + Схаваць у гісторыі + Схавана ў гісторыі + Паказана ў гісторыі Схаваць у выніках пошуку Схавана ў выніках пошуку Паказана ў выніках пошуку @@ -957,11 +960,25 @@ Second \"item\" text" Аўтаматычна хаваць кнопку «Прапусціць» Кнопка \"Прапусціць\" скрываецца праз некалькі секунд Кнопка «Прапусціць» паказана для ўсяго сегмента - Паказваць toast пры пропуску - Тост паказваецца, калі сегмент аўтаматычна прапускаецца. Націсніце тут, каб убачыць прыклад - Тост не паказваецца. Націсніце тут, каб убачыць прыклад + Працягласць кнопкі пропуску + Як доўга адлюстроўваюцца кнопкі аўтаматычнага хавання прапуску і пераходу да вылучэння + Паказаць усплываючае паведамленне для адмены прапуску + Усплываючае паведамленне паказваецца, калі сегмент аўтаматычна прапускаецца. Націсніце на ўсплываючае паведамленне, каб адмяніць прапуск + Усплывальнае апавяшчэнне не паказваецца + Працягласць усплывальнага апавяшчэння пра пропуск + Як доўга адлюстроўваецца ўсплываючае паведамленне пра прапуск + 1 секунда + 2 секунды + 3 секунды + 4 секунды + 5 секунд + 6 секунд + 7 секунд + 8 секунд + 9 секунд + 10 секунд Паказаць працягласць відэа без сегментаў - Працягласць відэа мінус усе сегменты, паказана ў дужках побач з поўнай працягласцю відэа + Даўжыня відэа без усіх сегментаў паказваецца на шкале пракруткі Паказана поўная даўжыня відэа Стварэнне новых сегментаў Паказваць кнопку «Стварыць новы сегмент» diff --git a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml index 6bd566681..bd0a8e617 100644 --- a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml +++ b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml @@ -285,10 +285,13 @@ Second \"item\" text" Описание на видеото Скриване или показване на компонентите за описание на видеоклиповете Лента с филтри - Скриване или показване на лентата за филтриране в емисията, резултатите от търсенето и свързаните видеоклипове - Скриване на горната лента с категории в емисията - Скрита - Показва се + Скриване или показване на лентата с филтри в емисиите, историята, резултатите от търсенето и свързаните видеоклипове + Скриване в емисии + Скрити в емисии + Показани в емисии + Скриване в историята + Скрити в историята + Показани в историята Скриване в резултатите от търсенето Скрито в резултатите от търсенето Показано в резултатите от търсенето @@ -957,11 +960,25 @@ Second \"item\" text" Автоматично скриване на бутона \"Пропускане\" Бутона за пропускане се скрива след няколко секунди Бутонът \"Пропускане\" е показан за целия сегмент - Показване на toast при пропускане - Показване на известие при автоматично пропусната част. Докоснете тук за пример - Известието не се показва. Докоснете тук за пример + Продължителност на бутона за пропускане + Колко дълго се показват бутоните за автоматично скриване на пропускане и за пропускане до акцент + Показване на известие за отмяна на пропускането + Показва се известие, когато сегмент е автоматично пропуснат. Докоснете известието, за да отмените пропускането. + Изскачащо съобщение не се показва + Продължителност на изскачащото съобщение за пропускане + Колко дълго се показва известието за пропускане + 1 секунда + 2 секунди + 3 секунди + 4 секунди + 5 секунди + 6 секунди + 7 секунди + 8 секунди + 9 секунди + 10 секунди Показване на дължината на видеото без сигментите - Дължината на видеото без всички части показана в скоби до цялата дължина + Дължината на видеото без всички сегменти се показва на лентата за напредък Цялата дължина на видето се показва Създаване на нови части Показване на бутон \"Създаване на нов сегмент\" diff --git a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml index f0acaa9e9..8a29b0f08 100644 --- a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml +++ b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml @@ -281,10 +281,13 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ ভিডিওর বিবরণ ভিডিও বিবরণ এর উপাদান লুকান বা প্রদর্শন করুন ফিল্টার বার - ফিড, অনুসন্ধানের ফলাফল এবং সম্পর্কিত ভিডিওগুলোতে ফিল্টার বার লুকান অথবা দেখান + ফিড, ইতিহাস, অনুসন্ধান ফলাফল এবং সম্পর্কিত ভিডিওগুলিতে ফিল্টার বার লুকান বা দেখান ফিডে লুকান - ফিডে লুকিয়ে রয়েছে - ফিডে প্রদর্শিত হয়েছে + ফিডে লুকানো + ফিডে দেখানো হয়েছে + ইতিহাসে লুকান + ইতিহাসে লুকানো + ইতিহাসে দেখানো হয়েছে অনুসন্ধান ফলাফলে লুকান অনুসন্ধান ফলাফলে লুকানো আছে অনুসন্ধান ফলাফলে দেখানো হয়েছে @@ -953,11 +956,25 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন Skip বোতামটি স্বয়ংক্রিয়ভাবে লুকান কয়েক সেকেন্ড পরে স্কিপ বোতাম লুকিয়ে যায় পুরো অংশের জন্য Skip বোতাম দেখানো হয়েছে - বাদ দেওয়ার সময় একটি toast দেখান - সেগমেন্ট স্বয়ংক্রিয়ভাবে এড়িয়ে যেতে একটি টোস্ট দেখানো হয়। উদাহরণ দেখতে এখানে ট্যাপ করুন - টোস্ট দেখানো হচ্ছে না। উদাহরণ দেখতে এখানে ট্যাপ করুন + স্কিপ বোতামের সময়কাল + অটো হাইড স্কিপ এবং হাইলাইট বোতাম কতক্ষণ দেখানো হয় + স্কিপ পূর্বাবস্থায় ফিরিয়ে আনার টোস্ট দেখান + যখন একটি সেগমেন্ট স্বয়ংক্রিয়ভাবে এড়িয়ে যাওয়া হয় তখন টোস্ট দেখানো হয়। স্কিপ পূর্বাবস্থায় ফিরিয়ে আনতে টোস্ট বিজ্ঞপ্তিতে ট্যাপ করুন + টোস্ট দেখানো হয়নি + টোস্ট এড়িয়ে যাওয়ার সময়কাল + স্কিপ টোস্ট বিজ্ঞপ্তি কতক্ষণ দেখানো হয় + ১ সেকেন্ড + ২ সেকেন্ড + ৩ সেকেন্ড + ৪ সেকেন্ড + ৫ সেকেন্ড + ৬ সেকেন্ড + ৭ সেকেন্ড + ৮ সেকেন্ড + ৯ সেকেন্ড + ১০ সেকেন্ড সেগমেন্ট ছাড়া ভিডিওর দৈর্ঘ্য দেখান - সমস্ত সেগমেন্ট ছাড়াই ভিডিওর দৈর্ঘ্য, পূর্ণ ভিডিওর দৈর্ঘ্যের পাশে বন্ধনীতে উল্লেখ করা হয় + ভিডিওর দৈর্ঘ্য থেকে সব অংশ বাদ দিয়ে সিকারবারে দেখানো হবে সম্পূর্ণ ভিডিও দৈর্ঘ্য প্রদর্শিত হয়েছে নতুন সেগমন্ট তৈরি হচ্ছে নতুন বিভাগ তৈরি করুন বোতামটি দেখান diff --git a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml index 6aea3e1e5..456c783fd 100644 --- a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml +++ b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml @@ -285,10 +285,13 @@ Nebudete informováni o žádné neočekávané události." Popis videa Skrýt nebo zobrazit komponenty popisu videa Lišta filtrů - Skrýt nebo zobrazit lištu filtrů v kanálu, výsledcích hledání a souvisejících videích - Skrýt ve feedu - Ve feedu skryto - Ve feedu zobrazeno + Skrýt nebo zobrazit panel filtru v kanálech, historii, výsledcích vyhledávání a souvisejících videích + Skrýt v kanálech + Skryto v kanálech + Zobrazeno v kanálech + Skrýt v historii + Skryto v historii + Zobrazeno v historii Skrýt ve výsledcích vyhledávání Skryto ve výsledcích vyhledávání Zobrazeno ve výsledcích vyhledávání @@ -958,11 +961,25 @@ Tato funkce funguje nejlépe s kvalitou videa 720p nebo nižší a při použit Automaticky skrýt tlačítko Přeskočit Tlačítko pro přeskočení se skrývá po několika sekundách Tlačítko Přeskočit se zobrazuje pro celý segment - Zobrazit toast při přeskakování - \"Toast\" se zobrazí, když se segment automaticky přeskočí. Klepněte zde, abyste se podívali na příklad - \"Toast\" se nezobrazí. Klepněte zde, abyste se podívali na příklad + Doba trvání tlačítka přeskočení + Jak dlouho se zobrazují tlačítka pro automatické skrytí přeskočení a přeskočení na zvýraznění + Zobrazit hlásku pro zrušení přeskočení + Hláska se zobrazí, když je segment automaticky přeskočen. Klepněte na hlásku pro zrušení přeskočení. + Toast se nezobrazuje + Doba trvání toastu přeskočení + Jak dlouho se zobrazuje hláska pro přeskočení + 1 sekunda + 2 sekundy + 3 sekundy + 4 sekundy + 5 sekund + 6 sekund + 7 sekund + 8 sekund + 9 sekund + 10 sekund Zobrazit délku videa bez segmentů - Délka videa minus všechny segmenty, zobrazená v závorkách vedle úplné délky videa + Na posuvníku je zobrazena délka videa minus všechny segmenty Zobrazena úplná délka videa Vytváření nových segmentů Zobrazit tlačítko Vytvořit nový segment diff --git a/patches/src/main/resources/addresources/values-da-rDK/strings.xml b/patches/src/main/resources/addresources/values-da-rDK/strings.xml index 67ccc2df4..5d1f84f64 100644 --- a/patches/src/main/resources/addresources/values-da-rDK/strings.xml +++ b/patches/src/main/resources/addresources/values-da-rDK/strings.xml @@ -285,10 +285,13 @@ Du modtager ikke notifikationer om uventede hændelser." Video beskrivelse Skjul eller vis komponenter til videobeskrivelse Filtrer bjælke - Skjul eller vis filterlinjen i feedet, søgeresultaterne og relaterede videoer - Skjul i feed - Skjult i feed - Vist i feed + Skjul eller vis filterlinjen i feeds, historik, søgeresultater og relaterede videoer + Skjul i feeds + Skjult i feeds + Vist i feeds + Skjul i historik + Skjult i historik + Vist i historik Skjul i søgeresultater Skjult i søgeresultater Vises i søgeresultater @@ -959,11 +962,25 @@ Denne funktion fungerer bedst med en videokvalitet på 720p eller lavere og ved Skjul automatisk Spring over-knap Skip knap skjuler efter et par sekunder Spring over-knappen vises for hele segmentet - Vis en toast ved spring - Toast vises, når et segment automatisk springes over. Tryk her for at se et eksempel - Toast er ikke vist. Tryk her for at se et eksempel + Spring over-knap varighed + Hvor længe knapperne til automatisk skjuling af overspring og spring til højdepunkt vises + Vis fortryd oversprings-toast + Toast vises, når et segment automatisk springes over. Tryk på toast-meddelelsen for at fortryde overspringelsen. + Toast vises ikke + Spring over-toast varighed + Hvor længe toast-meddelelsen ved overspringelse vises + 1 sekund + 2 sekunder + 3 sekunder + 4 sekunder + 5 sekunder + 6 sekunder + 7 sekunder + 8 sekunder + 9 sekunder + 10 sekunder Vis videolængde uden segmenter - Videolængde minus alle segmenter, vist i parentes ved siden af den fulde videolængde + Videolængde minus alle segmenter vises på tidslinjen Fuld videolængde vist Opretter nye segmenter Vis Opret nyt segment-knap diff --git a/patches/src/main/resources/addresources/values-de-rDE/strings.xml b/patches/src/main/resources/addresources/values-de-rDE/strings.xml index 804763c93..098c2f3bd 100644 --- a/patches/src/main/resources/addresources/values-de-rDE/strings.xml +++ b/patches/src/main/resources/addresources/values-de-rDE/strings.xml @@ -281,10 +281,13 @@ Sie werden nicht über unerwartete Ereignisse informiert." Videobeschreibung Komponenten der Videobeschreibung ausblenden oder anzeigen Filterleiste - Die Filterleiste im Feed, in den Suchergebnissen und in verwandten Videos ein- oder ausblenden - Im Feed ausblenden - Versteckt im Feed - Im Feed angezeigt + Filterleiste in den Feeds, im Verlauf, in den Suchergebnissen und in ähnlichen Videos ein- oder ausblenden + In Feeds ausblenden + In Feeds ausgeblendet + In Feeds angezeigt + Im Verlauf ausblenden + Im Verlauf ausgeblendet + Im Verlauf angezeigt In Suchergebnissen ausblenden In Suchergebnissen versteckt In den Suchergebnissen angezeigt @@ -950,11 +953,25 @@ Diese Funktion funktioniert am besten mit einer Videoqualität von 720p oder nie Überspringen-Button automatisch ausblenden Überspringe Taste verbirgt sich nach ein paar Sekunden Die Schaltfläche \"Überspringen\" wird für das gesamte Segment angezeigt - Einen toast beim Überspringen anzeigen - Toast wird angezeigt, wenn ein Segment automatisch übersprungen wird. Tippe hier, um ein Beispiel zu sehen - Toast wird nicht angezeigt. Tippe hier, um ein Beispiel zu sehen + Dauer des Überspringen-Buttons + Wie lange die automatisch ausgeblendeten Schaltflächen zum Überspringen und zum Springen zur Markierung angezeigt werden + Toast zum Rückgängigmachen des Überspringens anzeigen + Ein Toast wird angezeigt, wenn ein Segment automatisch übersprungen wird. Tippen Sie auf die Toast-Benachrichtigung, um das Überspringen rückgängig zu machen. + Toast-Nachricht wird nicht angezeigt + Dauer der Überspring-Toastmeldung + Wie lange die Überspringen-Toast-Benachrichtigung angezeigt wird + 1 Sekunde + 2 Sekunden + 3 Sekunden + 4 Sekunden + 5 Sekunden + 6 Sekunden + 7 Sekunden + 8 Sekunden + 9 Sekunden + 10 Sekunden Videolänge ohne Segmente anzeigen - Videolänge abzüglich aller Segmente in Klammern neben der vollständigen Videolänge + Videolänge abzüglich aller Segmente wird in der Suchleiste angezeigt Vollständige Videolänge angezeigt Neue Segmente erstellen Schaltfläche \"Neues Segment erstellen\" anzeigen diff --git a/patches/src/main/resources/addresources/values-el-rGR/strings.xml b/patches/src/main/resources/addresources/values-el-rGR/strings.xml index 178208fc2..39de0fcc8 100644 --- a/patches/src/main/resources/addresources/values-el-rGR/strings.xml +++ b/patches/src/main/resources/addresources/values-el-rGR/strings.xml @@ -287,10 +287,13 @@ Second \"item\" text" Περιγραφή βίντεο Απόκρυψη ή εμφάνιση στοιχείων περιγραφής βίντεο Γραμμή φίλτρων - Απόκρυψη ή εμφάνιση της γραμμής φίλτρων στην ροή, στα αποτελέσματα αναζήτησης και στα σχετικά βίντεο - Απόκρυψη στη ροή + Απόκρυψη ή εμφάνιση της γραμμής φίλτρων στις ροές, στο ιστορικό, στα αποτελέσματα αναζήτησης και στα σχετικά βίντεο + Απόκρυψη στις ροές Κρυμμένη Εμφανίζεται + Απόκρυψη στο ιστορικό + Κρυμμένη + Εμφανίζεται Απόκρυψη στα αποτελέσματα αναζήτησης Κρυμμένη Εμφανίζεται @@ -959,11 +962,25 @@ Second \"item\" text" Αυτόματη απόκρυψη κουμπιού παράλειψης Το κουμπί παράλειψης κρύβεται μετά από μερικά δευτερόλεπτα Το κουμπί παράλειψης εμφανίζεται σε όλο το τμήμα - Εμφάνιση μηνύματος κατά την παράλειψη - Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης όταν ένα τμήμα παραλείπεται αυτόματα. Πατήστε για να δείτε ένα παράδειγμα - Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης. Πατήστε για να δείτε ένα παράδειγμα + Διάρκεια κουμπιού παράλειψης + Διάρκεια εμφάνισης των κουμπιών αυτόματης απόκρυψης παράλειψης και μετάβασης σε επισήμανση + Εμφάνιση μηνύματος αναίρεσης παράλειψης + Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης όταν ένα τμήμα παραλείπεται αυτόματα. Πατήστε το μήνυμα για αναίρεση της παράλειψης + Το μήνυμα δεν εμφανίζεται + Διάρκεια μηνύματος παράλειψης + Πόση ώρα εμφανίζεται το μήνυμα παράλειψης + 1 δευτερόλεπτο + 2 δευτερόλεπτα + 3 δευτερόλεπτα + 4 δευτερόλεπτα + 5 δευτερόλεπτα + 6 δευτερόλεπτα + 7 δευτερόλεπτα + 8 δευτερόλεπτα + 9 δευτερόλεπτα + 10 δευτερόλεπτα Εμφάνιση μήκους βίντεο χωρίς τα τμήματα - Εμφανίζεται το μήκος βίντεο μείον όλα τα τμήματα, σε παρένθεση δίπλα στο πλήρες μήκος βίντεο + Το μήκος του βίντεο μείον όλα τα τμήματα εμφανίζεται στη γραμμή αναζήτησης Εμφανίζεται το πλήρες μήκος του βίντεο Δημιουργία νέων τμημάτων Εμφάνιση κουμπιού δημιουργίας νέου τμήματος diff --git a/patches/src/main/resources/addresources/values-es-rES/strings.xml b/patches/src/main/resources/addresources/values-es-rES/strings.xml index a110250e5..8b2d8e1a4 100644 --- a/patches/src/main/resources/addresources/values-es-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-es-rES/strings.xml @@ -282,10 +282,13 @@ Sin embargo, si activas esto, también se registrarán algunos datos del usuario Descripción del vídeo Ocultar o mostrar componentes de descripción de vídeo Barra de filtros - Ocultar o mostrar la barra de filtro en el feed, los resultados de búsqueda y los videos relacionados - Ocultar en el feed - Escondido en el feed - Mostrar en el feed + Ocultar o mostrar la barra de filtros en las fuentes, historial, resultados de búsqueda y vídeos relacionados + Ocultar en feeds + Oculto en feeds + Visible en feeds + Ocultar en el historial + Oculto en el historial + Visible en el historial Ocultar en los resultados de búsqueda Oculto en los resultados de búsqueda Mostrado en los resultados de búsqueda @@ -954,11 +957,25 @@ Esta función funciona mejor con una calidad de vídeo de 720p o inferior y cuan Ocultar automáticamente el botón Saltar Omitir botón se oculta después de unos segundos Se muestra el botón Saltar para todo el segmento - Mostrar un toast al saltar - Toast se muestra cuando un segmento se omite automáticamente. Pulse aquí para ver un ejemplo - Toast no se muestra. Toque aquí para ver un ejemplo + Duración del botón Omitir + ¿Cuánto tiempo se muestran automáticamente los botones de omitir y omitir para resaltar? + Mostrar mensaje emergente para deshacer omisión + Se muestra un mensaje emergente cuando un segmento se omite automáticamente. Toca la notificación de mensaje emergente para deshacer la omisión. + El mensaje emergente no se muestra + Duración del mensaje emergente al omitir + ¿Cuánto tiempo se muestra la notificación de mensaje emergente de omisión? + 1 segundo + 2 segundos + 3 segundos + 4 segundos + 5 segundos + 6 segundos + 7 segundos + 8 segundos + 9 segundos + 10 segundos Mostrar longitud de vídeo sin segmentos - Longitud del vídeo menos todos los segmentos, mostrados en paréntesis junto a la longitud completa del vídeo + La duración del vídeo, excluyendo todos los segmentos, se muestra en la barra de progreso Longitud completa del vídeo mostrada Creando nuevos segmentos Mostrar el botón Crear nuevo segmento diff --git a/patches/src/main/resources/addresources/values-et-rEE/strings.xml b/patches/src/main/resources/addresources/values-et-rEE/strings.xml index 65129110a..456557db2 100644 --- a/patches/src/main/resources/addresources/values-et-rEE/strings.xml +++ b/patches/src/main/resources/addresources/values-et-rEE/strings.xml @@ -285,10 +285,13 @@ Teid ei teavitata ühestki ootamatust sündmusest." Video kirjeldus Peida videokirjelduse komponendid või kuva need Filtriseriba - Peida või näita filtripaneeli voos, otsingutulemustes ja seotud videotes - Peida söötes - Peidetud söötes - Näidatud söötes + Peida või näita filtririba voogudes, ajaloos, otsingutulemustes ja seotud videotes + Peida voogudes + Peidetud voogudes + Näidatud voogudes + Peida ajaloos + Peidetud ajaloos + Näidatud ajaloos Peida otsingutulemustes Peidetud otsingutulemustes Kuvatakse otsingutulemustes @@ -956,11 +959,25 @@ See funktsioon toimib kõige paremini 720p või madalama video kvaliteedi ja vä Peida vahelejätmisnupp automaatselt Vahelejätmisnupp peitub mõne sekundi pärast Vahelejätmise nupp on kuvatud kogu segmendi jaoks - Näita toast teadet vahelejätmisel - Teatis näidatakse, kui segment vahele jäetakse automaatselt. Puuduta siia, et näha näidet - Teatist ei näidata. Puuduta siia, et näha näidet + Vahelejätnud nupu kestus + Kui kaua kuvatakse automaatselt peidetud nuppe \"jäta vahele\" ja \"jäta esiletõstmise juurde\" + Kuva tühista vahelejätmise teavitus (toast) + Teavitus (toast) kuvatakse, kui segment jäetakse automaatselt vahele. Vahelejätmise tühistamiseks puudutage teavitust (toast). + Hüpikut ei kuvata + Vahelejätnud hüpiku kestus + Kui kaua kuvatakse vahelejätmise teavitust (toast) + 1 sekund + 2 sekundit + 3 sekundit + 4 sekundit + 5 sekundit + 6 sekundit + 7 sekundit + 8 sekundit + 9 sekundit + 10 sekundit Näita video pikkust ilma segmentideta - Video pikkus miinus kõik segmendid, kuvatakse sulgudes täispika video pikkuse kõrval + Video pikkus miinus kõik segmendid kuvatakse edenemisribal Näidatakse täispikk video pikkust Uute segmentide loomine Näita Uue segmendi loomise nuppu diff --git a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml index d87229191..58be93e9b 100644 --- a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml +++ b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml @@ -285,10 +285,6 @@ Et saa ilmoituksia odottamattomista tapahtumista." Videon kuvaus Piilota tai näytä videon kuvauksen osia Suodatinpalkki - Piilota tai näytä suodatinpalkki syötteessä, haussa ja liittyvissä videoissa - Piilota syötteessä - Piilotettu syötteessä - Näytetään syötteessä Piilota hakutuloksissa Piilotettu hakutuloksissa Näytetään hakutuloksissa @@ -954,11 +950,7 @@ Tämä ominaisuus toimii parhaiten, kun videon laatu on 720p tai alhaisempi ja k Piilota ohita-painike automaattisesti Ohita-painike piiloutuu muutaman sekunnin kuluttua Ohita-painike näytetään koko osion ajan - Näytä ilmoitus ohitettaessa - Ponnahdusilmoitus näytetään, kun osio ohitetaan automaattisesti. Napauta tästä nähdäksesi esimerkin - Ponnahdusilmoitusta ei näytetä. Napauta tästä nähdäksesi esimerkin Näytä videon pituus ilman osioita - Videon pituus ilman osioita, näytetään suluissa koko videon pituuden vieressä Videon koko pituus näytetään Uusien osioiden luominen Näytä Luo uusi osio -painike diff --git a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml index 010fdcec1..eb345427e 100644 --- a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml +++ b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml @@ -285,10 +285,13 @@ Hindi ka aabisuhan ng anumang hindi inaasahang mga kaganapan." Paglalarawan ng video Itago o ipakita ang mga bahagi ng paglalarawan ng video Bar ng filter - Itago o ipakita ang filter bar sa feed, mga resulta ng paghahanap, at mga kaugnay na video - Itago sa feed - Nakatago sa feed - Ipinapakita sa feed + Itago o ipakita ang filter bar sa mga feed, history, mga resulta ng paghahanap, at mga kaugnay na video + Itago sa mga feed + Nakatago sa mga feed + Ipinapakita sa mga feed + Itago sa kasaysayan + Nakatago sa kasaysayan + Ipinapakita sa kasaysayan Itago sa mga resulta ng paghahanap Nakatago sa mga resulta ng paghahanap Ipinapakita sa mga resulta ng paghahanap @@ -951,11 +954,25 @@ Ang tampok na ito ay pinakamahusay na gumagana sa kalidad ng video na 720p o mas Awtomatikong itago ang button na Laktawan Tinatago ang pindutan ng skip pagkatapos ng ilang segundo Ipinapakita ang button na Laktawan para sa buong segment - Magpakita ng toast kapag lumaktaw - Ang toast ay ipinapakita kapag ang isang segment ay awtomatikong nilaktawan. Mag-tap dito para makakita ng halimbawa - Hindi ipinapakita ang toast. Mag-tap dito para makakita ng halimbawa + Tagal ng pindutan ng Paglaktaw + Gaano katagal ipinapakita ang mga pindutan ng awtomatikong pagtago ng laktaw at laktaw upang i-highlight + Ipakita ang undo skip toast + Ipinapakita ang toast kapag awtomatikong nilaktawan ang isang segment. Tapikin ang notipikasyon ng toast upang i-undo ang paglaktaw + Hindi ipinapakita ang toast + Tagal ng toast sa paglaktaw + Gaano katagal ipinapakita ang notipikasyon ng skip toast + 1 segundo + 2 segundo + 3 segundo + 4 segundo + 5 segundo + 6 segundo + 7 segundo + 8 segundo + 9 segundo + 10 segundo Ipakita ang haba ng video nang walang mga segment - Haba ng video na binawasan ang lahat ng mga segment, na ipinapakita sa mga panaklong sa tabi ng buong haba ng video + Ang haba ng video nang walang lahat ng segment ay ipinapakita sa seekbar Ipinapakita ang buong haba ng video Paglikha ng mga bagong segment Ipakita ang button na Gumawa ng bagong segment diff --git a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml index c89aa7c76..daf87f89e 100644 --- a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml +++ b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml @@ -285,10 +285,13 @@ Vous ne serez pas informé des événements inattendus." Description de la vidéo Masquez ou affichez des éléments dans la description des vidéos Barre des filtres - Masquez ou affichez la barre des filtres dans le flux, les résultats de recherche et les vidéos similaires - Masquer dans le flux - Masquée dans le flux - Affichée dans le flux + Masquez ou affichez la barre des filtres dans les flux, l\'historique, les résultats de recherche et les vidéos associées + Masquer dans les flux + Masquée dans les flux + Affichée dans les flux + Masquer dans l\'historique + Masquée dans l\'historique + Affichée dans l\'historique Masquer dans les résultats de recherche Masquée dans les résultats de recherche Affichée dans les résultats de recherche @@ -959,11 +962,25 @@ Cette fonctionnalité fonctionne de manière optimale avec une qualité vidéo d Masquer automatiquement le bouton Passer Le bouton Passer est masqué après quelques secondes Le bouton Passer est affiché pendant toute la durée du segment - Afficher un message toast lorsqu\'un segment est passé - Un message toast est affiché lorsqu\'un segment est passé automatiquement. Appuyez ici pour voir un exemple. - Message toast non affiché. Appuyez ici pour voir un exemple. + Durée du bouton Ignorer + Durée d\'affichage des boutons de masquage automatique de saut et de saut vers le surlignage + Afficher le toast d\'annulation de saut + Un toast s\'affiche lorsqu\'un segment est automatiquement sauté. Touchez la notification toast pour annuler le saut. + Le message n\'est pas affiché + Durée du message Ignorer + Durée d\'affichage de la notification toast de saut + 1 seconde + 2 secondes + 3 secondes + 4 secondes + 5 secondes + 6 secondes + 7 secondes + 8 secondes + 9 secondes + 10 secondes Afficher la durée de la vidéo sans les segments - Durée de la vidéo moins tous les segments, affichée entre parenthèses à côté de la durée totale de la vidéo + La durée de la vidéo moins tous les segments est affichée sur la barre de progression Affichage de la durée totale de la vidéo Création de nouveaux segments Afficher le bouton Créer un segment diff --git a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml index 65e1a0a0d..2963249ae 100644 --- a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml +++ b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml @@ -285,10 +285,13 @@ Ní chuirfear ar an eolas thú faoi aon imeachtaí gan choinne." Cur síos físeán Folaigh nó taispeáint comhpháirteanna tuairisc Barra scagaire - Folaigh nó taispeáin an barra scagaire sa sruth, torthaí cuardaigh agus físeáin ghaolmhara - Folaigh i mbeatha - I bhfolach i mbeatha - Taispeántar i mbeatha + Folaigh nó taispeáin an barra scagaire sna fothaí, stair, torthaí cuardaigh, agus físeáin ghaolmhara + Folaigh i bhfothaí + I bhfolach i bhfothaí + Taispeánta i bhfothaí + Folaigh sa stair + I bhfolach sa stair + Taispeánta sa stair Folaigh i dtorthaí cuardaigh Folaigh i dtorthaí cuardaigh Taispeáin i dtorthaí cuardaigh @@ -957,11 +960,25 @@ Oibríonn an ghné seo is fearr le caighdeán físeáin 720p nó níos ísle agu Folaigh cnaipe Scipeála go huathoibríoch Folaíonn cnaipe scipeáil tar éis cúpla soicindí Taispeántar cnaipe Scipeála don deighleog iomlán - Taispeáin tósta agus tú ag scipeáil - Taispeántar tósta nuair a scipeántar deighleog go huathoibríoch. Tapáil anseo chun sampla a fheiceáil - Ní thaispeántar tósta. Tapáil anseo chun sampla a fheiceáil + Fad an chnaipe scipeála + Cé chomh fada a thaispeántar na cnaipí uathfholaigh scipeála agus scipeála go buaicphointe + Taispeáin teast cealaigh scipeála + Taispeántar teast nuair a scipeáiltear deighleog go huathoibríoch. Tapáil an fógra teast chun an scipeáil a chealú + Ní thaispeántar an tóstas + Fad an tóstais scipeála + Cé chomh fada a thaispeántar an fógra teast scipeála + 1 soicind + 2 soicind + 3 soicind + 4 soicind + 5 soicind + 6 soicind + 7 soicindí + 8 soicindí + 9 soicindí + 10 soicindí Taispeáin fad físeáin gan codanna - Fad físeáin lúide gach mír, léirithe i lúibíní in aice le fad iomlán an fhíse + Taispeántar fad an fhíseáin lúide na deighleoga uile ar an mbarra cuardaigh Taispeántar fad físe iomlán Deighleoga nua a chruthú Taispeáin cnaipe Cruthaigh deighleog nua diff --git a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml index 636f6a0c6..d0a920858 100644 --- a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml +++ b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml @@ -285,10 +285,13 @@ Nem fog értesülni semmilyen váratlan eseményről." Videóleírás A videóleírás komponenseinek elrejtése vagy megjelenítése Szűrősáv - Szűrősáv elrejtése vagy megjelenítése a hírfolyamban, a keresési eredményekben és a kapcsolódó videókban - Elrejtés a feedekben - Elrejtve a feedekben - Megjelenítés a feedekben + A szűrősáv elrejtése vagy megjelenítése a feedekben, az előzményekben, a keresési eredményekben és a kapcsolódó videókban + Elrejtés a hírcsatornákban + Elrejtve a hírcsatornákban + Megjelenítve a hírcsatornákban + Elrejtés az előzményekben + Elrejtve az előzményekben + Megjelenítve az előzményekben Elrejtés a keresési eredmények között Elrejtve a keresési eredmények között Megjelenítve a keresési eredmények között @@ -957,11 +960,25 @@ Ez a funkció a legjobban 720p vagy annál alacsonyabb videóminőség mellett Az Átugrás gomb automatikus elrejtése A kihagyás gomb néhány másodperc után eltűnik Az Átugrás gomb a teljes szegmenshez megjelenik - toast megjelenítése átugráskor - Felugró üzenet megjelenítése, ha a szakasz automatikusan ki lett hagyva. Koppintson ide egy példa megtekintéséhez - Felugró üzenet nem látható. Koppintson ide egy példa megtekintéséhez + Átugrás gomb időtartama + Meddig láthatók az automatikus elrejtésű átugrás és kiemelés gombok + Ugrás visszavonása felugró értesítés megjelenítése + Felugró értesítés jelenik meg, amikor egy szegmens automatikusan átugrásra kerül. Érintse meg a felugró értesítést az átugrás visszavonásához. + A felugró üzenet nem jelenik meg + Átugrási felugró üzenet időtartama + Meddig látható az átugrás felugró értesítés + 1 másodperc + 2 másodperc + 3 másodperc + 4 másodperc + 5 másodperc + 6 másodperc + 7 másodperc + 8 másodperc + 9 másodperc + 10 másodperc A videó hosszának megjelenítése szegmensek nélkül - A videó hossza mínusz minden szegmens, zárójelben a teljes videó hossza mellett + A videó hossza az összes szegmens nélkül jelenik meg a csúszkán A videó teljes hossza látható Új szegmensek létrehozása Új szegmens létrehozása gomb megjelenítése diff --git a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml index 8e18637ed..b68a0accc 100644 --- a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml +++ b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml @@ -285,10 +285,13 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել Տեսանյութի նկարագրություն Թաքցնել կամ ցույց տալ տեսանյութի նկարագրության բաղադրամասերը Ֆիլտրի գիծ - Թաքցնել կամ ցուցադրել ֆիլտրի գոտին լրահոսում, որոնման արդյունքներում և հարակից տեսանյութերում - Թաքցնել լեզվականում - Թաքցված է լեզվականում - Ցույց է տրվում լեզվականում + Թաքցնել կամ ցուցադրել զտիչի գոտին լրահոսերում, պատմության մեջ, որոնման արդյունքներում և հարակից տեսանյութերում + Թաքցնել լրահոսերում + Թաքցված է լրահոսերում + Ցուցադրված է լրահոսերում + Թաքցնել պատմության մեջ + Թաքցված է պատմության մեջ + Ցուցադրված է պատմության մեջ Թաքցնել որոնման արդյունքներում Թաքնված է որոնման արդյունքներում Ցուցադրված է որոնման արդյունքներում @@ -958,11 +961,25 @@ Seekbar thumbnails-ները կօգտագործեն նույն որակը, ինչ Ավտոմատ կերպով թաքցնել Skip կոճակը Բաց թողնել կոճակը թաքնվում է մի քանի վայրկյանից հետո Skip կոճակը ցուցադրվում է ամբողջ հատվածի համար - Ցուցադրել toast, երբ բաց թողնվի - Toast ցույց է տրվում, երբ segment-ը ավտոմատ կերպով բաց թողնվում է: Տվեք այստեղ, որպեսզի տեսնեք օրինակը - Toast չի ցույց տրվում: Տվեք այստեղ, որպեսզի տեսնեք օրինակը + Բաց թողնելու կոճակի տևողությունը + Ինչքան ժամանակ են ցուցադրվում ավտոմատ թաքնվող բաց թողնելու և առանձնացված մասին անցնելու կոճակները։ + Ցուցադրել բաց թողնելը չեղարկելու ծանուցումը։ + Ծանուցում է ցուցադրվում, երբ հատվածն ավտոմատ կերպով բաց է թողնվում։ Հպեք ծանուցմանը՝ բացթողումը չեղարկելու համար։ + Ծանուցումը չի ցուցադրվում + Բաց թողնելու ծանուցման տևողությունը + Ինչքան ժամանակ է ցուցադրվում բաց թողնելու ծանուցումը։ + 1 վայրկյան + 2 վայրկյան + 3 վայրկյան + 4 վայրկյան + 5 վայրկյան + 6 վայրկյան + 7 վայրկյան + 8 վայրկյան + 9 վայրկյան + 10 վայրկյան Ցույց տալ տեսանյութի երկարությունը առանց segment-ների - Տեսանյութի երկարությունը մինուս բոլոր segment-ները, ցույց է տրվում ամբողջ տեսանյութի երկարության կողքին ծալքերում + Տեսանյութի երկարությունը հանած բոլոր հատվածները ցուցադրվում է որոնման գոտում Ցույց է տրվում ամբողջ տեսանյութի երկարությունը Նոր segment-ների ստեղծում Ցուցադրել նոր հատված ստեղծելու կոճակը diff --git a/patches/src/main/resources/addresources/values-in-rID/strings.xml b/patches/src/main/resources/addresources/values-in-rID/strings.xml index f464a8abd..2a4aef60e 100644 --- a/patches/src/main/resources/addresources/values-in-rID/strings.xml +++ b/patches/src/main/resources/addresources/values-in-rID/strings.xml @@ -285,10 +285,13 @@ Anda tidak akan diberi tahu tentang kejadian yang tidak terduga." Keterangan video Sembunyikan atau tampilkan komponen keterangan video Bilah saring - Sembunyikan atau tampilkan bilah saring di bagian umpan, hasil pencarian, dan video terkait - Sembunyikan di bagian umpan - Disembunyikan di bagian umpan - Tampilkan di bagian umpan + Sembunyikan atau tampilkan bilah penyaring di umpan, riwayat, hasil pencarian, dan video terkait + Sembunyikan di umpan + Disembunyikan di umpan + Ditampilkan di umpan + Sembunyikan di histori + Disembunyikan di riwayat + Ditampilkan di riwayat Sembunyikan di hasil penelusuran Disembunyikan di hasil penelusuran Ditampilkan di hasil penelusuran @@ -957,11 +960,25 @@ Fitur ini bekerja paling baik dengan kualitas video 720p atau lebih rendah dan s Sembunyikan tombol Lewati secara otomatis Tombol lewati disembunyikan setelah beberapa detik Tombol Lewati ditampilkan untuk seluruh segmen - Tampilkan sebuah pesan timbul ketika melewati - Pesan timbul ditampilkan saat segmen dilewati secara otomatis. Tekan di sini untuk melihat contohnya - Pesan timbul tidak ditampilkan. Tekan di sini untuk melihat contohnya + Durasi tombol Lewati + Berapa lama tombol sembunyikan otomatis lewati dan lewati ke sorotan ditampilkan + Tampilkan pembatalan pesan timbul lewati + Pesan timbul ditampilkan saat segmen dilewati secara otomatis. Ketuk notifikasi pesan timbul untuk membatalkan lewati + Pesan timbul tidak ditampilkan + Durasi pesan timbul lewati + Berapa lama notifikasi pesan timbul lewati ditampilkan + 1 detik + 2 detik + 3 detik + 4 detik + 5 detik + 6 detik + 7 detik + 8 detik + 9 detik + 10 detik Tampilkan durasi video tanpa segmen - Durasi video dikurangi semua segmen, ditampilkan dalam tanda kurung di samping durasi video penuh + Durasi video tanpa semua segmen ditampilkan pada bilah pencarian Durasi video penuh ditampilkan Membuat segmen baru Tampilkan tombol Buat segmen baru diff --git a/patches/src/main/resources/addresources/values-it-rIT/strings.xml b/patches/src/main/resources/addresources/values-it-rIT/strings.xml index b6c0493ae..732ba3793 100644 --- a/patches/src/main/resources/addresources/values-it-rIT/strings.xml +++ b/patches/src/main/resources/addresources/values-it-rIT/strings.xml @@ -285,10 +285,13 @@ Non sarai notificato di eventi imprevisti." Descrizione del video Mostra o nascondi i componenti della descrizione del video Barra dei filtri - Nascondi o mostra la barra dei filtri nel feed, nei risultati di ricerca e nei video correlati - Nascondi nel feed - È nascosto nel feed - È visibile nel feed + Nascondi o mostra la barra dei filtri nei feed, nella cronologia, nei risultati di ricerca e nei video correlati + Nascondi nei feed + Nascosto nei feed + Mostrato nei feed + Nascondi nella cronologia + Nascosto nella cronologia + Mostrato nella cronologia Nascondi nei risultati di ricerca Nascosto nei risultati di ricerca Mostrato nei risultati di ricerca @@ -957,11 +960,25 @@ Questa funzione funziona meglio con una qualità video di 720p o inferiore e qua Nascondi automaticamente il pulsante Salta Il pulsante Salta si nasconde dopo alcuni secondi Il pulsante Salta è mostrato per l\'intero segmento - Mostra un toast quando si salta - Mostra una notifica quando un segmento è saltato automaticamente. Tocca qui per vedere un esempio - La notifica è nascosta. Tocca qui per vedere un esempio + Durata pulsante Salta + Per quanto tempo vengono mostrati i pulsanti di nascondimento automatico e di salto all\'evidenziazione + Mostra toast annulla salto + Il toast viene mostrato quando un segmento viene automaticamente saltato. Tocca la notifica toast per annullare il salto. + Il toast non viene mostrato + Durata toast Salta + Per quanto tempo viene mostrata la notifica toast di salto + 1 secondo + 2 secondi + 3 secondi + 4 secondi + 5 secondi + 6 secondi + 7 secondi + 8 secondi + 9 secondi + 10 secondi Mostra la durata del video senza segmenti - La durata del video meno tutti gli eventuali segmenti, visibile tra parentesi accanto alla durata del video completo + La durata del video meno tutti i segmenti è mostrata sulla barra di ricerca La durata totale del video è visibile Creazione di nuovi segmenti Mostra il pulsante Crea nuovo segmento diff --git a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml index 736daedf5..eb34d34c9 100644 --- a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml +++ b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml @@ -285,10 +285,13 @@ Second \"item\" text" תיאור סרטון הסתר או הצג רכיבי תיאור סרטון סרגל סינון - הסתר או הצג את סרגל הסינון בפיד, תוצאות חיפוש, וסרטונים קשורים - הסתר בפיד - מוסתר בפיד - מוצג בפיד + הסתר או הצג את סרגל הסינון בפידים, היסטוריה, תוצאות חיפוש, וסרטונים קשורים + הסתר בפידים + מוסתר בפידים + מוצג בפידים + הסתר בהיסטוריה + מוסתר בהיסטוריה + מוצג בהיסטוריה הסתר בתוצאות חיפוש מוסתר בתוצאות חיפוש מוצג בתוצאות חיפוש @@ -960,11 +963,25 @@ Second \"item\" text" הסתר לחצן דילוג באופן אוטומטי לחצן דילוג נעלם לאחר כמה שניות לחצן דילוג מוצג עבור כל המקטע - הצג הודעה קופצת בעת דילוג - הודעה קופצת מוצגת כאשר מקטע מדולג באופן אוטומטי. הקש כאן כדי לראות דוגמא - הודעה קופצת אינה מוצגת. הקש כאן כדי לראות דוגמה + משך לחצן הדילוג + כמה זמן מוצגים כפתורי הדילוג והדילוג לסימון בהסתרה אוטומטית + הצג הודעה קופצת לביטול דילוג + הודעה קופצת מוצגת כאשר קטע מדולג אוטומטית. הקש על ההודעה הקופצת כדי לבטל את הדילוג + הטוסט לא מוצג + משך טוסט הדילוג + כמה זמן מוצגת ההודעה הקופצת של הדילוג + שנייה אחת + שתי שניות + 3 שניות + 4 שניות + 5 שניות + 6 שניות + 7 שניות + 8 שניות + 9 שניות + 10 שניות הצג אורך סרטון ללא מקטעים - אורך סרטון פחות כל המקטעים, מוצג בסוגריים ליד אורך הסרטון המלא + אורך הסרטון פחות כל המקטעים מוצג על פס הניווט אורך סרטון מלא מוצג יוצר מקטעים חדשים הצג לחצן יצירת מקטע חדש diff --git a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml index 5be0e73ad..3162b5c8a 100644 --- a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml +++ b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml @@ -286,10 +286,13 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 概要欄 概要欄の設定 カテゴリー バー - フィード、検索結果、関連動画の上部にカテゴリーごとに表示されるバーの設定 - フィードのカテゴリー バーを非表示 - カテゴリー バーはフィードに表示されません - カテゴリー バーはフィードに表示されます + フィード、履歴、検索結果、関連動画でフィルターバーを表示または非表示にします + フィードで非表示 + フィードで非表示にします + フィードで非表示にします + 履歴で非表示 + 履歴で非表示にします + 履歴で非表示にします 検索結果のカテゴリー バーを非表示 カテゴリー バーは検索結果に表示されません カテゴリー バーは検索結果に表示されます @@ -376,53 +379,53 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 一般的な広告を非表示 - 一般的な広告は表示されません - 一般的な広告は表示されます + 一般的な広告を非表示にします + 一般的な広告を非表示にします 全画面広告を非表示 - "全画面広告は、アプリ起動時に表示されません + "アプリ起動時の全画面広告を非表示にします この機能は、古いデバイスでのみ利用できます" - 全画面広告は、アプリ起動時に表示されます + アプリ起動時の全画面広告を非表示にします\n\nこの機能は、古いデバイスでのみ利用できます 「プロモーションを含みます」ボタンを非表示 - 「プロモーションを含みます」ボタンはプレーヤー画面に表示されません - 「プロモーションを含みます」ボタンはプレーヤー画面に表示されます + プレーヤー画面の「プロモーションを含みます」ボタンを非表示にします + プレーヤー画面の「プロモーションを含みます」ボタンを非表示にします 自己スポンサー カードを非表示 - 自己スポンサー カードは表示されません - 自己スポンサー カードは表示されます + 自己スポンサー カードを非表示にします + 自己スポンサー カードを非表示にします 「商品を表示」ボタンを非表示 - 「商品を表示」ボタンや商品ボタンはプレーヤー画面に表示されません - 「商品を表示」ボタンや商品ボタンはプレーヤー画面に表示されます + プレーヤー画面の「商品を表示」ボタンや商品ボタンを非表示にします + プレーヤー画面の「商品を表示」ボタンや商品ボタンを非表示にします 終了画面のストアバナーを非表示 - 終了画面のストアバナーは表示されません - 終了画面のストアバナーは表示されます + 終了画面のストアバナーを非表示にします + 終了画面のストアバナーを非表示にします ストア広告を非表示 - ストア広告は表示されません - ストア広告は表示されます + ストア広告を非表示にします + ストア広告を非表示にします 商品へのリンクを非表示 - タグ付けされた商品へのリンクは概要欄に表示されません - タグ付けされた商品へのリンクは概要欄に表示されます + 概要欄のタグ付けされた商品へのリンクを非表示にします + 概要欄のタグ付けされた商品へのリンクを非表示にします 「ストアに移動」ボタンを非表示 - 「ストアに移動」ボタンはチャンネル ページに表示されません - 「ストアに移動」ボタンはチャンネル ページに表示されます + チャンネル ページの「ストアに移動」ボタンを非表示にします + チャンネル ページの「ストアに移動」ボタンを非表示にします ウェブ検索結果を非表示 - ウェブ検索結果は表示されません - ウェブ検索結果は表示されます + ウェブ検索結果を非表示にします + ウェブ検索結果を非表示にします 商品バナーを非表示 - 商品バナーは表示されません - 商品バナーは表示されます + 商品バナーを非表示にします + 商品バナーを非表示にします 全画面広告の非表示は古いデバイス専用です YouTube Premium の広告を非表示 - YouTube Premium の広告は表示されません - YouTube Premium の広告は表示されます + YouTube Premium の広告を非表示にします + YouTube Premium の広告を非表示にします 動画広告を非表示 - 動画広告は表示されません - 動画広告は表示されます + 動画広告を非表示にします + 動画広告を非表示にします URL をクリップボードにコピーしました @@ -775,8 +778,8 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 今後の動画ボタンは表示されません 今後の動画ボタンは表示されます 効果ボタンを非表示 - 効果ボタンは表示されません - 効果ボタンは表示されます + 効果ボタンを非表示にします + 効果ボタンを非表示にします グリーンスクリーン ボタンを非表示 グリーンスクリーン ボタンは表示されません グリーンスクリーン ボタンは表示されます @@ -960,11 +963,25 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に スキップボタンを自動的に非表示 スキップボタンは、表示された数秒後に自動的に非表示になります スキップボタンは、セグメントの開始から終了まで表示されます - スキップ時にトーストを表示する - セグメントが自動的にスキップされると、トースト ポップアップが表示されます。サンプルを表示するには、ここをタップしてください - セグメントが自動的にスキップされても、トースト ポップアップは表示されません。サンプルを表示するには、ここをタップしてください + スキップボタンの表示時間 + 自動非表示のスキップボタンとハイライトへのスキップボタンがどれくらいの期間表示されるか + スキップの取り消しトーストを表示 + セグメントが自動的にスキップされたときにトーストが表示されます。スキップを取り消すには、トースト通知をタップします。 + トーストは表示されません + スキップトーストの表示時間 + スキップトースト通知がどれくらいの期間表示されるか + 1秒 + 2秒 + 3秒 + 4秒 + 5秒 + 6秒 + 7秒 + 8秒 + 9秒 + 10秒 セグメントを除いた再生時間を表示する - セグメントを除いた再生時間が、動画全体の再生時間の横に括弧付きで表示されます + すべてのセグメントを除いた動画の長さがシークバーに表示されます 動画全体の再生時間のみが表示されます セグメントの作成 セグメント作成ボタンを表示する @@ -1387,9 +1404,9 @@ Automotive レイアウト 追跡パラメータはリンクから削除されません - デフォルトでの吹き替え再生を無効にする + デフォルトでの吹き替え再生を無効化 動画を開いたとき、オリジナルの音声が再生されます - 動画を開いたとき、吹き替え音声が再生される場合があります + 動画を開いたとき、オリジナルの音声が再生されます この機能を使用するには、「動画ストリームを偽装する」のクライアントを iOS TV に変更してください diff --git a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml index bf292b350..0d72ce8e3 100644 --- a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml +++ b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml @@ -126,7 +126,7 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 로그 스택 트레이스 디버그 로그에 로그 스택 트레이스를 포함합니다 디버그 로그에 로그 스택 트레이스를 포함하지 않습니다 - ReVanced 오류 팝업 메시지 표시하기 + ReVanced 오류 메시지 표시하기 오류가 발생하면 팝업 메시지를 표시합니다 오류가 발생하면 팝업 메시지를 표시하지 않습니다 "오류 메시지를 비활성화하면 모든 ReVanced 오류 알림이 숨겨집니다. @@ -289,10 +289,13 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 동영상 설명 동영상 설명에서 구성요소를 숨기거나 표시할 수 있습니다 카테고리 바 - 피드, 검색 결과, 관련 동영상에서 카테고리 바를 숨기거나 표시할 수 있습니다 + 피드, 기록, 검색 결과 그리고 관련 동영상에서 카테고리 바를 숨기거나 표시할 수 있습니다 피드에서 카테고리 바 숨기기 피드에서 카테고리 바가 숨겨집니다 피드에서 카테고리 바가 표시됩니다 + 기록에서 카테고리 바 숨기기 + 기록에서 카테고리 바가 숨겨집니다 + 기록에서 카테고리 바가 표시됩니다 검색 결과에서 카테고리 바 숨기기 검색 결과에서 카테고리 바가 숨겨집니다 검색 결과에서 카테고리 바가 표시됩니다 @@ -761,9 +764,9 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 댓글 미리보기 숨기기 댓글 미리보기가 숨겨집니다 댓글 미리보기가 표시됩니다 - (재생목록에) 음악 저장 버튼 숨기기 - (재생목록에) 음악 저장 버튼이 숨겨집니다 - (재생목록에) 음악 저장 버튼이 표시됩니다 + 음악 저장 버튼 숨기기 + 음악 저장 버튼이 숨겨집니다 + 음악 저장 버튼이 표시됩니다 \'이 사운드 사용\' 버튼 숨기기 \'이 사운드 사용\' 버튼이 숨겨집니다 \'이 사운드 사용\' 버튼이 표시됩니다 @@ -901,7 +904,7 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 추정되는 좋아요 수 표시하기 좋아요 수가 숨겨진 동영상에서 추정되는 좋아요 수를 표시합니다 좋아요 수가 숨겨진 동영상에서 추정되는 좋아요 수를 표시하지 않습니다 - API를 사용할 수 없을 때, 팝업 메시지 표시하기 + API 사용 불가 메시지 표시하기 ReturnYouTubeDislike를 사용할 수 없을 때, 팝업 메시지를 표시합니다 ReturnYouTubeDislike를 사용할 수 없을 때, 팝업 메시지를 표시하지 않습니다 싫어요 수의 데이터는 Return YouTube Dislike API에 의해 제공됩니다. 자세한 내용을 보려면 여기를 누르세요 @@ -960,12 +963,26 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 자동으로 건너뛰기 버튼 숨기기 건너뛰기 버튼이 몇 초 후에 사라집니다 건너뛰기 버튼이 해당 구간이 끝날 때까지 표시됩니다 - 건너뛸 때, 팝업 메시지 표시하기 - 자동으로 구간을 건너뛸 때, 팝업 메시지를 표시합니다. 여기를 누르면 예시를 볼 수 있습니다 - 자동으로 구간을 건너뛸 때, 팝업 메시지를 표시하지 않습니다. 여기를 누르면 예시를 볼 수 있습니다 + 건너뛰기 버튼 표시 시간 + 자동으로 숨겨지는 \'건너뛰기\' 및 \'하이라이트로 건너뛰기\' 버튼이 표시되는 시간을 설정할 수 있습니다 + 건너뛰기 취소 메시지 표시하기 + 구간을 자동으로 건너뛰는 경우에 팝업 메시지를 표시합니다\n\n팝업 메시지를 눌러서 건너뛰기를 취소할 수 있습니다 + 팝업 메시지를 표시하지 않습니다 + 건너뛰기 팝업 메시지 표시 시간 + 건너뛰기 팝업 메시지가 표시되는 시간을 설정할 수 있습니다 + 1 초 + 2 초 + 3 초 + 4 초 + 5 초 + 6 초 + 7 초 + 8 초 + 9 초 + 10 초 건너뛸 구간을 제외한 시간 표시하기 - 건너뛸 구간을 제외한 전체 동영상 길이를 타임스탬프에 표시합니다 - 건너뛸 구간을 포함한 전체 동영상 길이를 타임스탬프에 표시합니다 + 건너뛸 구간을 제외한 동영상 길이를 재생바에 표시합니다 + 건너뛸 구간을 포함한 동영상 길이를 재생바에 표시합니다 새로운 구간 추가하기 구간 추가 버튼 표시하기 플레이어에서 구간 추가 버튼을 표시합니다 @@ -980,7 +997,7 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 이미 읽음 보기 일반 - API를 사용할 수 없을 때, 팝업 메시지 표시하기 + API 사용 불가 메시지 표시하기 SponsorBlock을 사용할 수 없을 때, 팝업 메시지를 표시합니다 SponsorBlock을 사용할 수 없을 때, 팝업 메시지를 표시하지 않습니다 건너뛴 횟수 기록 활성화하기 @@ -1311,7 +1328,7 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 이 설정을 활성화하면 동영상 URL이 API 서버로 전송되며, 다른 데이터는 전송되지 않습니다. 동영상에 DeArrow 썸네일이 없는 경우에는 원본 썸네일 또는 스틸 컷 썸네일이 표시됩니다 DeArrow에 대해 자세히 알아보려면 여기를 누르세요" - API를 사용할 수 없을 때, 팝업 메시지 표시하기 + API 사용 불가 메시지 표시하기 DeArrow를 사용할 수 없을 때, 팝업 메시지를 표시합니다 DeArrow를 사용할 수 없을 때, 팝업 메시지를 표시하지 않습니다 DeArrow API 엔드포인트 diff --git a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml index 26a64a5eb..f4051be84 100644 --- a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml +++ b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml @@ -285,10 +285,13 @@ Apie netikėtus įvykius nebus pranešta." Vaizdo įrašo aprašymas Slėpti arba rodyti vaizdo įrašo aprašymo komponentus Filtravimo juosta - Slėpti arba rodyti filtrų juostą sklaidoje, paieškos rezultatuose ir susijusiuose vaizdo įrašuose - Slėpti sklaidoje - Paslėpta sklaidoje - Rodoma sklaidoje + Slėpti arba rodyti filtrų juostą sklaidos kanaluose, istorijoje, paieškos rezultatuose ir susijusiuose vaizdo įrašuose. + Slėpti sklaidos kanaluose + Paslėpta sklaidos kanaluose + Matoma sklaidos kanaluose + Slėpti istorijoje + Paslėpta istorijoje + Matoma istorijoje Slėpti paieškos rezultatuose Paslėpta paieškos rezultatuose Rodoma paieškos rezultatuose @@ -955,11 +958,25 @@ Paieškos juostos miniatiūros bus naudojamos tos pačios kokybės kaip dabartin Automatiškai slėpti praleidimo mygtuką Praleidimo mygtukas pasislėps po kelių sekundžių Praleidimo mygtukas rodomas visam segmentui - Rodyti toast praleidžiant - Pranešimas rodomas automatiškai praleidžiant segmentą. Bakstelėkite čia, norėdami pamatyti pavyzdį - Pranešimas nerodomas. Bakstelėkite čia, norėdami pamatyti pavyzdį + Praleidimo mygtuko trukmė + Kiek laiko rodomi automatinio paslėpimo praleidimo ir praleidimo iki paryškinimo mygtukai + Rodyti praleidimo anuliavimo pranešimą + Pranešimas rodomas, kai segmentas automatiškai praleidžiamas. Bakstelėkite pranešimą, norėdami anuliuoti praleidimą + Pranešimas nerodomas + Praleidimo pranešimo trukmė + Kiek laiko rodomas praleidimo pranešimas + 1 sekundė + 2 sekundės + 3 sekundės + 4 sekundės + 5 sekundės + 6 sekundės + 7 sekundės + 8 sekundės + 9 sekundės + 10 sekundžių Rodyti vaizdo įrašo trukmę be segmentų - Vaizdo įrašo trukmė minus visi segmentai, rodoma skliausteliuose šalia visos vaizdo įrašo trukmės + Vaizdo įrašo trukmė be visų segmentų rodoma paieškos juostoje Rodoma visa vaizdo įrašo trukmė Kuriant naujus segmentus Rodyti mygtuką „Kurti naują segmentą“ diff --git a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml index 1382fcb81..9237dda5f 100644 --- a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml +++ b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml @@ -285,10 +285,13 @@ Jūs netiksit informēts par neparedzētiem notikumiem." Videoklipa apraksts Slēpt vai parādīt videoklipa apraksta komponentus Filtra josla - Paslēpt vai rādīt filtru joslu plūsmā, meklēšanas rezultātos un saistītajos videoklipos - Slēpt plūsmā - Paslēpts plūsmā - Redzams plūsmā + Slēpt vai rādīt filtru joslu plūsmās, vēsturē, meklēšanas rezultātos un saistītajos videoklipos + Slēpt plūsmās + Slēpts plūsmās + Rādīts plūsmās + Slēpt vēsturē + Slēpts vēsturē + Rādīts vēsturē Paslēpt meklēšanas rezultātos Paslēpts meklēšanas rezultātos Redzams meklēšanas rezultātos @@ -959,11 +962,25 @@ Laika skalas miniatūras izmantos tādu pašu kvalitāti kā pašreizējais vide Automātiski paslēpt pogu Izlaist Izlaides poga paslēpjas pēc dažām sekundēm Poga Izlaist ir redzama visam segmentam - Rādīt paziņojumu, kad tiek veikta izlaišana - Paziņojums parādās, kad segments tiek automātiski izlaists. Pieskarieties šeit, lai redzētu piemēru - Paziņojums netiek parādīts. Pieskarieties šeit, lai redzētu piemēru + Izlaišanas pogas ilgums + Cik ilgi tiek rādītas automātiskās paslēpšanas izlaišanas un pārejas uz izcēlumu pogas + Rādīt atsaukt izlaišanas paziņojumu + Paziņojums tiek rādīts, kad segments tiek automātiski izlaists. Pieskarieties paziņojumam, lai atsauktu izlaišanu + Paziņojums netiek rādīts + Izlaišanas paziņojuma ilgums + Cik ilgi tiek rādīts izlaišanas paziņojums + 1 sekunde + 2 sekundes + 3 sekundes + 4 sekundes + 5 sekundes + 6 sekundes + 7 sekundes + 8 sekundes + 9 sekundes + 10 sekundes Parādīt video garumu bez segmentiem - Video garums mīnus visi segmenti, parādīts iekavās blakus pilnam video garumam + Video garums bez visiem segmentiem tiek rādīts meklēšanas joslā Pilns video garums parādīts Jaunu segmentu izveide Rādīt pogu Izveidot jaunu segmentu diff --git a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml index 84be60e74..a89da6410 100644 --- a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml +++ b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml @@ -285,10 +285,13 @@ U wordt niet op de hoogte gesteld van onverwachte gebeurtenissen." Videobeschrijving Skjul eller vis komponentene i videoens beskrivelse Filterbaren - De filterbalk in de feed, zoekresultaten en gerelateerde video\'s verbergen of weergeven - Skjul i feed - Sjul i feed - Vis i feed + Filterbalk verbergen of tonen in de feeds, geschiedenis, zoekresultaten en gerelateerde video\'s + Verbergen in feeds + Verborgen in feeds + Weergegeven in feeds + Verbergen in geschiedenis + Verborgen in geschiedenis + Weergegeven in geschiedenis Verbergen in zoekresultaten Verborgen in zoekresultaten Weergegeven in zoekresultaten @@ -957,11 +960,25 @@ Deze functie werkt het beste met een videokwaliteit van 720p of lager en wanneer Skip-knop automatisch verbergen Oversla-knop wordt na een paar seconden verborgen Skip-knop wordt weergegeven voor het hele segment - Een toast weergeven bij overslaan - \"Toast\" wordt weergegeven wanneer een segment automatisch wordt overgeslagen. Tik hier om een voorbeeld te bekijken - \"Toast\" wordt niet weergegeven. Tik hier om een voorbeeld te bekijken + Duur van overslaan-knop + Hoe lang de \"automatisch verbergen overslaan\"- en \"markeer\"-knoppen worden getoond + Toon \"overslaan ongedaan maken\"-melding + Een melding wordt getoond wanneer een segment automatisch wordt overgeslagen. Tik op de melding om het overslaan ongedaan te maken. + Toast wordt niet getoond + Duur van overslaan-toast + Hoe lang de overslaan-melding wordt getoond + 1 seconde + 2 seconden + 3 seconden + 4 seconden + 5 seconden + 6 seconden + 7 seconden + 8 seconden + 9 seconden + 10 seconden Toon de videolengte zonder segmenten - Videolengte minus alle segmenten, weergegeven tussen haakjes naast de volledige videolengte + Videolengte minus alle segmenten wordt getoond op de voortgangsbalk Volledige videolengte weergegeven Nieuwe segmenten maken Knop \'Nieuw segment maken\' weergeven diff --git a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml index 6193adc2c..41a438128 100644 --- a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml +++ b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml @@ -281,10 +281,13 @@ Nie będziesz informowany o żadnych nieoczekiwanych zdarzeniach." Opis filmu Ukryj lub pokaż elementy opisu filmu Pasek filtrowania - Ukryj lub pokaż pasek filtrów w aktualnościach, wynikach wyszukiwania i powiązanych filmach - Na stronie głównej - Ukryte na stronie głównej - Widoczne na stronie głównej + Ukryj lub pokaż pasek filtrów w kanałach, historii, wynikach wyszukiwania i powiązanych filmach + Ukryj w kanałach + Ukryte w kanałach + Pokazane w kanałach + Ukryj w historii + Ukryte w historii + Pokazane w historii Ukryj w wynikach wyszukiwania Ukryte w wynikach wyszukiwania Wyświetlane w wynikach wyszukiwania @@ -953,11 +956,25 @@ Ta funkcja działa najlepiej przy jakości wideo 720p lub niższej i przy korzys Automatycznie ukryj przycisk pomijania Przycisk od pomijania ukrywa się po kilku sekundach Przycisk pomijania jest wyświetlany dla całego segmentu - Pokaż toast podczas pomijania - Komunikat jest wyświetlany, gdy segment zostanie automatycznie pominięty. Dotknij tutaj, aby zobaczyć przykład - Komunikat nie jest wyświetlany. Dotknij tutaj, aby zobaczyć przykład + Czas trwania przycisku pominięcia + Jak długo wyświetlane są przyciski automatycznego ukrywania pomijania i przechodzenia do wyróżnienia + Pokaż komunikat o cofnięciu pominięcia + Komunikat jest wyświetlany, gdy segment zostanie automatycznie pominięty. Dotknij powiadomienia, aby cofnąć pominięcie + Komunikat nie jest wyświetlany + Czas trwania komunikatu pominięcia + Jak długo wyświetlane jest powiadomienie o pominięciu + 1 sekunda + 2 sekundy + 3 sekundy + 4 sekundy + 5 sekund + 6 sekund + 7 sekund + 8 sekund + 9 sekund + 10 sekund Długość filmu bez segmentów - Długość filmu pomniejszona o wszystkie segmenty, wyświetlana w nawiasie obok pełnej długości wideo + Długość wideo pomniejszona o wszystkie segmenty jest wyświetlana na pasku przewijania Pełna długość wideo wyświetlana Tworzenie nowych segmentów Pokaż przycisk „Utwórz nowy segment” diff --git a/patches/src/main/resources/addresources/values-pt-rBR/strings.xml b/patches/src/main/resources/addresources/values-pt-rBR/strings.xml index 4c457132b..c52fe55e6 100644 --- a/patches/src/main/resources/addresources/values-pt-rBR/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rBR/strings.xml @@ -285,10 +285,13 @@ Você não será notificado sobre nenhum evento inesperado." Descrição do vídeo Ocultar ou mostrar componentes de descrição do vídeo Barra de filtro - Ocultar ou mostrar a barra de filtros no feed, nos resultados da pesquisa e nos vídeos relacionados - Ocultar na tela inicial - Está oculto na tela inicial - Não está oculto na tela inicial + Ocultar ou mostrar a barra de filtro nos feeds, histórico, resultados da pesquisa e vídeos relacionados + Ocultar em feeds + Oculto em feeds + Exibido em feeds + Ocultar no histórico + Oculto no histórico + Exibido no histórico Ocultar nos resultados da pesquisa Oculto nos resultados da pesquisa Exibido nos resultados da pesquisa @@ -957,11 +960,25 @@ Este recurso funciona melhor com uma qualidade de vídeo de 720p ou inferior e a Ocultar automaticamente o botão Pular Ocultar botão pular após alguns segundos O botão Pular é mostrado para todo o segmento - Mostrar um toast ao pular - Mostrar uma notificação flutuante quando um segmento é automaticamente pulado. Toque aqui para ver um exemplo - Não mostrar notificação flutuante. Toque aqui para ver um exemplo + Duração do botão Pular + Por quanto tempo os botões de pular e pular para destaque com ocultação automática são exibidos + Mostrar aviso de desfazer pulo + O aviso é exibido quando um segmento é pulado automaticamente. Toque na notificação de aviso para desfazer o pulo + A notificação não é exibida + Duração da notificação de pular + Por quanto tempo a notificação de aviso de pulo é exibida + 1 segundo + 2 segundos + 3 segundos + 4 segundos + 5 segundos + 6 segundos + 7 segundos + 8 segundos + 9 segundos + 10 segundos Mostrar duração do vídeo sem segmentos - Duração do vídeo sem os segmentos, mostrado entre parênteses ao lado da duração total do vídeo + O comprimento do vídeo menos todos os segmentos é mostrado na barra de busca Mostrar duração total do vídeo Criando segmentos Mostrar o botão Criar novo segmento diff --git a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml index 32de67662..4c7141e43 100644 --- a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml @@ -285,10 +285,13 @@ Não será notificado de quaisquer eventos inesperados." Descrição do vídeo Esconder ou mostrar componentes de descrição do vídeo Barra de Filtro - Ocultar ou mostrar a barra de filtro no feed, nos resultados da pesquisa e nos vídeos relacionados - Esconder no feed - Escondido no feed - Mostrar no feed + Ocultar ou mostrar a barra de filtros nos feeds, histórico, resultados da pesquisa e vídeos relacionados + Ocultar em feeds + Oculto em feeds + Exibido em feeds + Ocultar no histórico + Oculto no histórico + Exibido no histórico Ocultar nos resultados da pesquisa Oculto nos resultados da pesquisa Exibido nos resultados da pesquisa @@ -957,11 +960,25 @@ Tính năng này hoạt động tốt nhất với chất lg video là 720p tr Ocultar automaticamente o botão \"Ignorar\" Pular botão esconde após alguns segundos O botão \"Ignorar\" é mostrado para todo o segmento - Mostrar um toast ao ignorar - Toast é visível quando um segmento é automaticamente ignorado. Toque aqui para ver um exemplo - Toast não é visível. Toque aqui para ver um exemplo + Duração do botão de pular + Por quanto tempo os botões de ocultar automaticamente pular e pular para destacar são exibidos + Mostrar notificação de desfazer pular + Uma notificação é exibida quando um segmento é pulado automaticamente. Toque na notificação para desfazer o pulo + Notificação não é exibida + Duração da notificação de pular + Por quanto tempo a notificação de pular é exibida + 1 segundo + 2 segundos + 3 segundos + 4 segundos + 5 segundos + 6 segundos + 7 segundos + 8 segundos + 9 segundos + 10 segundos Mostrar duração do vídeo sem segmentos - Duração do vídeo menos todos os segmentos, visível entre parênteses ao lado da duração completa do vídeo + O comprimento do vídeo menos todos os segmentos é mostrado na barra de busca Duração total do vídeo exibido Criando novos segmentos Mostrar o botão Criar novo segmento diff --git a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml index 3b902fe57..dd65662b7 100644 --- a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml +++ b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml @@ -285,10 +285,13 @@ Nu veți fi notificat de niciun eveniment neașteptat." Descriere video Ascunde sau afișează componentele descrierii video Bară de filtrare - Ascunde sau afișează bara de filtre în flux, rezultatele căutării și videoclipurile conexe - Ascunde în feed - Ascuns în feed - Afișat în feed + Ascundeți sau afișați bara de filtre în fluxuri, istoric, rezultate ale căutării și videoclipuri conexe + Ascunde în feeduri + Ascuns în feeduri + Afișat în feeduri + Ascunde în istoric + Ascuns în istoric + Afișat în istoric Ascunde în rezultatele căutării Ascuns în rezultatele căutării Afișat în rezultatele căutării @@ -957,11 +960,25 @@ Această caracteristică funcționează cel mai bine cu o calitate video de 720p Ascunde automat butonul Skip Omite ascunderea butonului după câteva secunde Butonul Skip este afișat pentru întregul segment - Afișați un toast la omitere - Toast este afișat atunci când un segment este omis automat. Apăsați aici pentru a vedea un exemplu - Toast nu este afișat. Apăsați aici pentru a vedea un exemplu + Durata butonului de omitere + Cât timp sunt afișate butoanele de ascundere automată a săriturii și de săritură la evidențiere + Afișează notificare toast de anulare a săriturii + Notificarea toast este afișată când un segment este sărit automat. Atingeți notificarea toast pentru a anula săritura. + Notificarea pop-up nu este afișată + Durata notificării pop-up de omitere + Cât timp este afișată notificarea toast de săritură + 1 secundă + 2 secunde + 3 secunde + 4 secunde + 5 secunde + 6 secunde + 7 secunde + 8 secunde + 9 secunde + 10 secunde Arată lungimea videoclipului fără segmente - Lungimea video minus toate segmentele, afișată în paranteze lângă lungimea completă a videoclipului + Lungimea videoclipului fără toate segmentele este afișată pe bara de căutare Lungimea completă a videoclipului afișată Crearea de noi segmente Afișează butonul Creează segment nou diff --git a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml index bd7383437..7a6602ea6 100644 --- a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml +++ b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml @@ -126,7 +126,7 @@ Second \"item\" text" Журнал трассировки стека В журналы отладки включена трассировка стека В журналы отладки не включена трассировка стека - Показывать уведомление при ошибке Revanced + Показать всплывающее уведомление при ошибке Revanced Всплывающее уведомление при возникновении ошибки Revanced показано Всплывающее уведомление при возникновении ошибки Revanced скрыто "Отключение всплывающих уведомлений об ошибках скроет все сообщения об ошибках ReVanced. @@ -285,10 +285,13 @@ Second \"item\" text" Описание видео Скрыть или показать компоненты описания видео Панель фильтров - Скрыть или показать панель фильтров в ленте, результатах поиска и похожих видео + Скрыть или показать панель фильтров в лентах, истории, результатах поиска и похожих видео Скрыть панель фильтров в ленте Панель фильтров в ленте скрыта Панель фильтров в ленте показана + Скрыть панель фильтров в истории просмотров + Панель фильтров в истории просмотров скрыта + Панель фильтров в истории просмотров показана Скрыть панель фильтров в поиске Панель фильтров в поиске скрыта Панель фильтров в поиске показана @@ -534,9 +537,9 @@ Second \"item\" text" Кнопка \"Поделиться\" под плеером скрыта Кнопка \"Поделиться\" под плеером показана - Скрыть \"Остановить рекламу\" - Кнопка \"Отключить рекламу\" скрыта - Кнопка \"Отключить рекламу\" показана + Скрыть кнопку \"Не показывать рекламу\" + Кнопка \"Не показывать рекламу\" скрыта + Кнопка \"Не показывать рекламу\" показана Скрыть кнопку \"Пожаловаться\" @@ -959,11 +962,25 @@ Second \"item\" text" Автоскрытие кнопки пропуска Кнопка пропуска автоматически скрывается через несколько секунд Кнопка пропуска показывается для всего сегмента - Уведомление при пропуске сегмента - Всплывающее уведомление при автоматическом пропуске сегмента показано. Нажмите для просмотра примера - Всплывающее уведомление при автоматическом пропуске сегмента скрыто. Нажмите для просмотра примера + Длительность кнопки пропуска + Длительность отображения кнопок автоматического скрытия \"Пропустить\" и \"Перейти к выделенному\" + Показывать тост отмены пропуска + Тост показывается, когда сегмент автоматически пропускается. Нажмите на уведомление-тост, чтобы отменить пропуск. + Всплывающее сообщение не показывается + Длительность всплывающего сообщения при пропуске + Как долго показывается уведомление-тост о пропуске + 1 секунда + 2 секунды + 3 секунды + 4 секунды + 5 секунд + 6 секунд + 7 секунд + 8 секунд + 9 секунд + 10 секунд Длительность видео без сегментов - Длительность видео за исключением всех сегментов показана в скобках рядом с полной длительностью видео + Длина видео без учета всех сегментов отображается на полосе прокрутки Полная длительность видео показана Создание новых сегментов Кнопка создания сегмента @@ -1310,7 +1327,7 @@ Second \"item\" text" При активации URL-адреса видео (и никакие другие данные) будут отправлены на сервер API. При отсутствии миниатюр DeArrow в видео показываются оригинальные или миниатюры захвата кадра Нажмите для дополнительной информации о DeArrow" - Показать уведомление при недоступности API + Показать всплывающее уведомление при недоступности API Всплывающее уведомление при недоступности DeArrow показано Всплывающее уведомление при недоступности DeArrow скрыто Конечная точка DeArrow API @@ -1407,9 +1424,9 @@ Second \"item\" text" Запоминать изменения качества видео Изменения качества воспроизведения применяются ко всем видео Изменения качества воспроизведения применяются только к текущему видео - Показывать всплывающее сообщение при изменениях качества видео - Всплывающее сообщение показывается, когда изменяется качество видео по умолчанию - Всплывающее сообщение не показывается, когда изменяется качество видео по умолчанию + Показать всплывающее уведомление при изменении качества видео + Всплывающее уведомление при изменении качества видео по умолчанию показано + Всплывающее уведомление при изменении качества видео по умолчанию скрыто Качество видео по умолчанию в Wi-Fi сети Качество видео по умолчанию в мобильной сети Запоминать изменения качества Shorts @@ -1443,9 +1460,9 @@ Second \"item\" text" Запоминать изменения скорости воспроизведения Изменения скорости воспроизведения применяются ко всем видео Изменения скорости воспроизведения применяются только к текущему видео - Показывать всплывающее сообщение при изменениях скорости воспроизведения - Всплывающее сообщение показывается, когда изменяется скорость воспроизведения по умолчанию - Всплывающее сообщение не отображается, когда изменяется скорость воспроизведения по умолчанию + Показать всплывающее уведомление при изменении скорости воспроизведения + Всплывающее уведомление при изменении скорости воспроизведения по умолчанию показано + Всплывающее уведомление при изменении скорости воспроизведения по умолчанию скрыто Скорость воспроизведения по умолчанию Скорость изменена на: %s diff --git a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml index 01396dd1e..47dbdc3a1 100644 --- a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml +++ b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml @@ -283,10 +283,13 @@ Nebudete informovaní o žiadnych nepredvídaných udalostiach." Popis videa Skryť alebo zobraziť komponenty popisu videa Panel filtra - Skryť alebo zobraziť panel filtra v informačnom kanáli, vo výsledkoch vyhľadávania a v súvisiacich videách - Skryť v feede - Skryté v krmive - Zobrazené v informačnom kanáli + Skryť alebo zobraziť panel filtra v zdrojoch, histórii, výsledkoch vyhľadávania a súvisiacich videách + Skryť v kanáloch + Skryté v kanáloch + Zobrazené v kanáloch + Skryť v histórii + Skryté v histórii + Zobrazené v histórii Skryť vo výsledkoch vyhľadávania Zobrazené vo výsledkoch vyhľadávania Zobrazené vo výsledkoch vyhľadávania @@ -950,11 +953,25 @@ Táto funkcia najlepšie funguje s kvalitou videa 720p alebo nižšou a pri pou Automaticky skryť tlačidlo Preskočiť Tlačidlo preskočenia sa po niekoľkých sekundách skryje Tlačidlo Preskočiť sa zobrazuje pre celý segment - Zobraziť toast pri preskakovaní - Toast sa zobrazí, keď sa segment automaticky preskočí. Klepnutím sem zobrazíte príklad - Toast sa nezobrazuje. Klepnutím sem zobrazíte príklad + Dĺžka trvania tlačidla preskočiť + Ako dlho sú zobrazené tlačidlá pre automatické skrytie preskočenia a preskočenie na zvýraznenie + Zobraziť hlásenie o vrátení preskočenia + Hlásenie sa zobrazí, keď je segment automaticky preskočený. Klepnutím na hlásenie preskočenie vrátite. + Hlásenie sa nezobrazuje + Dĺžka trvania hlásenia preskočenia + Ako dlho je zobrazené hlásenie o preskočení + 1 sekunda + 2 sekundy + 3 sekundy + 4 sekundy + 5 sekúnd + 6 sekúnd + 7 sekúnd + 8 sekúnd + 9 sekúnd + 10 sekúnd Zobraziť dĺžku videa bez segmentov - Dĺžka videa mínus všetky segmenty, zobrazené v zátvorkách vedľa celej dĺžky videa + Dĺžka videa mínus všetky segmenty sa zobrazuje na posuvníku Zobrazená celá dĺžka videa Vytváranie nových segmentov Zobraziť tlačidlo Vytvoriť nový segment diff --git a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml index 7f3264f8c..cae198a91 100644 --- a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml +++ b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml @@ -285,10 +285,13 @@ Ne boste obveščeni o nobenih nepričakovanih dogodkih." Opis videoposnetka Skrij ali prikaži komponente opisa videoposnetka Vrstica filtra - Skrije ali prikaže filtrirno vrstico v viru, rezultatih iskanja in povezanih videoposnetkih - Skrij v viru - Skrita v viru - Prikazana v viru + Skrijte ali prikažite vrstico filtra v virih, zgodovini, rezultatih iskanja in povezanih videoposnetkih + Skrij v virih + Skrito v virih + Prikazano v virih + Skrij v zgodovini + Skrito v zgodovini + Prikazano v zgodovini Skrij v rezultatih iskanja Skrito v rezultatih iskanja Prikazano v rezultatih iskanja @@ -957,11 +960,25 @@ Ta funkcija deluje najbolje pri kakovosti videa 720p ali nižji in pri uporabi z Samodejno skrij gumb za preskok Gumb za preskakovanje se po nekaj sekundah skrije Gumb za preskok je prikazan za celoten segment - Pokaži toast pri preskakovanju - Sporočilo se prikaže, ko se segment samodejno preskoči. Tapnite tukaj za ogled primera - Sporočilo ni prikazano. Tapnite tukaj za ogled primera + Trajanje gumba za preskok + Kako dolgo so prikazani gumbi za samodejno skrivanje preskakovanja in preskok na poudarek + Prikaži obvestilo za razveljavitev preskakovanja + Obvestilo se prikaže, ko je segment samodejno preskočen. Dotaknite se obvestila, da razveljavite preskok. + Obvestilo ni prikazano + Trajanje obvestila o preskoku + Kako dolgo je prikazano obvestilo o preskakovanju. + 1 sekunda + 2 sekundi + 3 sekunde + 4 sekunde + 5 sekund + 6 sekund + 7 sekund + 8 sekund + 9 sekund + 10 sekund Pokaži dolžino videoposnetka brez segmentov - Dolžina videoposnetka minus vsi segmenti, prikazana v oklepajih ob polni dolžini videoposnetka + Dolžina videa brez vseh segmentov je prikazana na drsniku Prikazana je polna dolžina videoposnetka Ustvarjanje novih segmentov Pokaži gumb za ustvarjanje novega segmenta diff --git a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml index 3eef070c1..0aaba3f36 100644 --- a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml +++ b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml @@ -285,10 +285,13 @@ Ju nuk do të njoftoheni për ndonjë ngjarje të papritur." Përshkrimi i videos Fshi ose shfaq komponentët e përshkrimit të videos Shiriti i filtrimit - Fshih ose shfaq shiritin e filtrit në burim, rezultatet e kërkimit dhe videot e ngjashme - Fshi në ushqim - I fshehur në ushqim - I dukshme në ushqim + Fshi ose shfaq shiritin e filtrit te burimet, historia, rezultatet e kërkimit dhe videot e lidhura + Fshih te burimet + I fshehur te burimet + I shfaqur te burimet + Fshih te historia + I fshehur te historia + I shfaqur te historia Fsheh në rezultatet e kërkimit E fshehur në rezultatet e kërkimit E shfaqur në rezultatet e kërkimit @@ -957,11 +960,25 @@ Kjo veçori funksionon më mirë me një cilësi video prej 720p ose më të ul Fshih automatikisht butonin Kalo Butoni i kalimit fshihet pas disa sekondash Butoni Kalo është i shfaqur për të gjithë segmentin - Shfaq një toast kur kalohet - Lajmërimi shfaqet kur një segment kalon automatikisht. Shtypni këtu për të parë një shembull - Lajmërimi nuk shfaqet. Shtypni këtu për të parë një shembull + Kohëzgjatja e butonit të kapërcimit + Sa gjatë shfaqen butonat e fshehjes automatike të anashkalimit dhe anashkalimit te theksimi + Shfaq njoftimin e zhbërjes së anashkalimit + Njoftimi shfaqet kur një segment anashkalohet automatikisht. Prek njoftimin për të zhbërë anashkalimin + Njoftimi i shkurtër nuk shfaqet + Kohëzgjatja e njoftimit të kapërcimit + Sa gjatë shfaqet njoftimi i anashkalimit + 1 sekondë + 2 sekonda + 3 sekonda + 4 sekonda + 5 sekonda + 6 sekonda + 7 sekonda + 8 sekonda + 9 sekonda + 10 sekonda Shfaq kohën e videos pa segmente - Kohëzgjatja e videos minus të gjitha segmentet, tregohet në kllapa pranë kohëzgjatjes së plotë të videos + Gjatësia e videos minus të gjitha segmentet shfaqet në shiritin e kërkimit Kohëzgjatja e plotë e videos tregohet Krijimi i segmenteve të reja Shfaq butonin Krijo segment të ri diff --git a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml index 9ecf70324..9d2d6a254 100644 --- a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml @@ -285,10 +285,13 @@ Nećete biti obavešteni ni o kakvim neočekivanim događajima." Opis videa Sakrijte ili prikažite komponente opisa videa Traka filtera - Sakrijte ili prikažite traku filtera u fidu, rezultatima pretrage i srodnim videima - Sakrij u fidu - Skriveno u fidu - Prikazano u fidu + Sakrijte ili prikažite traku filtera u fidovima, istoriji, rezultatima pretrage i srodnim videima + Sakrij u fidovima + Skriveno u fidovima + Prikazano u fidovima + Sakrij u istoriji + Skriveno u istoriji + Prikazano u istoriji Sakrij u rezultatima pretrage Skriveno u rezultatima pretrage Prikazano u rezultatima pretrage @@ -957,11 +960,25 @@ Ova funkcija najbolje radi sa kvalitetom videa od 720p ili nižim i kada koristi Automatski sakrij dugme za preskakanje Dugme za preskakanje će biti skriveno nakon nekoliko sekundi Dugme za preskakanje je prikazano za ceo segment - Prikaži iskačuće obaveštenje pri preskakanju - Iskačuće obaveštenje se prikazuje, kada je segment automatski preskočen. Dodirnite ovde da vidite primer - Iskačuće obaveštenje se ne prikazuje. Dodirnite ovde da vidite primer + Trajanje dugmeta za preskakanje + Koliko dugo se prikazuju dugmad za automatsko sakrivanje preskakanja i preskakanje do isticanja + Prikaži obaveštenje o poništavanju preskakanja + Obaveštenje se prikazuje kada se segment automatski preskoči. Dodirnite obaveštenje da biste poništili preskakanje + Toast se ne prikazuje + Trajanje toasta prilikom preskakanja + Koliko dugo se prikazuje obaveštenje o preskakanju + 1 sekunda + 2 sekunde + 3 sekunde + 4 sekunde + 5 sekundi + 6 sekundi + 7 sekundi + 8 sekundi + 9 sekundi + 10 sekundi Prikaži dužinu videa bez segmenata - Dužina videa minus svi segmenti, prikazana u zagradama pored pune dužine videa + Dužina video snimka minus svi segmenti prikazuje se na traci za pretragu Puna dužina videa je prikazana Pravljenje novih segmenata Prikaži dugme za pravljenje novog segmenta diff --git a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml index 3eb35b583..66f039939 100644 --- a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml @@ -285,10 +285,13 @@ Second \"item\" text" Опис видеа Сакријте или прикажите компоненте описа видеа Трака филтера - Сакријте или прикажите траку филтера у фиду, резултатима претраге или сродним видеима - Сакриј у фиду - Скривено у фиду - Приказано у фиду + Сакријте или прикажите траку филтера у фидовима, историји, резултатима претраге и сродним видеима + Сакриј у фидовима + Скривено у фидовима + Приказано у фидовима + Сакриј у историји + Скривено у историји + Приказано у историји Сакриј у резултатима претраге Скривено у резултатима претраге Приказано у резултатима претраге @@ -957,11 +960,25 @@ Second \"item\" text" Аутоматски сакриј дугме за прескакање Дугме за прескакање ће бити скривено након неколико секунди Дугме за прескакање је приказано за цео сегмент - Прикажи искачуће обавештење при прескакању - Искачуће обавештење се приказује, када је сегмент аутоматски прескочен. Додирните овде да видите пример - Искачуће обавештење се не приказује. Додирните овде да видите пример + Трајање дугмета за прескакање + Колико дуго се приказују дугмад за аутоматско скривање прескакања и прескакање до истакнутог + Прикажи искачућу поруку за поништавање прескакања + Искачућа порука се приказује када се сегмент аутоматски прескочи. Додирните искачућу поруку да бисте поништили прескакање + Тост није приказан + Трајање тост поруке при прескакању + Колико дуго се приказује искачућа порука о прескакању + 1 секунда + 2 секунде + 3 секунде + 4 секунде + 5 секунди + 6 секунди + 7 секунди + 8 секунди + 9 секунди + 10 секунди Прикажи дужину видеа без сегмената - Дужина видеа минус сви сегменти, приказана у заградама поред пуне дужине видеа + Дужина видеа без свих сегмената приказана је на траци напретка Пуна дужина видеа је приказана Прављење нових сегмената Прикажи дугме за прављење новог сегмента diff --git a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml index e045f9984..a36344b42 100644 --- a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml +++ b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml @@ -91,10 +91,10 @@ Tryck på Fortsätt-knappen och tillåt optimeringsändringar." Annonser Alternativa miniatyrbilder Flöde - Generell + Allmänt Spelare - Sökfält - Dragkontroller + Sökreglage + Svepkontroller Diverse Video Återställ gamla inställningsmenyer @@ -149,9 +149,9 @@ Du kommer inte att bli meddelad om oväntade händelser." Dölj crowdfunding-rutan Crowdfunding-rutan är dold Crowdfunding-rutan är synlig - Dölj flytande mikrofonknapp - Mikrofon knapp dold - Mikrofonknappen är synlig + Dölj svävande mikrofonknapp + Mikrofonknappen är dold + Mikrofonknappen visas Dölj kanalens vattenstämpel Vattenstämpeln är dold Vattenstämpeln är synlig @@ -169,12 +169,12 @@ Du kommer inte att bli meddelad om oväntade händelser." Knappen är dold Knappen är synlig - Dölj \"För dig\"-hyllan - Hylla på kanalsidan är dold - Hylla på kanalsidan visas + Dölj hyllan \"För dig\" + Hyllan på kanalsidan är dold + Hyllan på kanalsidan visas - Dölj knappen \'Meddela mig\' + Dölj knappen \"Meddela mig\" Knappen är dold Knappen är synlig @@ -285,10 +285,13 @@ Du kommer inte att bli meddelad om oväntade händelser." Videobeskrivning Dölj eller visa videobeskrivningskomponenter Filterfält - Visa eller dölj filterfältet i flödet, sökresultaten och relaterade videor - Dölj i flöde - Dold i flödet - Visas i flöde + Dölj eller visa filterfältet i flödena, historiken, sökresultaten och relaterade videor + Dölj i flöden + Dold i flöden + Visas i flöden + Dölj i historik + Dold i historik + Visas i historik Dölj i sökresultat Dold i sökresultat Visas i sökresultat @@ -377,41 +380,41 @@ Begränsningar Dölj allmänna annonser Allmänna annonser är dolda Allmänna annonser är synliga - Dölj fullskärmsannonser + Dölj helskärmsannonser "Helskärmsannonser är dolda Den här funktionen är endast tillgänglig för äldre enheter" - Fullskärmsannonser är synliga - Dölj betald kampanjetikett - Betald kampanjetikett är dold - Betald kampanjetikett är synlig + Helskärmsannonser visas + Dölj etikett för betald marknadsföring + Etiketten för betald marknadsföring är dold + Etiketten för betald marknadsföring visas Dölj självsponsrade kort Självsponsrade kort är dolda Självsponsrade kort är synliga Dölj \"Visa produkter\"-banner Banner är dold Banner är synlig - Dölj bannern för butik på slutskärmen + Dölj butiksbannern på slutskärmen Butiksbannern är dold Butiksbannern visas - Dölj spelarbutikshyllan - Hyllan för shopping är dold - Hyllan för shopping visas - Dölj shoppinglänkar i videobeskrivning - Shoppinglänkar i videobeskrivningen är dolda - Shoppinglänkar i videobeskrivningen visas + Dölj butikshyllan i spelaren + Butikshyllan är dold + Butikshyllan visas + Dölj butikslänkar + Butikslänkar i videobeskrivningen är dolda + Butikslänkar i videobeskrivningen visas - Dölj knappen \'Besök butik\' på kanalsidor + Dölj knappen Besök butiken Knappen på kanalsidan är dold Knappen på kanalsidan visas Dölj sökresultat på webben Sökresultat på webben är dolda Sökresultat på webben är synliga - Dölj reklambanners - Reklambanners är dolda - Reklambanners är synliga + Dölj banners för varor + Banners för varor är dolda + Banners för varor visas - Dölj fullskärmsannonser fungerar endast med äldre enheter + Helskärmsannonser kan döljas bara på äldre enheter Dölj YouTube Premium-kampanjer @@ -454,9 +457,9 @@ Den här funktionen är endast tillgänglig för äldre enheter" %s är inte installerat. Installera det. - Inaktivera exakt sök-gest - Gest är inaktiverad - Gest är aktiverad + Inaktivera gest för exakt sökning + Gesten är inaktiverad + Gesten är aktiverad Aktivera tryck för att söka @@ -465,45 +468,45 @@ Den här funktionen är endast tillgänglig för äldre enheter" Aktivera ljusstyrkegest - "Helskärmens ljusstyrkesvep är aktiverat + "Svepgest för ljusstyrka i helskärm är aktiverad Justera ljusstyrkan genom att svepa vertikalt på vänster sida av skärmen" - Helskärmens ljusstyrkesvep är inaktiverat + Svepgest för ljusstyrka i helskärm är inaktiverad Aktivera volymgest - "Helskärmsvolymsvep är aktiverat + "Svepgest för volym i helskärm är aktiverad Justera volymen genom att svepa vertikalt på höger sida av skärmen" - Helskärmsvolymsvep är inaktiverat + Svepgest för volym i helskärm är inaktiverad Aktivera tryck för att svepa-gest Tryck för att svepa är aktiverat Tryck för att svepa är inaktiverat Aktivera haptisk feedback Haptisk feedback är aktiverad Haptisk feedback är inaktiverad - Spara och återställ ljusstyrkan - Spara och återställ ljusstyrkan när du avslutar eller går in i fullskärm - Spara inte och återställ ljusstyrkan när du avslutar eller går in i fullskärm - Aktivera automatisk ljusstyrkegest - Genom att svepa ner till det lägsta värdet av gesten för ljusstyrka aktiveras automatisk ljusstyrka - Att svepa ner till det lägsta värdet aktiverar inte automatisk ljusstyrka + Spara och återställ ljusstyrka + Spara och återställ ljusstyrkan när du avslutar eller aktiverar helskärmsläge + Spara och återställ inte ljusstyrkan när du avslutar eller aktiverar helskärmsläge + Aktivera gest för automatisk ljusstyrka + Automatisk ljusstyrka aktiveras om du sveper ner till ljusstyrkegestens lägsta värde + Automatisk ljusstyrka aktiveras inte om du sveper ner till det lägsta värdet Automatiskt - Tidsgräns för svepöverlagring + Tidsgräns för svepöverlägg Mängden millisekunder överlappningen är synlig - Överlägg svepbakgrund opacitet + Bakgrundsopacitet för svepöverlägg Opacitetsvärde mellan 0-100 - Överlagrad svepopacitet måste vara mellan 0-100 - Färg för svepgestöverlagringens ljusstyrka - Färgen på förloppsindikatorn för ljusstyrkekontroller - Färg för svepgestöverlagringens volym - Färgen på förloppsindikatorn för volymkontroller - Textstorlek för svepöverlagring - Textstorleken för svepöverlagring mellan 1 och 30 + Opacitet för svepöverlägg måste vara mellan 0-100 + Färg på svepöverlägg för ljusstyrka + Färgen på reglaget för kontroll av ljusstyrka + Färg på svepöverlägg för volym + Färgen på reglaget för volymkontroll + Textstorlek för svepöverlägg + Textstorleken för svepöverlägg mellan 1-30 Textstorleken måste vara mellan 1 och 30 - Svep magnitud tröskel - Mängden tröskel för att svepa ska uppstå - Volym svepkänslighet + Tröskelvärde för svep + Tröskelvärdet för att svep ska uppstå + Svepkänslighet för volymgest Hur mycket volymen ändras per svep - Svep överläggningsstil + Stil för svepöverlägg Horisontellt överlägg Horisontellt överlägg (minimalt - överst) Horisontellt överlägg (minimalt - mitten) @@ -511,9 +514,9 @@ Justera volymen genom att svepa vertikalt på höger sida av skärmen" Cirkulärt överlägg (minimalt) Vertikalt överlägg Vertikalt överlägg (minimalt) - Aktivera svepning för att byta video - Svepning i helskärmsläge ändrar till följande/föregående video - Svepning i helskärmsläge ändrar inte till följande/föregående video + Aktivera svep för att byta videor + Svep i helskärmsläge byter till nästa/föregående video + Svep i helskärmsläge byter inte till nästa/föregående video Inaktivera automatisk bildtext @@ -711,12 +714,12 @@ För att visa ljudspårsmenyn, ändra \"Spoof video streams\" till iOS TV"Rullande nummer är animerade - Dölj sökfältet i videospelare - Sökfältet för videospelare är dolt - Sökfältet för videospelaren är synlig - Dölj sökfältet i videominiatyrer - Miniatyrsökningsfältet är dolt - Miniatyrens sökfält är synlig + Dölj sökreglage i videospelare + Sökreglaget i videospelaren är dolt + Sökreglaget i videospelaren visas + Dölj sökreglage i videominiatyrer + Sökreglaget i miniatyrbilder är dolt + Sökreglaget i miniatyrbilder visas Shorts spelare @@ -732,7 +735,7 @@ För att visa ljudspårsmenyn, ändra \"Spoof video streams\" till iOS TV"Dölj Shorts i sökresultat Dolda i sökresultaten Visas i sökresultaten - Dölj Shorts i titthistoriken + Dölj Shorts-videor i visningshistoriken Dolda i visningshistoriken Visas i titthistoriken @@ -929,16 +932,16 @@ Begränsning: Ogillanden kanske inte visas i inkognitoläge" Aktivera högkvalitativa miniatyrer - Seekbar miniatyrer är av hög kvalitet - Seekbar miniatyrer är av medelhög kvalitet - "Detta återställer även miniatyrer på livestreams som inte har miniatyrer i sökfältet. + Sökreglageminiatyrer är av hög kvalitet + Sökreglageminiatyrer är av medelhög kvalitet + "Detta återställer även miniatyrer på livestreamar som inte har sökreglageminiatyrer. -Miniatyrer i sökfältet kommer att använda samma kvalitet som den aktuella videon. +Sökreglageminiatyrer kommer att använda samma kvalitet som den aktuella videon. Den här funktionen fungerar bäst med en videokvalitet på 720p eller lägre och när du använder en mycket snabb internetanslutning." - Återställ gamla miniatyrer i sökfältet - Seekbar miniatyrer visas ovanför sökfältet - Seekbar miniatyrer visas i helskärm + Återställ gamla sökreglageminiatyrer + Sökreglageminiatyrer visas ovanför sökreglaget + Sökreglageminiatyrer visas i helskärm Aktivera SponsorBlock @@ -957,11 +960,25 @@ Den här funktionen fungerar bäst med en videokvalitet på 720p eller lägre oc Dölj Hoppa över-knappen automatiskt Hoppa över-knappen döljs efter några sekunder Hoppa över-knappen visas för hela segmentet - Visa ett meddelande vid överhoppning - Meddelande visas när ett segment hoppas över automatiskt. Tryck här för att se ett exempel - Meddelande visas inte. Tryck här för att se ett exempel + Varaktighet för Hoppa över-knappen + Hur länge knapparna för automatisk döljning av överhoppning och hoppa till markering visas + Visa toastmeddelande för ångra överhoppning + Meddelande visas när ett segment hoppas över automatiskt. Tryck på toastmeddelandet för att ångra överhoppningen + Toastmeddelande visas inte + Varaktighet för överhoppningstoastmeddelande + Hur länge toastmeddelandet för överhoppning visas + 1 sekund + 2 sekunder + 3 sekunder + 4 sekunder + 5 sekunder + 6 sekunder + 7 sekunder + 8 sekunder + 9 sekunder + 10 sekunder Visa videons längd utan segment - Videolängd minus alla segment, som visas i parentes bredvid den fullständiga videolängden + Videolängden minus alla segment visas på sökfältet Hela videons längd visas Skapa nya segment Visa knappen Skapa nytt segment @@ -987,23 +1004,23 @@ Den här funktionen fungerar bäst med en videokvalitet på 720p eller lägre oc Segment kortare än detta värde (i sekunder) kommer inte att visas eller hoppas över Ogiltig tidslängd Ditt privata användar-id - Detta bör hållas privat. Detta är som ett lösenord och bör inte delas med någon. Om någon har det här, kan de utge sig för att vara dig + Detta bör hållas privat. Detta är som ett lösenord och bör inte delas med någon. Om någon har detta kan de utge sig för att vara du Privat användar-id måste vara minst 30 tecken långt - Ändra API URL + Ändra API-webbadress Adressen SponsorBlock använder för att ringa samtal till servern - API URL återställning - API-URL är ogiltig - API URL ändrad + API-webbadress återställdes + API-webbadress är ogiltig + API-webbadress ändrades Importera/exportera inställningar Kopiera Din SponsorBlock JSON-konfiguration som kan importeras/exporteras till ReVanced och andra SponsorBlock plattformar - Din SponsorBlock JSON-konfiguration som kan importeras/exporteras till ReVanced och andra SponsorBlock plattformar. Detta inkluderar ditt privata användar-id. Se till att dela detta klokt + Din JSON-konfiguration för SponsorBlock som kan importeras/exporteras till ReVanced och andra SponsorBlock-plattformar. Detta inkluderar ditt privata användar-id. Se till att dela detta klokt Inställningar har importerats Det gick inte att importera: %s Det gick inte att exportera: %s - "Dina inställningar innehåller ett privat användar-ID för SponsorBlock. + "Dina inställningar innehåller ett privat användar-id för SponsorBlock. -Ditt användar-ID är som ett lösenord och det bör aldrig delas." +Ditt användar-id är som ett lösenord och det bör aldrig delas." Visa inte igen Ändra segmentbeteende Sponsor @@ -1058,7 +1075,7 @@ Ditt användar-ID är som ett lösenord och det bör aldrig delas." Hoppa över automatiskt Hoppa över automatiskt en gång Visa en Hoppa över-knapp - Visa i sökfältet + Visa i sökreglaget Inaktivera Det går inte att skicka segment: %s SponsorBlock är tillfälligt nere @@ -1134,7 +1151,7 @@ Redo att skicka in?" Data tillhandahålls av SponsorBlock API. Tryck här för att läsa mer och se nedladdningar för andra plattformar - Formulärformfaktor + Layout-formfaktor Standard Telefon Platta @@ -1168,25 +1185,25 @@ Om det senare stängs av rekommenderas det att rensa appens data för att förhi Standard Alla prenumerationer Bläddra bland kanaler - Kurser / Lärande + Kurser/lärande Utforska - Mode & Skönhet - Spel + Mode och skönhet + Gaming Historik Bibliotek - Gillade videor - Direkt + Videor du gillat + Live Filmer Musik Nyheter - Meddelanden + Aviseringar Spellistor Sök Shopping Sport Prenumerationer - Trendande - Virtual reality + Populärt + Virtuell verklighet Titta senare Dina klipp Ändra alltid startsida @@ -1228,7 +1245,7 @@ Begränsning: Att använda bakåtknappen i verktygsfältet kanske inte fungerar" Modern 4 Aktivera rundade hörn Hörnen är rundade - Hörnen är kvadratiska + Hörnen är fyrkantiga Aktivera dubbeltryck och nypa för att ändra storlek "Dubbeltrycksåtgärd och nypning för att ändra storlek är aktiverat @@ -1240,11 +1257,11 @@ Begränsning: Att använda bakåtknappen i verktygsfältet kanske inte fungerar" Minispelaren kan dras till valfritt hörn av skärmen" Dra och släpp är inaktiverat - Aktivera horisontell drag gest - "Gester för horisontell dragning är aktiverade + Aktivera horisontell draggest + "Horisontell draggest är aktiverad -Minispelare kan dras av skärmen till vänster eller höger" - Horisontell drag gest inaktiverad +Minispelaren kan dras utanför skärmen till vänster eller höger" + Horisontell draggest är inaktiverad Dölj överlagringsknappar Överlagringsknappar är dolda Överlagringsknappar visas @@ -1255,7 +1272,7 @@ Minispelare kan dras av skärmen till vänster eller höger" Hoppa framåt och bakåt är dolda Hoppa framåt och bakåt visas Ursprunglig storlek - Inledande på skärmstorlek, i pixlar + Ursprunglig storlek på skärmen, i pixlar Pixelstorlek måste vara mellan %1$s och %2$s Överlager opacitet Opacitetsvärde mellan 0-100, där 0 är transparent @@ -1268,14 +1285,14 @@ Minispelare kan dras av skärmen till vänster eller höger" Startskärmens stil Färg Svartvitt - Aktivera anpassad sökfält färg - Anpassad sökfält färg visas - Original sökfält färg visas - Egendefinierad sökfälgsfärg - Färgen på sökfältet - Egendefinierad accentfärg för sökfältet - Accentfärgen på sökfältet - Ogiltigt sökfältets färgvärde + Aktivera anpassad färg på sökreglaget + Sökreglagets anpassade färg visas + Sökreglagets ursprungliga färg visas + Anpassad färg på sökreglaget + Färgen på sökreglaget + Anpassad accentfärg på sökreglaget + Accentfärgen på sökreglaget + Ogiltigt färgvärde för sökreglaget Begränsningar för förbipassering av bildregionen @@ -1297,11 +1314,11 @@ Att aktivera detta kan åtgärda saknade bilder som är blockerade i vissa regio DeArrow & Original miniatyrer DeArrow & fångar fortfarande Fortfarande fångar - "DeArrow tillhandahåller crowdsourcade miniatyrbilder för YouTube-videor. Dessa miniatyrbilder är ofta mer relevanta än de som tillhandahålls av YouTube + "DeArrow tillhandahåller crowdsourcing-baserade miniatyrbilder för YouTube-videor. Dessa miniatyrbilder är ofta mer relevanta än de som tillhandahålls av YouTube -Om detta är aktiverat skickas video-URL:er till API-servern och inga andra data skickas. Om en video inte har DeArrow-miniatyrer visas originalet eller stillbilder +Om detta aktiveras skickas videoadresser till API-servern och inga andra data skickas. Om en video inte har DeArrow-miniatyrer visas originalet eller stillbilder -Klicka här för att lära dig mer om DeArrow" +Tryck här för att läsa mer om DeArrow" Visa ett meddelande om API inte är tillgängligt Meddelande visas om DeArrow inte är tillgängligt Meddelande visas inte om DeArrow inte är tillgängligt @@ -1358,9 +1375,9 @@ Att aktivera detta kan låsa upp högre videokvalitet" Inaktivera haptik för kapitel Haptik för kapitel är inaktiverad Haptik för kapitel är aktiverad - Inaktivera exakt sökhaptik - Precisionssökning med haptik är inaktiverad - Exakt sökhaptik är aktiverad + Inaktivera haptik för exakt sökning + Haptik för exakt sökning är inaktiverad + Haptik för exakt sökning är aktiverad Inaktivera ångra-sökning haptik Ångra-sökning haptik är inaktiverad Ångra-sökning haptik är aktiverad diff --git a/patches/src/main/resources/addresources/values-th-rTH/strings.xml b/patches/src/main/resources/addresources/values-th-rTH/strings.xml index 32170e893..f4c478c92 100644 --- a/patches/src/main/resources/addresources/values-th-rTH/strings.xml +++ b/patches/src/main/resources/addresources/values-th-rTH/strings.xml @@ -285,10 +285,13 @@ Second \"item\" text" คำอธิบายวิดีโอ ซ่อนหรือแสดงส่วนประกอบของคำอธิบายวิดีโอ แถบตัวกรอง - ซ่อนหรือแสดงแถบตัวกรองในฟีด ผลการค้นหา และวิดีโอที่เกี่ยวข้อง + ซ่อนหรือแสดงแถบตัวกรองในฟีด ประวัติ ผลการค้นหา และวิดีโอที่เกี่ยวข้อง ซ่อนในฟีด - ซ่อนในฟีด + ซ่อนอยู่ในฟีด แสดงในฟีด + ซ่อนในประวัติ + ซ่อนอยู่ในประวัติ + แสดงในประวัติ ซ่อนในผลการค้นหา ซ่อนในการค้นหา แสดงในผลการค้นหา @@ -956,11 +959,25 @@ Second \"item\" text" ซ่อนปุ่มข้ามโดยอัตโนมัติ ปุ่มข้ามซ่อนหลังจากผ่านไปไม่กี่วินาที ปุ่มข้ามจะแสดงสำหรับทั้งส่วน - แสดง toast เมื่อข้าม - ขนมปังปิ้งจะปรากฏขึ้นเมื่อข้ามส่วนโดยอัตโนมัติ แตะที่นี่เพื่อดูตัวอย่าง - «Toast» ไม่แสดง แตะที่นี่เพื่อดูตัวอย่าง + ระยะเวลาปุ่มข้าม + ระยะเวลาที่ปุ่มซ่อนอัตโนมัติสำหรับข้ามและข้ามไปยังไฮไลต์จะแสดง + แสดงการแจ้งเตือนยกเลิกการข้าม + จะมีการแจ้งเตือนแสดงขึ้นเมื่อมีการข้ามส่วนโดยอัตโนมัติ แตะการแจ้งเตือนแบบชั่วคราวเพื่อยกเลิกการข้าม + ไม่แสดงข้อความแจ้งเตือน + ระยะเวลาข้อความแจ้งเตือนการข้าม + ระยะเวลาที่แสดงการแจ้งเตือนข้ามแบบชั่วคราว + 1 วินาที + 2 วินาที + 3 วินาที + 4 วินาที + 5 วินาที + 6 วินาที + 7 วินาที + 8 วินาที + 9 วินาที + 10 วินาที แสดงความยาววิดีโอโดยไม่มีส่วนต่างๆ - ความยาววิดีโอลบด้วยส่วนทั้งหมด แสดงในวงเล็บถัดจากความยาววิดีโอเต็ม + ความยาววิดีโอที่ลบทุกส่วนแล้วจะแสดงบนแถบเวลา แสดงความยาววิดีโอเต็ม การสร้างกลุ่มใหม่ แสดงปุ่มสร้างส่วนใหม่ diff --git a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml index c38ec5c48..c4a73f49c 100644 --- a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml +++ b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml @@ -285,10 +285,13 @@ Beklenmedik olaylar hakkında bilgilendirilmeyeceksiniz." Video açıklaması Video açıklamasındaki öğeleri gizle veya göster Filtreleme çubuğu - Akışta, arama sonuçlarında ve ilgili videolardaki filtreleme çubuğunu gizle veya göster - Akıştakini gizle - Akıştaki gizli - Akıştaki görünür + Akışlarda, geçmişte, arama sonuçlarında ve ilgili videolarda filtre çubuğunu gizle veya göster. + Beslemelerde gizle + Beslemelerde gizlendi + Beslemelerde gösterildi + Geçmişte gizle + Geçmişte gizlendi + Geçmişte gösterildi Arama sonuçlarında gizle Arama sonuçlarında gizli Arama sonuçlarında görünür @@ -959,11 +962,25 @@ Bu özellik, 720p veya daha düşük video kalitesi ve çok hızlı bir internet Atlama düğmesini otomatik olarak gizle Atlama düğmesi birkaç saniye sonra gizlenir Atlama düğmesi bütün kısım boyunca gösterilir - Otomatik olarak atlarken bir uyarı göster - Kısım otomatik olarak atlandığında tost bildirimi gösterilir. Örnek görmek için buraya dokunun - Tost bildirimi gösterilmez. Örnek görmek için buraya dokunun + Atla düğmesi süresi + Otomatik gizlenen atla ve vurgulaya atla düğmelerinin ne kadar süreyle gösterildiği + Atlamayı geri al bildirimini göster + Bildirim, bir segment otomatik olarak atlandığında gösterilir. Atlamayı geri almak için bildirimine dokunun. + Toast gösterilmiyor + Atlama toast süresi + Atlama bildiriminin ne kadar süreyle gösterildiği + 1 saniye + 2 saniye + 3 saniye + 4 saniye + 5 saniye + 6 saniye + 7 saniye + 8 saniye + 9 saniye + 10 saniye Kısımlar çıkarıldığında kalan video süresini göster - Video uzunluğu eksi bütün kısımlar, tam video uzunluğunun yanında parantez içinde gösterilir + Tüm segmentler çıkarıldıktan sonra video uzunluğu arama çubuğunda gösterilir Tam video uzunluğu gösterilir Yeni kısım oluşturma Yeni kısım oluşturma düğmesini göster diff --git a/patches/src/main/resources/addresources/values-uk-rUA/strings.xml b/patches/src/main/resources/addresources/values-uk-rUA/strings.xml index bbaa85cdb..6fc5f6b94 100644 --- a/patches/src/main/resources/addresources/values-uk-rUA/strings.xml +++ b/patches/src/main/resources/addresources/values-uk-rUA/strings.xml @@ -286,10 +286,13 @@ Second \"item\" text" Опис відео Приховати або показувати компоненти опису відео Панель фільтрів - Приховати або показувати панель фільтрів у стрічці, результатах пошуку та пов\'язаних відео - Приховати панель у стрічці - Панель фільтрів у стрічці приховано - Панель фільтрів у стрічці показується + Приховати або показувати панель фільтрів у стрічках, історії, результатах пошуку та пов\'язаних відео + Приховати панель у стрічках + Панель фільтрів у стрічках приховано + Панель фільтрів у стрічках показується + Приховати панель в історії + Панель фільтрів у історії приховано + Панель фільтрів у історії показується Приховати панель у результатах пошуку Панель фільтрів у результатах пошуку приховано Панель фільтрів у результатах пошуку показується @@ -958,12 +961,26 @@ Second \"item\" text" Приховувати кнопку пропуску Кнопка пропуску автоматично приховується після декількох секунд Кнопка пропуску показується для всього сегменту - Показувати тост при пропуску - Тост показується, коли сегмент автоматично пропускається. Натисніть тут, щоб побачити приклад - Тост не показується. Натисніть тут, щоб побачити приклад - Тривалість відео без сегментів - Показується тривалість відео мінус всі сегменти, вказано в дужках поруч з повною тривалістю відео - Показується тривалість повного відео + Тривалість кнопки пропуску + Як довго показуються кнопки автоматичного пропуску та переходу до основного моменту + Показувати тост скасування пропуску + Тост показується, коли сегмент автоматично пропускається. Натисніть на нього, щоб скасувати пропуск + Тост не показується + Тривалість тосту пропуску + Як довго показується тост про пропуск + 1 секунда + 2 секунди + 3 секунди + 4 секунди + 5 секунд + 6 секунд + 7 секунд + 8 секунд + 9 секунд + 10 секунд + Показувати тривалість відео без сегментів + Показується тривалість відео без урахування всіх сегментів, які показуються на панелі прогресу + Показується повна тривалість відео Створення нових сегментів Показувати кнопку створення нового сегмента Кнопка створення нового сегменту показується в відеоплеєрі diff --git a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml index e288acd6c..164ef2f8d 100644 --- a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml +++ b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml @@ -285,16 +285,19 @@ Bạn sẽ không được thông báo về bất kỳ sự kiện bất ngờ n Mô tả video Ẩn hoặc hiện các thành phần mô tả video Thanh bộ lọc - Ẩn hoặc hiện thanh bộ lọc trong bảng tin, kết quả tìm kiếm và video liên quan + Ẩn hoặc hiện thanh bộ lọc trong bảng tin, lịch sử xem, kết quả tìm kiếm và video liên quan Ẩn trong bảng tin Đã ẩn trong bảng tin - Đã hiện trong bảng tin + Đã hiển thị trong bảng tin + Ẩn trong lịch sử xem + Đã ẩn trong lịch sử xem + Đã hiển thị trong lịch sử xem Ẩn trong kết quả tìm kiếm Đã ẩn trong kết quả tìm kiếm - Đã hiện trong kết quả tìm kiếm + Đã hiển thị trong kết quả tìm kiếm Ẩn trong video liên quan Đã ẩn trong video liên quan - Đã hiện trong video liên quan + Đã hiển thị trong video liên quan Bình luận Ẩn hoặc hiện các thành phần bình luận Ẩn Tóm tắt cuộc trò chuyện AI @@ -959,11 +962,25 @@ Tính năng này hoạt động tốt nhất với chất lượng video 720p tr Tự động ẩn nút Bỏ qua Nút bỏ qua ẩn sau vài giây Nút bỏ qua được hiển thị cho toàn bộ phân đoạn - Hiện thông báo nổi khi bỏ qua - Thông báo nổi được hiển thị mỗi khi tự động bỏ qua một phân đoạn. Nhấn vào đây để xem ví dụ - Thông báo nổi không được hiển thị. Nhấn vào đây để xem ví dụ + Thời lượng nút bỏ qua + Thời gian hiển thị các nút tự động ẩn bỏ qua và bỏ qua đến điểm nổi bật + Hiện thông báo nổi hoàn tác bỏ qua + Thông báo nổi được hiển thị mỗi khi tự động bỏ qua một phân đoạn. Chạm vào thông báo nổi để hoàn tác bỏ qua + Toast không được hiển thị + Thời lượng toast bỏ qua + Thời gian hiển thị thông báo nổi bỏ qua + 1 giây + 2 giây + 3 giây + 4 giây + 5 giây + 6 giây + 7 giây + 8 giây + 9 giây + 10 giây Hiện thời lượng video không có phân đoạn - Thời lượng video trừ đi tất cả phân đoạn, được hiển thị trong dấu ngoặc đơn bên cạnh thời lượng đầy đủ của video + Thời lượng video trừ tất cả các phân đoạn được hiển thị trên thanh tua Thời lượng đầy đủ của video được hiển thị Tạo phân đoạn mới Hiện nút Tạo phân đoạn mới @@ -1136,17 +1153,17 @@ Bạn đã sẵn sàng gửi?" Dữ liệu được cung cấp bởi API SponsorBlock. Nhấn vào đây để tìm hiểu thêm và xem các bản tải cho các nền tảng khác - Bố cục dạng yếu tố + Yếu tố hình thức bố cục Mặc định Điện thoại Máy tính bảng - Ô tô + Màn hình ô tô "Thay đổi bao gồm: Bố cục máy tính bảng -• Bài đăng cộng đồng đã bị ẩn +• Bài đăng cộng đồng bị ẩn -Bố cục ô tô +Bố cục màn hình ô tô • Shorts mở trong trình phát thông thường • Bảng tin được sắp xếp theo chủ đề và kênh" @@ -1161,7 +1178,7 @@ Bố cục ô tô Nếu tắt đi sau đó, bạn nên xóa dữ liệu ứng dụng để tránh phát sinh lỗi giao diện." - Phiên bản giả mạo đích + Mục tiêu phiên bản giả mạo 19.35.36 - Khôi phục biểu tượng trình phát Shorts cũ 19.01.34 - Khôi phục biểu tượng điều hướng cũ diff --git a/patches/src/main/resources/addresources/values-zh-rCN/strings.xml b/patches/src/main/resources/addresources/values-zh-rCN/strings.xml index 2e7abd5ed..df7c03a8d 100644 --- a/patches/src/main/resources/addresources/values-zh-rCN/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rCN/strings.xml @@ -285,10 +285,13 @@ Second \"item\" text" 视频说明 隐藏或显示视频说明组件 筛选栏 - 隐藏或显示订阅源、搜索结果和相关视频中的过滤栏 - 在首页动态中隐藏 - 已在首页动态中隐藏 - 已在首页动态中显示 + 在动态、历史记录、搜索结果和相关视频中隐藏或显示筛选栏 + 在动态中隐藏 + 已在动态中隐藏 + 已在动态中显示 + 在历史记录中隐藏 + 已在历史记录中隐藏 + 已在历史记录中显示 在搜索结果中隐藏 在搜索结果中已隐藏 在搜索结果中显示 @@ -958,11 +961,25 @@ Second \"item\" text" 自动隐藏跳过按钮 跳过按钮在几秒后隐藏 整个片段都会显示“跳过”按钮 - 跳过时显示一个toast - 自动跳过片段时显示\"提示\"。点击这里查看示例 - 不显示\"提示\"。点击这里查看示例 + 跳过按钮时长 + 自动隐藏跳过和跳转到精彩片段按钮的显示时长 + 显示撤销跳过浮层提示 + 当片段被自动跳过时会显示浮层提示。轻触浮层提示通知以撤销跳过 + 提示未显示 + 跳过提示时长 + 跳过浮层提示通知的显示时长 + 1 秒 + 2 秒 + 3 秒 + 4 秒 + 5秒 + 6 秒 + 7 秒 + 8 秒 + 9 秒 + 10 秒 显示没有片段的视频长度 - 视频长度减去所有片段,显示在完整视频长度旁边的括号中 + 进度条上显示视频总时长(已减去所有分段) 显示完整视频长度 创建新的片段 显示“创建新片段”按钮 diff --git a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml index 7d7334493..8a9d00d90 100644 --- a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml @@ -38,6 +38,7 @@ Second \"item\" text" 重設顏色 無效的顏色 需要重新啟動 + 重新啟動應用程式以使此變更生效。 重新啟動 匯入 複製 @@ -46,6 +47,7 @@ Second \"item\" text" 無法匯入:%s 搜尋設定 沒有找到「%s」的結果 + 嘗試其他關鍵字 要從搜尋記錄中移除嗎? 顯示 ReVanced 設定圖示 已顯示設定圖示 @@ -130,7 +132,15 @@ Second \"item\" text" "關閉錯誤提示訊息會隱藏所有 ReVanced 的錯誤通知。 你將不會收到任何非預期的事件通知。" + 匯出偵錯記錄 + 將 ReVanced 偵錯記錄複製到剪貼簿 + 偵錯記錄已停用 + 找不到記錄 日誌已複製 + 匯出記錄失敗:$s + 清除偵錯記錄 + 清除所有儲存的 ReVanced 偵錯記錄 + 記錄已清除 隱藏專輯資訊卡 @@ -168,11 +178,17 @@ Second \"item\" text" 已隱藏按鈕 已顯示按鈕 + 隱藏影片推薦標籤 + 「其他人也觀看」與「您可能也喜歡」的標籤已隱藏 + 「其他人也觀看」與「您可能也喜歡」的標籤已顯示 隱藏「顯示更多」按鈕 已隱藏按鈕 已顯示按鈕 + 隱藏票券架 + 票券架已隱藏 + 票券架已顯示 隱藏直播即時反應 已隱藏直播即時反應 已顯示直播即時反應 @@ -243,6 +259,8 @@ Second \"item\" text" 已隱藏影片摘要區塊 已顯示影片摘要區塊 隱藏詢問 + 「提問區」已隱藏 + 「提問區」已顯示 隱藏屬性 已隱藏精選地點、遊戲、音樂和提及的人區塊 已顯示精選地點、遊戲、音樂和提及的人區塊 @@ -267,10 +285,13 @@ Second \"item\" text" 影片說明 隱藏或顯示影片說明元件 篩選列 - 隱藏或顯示動態內容、搜尋結果和相關影片中的篩選列 - 已在推薦內容中隱藏 - 已在推薦內容中隱藏 - 已在推薦內容中顯示 + 在動態、觀看紀錄、搜尋結果和相關影片中隱藏或顯示篩選欄 + 在動態中隱藏 + 已在動態中隱藏 + 已在動態中顯示 + 在觀看紀錄中隱藏 + 已在觀看紀錄中隱藏 + 已在觀看紀錄中顯示 在搜尋結果中隱藏 已在搜尋結果中隱藏 已在搜尋結果中顯示 @@ -294,6 +315,9 @@ Second \"item\" text" 隱藏「建立 Short」按鈕 已隱藏「建立 Short」按鈕 已顯示「建立 Short」按鈕 + 隱藏時間戳記按鈕 + 時間戳記按鈕已隱藏 + 時間戳記按鈕已顯示 隱藏留言預覽 已隱藏留言預覽 已顯示留言預覽 @@ -471,10 +495,24 @@ Second \"item\" text" 滑動覆蓋背景透明度 不透明度值介於 0 到 100 之間 滑動透明度必須介於 0 到 100 之間 + 滑動疊加亮度顏色 + 亮度控制用進度條的顏色 + 滑動疊加音量顏色 + 音量控制用進度條的顏色 + 滑動疊加文字大小 + 滑動疊加顯示的文字大小(介於 1 至 30) + 文字大小必須介於 1 至 30 之間 滑動幅度臨界點 滑動幅度臨界點 音量滑動靈敏度 滑動一下音量調整的大小 + 滑動疊加樣式 + 水平疊加 + 水平疊加(極簡風格-頂部) + 水平疊加(極簡風格-中間) + 圓形疊加 + 圓形疊加(極簡風格) + 垂直疊加 垂直覆蓋(最小) 啟用滑動切換影片 在全螢幕模式下滑動將切換到下一部/上一部影片 @@ -499,6 +537,9 @@ Second \"item\" text" 已隱藏「分享」按鈕 已顯示「分享」按鈕 + 隱藏「停止廣告」 + 「停止廣告」按鈕已隱藏 + 「停止廣告」按鈕已顯示 隱藏檢舉 @@ -526,6 +567,9 @@ Second \"item\" text" 已隱藏「剪輯片段」按鈕 已顯示「剪輯片段」按鈕 + 隱藏「儲存」 + 「儲存」按鈕已隱藏 + 「儲存」按鈕已顯示 導覽列按鈕 @@ -645,6 +689,9 @@ Second \"item\" text" 隱藏「自動播放」按鈕 已隱藏「自動播放」按鈕 已顯示「自動播放」按鈕 + 隱藏播放器控制按鈕背景 + 播放器控制按鈕背景已隱藏 + 播放器控制按鈕背景已顯示 隱藏片尾資訊卡 @@ -714,15 +761,30 @@ Second \"item\" text" 隱藏地點標籤 已隱藏地點標籤 已顯示地點標籤 + 隱藏留言預覽 + 留言預覽已隱藏 + 留言預覽已顯示 隱藏「儲存音樂」按鈕 已隱藏「儲存音樂」按鈕 已顯示「儲存音樂」按鈕 + 隱藏「使用此音效」按鈕 + 「使用此音效」按鈕已隱藏 + 「使用此音效」按鈕已顯示 + 隱藏「使用此範本」按鈕 + 「使用此範本」按鈕已隱藏 + 「使用此範本」按鈕已顯示 隱藏「即將直播/首播」按鈕 已隱藏「即將直播/首播」按鈕 已顯示「即將直播/首播」按鈕 + 隱藏「特效」按鈕 + 「特效」按鈕已隱藏 + 「特效」按鈕已顯示 隱藏「綠幕」按鈕 已隱藏「綠幕」按鈕 已顯示「綠幕」按鈕 + 隱藏「新貼文」按鈕 + 「新貼文」按鈕已顯示 + 「新貼文」按鈕已隱藏 隱藏主題標記按鈕 已隱藏主題標記按鈕 已顯示主題標記按鈕 @@ -783,6 +845,9 @@ Second \"item\" text" 已顯示片尾推薦影片 + 在全螢幕中隱藏相關影片覆蓋層 + 相關影片覆蓋層已隱藏 + 相關影片覆蓋層已顯示 隱藏影片時間戳記 @@ -896,11 +961,7 @@ Second \"item\" text" 自動隱藏「略過」按鈕 在幾秒過後隱藏「跳過」按鈕 整個片段皆顯示「跳過」按鈕 - 跳過時顯示提示訊息 - 已顯示在片段被自動跳過時的提示。輕觸這裡來查看範例 - 不顯示提示。輕觸這裡來查看範例 顯示不包含被跳過片段的時間戳記 - 將被跳過片段減去的時間戳括號後,顯示於完整時間戳記旁邊 只顯示完整的時間戳記 建立新片段 顯示「建立片段」按鈕 @@ -1210,6 +1271,7 @@ Second \"item\" text" 啟用漸層載入畫面 載入畫面將具有漸層背景 載入畫面將具有純色背景 + 啟動畫面樣式 顏色 黑白 啟用自訂跳轉列顏色 @@ -1301,7 +1363,20 @@ Second \"item\" text" GmsCore 設定 + 觸覺回饋 + 變更觸覺回饋 + 停用章節觸覺回饋 + 章節觸覺回饋已停用 + 章節觸覺回饋已啟用 + 停用精準拖曳觸覺回饋 + 精準拖曳觸覺回饋已停用 + 精準拖曳觸覺回饋已啟用 + 停用拖曳還原觸覺回饋 + 拖曳還原觸覺回饋已停用 + 拖曳還原觸覺回饋已啟用 停用縮放震動 + 縮放觸覺回饋已停用 + 縮放觸覺回饋已啟用 如果您最近變更了帳戶登入詳細資訊,請解除安裝並重新安裝 MicroG。 @@ -1334,6 +1409,9 @@ Second \"item\" text" 記住影片畫質 畫質變更適用於所有影片 畫質變更僅適用於目前的影片 + 在變更影片畫質時顯示提示 + 變更預設影片畫質時會顯示提示 + 變更預設影片畫質時不會顯示提示 使用 Wi-Fi 時的預設影片畫質 使用行動數據時的預設影片畫質 記住 Shorts 的畫質變更 @@ -1348,6 +1426,7 @@ Second \"item\" text" 顯示速度對話方塊按鈕 + 按鈕已顯示。長按可將播放速度重設為預設值 不顯示按鈕 @@ -1366,6 +1445,9 @@ Second \"item\" text" 記住播放速度 播放速度變更適用於所有影片 播放速度變更僅適用於目前的影片 + 在變更播放速度時顯示提示 + 變更預設播放速度時會顯示提示 + 變更預設播放速度時不會顯示提示 預設播放速度 已將預設速度變更為:%s diff --git a/patches/src/main/resources/addresources/values-zu-rZA/strings.xml b/patches/src/main/resources/addresources/values-zu-rZA/strings.xml index 0eef95eab..af2c63ca8 100644 --- a/patches/src/main/resources/addresources/values-zu-rZA/strings.xml +++ b/patches/src/main/resources/addresources/values-zu-rZA/strings.xml @@ -19,26 +19,26 @@ Second \"item\" text" --> - - - - + + + + - - + + - - - - - - - - - - + + + + + + + + + + @@ -53,31 +53,31 @@ Second \"item\" text" This is because keywords can be in any language, and showing an example in the localized script helps convey this. --> - - + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - + + - - + + @@ -111,141 +111,141 @@ Second \"item\" text" - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + From ad6da6728122389ef601a7065eb1718ae538a63f Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:28:01 +0530 Subject: [PATCH 18/33] fix(YouTube - Hide layout components): Fix "Hide ticket shelf" hiding unwanted components (#5292) --- .../youtube/patches/components/LayoutComponentsFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java index 30244b361..a39decc43 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java @@ -253,7 +253,7 @@ public final class LayoutComponentsFilter extends Filter { ticketShelf = new ByteArrayFilterGroup( Settings.HIDE_TICKET_SHELF, - "ticket" + "ticket.eml" ); addPathCallbacks( From 6c32591f62ec36793d6c10de9ccef600fe1937a0 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 30 Jun 2025 08:01:39 +0000 Subject: [PATCH 19/33] chore: Release v5.30.0-dev.5 [skip ci] # [5.30.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.4...v5.30.0-dev.5) (2025-06-30) ### Bug Fixes * **YouTube - Hide layout components:** Fix "Hide ticket shelf" hiding unwanted components ([#5292](https://github.com/ReVanced/revanced-patches/issues/5292)) ([ad6da67](https://github.com/ReVanced/revanced-patches/commit/ad6da6728122389ef601a7065eb1718ae538a63f)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f17acaf1d..c5be45fb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.4...v5.30.0-dev.5) (2025-06-30) + + +### Bug Fixes + +* **YouTube - Hide layout components:** Fix "Hide ticket shelf" hiding unwanted components ([#5292](https://github.com/ReVanced/revanced-patches/issues/5292)) ([d6b1f7a](https://github.com/ReVanced/revanced-patches/commit/d6b1f7a6e18b1c0eb4374c5e22a1c746dcb3a522)) + # [5.30.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.3...v5.30.0-dev.4) (2025-06-30) diff --git a/gradle.properties b/gradle.properties index 5a3d70d23..46b74feb0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.4 +version = 5.30.0-dev.5 From bbe504e616ed7f62b804c2204096742c07e9db74 Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Tue, 1 Jul 2025 01:42:01 +0530 Subject: [PATCH 20/33] refactor(YouTube): Match YouTube naming and sort strings (#5309) --- .../youtube/patches/components/AdsFilter.java | 33 +++++++----- .../extension/youtube/settings/Settings.java | 8 +-- .../youtube/ad/general/HideAdsPatch.kt | 10 ++-- .../hide/general/HideLayoutComponentsPatch.kt | 2 +- .../resources/addresources/values/strings.xml | 53 ++++++++++--------- 5 files changed, 56 insertions(+), 50 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java index 51903793c..6cd179391 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java @@ -107,21 +107,24 @@ public final class AdsFilter extends Filter { ); final var viewProducts = new StringFilterGroup( - Settings.HIDE_PRODUCTS_BANNER, + Settings.HIDE_VIEW_PRODUCTS_BANNER, "product_item", "products_in_video", - "shopping_overlay.eml", // Video player overlay shopping links. - "shopping_carousel.eml" // Channel profile shopping shelf. + "shopping_overlay.eml" // Video player overlay shopping links. ); shoppingLinks = new StringFilterGroup( - Settings.HIDE_SHOPPING_LINKS, - "expandable_list", + Settings.HIDE_TAGGED_PRODUCTS, + "expandable_list" + ); + + final var storeProductsShelf = new StringFilterGroup( + Settings.HIDE_CREATOR_STORE_SHELVES, "shopping_description_shelf.eml" ); playerShoppingShelf = new StringFilterGroup( - Settings.HIDE_PLAYER_STORE_SHELF, + Settings.HIDE_CREATOR_STORE_SHELVES, "horizontal_shelf.eml" ); @@ -148,7 +151,8 @@ public final class AdsFilter extends Filter { final var merchandise = new StringFilterGroup( Settings.HIDE_MERCHANDISE_BANNERS, - "product_carousel" + "product_carousel", + "shopping_carousel.eml" // Channel profile shopping shelf. ); final var selfSponsor = new StringFilterGroup( @@ -157,16 +161,17 @@ public final class AdsFilter extends Filter { ); addPathCallbacks( + channelProfile, + fullscreenAd, generalAds, merchandise, - viewProducts, - selfSponsor, - fullscreenAd, - channelProfile, - webLinkPanel, - shoppingLinks, + movieAds, playerShoppingShelf, - movieAds + selfSponsor, + shoppingLinks, + storeProductsShelf, + viewProducts, + webLinkPanel ); } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index f0eecb5c9..ecdf17fbc 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -74,6 +74,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, new ForceOriginalAudioAvailability()); // Ads + public static final BooleanSetting HIDE_CREATOR_STORE_SHELVES = new BooleanSetting("revanced_hide_creator_store_shelves", TRUE); public static final BooleanSetting HIDE_END_SCREEN_STORE_BANNER = new BooleanSetting("revanced_hide_end_screen_store_banner", TRUE, true); public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", TRUE); public static final BooleanSetting HIDE_GENERAL_ADS = new BooleanSetting("revanced_hide_general_ads", TRUE); @@ -81,11 +82,10 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_HIDE_LATEST_POSTS = new BooleanSetting("revanced_hide_latest_posts_ads", TRUE); public static final BooleanSetting HIDE_MERCHANDISE_BANNERS = new BooleanSetting("revanced_hide_merchandise_banners", TRUE); public static final BooleanSetting HIDE_PAID_PROMOTION_LABEL = new BooleanSetting("revanced_hide_paid_promotion_label", TRUE); - public static final BooleanSetting HIDE_PLAYER_STORE_SHELF = new BooleanSetting("revanced_hide_player_store_shelf", TRUE); - public static final BooleanSetting HIDE_PRODUCTS_BANNER = new BooleanSetting("revanced_hide_products_banner", TRUE); public static final BooleanSetting HIDE_SELF_SPONSOR = new BooleanSetting("revanced_hide_self_sponsor_ads", TRUE); - public static final BooleanSetting HIDE_SHOPPING_LINKS = new BooleanSetting("revanced_hide_shopping_links", TRUE); + public static final BooleanSetting HIDE_TAGGED_PRODUCTS = new BooleanSetting("revanced_hide_tagged_products", TRUE); public static final BooleanSetting HIDE_VIDEO_ADS = new BooleanSetting("revanced_hide_video_ads", TRUE, true); + public static final BooleanSetting HIDE_VIEW_PRODUCTS_BANNER = new BooleanSetting("revanced_hide_view_products_banner", TRUE); public static final BooleanSetting HIDE_VISIT_STORE_BUTTON = new BooleanSetting("revanced_hide_visit_store_button", TRUE); public static final BooleanSetting HIDE_WEB_SEARCH_RESULTS = new BooleanSetting("revanced_hide_web_search_results", TRUE); @@ -187,10 +187,10 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_COMMENTS_AI_SUMMARY = new BooleanSetting("revanced_hide_comments_ai_summary", FALSE); public static final BooleanSetting HIDE_COMMENTS_BY_MEMBERS_HEADER = new BooleanSetting("revanced_hide_comments_by_members_header", FALSE); public static final BooleanSetting HIDE_COMMENTS_CREATE_A_SHORT_BUTTON = new BooleanSetting("revanced_hide_comments_create_a_short_button", TRUE); - public static final BooleanSetting HIDE_COMMENTS_TIMESTAMP_BUTTON = new BooleanSetting("revanced_hide_comments_timestamp_button", FALSE); public static final BooleanSetting HIDE_COMMENTS_PREVIEW_COMMENT = new BooleanSetting("revanced_hide_comments_preview_comment", FALSE); public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE); public static final BooleanSetting HIDE_COMMENTS_THANKS_BUTTON = new BooleanSetting("revanced_hide_comments_thanks_button", TRUE); + public static final BooleanSetting HIDE_COMMENTS_TIMESTAMP_BUTTON = new BooleanSetting("revanced_hide_comments_timestamp_button", FALSE); // Description public static final BooleanSetting HIDE_AI_GENERATED_VIDEO_SUMMARY_SECTION = new BooleanSetting("revanced_hide_ai_generated_video_summary_section", FALSE); public static final BooleanSetting HIDE_ASK_SECTION = new BooleanSetting("revanced_hide_ask_section", FALSE); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt index be632ff76..4e1b8b38e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt @@ -43,17 +43,17 @@ private val hideAdsResourcePatch = resourcePatch { addResources("youtube", "ad.general.hideAdsResourcePatch") PreferenceScreen.ADS.addPreferences( - SwitchPreference("revanced_hide_general_ads"), + SwitchPreference("revanced_hide_creator_store_shelves"), SwitchPreference("revanced_hide_end_screen_store_banner"), SwitchPreference("revanced_hide_fullscreen_ads"), + SwitchPreference("revanced_hide_general_ads"), + SwitchPreference("revanced_hide_merchandise_banners"), SwitchPreference("revanced_hide_paid_promotion_label"), - SwitchPreference("revanced_hide_player_store_shelf"), SwitchPreference("revanced_hide_self_sponsor_ads"), - SwitchPreference("revanced_hide_products_banner"), - SwitchPreference("revanced_hide_shopping_links"), + SwitchPreference("revanced_hide_tagged_products"), + SwitchPreference("revanced_hide_view_products_banner"), SwitchPreference("revanced_hide_visit_store_button"), SwitchPreference("revanced_hide_web_search_results"), - SwitchPreference("revanced_hide_merchandise_banners"), ) addLithoFilter("Lapp/revanced/extension/youtube/patches/components/AdsFilter;") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt index 34925d565..189619214 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt @@ -160,9 +160,9 @@ val hideLayoutComponentsPatch = bytecodePatch( SwitchPreference("revanced_hide_comments_by_members_header"), SwitchPreference("revanced_hide_comments_section"), SwitchPreference("revanced_hide_comments_create_a_short_button"), - SwitchPreference("revanced_hide_comments_timestamp_button"), SwitchPreference("revanced_hide_comments_preview_comment"), SwitchPreference("revanced_hide_comments_thanks_button"), + SwitchPreference("revanced_hide_comments_timestamp_button"), ), sorting = PreferenceScreenPreference.Sorting.UNSORTED, ), diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index bec6c8537..d8c18f4b1 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -363,7 +363,7 @@ You will not be notified of any unexpected events." Hide AI Chat summary Chat summary is hidden Chat summary is shown - Hide AI Comments summary + Hide AI comments summary Comments summary is hidden Comments summary is shown Hide \'Comments by members\' header @@ -375,15 +375,15 @@ You will not be notified of any unexpected events." Hide \'Create a Short\' button Create a Short button is hidden Create a Short button is shown - Hide timestamp button - Timestamp button is hidden - Timestamp button is shown Hide preview comment Preview comment is hidden Preview comment is shown Hide Thanks button Thanks button is hidden Thanks button is shown + Hide timestamp button + Timestamp button is hidden + Timestamp button is shown Hide YouTube Doodles @@ -439,32 +439,38 @@ Limitations Keyword will hide all videos: %s - Hide general ads - General ads are hidden - General ads are shown + Hide creator store shelves + Store shelves below the player and in video description are hidden + Store shelves below the player and in video description are shown + Hide end screen store banner + Store banner is hidden + Store banner is shown Hide fullscreen ads "Fullscreen ads are hidden This feature is only available for older devices" Fullscreen ads are shown + + Hide fullscreen ads only works with older devices + Hide general ads + General ads are hidden + General ads are shown + Hide merchandise banners + Merchandise banners are hidden + Merchandise banners are shown Hide paid promotion label Paid promotion label is hidden Paid promotion label is shown + + Hide \'View products\' banner + Banner in video overlay is hidden + Banner in video overlay is shown Hide self sponsored cards Self sponsored cards are hidden Self sponsored cards are shown - Hide \'View products\' banner - Banner is hidden - Banner is shown - Hide end screen store banner - Store banner is hidden - Store banner is shown - Hide player shopping shelf - Shopping shelf is hidden - Shopping shelf is shown - Hide shopping links - Shopping links in video description are hidden - Shopping links in video description are shown + Hide tagged products + Tagged products in video description are hidden + Tagged products in video description are shown Hide \'Visit store\' button Button in channel page is hidden @@ -472,11 +478,6 @@ This feature is only available for older devices" Hide web search results Web search results are hidden Web search results are shown - Hide merchandise banners - Merchandise banners are hidden - Merchandise banners are shown - - Hide fullscreen ads only works with older devices Hide YouTube Premium promotions @@ -888,10 +889,10 @@ To show the Audio track menu, change \'Spoof video streams\' to iOS TV" Hide sound metadata label Metadata label is hidden Metadata label is shown - Hide full video link label + Hide video link label Video link label is hidden Video link label is shown - Hide sound button + Hide Sound button Sound button is hidden Sound button is shown Hide navigation bar From 2b3419571f72b7531a45cd0d727b631e089f3e5d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:35:50 +0400 Subject: [PATCH 21/33] chore: Sync translations (#5315) --- .../addresources/values-af-rZA/strings.xml | 3 +- .../addresources/values-am-rET/strings.xml | 3 +- .../addresources/values-ar-rSA/strings.xml | 52 +++++----- .../addresources/values-as-rIN/strings.xml | 3 +- .../addresources/values-az-rAZ/strings.xml | 74 +++++++++----- .../addresources/values-be-rBY/strings.xml | 49 ++++----- .../addresources/values-bg-rBG/strings.xml | 51 +++++----- .../addresources/values-bn-rBD/strings.xml | 49 ++++----- .../addresources/values-bs-rBA/strings.xml | 3 +- .../addresources/values-ca-rES/strings.xml | 3 +- .../addresources/values-cs-rCZ/strings.xml | 51 +++++----- .../addresources/values-da-rDK/strings.xml | 51 +++++----- .../addresources/values-de-rDE/strings.xml | 59 +++++------ .../addresources/values-el-rGR/strings.xml | 57 +++++------ .../addresources/values-es-rES/strings.xml | 51 +++++----- .../addresources/values-et-rEE/strings.xml | 54 +++++----- .../addresources/values-eu-rES/strings.xml | 3 +- .../addresources/values-fa-rIR/strings.xml | 3 +- .../addresources/values-fi-rFI/strings.xml | 58 ++++++----- .../addresources/values-fil-rPH/strings.xml | 70 ++++++++----- .../addresources/values-fr-rFR/strings.xml | 65 ++++++------ .../addresources/values-ga-rIE/strings.xml | 49 ++++----- .../addresources/values-gl-rES/strings.xml | 3 +- .../addresources/values-gu-rIN/strings.xml | 3 +- .../addresources/values-hi-rIN/strings.xml | 3 +- .../addresources/values-hr-rHR/strings.xml | 3 +- .../addresources/values-hu-rHU/strings.xml | 51 +++++----- .../addresources/values-hy-rAM/strings.xml | 51 +++++----- .../addresources/values-in-rID/strings.xml | 49 ++++----- .../addresources/values-is-rIS/strings.xml | 3 +- .../addresources/values-it-rIT/strings.xml | 51 +++++----- .../addresources/values-iw-rIL/strings.xml | 49 ++++----- .../addresources/values-ja-rJP/strings.xml | 99 ++++++++++--------- .../addresources/values-ka-rGE/strings.xml | 3 +- .../addresources/values-kk-rKZ/strings.xml | 3 +- .../addresources/values-km-rKH/strings.xml | 3 +- .../addresources/values-kn-rIN/strings.xml | 3 +- .../addresources/values-ko-rKR/strings.xml | 61 ++++++------ .../addresources/values-ky-rKG/strings.xml | 3 +- .../addresources/values-lo-rLA/strings.xml | 3 +- .../addresources/values-lt-rLT/strings.xml | 50 +++++----- .../addresources/values-lv-rLV/strings.xml | 49 ++++----- .../addresources/values-mk-rMK/strings.xml | 3 +- .../addresources/values-ml-rIN/strings.xml | 3 +- .../addresources/values-mn-rMN/strings.xml | 3 +- .../addresources/values-mr-rIN/strings.xml | 3 +- .../addresources/values-ms-rMY/strings.xml | 3 +- .../addresources/values-my-rMM/strings.xml | 3 +- .../addresources/values-nb-rNO/strings.xml | 3 +- .../addresources/values-ne-rIN/strings.xml | 3 +- .../addresources/values-nl-rNL/strings.xml | 51 +++++----- .../addresources/values-or-rIN/strings.xml | 3 +- .../addresources/values-pa-rIN/strings.xml | 3 +- .../addresources/values-pl-rPL/strings.xml | 49 ++++----- .../addresources/values-pt-rBR/strings.xml | 49 ++++----- .../addresources/values-pt-rPT/strings.xml | 51 +++++----- .../addresources/values-ro-rRO/strings.xml | 51 +++++----- .../addresources/values-ru-rRU/strings.xml | 65 ++++++------ .../addresources/values-si-rLK/strings.xml | 3 +- .../addresources/values-sk-rSK/strings.xml | 51 +++++----- .../addresources/values-sl-rSI/strings.xml | 51 +++++----- .../addresources/values-sq-rAL/strings.xml | 49 ++++----- .../addresources/values-sr-rCS/strings.xml | 65 ++++++------ .../addresources/values-sr-rSP/strings.xml | 61 ++++++------ .../addresources/values-sv-rSE/strings.xml | 49 ++++----- .../addresources/values-sw-rKE/strings.xml | 3 +- .../addresources/values-ta-rIN/strings.xml | 3 +- .../addresources/values-te-rIN/strings.xml | 3 +- .../addresources/values-th-rTH/strings.xml | 49 ++++----- .../addresources/values-tr-rTR/strings.xml | 51 +++++----- .../addresources/values-uk-rUA/strings.xml | 51 +++++----- .../addresources/values-ur-rIN/strings.xml | 3 +- .../addresources/values-uz-rUZ/strings.xml | 3 +- .../addresources/values-vi-rVN/strings.xml | 75 +++++++------- .../addresources/values-zh-rCN/strings.xml | 49 ++++----- .../addresources/values-zh-rTW/strings.xml | 39 +++----- .../addresources/values-zu-rZA/strings.xml | 3 +- 77 files changed, 1271 insertions(+), 1140 deletions(-) diff --git a/patches/src/main/resources/addresources/values-af-rZA/strings.xml b/patches/src/main/resources/addresources/values-af-rZA/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-af-rZA/strings.xml +++ b/patches/src/main/resources/addresources/values-af-rZA/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-am-rET/strings.xml b/patches/src/main/resources/addresources/values-am-rET/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-am-rET/strings.xml +++ b/patches/src/main/resources/addresources/values-am-rET/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml index afea1a33f..58591e121 100644 --- a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml +++ b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml @@ -315,15 +315,15 @@ Second \"item\" text" إخفاء زر \'إنشاء Short\' تم إخفاء زر إنشاء Short يتم عرض زر إنشاء Short - زر إخفاء الطابع الزمني - زر الطابع الزمني مخفي - زر الطابع الزمني معروض إخفاء تعليق المعاينة تم إخفاء تعليق المعاينة يتم عرض تعليق المعاينة إخفاء زر شكرًا تم إخفاء زر شكرًا يتم عرض زر شكرًا + زر إخفاء الطابع الزمني + زر الطابع الزمني مخفي + زر الطابع الزمني معروض إخفاء رسومات YouTube تم إخفاء رسومات شريط البحث @@ -377,32 +377,38 @@ Second \"item\" text" الكلمة المفتاحية سوف تخفي جميع الفيديوهات: %s - إخفاء الإعلانات العامة - تم إخفاء الإعلانات بشكل عام - يتم عرض الإعلانات العامة + إخفاء رفوف متجر المنشئ + رفوف المتجر أسفل المشغل وفي وصف الفيديو مخفية + تظهر أرفف المتجر أسفل المشغل وفي وصف الفيديو + إخفاء لافتة شاشة المتجر النهائية + تم إخفاء لافتة المتجر + يتم عرض لافتة المتجر إخفاء إعلانات ملء الشاشة "يتم إخفاء إعلانات ملء الشاشة هذه الميزة متاحة فقط للأجهزة القديمة" يتم عرض إعلانات ملء الشاشة + + إخفاء إعلانات ملء الشاشة يعمل فقط مع الأجهزة القديمة + إخفاء الإعلانات العامة + تم إخفاء الإعلانات بشكل عام + يتم عرض الإعلانات العامة + إخفاء لافتات البضائع + تم إخفاء لافتات البضائع + يتم عرض لافتات البضائع إخفاء تسمية الترقية المدفوعة تم إخفاء تسمية الترقية المدفوعة يتم عرض تسمية الترقية المدفوعة + + إخفاء لافتة \'عرض المنتجات\' + الشعار في تراكب الفيديو مخفي + تظهر اللافتة في تراكب الفيديو إخفاء بطاقات الرعاية الذاتية تم إخفاء بطاقات الرعاية الذاتية يتم عرض بطاقات الرعاية الذاتية - إخفاء لافتة \'عرض المنتجات\' - تم إخفاء البانر - يتم عرض البانر - إخفاء لافتة شاشة المتجر النهائية - تم إخفاء لافتة المتجر - يتم عرض لافتة المتجر - إخفاء رف مشغل التسوق - تم إخفاء رف التسوق - يتم عرض رف التسوق - إخفاء روابط التسوق في وصف الفيديو - تم إخفاء روابط التسوق في وصف الفيديو - يتم عرض روابط التسوق في وصف الفيديو + إخفاء المنتجات الموسومة + المنتجات الموسومة في وصف الفيديو مخفية + تظهر المنتجات الموسومة في وصف الفيديو إخفاء زر \'زيارة المتجر\' على صفحات القناة تم إخفاء الزر في صفحة القناة @@ -410,11 +416,6 @@ Second \"item\" text" إخفاء نتائج بحث الويب تم إخفاء نتائج البحث على الويب يتم عرض نتائج البحث على الويب - إخفاء لافتات البضائع - تم إخفاء لافتات البضائع - يتم عرض لافتات البضائع - - إخفاء إعلانات ملء الشاشة يعمل فقط مع الأجهزة القديمة إخفاء ترقية YouTube Premium @@ -826,7 +827,7 @@ Second \"item\" text" إخفاء تسمية بيانات التعريف الصوتية تم إخفاء تسمية بيانات التعريف يتم عرض تسمية بيانات التعريف - إخفاء تسمية رابط الفيديو الكامل + إخفاء تسمية رابط الفيديو تم إخفاء تسمية رابط الفيديو يتم عرض تسمية رابط الفيديو إخفاء زر الصوت @@ -963,7 +964,7 @@ Second \"item\" text" مدة زر التخطي المدة التي تظهر فيها أزرار التخطي والتخطي إلى التمييز المخفية تلقائيًا إظهار إشعار التراجع عن التخطي - يظهر إشعار عند تخطي مقطع تلقائيًا. انقر على الإشعار للتراجع عن التخطي. + يظهر إشعار عند تخطي مقطع تلقائيًا. انقر على الإشعار للتراجع عن التخطي لا يتم عرض التوست مدة توست التخطي المدة التي يظهر فيها إشعار التخطي @@ -1156,6 +1157,7 @@ Second \"item\" text" الافتراضي الجوّال الجهاز اللوحي + السيارات "التغييرات تشمل: تصميم الجهاز اللوحي diff --git a/patches/src/main/resources/addresources/values-as-rIN/strings.xml b/patches/src/main/resources/addresources/values-as-rIN/strings.xml index 3cd7a6fb8..95f2a93b9 100644 --- a/patches/src/main/resources/addresources/values-as-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-as-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-az-rAZ/strings.xml b/patches/src/main/resources/addresources/values-az-rAZ/strings.xml index b95bd8e4f..34db5b71c 100644 --- a/patches/src/main/resources/addresources/values-az-rAZ/strings.xml +++ b/patches/src/main/resources/addresources/values-az-rAZ/strings.xml @@ -285,6 +285,13 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız." Video təsviri Video təsviri elementlərini gizlət və ya göstər Filtr çubuğu + Axınlar, tarixçə, axtarış nəticələri və əlaqəli videolarda filtr panelini gizlət və ya göstər + Axınlarda gizlət + Axınlarda gizlidir + Axınlarda göstər + Tarixçədə gizlət + Tarixçədə gizlədilib + Tarixçədə göstərilib Axtarış nəticələrində gizlət Axtarış nəticələrində gizlədilib Axtarış nəticələrində göstərilir @@ -308,15 +315,15 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız." \"Shorts Yarat\" düyməsini gizlət Short yarat düyməsi gizlidir Short yarat düyməsi görünür - Vaxt möhürü düyməsini gizlət - Vaxt damğası düyməsi gizlidir - Vaxt möhürü düyməsi göstərilir Önbaxış şərhin gizlət Önbaxış şərhi gizlədilib Önbaxış şərhi göstərilir Təşəkkür Düyməsini Gizlət Təşəkkür düyməsi gizlidir Təşəkkür düyməsi göstərilir + Vaxt möhürü düyməsini gizlət + Vaxt damğası düyməsi gizlidir + Vaxt möhürü düyməsi göstərilir YouTube Doodle-ları gizlət Axtarış çubuğu Doodle-ları gizlidir @@ -370,32 +377,38 @@ Məhdudiyyətlər Açar söz, bütün videoları gizlədəcək: %s - Ümumi reklamları gizlət - Ümumi reklamlar gizlidir - Ümumi reklamlar göstərilir + Yaradıcı mağaza bölmələrin gizlət + Oynadıcı altında və video təsvirində mağaza bölümün gizlidir + Oynadıcı altında və video təsvirində mağaza bölümün görünür + Son ekran mağaza etiketini gizlət + Mağaza etiketi gizlidir + Mağaza etiketi görünür Tam ekran reklamlarını gizlət "Tam ekran reklamları gizlidir Bu xüsusiyyət yalnız köhnə cihazlar üçün mövcuddur" Tam ekran reklamları göstərilir + + Tam ekran reklamları gizlətmə yalnız köhnə cihazlarda işləyir + Ümumi reklamları gizlət + Ümumi reklamlar gizlidir + Ümumi reklamlar göstərilir + Məhsul etiketlərini gizlət + Məhsul etiketləri gizlədilir + Məhsul etiketləri göstərilir Ödənişli tanıtım etiketini gizlət Ödənişli reklam etiketi gizlədilib Ödənişli reklam etiketi göstərilir + + “Məhsullara baxın” panelin gizlət + Video örtüyündəki panel gizlədilib + Video örtüyündəki panel görünür Öz-sponsorlu kartları gizlət Özünə sponsorluq edilən kartlar gizlidir Özünə sponsorluq edilən kartlar göstərilir - \"Məhsullara baxın\" etiketin gizlət - Etiket gizlədilib - Etiket göstərilir - Son ekran mağaza etiketini gizlət - Mağaza etiketi gizlidir - Mağaza etiketi görünür - Oynadıcı mağaza bölməsin gizlət - Alış-veriş rəfi gizlidir - Alış-veriş rəfi göstərilir - Video təsvirdə mağaza linklərin gizlə - Video təsvirində alış-veriş linkləri gizlədilib - Video təsvirində alış-veriş linkləri görünür + Etiketlənən məhsulları gizlət + Video təsvirdəki etiketlənən məhsullar gizlidir + Video təsvirdəki etiketlənən məhsullar görünür Kanalda \"Mağazaya baxın\" düyməsin gizlə Kanal səhifəsindəki düymə gizlidir @@ -403,11 +416,6 @@ Bu xüsusiyyət yalnız köhnə cihazlar üçün mövcuddur" Veb axtarış nəticələrini gizlət Veb axtarış nəticələri gizlədilir Veb axtarış nəticələri göstərilir - Məhsul etiketlərini gizlət - Məhsul etiketləri gizlədilir - Məhsul etiketləri göstərilir - - Tam ekran reklamları gizlətmə yalnız köhnə cihazlarda işləyir YouTube Premium reklamlarını gizlət @@ -819,7 +827,7 @@ Audio trek seçimin göstərmək üçün \"Video axınları saxtalaşdır\"ı iO Səs üst məlumat etiketini gizlət Üst məlumat etiketi gizlidir Üst məlumat etiketi göstərilir - Tam video bağlantısı etiketini gizlət + Video keçidi etiketini gizlət Video linki etiketi gizlidir Video link etiketi göstərilir Səs düyməsini gizlət @@ -952,7 +960,25 @@ Bu funksiya 720p və ya daha aşağı video keyfiyyəti ilə və çox sürətli Ötürmə düyməsini avtomatik gizlət Ötürmə düyməsi bir neçə saniyə sonra gizlənir Ötürmə düyməsi bütün bölüm ərzində göstərilir + Ötür düyməsi müddəti + Avtomatik gizlənən ötür və vurğulama düymələri nə qədər göstərilir + Ötürməni geri al bildirişin göstər + Ani bildiriş bölüm birbaşa ötürüldükdə görünür. Ötürməni geri qaytarmaq üçün bildirişə toxun + Ani bildiriş görünmür + Ötür ani bildiriş müddəti + Ötürmə ani bildirişi nə qədər göstərilir + 1 saniyə + 2 saniyə + 3 saniyə + 4 saniyə + 5 saniyə + 6 saniyə + 7 saniyə + 8 saniyə + 9 saniyə + 10 saniyə Bölümsüz video uzunluğun göstər + Video uzunluğu bütün bölümləri çıxarır, irəliləyiş cizgisində göstərir Tam video uzunluğu göstərilir Yeni bölümlər yaradılır Yeni Bölüm Yarat Düyməsini Göstər diff --git a/patches/src/main/resources/addresources/values-be-rBY/strings.xml b/patches/src/main/resources/addresources/values-be-rBY/strings.xml index 8cb2733ef..12fef4cf6 100644 --- a/patches/src/main/resources/addresources/values-be-rBY/strings.xml +++ b/patches/src/main/resources/addresources/values-be-rBY/strings.xml @@ -315,15 +315,15 @@ Second \"item\" text" Схаваць кнопку \"Створиць Short\" Кнопка «Стварыць Shorts» схаваная Кнопка «Стварыць Shorts» паказаная - Схаваць кнопку часу - Кнопка часу схаваная - Кнопка часу паказаная Схаваць каментарый для папярэдняга прагляду Каментарый перад праглядам схаваны Паказваецца папярэдні прагляд каментарыя Схаваць кнопку \"Дзякуй\"\" Кнопка падзякі схавана Паказана кнопка падзякі + Схаваць кнопку часу + Кнопка часу схаваная + Кнопка часу паказаная Схаваць YouTube Doodles Doodles у панэлі пошуку схаваны @@ -377,32 +377,38 @@ Second \"item\" text" Ключавое слова схавае ўсе відэа: %s - Схаваць агульную рэкламу - Агульныя аб\"явы схаваныя - Паказваюцца агульныя аб\"явы + Схаваць паліцы крамы стваральніка + Паліцы крамы пад плэерам і ў апісанні відэа схаваныя + Паліцы крамы пад плэерам і ў апісанні відэа паказаны + Схаваць банер крамы на канчатковым экране + Банэр крамы схаваны + Банэр крамы паказаны Схаваць поўнаэкранную рэкламу "Схаваны поўнаэкранныя рэкламныя ролікі Гэтая функцыя даступная толькі для старых прылад" Адлюстроўваецца поўнаэкранная рэклама + + Схаваць поўнаэкранную рэкламу працуе толькі са старымі прыладамі + Схаваць агульную рэкламу + Агульныя аб\"явы схаваныя + Паказваюцца агульныя аб\"явы + Схаваць банеры з таварамі + Таварныя банеры схаваныя + Паказваюцца таварныя банеры Схаваць метку аплачанай акцыі Пазнака платнай акцыі схавана Адлюстроўваецца ярлык платнай акцыі + + Схаваць банэр \"Прагледзець тавары\" + Банэр у накладцы відэа схаваны + Банэр у накладцы відэа паказаны Схаваць самі спансаваныя карты Спонсарскія карткі схаваныя Паказваюцца ўласныя карты - Схаваць банер «Паглядзець прадукты» - Банэр схаваны - Паказваецца банэр - Схаваць банер крамы на канчатковым экране - Банэр крамы схаваны - Банэр крамы паказаны - Схаваць полку крамы прайгравальніка - Паліца крамы схавана - Паліца крамы паказана - Схаваць спасылкі на пакупкі ў апісанні відэа - Спасылкі на пакупкі ў апісанні відэа схаваныя - Спасылкі на пакупкі ў апісанні відэа паказаныя + Схаваць пазначаныя тавары + Пазначаныя тавары ў апісанні відэа схаваныя + Пазначаныя тавары ў апісанні відэа паказаны Схавайце кнопку \"Наведайце краму\" на старонках канала Кнопка на старонцы канала схаваная @@ -410,11 +416,6 @@ Second \"item\" text" Схаваць вынікі вэб-пошуку Вынікі вэб-пошуку схаваныя Паказваюцца вынікі вэб-пошуку - Схаваць банеры з таварамі - Таварныя банеры схаваныя - Паказваюцца таварныя банеры - - Схаваць поўнаэкранную рэкламу працуе толькі са старымі прыладамі Схаваць акцыі YouTube Premium @@ -826,7 +827,7 @@ Second \"item\" text" Схаваць метку метаданых гуку Метка метаданых схавана Паказана метка метаданых - Схаваць поўную метку спасылкі на відэа + Схаваць надпіс са спасылкай на відэа Метка спасылкі на відэа схавана Адлюструецца метка спасылкі на відэа Кнопка \"Схаваць гук\" diff --git a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml index bd0a8e617..9175dc42a 100644 --- a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml +++ b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml @@ -315,15 +315,15 @@ Second \"item\" text" Бутон за създаване на Shorts Бутонът \"Създаване на Short\" е скрит Бутонът \"Създаване на Short\" е показан - Скриване на бутона за времеви печат - Бутонът за времеви печат е скрит - Бутонът за времеви печат е показан Преглед на коментари Прегледа на коментари е скрит Прегледа на коментари се показва Скрий бутона за харесване Бутона за благодарност е скрит Бутона за благодарност се показва + Скриване на бутона за времеви печат + Бутонът за времеви печат е скрит + Бутонът за времеви печат е показан YouTube Doodles Doodles в лентата за търсене са скрити @@ -377,32 +377,38 @@ Second \"item\" text" Всички видеа с ключовата дума ще бъдат скрити: %s - Скриване на общите реклами - Общите реклами са скрити - Общите реклами се показват + Скриване на рафтовете на магазина за създатели + Рафтовете на магазина под плейъра и в описанието на видеоклипа са скрити + Рафтовете на магазина под плейъра и в описанието на видеоклипа се показват + Скрий банера за реклама в края на екрана + Банерът на магазина е скрит + Банерът на магазина се показва Скриване на рекламите в режим на цял екран "Всички реклами на цял екран са скрити Тази функция е налична само за по-стари устройства" Рекламите в режим на цял екран са показани + + Скр. на реклами на цял екран, за по-стари устройства + Скриване на общите реклами + Общите реклами са скрити + Общите реклами се показват + Скриване на банерите за стоки + Рекламните банери за стоки са скрити + Банерите за стоки се показват Скриване на платените промоции Промоционалните етикети са скрити Промоционалните етикети се показват + + Скриване на банера „Преглед на продукти“ + Банерът в наслагването на видеоклипа е скрит + Банерът във видео наслагването се показва Скриване на самоспонсорирани карти Самоспонсорираните карти са скрити Самоспонсорираните карти са показани - Скриване на банера \"Преглед на продукти\" - Банерът е скрит - Банерът е показан - Скрий банера за реклама в края на екрана - Банерът на магазина е скрит - Банерът на магазина се показва - Скриване на рафта за пазаруване - Рафта за пазаруване е скрит - Рафта за пазаруване се показва - Скриване на връзки за пазаруване - Връзките за пазаруване в описанието на видеоклипа са скрити - Връзките за пазаруване в описанието на видеоклипа са показани + Скриване на маркирани продукти + Маркираните продукти в описанието на видеоклипа са скрити + Маркираните продукти в описанието на видеоклипа се показват Скрийте бутона „Посетете магазина“ на страниците на каналите Бутонът в страницата на канала е скрит @@ -410,11 +416,6 @@ Second \"item\" text" Скриване на резултатите от уеб търсенето Резултатите от уеб търсенето са скрити Резултатите от уеб търсенето са показани. - Скриване на банерите за стоки - Рекламните банери за стоки са скрити - Банерите за стоки се показват - - Скр. на реклами на цял екран, за по-стари устройства Скриване на YouTube Premium промоциите @@ -826,7 +827,7 @@ Second \"item\" text" Скриване на музикални метаданни Метаданни са скрити Метаданни се показват - Скриване на етикет за връзка към видеоклипа + Скриване на етикета на видеовръзката Етикетът за видео връзка е скрит Етикетът за видео връзка се показва Скрийте бутона „Звук“ @@ -963,7 +964,7 @@ Second \"item\" text" Продължителност на бутона за пропускане Колко дълго се показват бутоните за автоматично скриване на пропускане и за пропускане до акцент Показване на известие за отмяна на пропускането - Показва се известие, когато сегмент е автоматично пропуснат. Докоснете известието, за да отмените пропускането. + Показва се известие, когато сегмент е автоматично пропуснат. Докоснете известието, за да отмените пропускането Изскачащо съобщение не се показва Продължителност на изскачащото съобщение за пропускане Колко дълго се показва известието за пропускане diff --git a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml index 8a29b0f08..a39605cb3 100644 --- a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml +++ b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml @@ -311,15 +311,15 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ \'Short তৈরি করুন\' বোতাম লুকান একটি Shorts বোতাম তৈরি করুন লুকানো আছে একটি Shorts বোতাম তৈরি করুন দেখানো হয়েছে - সময় চিহ্নিত করার বোতাম লুকান - সময় চিহ্নিত করার বোতাম লুকানো আছে - সময় চিহ্নিত করার বোতাম দেখানো হয়েছে মন্তব্যের পূর্বরূপ লুকান মন্তব্যের পূর্বরূপ লুকিয়ে রয়েছে মন্তব্যের পূর্বরূপ প্রদর্শিত হয়েছে ধন্যবাদ বাটন লুকান ধন্যবাদ বোতাম লুকিয়ে রয়েছে ধন্যবাদ বোতাম প্রদর্শিত হয়েছে + সময় চিহ্নিত করার বোতাম লুকান + সময় চিহ্নিত করার বোতাম লুকানো আছে + সময় চিহ্নিত করার বোতাম দেখানো হয়েছে YouTube Doodles छिपाएँ सर्च बार Doodles छिपे हुए हैं @@ -373,32 +373,38 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ কিওয়ার্ড সমস্ত ভিডিও লুকিয়ে রাখবে: %s - সাধারণ বিজ্ঞাপন লুকান - সাধারণ বিজ্ঞাপন লুকিয়ে রয়েছে - সাধারণ বিজ্ঞাপন প্রদর্শিত হয়েছে + স্রষ্টার স্টোর শেল্ফগুলি লুকান + প্লেয়ারের নিচে এবং ভিডিও বর্ণনায় থাকা স্টোর শেল্ফগুলি লুকানো হয়েছে + প্লেয়ারের নিচে এবং ভিডিও বর্ণনায় স্টোর শেল্ফগুলি দেখানো হয়েছে + শেষ পর্দার স্টোর ব্যানার লুকান + স্টোর ব্যানারটি লুকানো আছে + স্টোর ব্যানারটি প্রদর্শন করা হবে পূর্ণ স্ক্রীন প্যানেল লুকান "পূর্ণ পর্দার বিজ্ঞাপন লুকানো হয় এই বৈশিষ্ট্যটি কেবল পুরনো ডিভাইসের জন্য উপলব্ধ" পূর্ণ স্ক্রীন বিজ্ঞাপন প্রদর্শিত হয়েছে + + পূর্ণস্ক্রীন বিজ্ঞাপন লুকানো পুরোনো ডিভাইসে কাজ করে + সাধারণ বিজ্ঞাপন লুকান + সাধারণ বিজ্ঞাপন লুকিয়ে রয়েছে + সাধারণ বিজ্ঞাপন প্রদর্শিত হয়েছে + পণ্যদ্রব্য ব্যানার লুকান + পণ্যদ্রব্যের ব্যানার লুকিয়ে রয়েছে + পণ্যদ্রব্যের ব্যানার প্রদর্শিত হয়েছে অর্থের বিনিময়ে প্রচার অন্তর্ভুক্ত রয়েছে ব্যানার লুকান অর্থের বিনিময়ে প্রচার অন্তর্ভুক্ত রয়েছে ব্যানার লুকিয়ে রয়েছে অর্থের বিনিময়ে প্রচার অন্তর্ভুক্ত রয়েছে ব্যানার প্রদর্শিত হয়েছে + + \'পণ্য দেখুন\' ব্যানার লুকান + ভিডিও ওভারলেতে থাকা ব্যানারটি লুকানো হয়েছে + ভিডিও ওভারলেতে ব্যানার দেখানো হয়েছে স্ব-স্পন্সর কার্ড লুকান স্ব-স্পন্সর কার্ড লুকিয়ে রয়েছে স্ব-স্পন্সর কার্ড প্রদর্শিত হয়েছে - \'পণ্য দেখুন\' ব্যানার লুকান - ব্যানার লুকিয়ে রয়েছে - ব্যানার প্রদর্শিত হয়েছে - শেষ পর্দার স্টোর ব্যানার লুকান - স্টোর ব্যানারটি লুকানো আছে - স্টোর ব্যানারটি প্রদর্শন করা হবে - প্লেয়ার শপিং শেলফ লুকান - শপিং শেলফ লুকানো আছে - শপিং শেলফ দেখানো হচ্ছে - ভিডিওর বিবরণে কেনাকাটার লিঙ্ক লুকান - ভিডিও বিবরণে শপিং লিঙ্ক লুকানো আছে - ভিডিও বিবরণে শপিং লিঙ্ক দেখানো হয়েছে + ট্যাগ করা পণ্যগুলি লুকান + ভিডিও বর্ণনায় ট্যাগ করা পণ্যগুলি লুকানো হয়েছে + ভিডিও বর্ণনায় ট্যাগ করা পণ্যগুলি দেখানো হয়েছে চ্যানেল পাতায় \'স্টোরে যান\' বোতাম লুকান চ্যানেল পৃষ্ঠায় বোতাম লুকানো আছে @@ -406,11 +412,6 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ লোকেরা এইগুলিও সার্চ করছে লুকান লোকেরা এইগুলিও সার্চ করছে লুকিয়ে রয়েছে লোকেরা এইগুলিও সার্চ করছে প্রদর্শিত হয়েছে - পণ্যদ্রব্য ব্যানার লুকান - পণ্যদ্রব্যের ব্যানার লুকিয়ে রয়েছে - পণ্যদ্রব্যের ব্যানার প্রদর্শিত হয়েছে - - পূর্ণস্ক্রীন বিজ্ঞাপন লুকানো পুরোনো ডিভাইসে কাজ করে YouTube প্রিমিয়াম প্রচারণা লুকান @@ -822,7 +823,7 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ সাউন্ড মেটাডাটা লেবেল লুকান সাউন্ড মেটাডাটা লেবেল লুকিয়ে রয়েছে সাউন্ড মেটাডাটা লেবেল প্রদর্শিত হয়েছে - সম্পূর্ণ ভিডিও লিঙ্ক লেবেল লুকান + ভিডিও লিঙ্ক লেবেল লুকান ভিডিও লিঙ্ক লেবেল লুকিয়ে রয়েছে ভিডিও লিঙ্ক লেবেল প্রদর্শিত হয়েছে সাউন্ড বোতাম লুকান diff --git a/patches/src/main/resources/addresources/values-bs-rBA/strings.xml b/patches/src/main/resources/addresources/values-bs-rBA/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-bs-rBA/strings.xml +++ b/patches/src/main/resources/addresources/values-bs-rBA/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-ca-rES/strings.xml b/patches/src/main/resources/addresources/values-ca-rES/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-ca-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-ca-rES/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml index 456c783fd..2cf8cfcd4 100644 --- a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml +++ b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml @@ -315,15 +315,15 @@ Nebudete informováni o žádné neočekávané události." Skrýt tlačítko \"Vytvořit Short\" Tlačítko Vytvořit Short je skryté Tlačítko Vytvořit Short je zobrazeno - Skrýt tlačítko časové osy - Tlačítko časové osy je skryté - Tlačítko časové osy je zobrazeno Skrýt náhled komentáře Náhled komentáře je skryt Náhled komentáře je zobrazen Skrýt tlačítko děk」、「 Tlačítko poděkování je skryto Tlačítko poděkování je zobrazeno + Skrýt tlačítko časové osy + Tlačítko časové osy je skryté + Tlačítko časové osy je zobrazeno Skrýt YouTube Doodles Doodles na liště vyhledávání jsou skryty @@ -377,32 +377,38 @@ Omezení: Klíčové slovo skryje všechna videa: %s - Skrýt běžné reklamy - Běžné reklamy jsou skryty - Běžné reklamy jsou zobrazeny + Skrýt regály obchodu tvůrce + Regály obchodu pod přehrávačem a v popisu videa jsou skryty + Police obchodu pod přehrávačem a v popisu videa jsou zobrazeny + Skrýt koncový banner obchodu + Banner obchodu je skrytý + Banner obchodu je zobrazen Skrýt celostránkové reklamy "Celoobrazovkové reklamy jsou skryty Tato funkce je dostupná pouze pro starší zařízení" Celostránkové reklamy jsou zobrazeny + + Blokování reklam na celou obrazovku je funkční pouze na starších zařízeních + Skrýt běžné reklamy + Běžné reklamy jsou skryty + Běžné reklamy jsou zobrazeny + Skrýt reklamní bannery + Merchandise bannery jsou skryty + Merchandise bannery jsou zobrazeny Skrýt štítek placené propagace Štítek placené propagace je skryt Štítek placené propagace je zobrazen + + Skrýt banner „Zobrazit produkty“ + Banner v překryvu videa je skryt + Banner v překrytí videa je zobrazen Skrýt karty se sponzorovanými produkty Karty se sponzorovanými produkty jsou skryty Karty se sponzorovanými produkty jsou zobrazeny - Skrýt banner „Zobrazit produkty“ - Banner je skryt - Banner je zobrazen - Skrýt koncový banner obchodu - Banner obchodu je skrytý - Banner obchodu je zobrazen - Skrýt nákupní polici přehrávače - Nákupní police je skryta - Nákupní police je zobrazena - Skrýt odkazy na nakupování v popisu videa - Nákupní odkazy v popisu videa jsou skryty - Nákupní odkazy v popisu videa jsou zobrazeny + Skrýt označené produkty + Označené produkty v popisu videa jsou skryty + Označení produktů v popisu videa jsou zobrazeny Skrýt tlačítko \'Navštívit obchod\' na stránkách kanálů Tlačítko na stránce kanálu je skryto @@ -410,11 +416,6 @@ Tato funkce je dostupná pouze pro starší zařízení" Skryté webové výsledky vyhledávání Webové výsledky vyhledávání jsou skryté Webové výsledky vyhledávání jsou zobrazeny - Skrýt reklamní bannery - Merchandise bannery jsou skryty - Merchandise bannery jsou zobrazeny - - Blokování reklam na celou obrazovku je funkční pouze na starších zařízeních Skrýt nabídky YouTube Premium @@ -826,7 +827,7 @@ Chcete-li zobrazit nabídku zvukové stopy, změňte možnost „Zfalšovat stre Skrýt štítek zvukového metadata Štítek metadata je skrytý Štítek metadata je zobrazen - Skrýt štítek odkazu na celé video + Skrýt popisek odkazu na video Štítek odkazu na video je skrytý Štítek odkazu na video je zobrazen Skrýt tlačítko zvuku @@ -964,7 +965,7 @@ Tato funkce funguje nejlépe s kvalitou videa 720p nebo nižší a při použit Doba trvání tlačítka přeskočení Jak dlouho se zobrazují tlačítka pro automatické skrytí přeskočení a přeskočení na zvýraznění Zobrazit hlásku pro zrušení přeskočení - Hláska se zobrazí, když je segment automaticky přeskočen. Klepněte na hlásku pro zrušení přeskočení. + Hláska se zobrazí, když je segment automaticky přeskočen. Klepněte na hlásku pro zrušení přeskočení Toast se nezobrazuje Doba trvání toastu přeskočení Jak dlouho se zobrazuje hláska pro přeskočení diff --git a/patches/src/main/resources/addresources/values-da-rDK/strings.xml b/patches/src/main/resources/addresources/values-da-rDK/strings.xml index 5d1f84f64..7e65b1b02 100644 --- a/patches/src/main/resources/addresources/values-da-rDK/strings.xml +++ b/patches/src/main/resources/addresources/values-da-rDK/strings.xml @@ -315,15 +315,15 @@ Du modtager ikke notifikationer om uventede hændelser." Skjul knappen \"Opret en Short\" Opret en Short knap er skjult Opret en Short knap vises - Skjul tidsstempelknap - Tidsstempelknappen er skjult - Tidsstempelknappen vises Skjul forhåndsvisning kommentar Forhåndsvisning kommentar er skjult Forhåndsvis kommentar er vist Skjul \"Tak\"-knap Tak knappen er skjult Tak knappen er vist + Skjul tidsstempelknap + Tidsstempelknappen er skjult + Tidsstempelknappen vises Skjul YouTube-Doudler Søgebjælke Doudler er skjult @@ -377,32 +377,38 @@ Begrænsninger Nøgleord vil skjule alle videoer: %s - Skjul generelle annoncer - Generelle annoncer er skjult - Generelle annoncer vises + Skjul skaberens butikshylder + Butikshylder under afspilleren og i videobeskrivelsen er skjult + Butikshylder under afspilleren og i videobeskrivelsen vises + Skjul banner fra butikken på slutskærmen + Gem banner skjult + Gem banner vises Skjul fuldskærmsannoncer "Fuldsskærmsannoncer er skjult Denne funktion er kun tilgængelig for ældre enheder" Fuldskærms annoncer vises + + Skjul reklamer på fuld skærm virker kun med ældre enheder + Skjul generelle annoncer + Generelle annoncer er skjult + Generelle annoncer vises + Skjul merchandise bannere + Varer bannere er skjult + Varer bannere er vist Skjul betalt kampagneetiket Betalt reklamemærke er skjult Betalt salgsfremmende mærke er vist + + Skjul banneret \"Se produkter\" + Banner i video-overlay er skjult + Banner i video-overlay vises Skjul selvsponsorerede kort Selvsponsorerede kort er skjult Selvsponsorerede kort vises - Skjul banneret \"Se produkter\" - Banner er skjult - Banner er vist - Skjul banner fra butikken på slutskærmen - Gem banner skjult - Gem banner vises - Skjul spillerens indkøbshylde - Shopping hylde er skjult - Shopping hylde er vist - Skjul shopping links i video beskrivelse - Shopping links i videobeskrivelsen er skjult - Shopping links i videobeskrivelsen vises + Skjul taggede produkter + Taggede produkter i videobeskrivelsen er skjult + Taggere produkter i videobeskrivelsen vises Skjul knappen \'Besøg butik\' på kanalsider Knap på kanalsiden er skjult @@ -410,11 +416,6 @@ Denne funktion er kun tilgængelig for ældre enheder" Skjul søgeresultater Websøgeresultater er skjult Websøgeresultater vises - Skjul merchandise bannere - Varer bannere er skjult - Varer bannere er vist - - Skjul reklamer på fuld skærm virker kun med ældre enheder Skjul YouTube Premium kampagner @@ -826,7 +827,7 @@ For at vise lydspormenuen skal du ændre \"Spoof videostream\" til iOS TV"Skjul lyd metadata etiket Metadata etiket er skjult Metadata etiket er vist - Skjul fuld video link etiket + Skjul videolinketiket Videolink etiket er skjult Videolink etiket er vist Skjul lydknap @@ -965,7 +966,7 @@ Denne funktion fungerer bedst med en videokvalitet på 720p eller lavere og ved Spring over-knap varighed Hvor længe knapperne til automatisk skjuling af overspring og spring til højdepunkt vises Vis fortryd oversprings-toast - Toast vises, når et segment automatisk springes over. Tryk på toast-meddelelsen for at fortryde overspringelsen. + Toast vises, når et segment automatisk springes over. Tryk på toast-meddelelsen for at fortryde overspringelsen Toast vises ikke Spring over-toast varighed Hvor længe toast-meddelelsen ved overspringelse vises diff --git a/patches/src/main/resources/addresources/values-de-rDE/strings.xml b/patches/src/main/resources/addresources/values-de-rDE/strings.xml index 098c2f3bd..ff567ee1f 100644 --- a/patches/src/main/resources/addresources/values-de-rDE/strings.xml +++ b/patches/src/main/resources/addresources/values-de-rDE/strings.xml @@ -124,7 +124,7 @@ Wenn Sie dies aktivieren, werden jedoch auch einige Benutzerdaten wie Ihre IP-Ad Debug-Logs enthalten keine Stack-Traces Toast bei ReVanced Fehler anzeigen Ein Toast wird angezeigt, wenn ein Fehler auftritt - Kein Toast wird angezeigt, wenn ein Fehler auftritt + Es wird keine Toast-Nachricht angezeigt, wenn ein Fehler Auftritt "Das Ausschalten von Fehler-Toasts blendet alle Benachrichtigungen über Fehler in ReVanced aus. Sie werden nicht über unerwartete Ereignisse informiert." @@ -165,9 +165,9 @@ Sie werden nicht über unerwartete Ereignisse informiert." Button ist ausgeblendet Button wird angezeigt - Regal \"Für dich\" ausblenden - Regal auf der Kanalseite ist ausgeblendet - Regal auf der Kanalseite wird angezeigt + \"Für dich\" Bereich ausblenden + Bereich auf der Kanalseite ist ausgeblendet + Bereich auf der Kanalseite wird angezeigt \'Benachrichtigungen\' Button ausblenden @@ -311,15 +311,15 @@ Sie werden nicht über unerwartete Ereignisse informiert." \'Verknüpfung erstellen\'-Button ausblenden Schaltfläche \" Short erstellen\" ist ausgeblendet Schaltfläche \" Short erstellen\" wird angezeigt - Timestamp-Button ausblenden - Timestamp-Button ist ausgeblendet - Timestamp-Button wird angezeigt Vorschaukommentar ausblenden Vorschaukommentar ist ausgeblendet Vorschau des Kommentars wird angezeigt Schließe die Dankeschön-Schaltfläche aus Dankeschön-Taste ist ausgeblendet Dankeschön Button wird angezeigt + Timestamp-Button ausblenden + Timestamp-Button ist ausgeblendet + Timestamp-Button wird angezeigt YouTube Doodles ausblenden Suchleiste Doodles sind versteckt @@ -372,32 +372,38 @@ Einschränkungen Stichwort wird alle Videos ausblenden: %s - Allgemeine Werbung ausblenden - Allgemeine Anzeigen sind ausgeblendet - Allgemeine Anzeigen werden angezeigt + Creator-Shop-Regale ausblenden + Shop-Regale unter dem Player und in der Videobeschreibung sind ausgeblendet + Store-Regale unter dem Player und in der Videobeschreibung werden angezeigt + Endbild-Banner ausblenden + Store-Banner wird ausgeblendet + Store-Banner wird angezeigt Vollbild-Werbung ausblenden "Vollbildwerbung wird ausgeblendet Diese Funktion ist nur für ältere Geräte verfügbar" Vollbild-Anzeigen werden angezeigt + + Vollbild-Werbung ausblenden funktioniert nur mit älteren Geräten + Allgemeine Werbung ausblenden + Allgemeine Anzeigen sind ausgeblendet + Allgemeine Anzeigen werden angezeigt + Merchandise-Banner ausblenden + Merchandise-Banner sind ausgeblendet + Warenbanner werden angezeigt Bezahltes Werbe-Label ausblenden Bezahltes Werbelabel ist ausgeblendet Bezahltes Werbe-Label wird angezeigt + + „Produkte ansehen“-Banner ausblenden + Banner im Video-Overlay ist ausgeblendet + Banner im Video-Overlay wird angezeigt Selbst gesponserte Karten ausblenden Selbst gesponserte Karten sind ausgeblendet Selbstgesponserte Karten werden angezeigt - Banner \"Produkte ansehen\" ausblenden - Banner ist ausgeblendet - Banner wird angezeigt - Endbild-Banner ausblenden - Store-Banner wird ausgeblendet - Store-Banner wird angezeigt - Spieler-Einkaufsregal ausblenden - Einkaufsregal ist ausgeblendet - Einkaufsregal wird angezeigt - Einkaufslinks in der Videobeschreibung ausblenden - Shopping-Links in der Videobeschreibung sind ausgeblendet - Shopping-Links in der Videobeschreibung werden angezeigt + Markierte Produkte ausblenden + Markierte Produkte in der Videobeschreibung sind ausgeblendet + Getaggte Produkte in der Videobeschreibung werden angezeigt Den \'Store besuchen\'-Button auf Kanalseiten ausblenden Button auf der Kanalseite ist ausgeblendet @@ -405,11 +411,6 @@ Diese Funktion ist nur für ältere Geräte verfügbar" Suchergebnisse ausblenden Web-Suchergebnisse sind ausgeblendet Web-Suchergebnisse werden angezeigt - Merchandise-Banner ausblenden - Merchandise-Banner sind ausgeblendet - Warenbanner werden angezeigt - - Vollbild-Werbung ausblenden funktioniert nur mit älteren Geräten YouTube Premium-Aktionen ausblenden @@ -819,7 +820,7 @@ Um das Audiotrack-Menü anzuzeigen, ändere \"Video-Streams fälschen\" zu iOS T Sound-Metadaten-Label ausblenden Metadatenlabel ist ausgeblendet Metadaten-Label wird angezeigt - Verstecke vollständige Video-Linkbezeichnung + Video-Link-Label ausblenden Video-Link-Label ist ausgeblendet Video-Link-Label wird angezeigt Tonschaltfläche ausblenden @@ -956,7 +957,7 @@ Diese Funktion funktioniert am besten mit einer Videoqualität von 720p oder nie Dauer des Überspringen-Buttons Wie lange die automatisch ausgeblendeten Schaltflächen zum Überspringen und zum Springen zur Markierung angezeigt werden Toast zum Rückgängigmachen des Überspringens anzeigen - Ein Toast wird angezeigt, wenn ein Segment automatisch übersprungen wird. Tippen Sie auf die Toast-Benachrichtigung, um das Überspringen rückgängig zu machen. + Ein Toast wird angezeigt, wenn ein Segment automatisch übersprungen wird. Tippen Sie auf die Toast-Benachrichtigung, um das Überspringen rückgängig zu machen Toast-Nachricht wird nicht angezeigt Dauer der Überspring-Toastmeldung Wie lange die Überspringen-Toast-Benachrichtigung angezeigt wird diff --git a/patches/src/main/resources/addresources/values-el-rGR/strings.xml b/patches/src/main/resources/addresources/values-el-rGR/strings.xml index 39de0fcc8..410e45ce0 100644 --- a/patches/src/main/resources/addresources/values-el-rGR/strings.xml +++ b/patches/src/main/resources/addresources/values-el-rGR/strings.xml @@ -317,15 +317,15 @@ Second \"item\" text" Κουμπί «Δημιουργία Short» Κρυμμένο Εμφανίζεται - Κουμπί χρονοσήμανσης - Κρυμμένο - Εμφανίζεται Προεπισκόπηση σχολίου Κρυμμένη Εμφανίζεται Κουμπί «Σας ευχαριστούμε» Κρυμμένο Εμφανίζεται + Κουμπί χρονοσήμανσης + Κρυμμένο + Εμφανίζεται YouTube Doodles Κρυμμένα @@ -379,32 +379,38 @@ Second \"item\" text" Θα κρυφτούν όλα τα βίντεο με την λέξη-κλειδί: %s - Γενικές διαφημίσεις - Κρυμμένες - Εμφανίζονται + Ενότητες καταστήματος δημιουργών + Κρυμμένες\n\nΑφορά τις ενότητες καταστήματος κάτω από το πρόγραμμα αναπαραγωγής και στην περιγραφή βίντεο + Εμφανίζονται\n\nΑφορά τις ενότητες καταστήματος κάτω από το πρόγραμμα αναπαραγωγής και στην περιγραφή βίντεο + Ετικέτα καταστήματος στην τελική οθόνη + Κρυμμένη + Εμφανίζεται Διαφημίσεις πλήρους οθόνης "Κρυμμένες Αυτή η λειτουργία είναι διαθέσιμη μόνο για παλιότερες συσκευές" Οι διαφημίσεις πλήρους οθόνης εμφανίζονται + + Η απόκρυψη διαφημίσεων πλήρους οθόνης λειτουργεί μόνο με παλαιότερες συσκευές + Γενικές διαφημίσεις + Κρυμμένες + Εμφανίζονται + Εμβλήματα εμπορευμάτων + Κρυμμένα + Εμφανίζονται Ετικέτες προώθησης επί πληρωμή Κρυμμένες Εμφανίζονται + + Ετικέτα «Προβολή προϊόντων» + Κρυμμένη + Εμφανίζεται Κάρτες αυτοπροώθησης Κρυμμένες Εμφανίζονται - Ετικέτα «Προβολή προϊόντων» - Κρυμμένες - Εμφανίζονται - Ετικέτα καταστήματος στην τελική οθόνη - Κρυμμένη - Εμφανίζεται - Ενότητα αγορών οθόνης αναπαραγωγής - Κρυμμένη - Εμφανίζεται - Σύνδεσμοι αγορών - Κρυμμένοι - Εμφανίζονται + Ετικέτες προϊόντων στην περιγραφή βίντεο + Κρυμμένα + Κρυμμένες Κουμπί «Επίσκεψη στο κατάστημα» στη σελίδα καναλιού Κρυμμένο @@ -412,11 +418,6 @@ Second \"item\" text" Αποτελέσματα αναζήτησης στο διαδίκτυο Κρυμμένα Εμφανίζονται - Εμβλήματα εμπορευμάτων - Κρυμμένα - Εμφανίζονται - - Η απόκρυψη διαφημίσεων πλήρους οθόνης λειτουργεί μόνο με παλαιότερες συσκευές Προωθήσεις για απόκτηση YouTube Premium @@ -828,7 +829,7 @@ Second \"item\" text" Ετικέτες μεταδεδομένων ήχου Κρυμμένες Εμφανίζονται - Ετικέτες συνδέσμων πλήρους βίντεο + Ετικέτα συνδέσμου βίντεο Κρυμμένες Εμφανίζονται Κουμπί ήχου @@ -963,12 +964,12 @@ Second \"item\" text" Το κουμπί παράλειψης κρύβεται μετά από μερικά δευτερόλεπτα Το κουμπί παράλειψης εμφανίζεται σε όλο το τμήμα Διάρκεια κουμπιού παράλειψης - Διάρκεια εμφάνισης των κουμπιών αυτόματης απόκρυψης παράλειψης και μετάβασης σε επισήμανση + Διάρκεια εμφάνισης των κουμπιών παράλειψης και μετάβασης στο αποκορύφωμα πριν την αυτόματη απόκρυψη Εμφάνιση μηνύματος αναίρεσης παράλειψης Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης όταν ένα τμήμα παραλείπεται αυτόματα. Πατήστε το μήνυμα για αναίρεση της παράλειψης - Το μήνυμα δεν εμφανίζεται + Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης όταν ένα τμήμα παραλείπεται αυτόματα Διάρκεια μηνύματος παράλειψης - Πόση ώρα εμφανίζεται το μήνυμα παράλειψης + Διάρκεια εμφάνισης μηνύματος παράλειψης 1 δευτερόλεπτο 2 δευτερόλεπτα 3 δευτερόλεπτα @@ -980,7 +981,7 @@ Second \"item\" text" 9 δευτερόλεπτα 10 δευτερόλεπτα Εμφάνιση μήκους βίντεο χωρίς τα τμήματα - Το μήκος του βίντεο μείον όλα τα τμήματα εμφανίζεται στη γραμμή αναζήτησης + Το μήκος του βίντεο χωρίς όλα τα τμήματα εμφανίζεται πάνω στη γραμμή προόδου Εμφανίζεται το πλήρες μήκος του βίντεο Δημιουργία νέων τμημάτων Εμφάνιση κουμπιού δημιουργίας νέου τμήματος diff --git a/patches/src/main/resources/addresources/values-es-rES/strings.xml b/patches/src/main/resources/addresources/values-es-rES/strings.xml index 8b2d8e1a4..0d7d3e4cd 100644 --- a/patches/src/main/resources/addresources/values-es-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-es-rES/strings.xml @@ -312,15 +312,15 @@ Sin embargo, si activas esto, también se registrarán algunos datos del usuario Ocultar botón \'Crear un Short\' El botón Crear un Short está oculto Se muestra el botón Crear un Short - Ocultar botón de marca de tiempo - Botón de marca de tiempo oculto - Botón de marca de tiempo mostrado Ocultar comentario de vista previa El comentario de la vista previa está oculto Vista previa del comentario se muestra Ocultar botón Gracias El botón de gracias está oculto Se muestra el botón de gracias + Ocultar botón de marca de tiempo + Botón de marca de tiempo oculto + Botón de marca de tiempo mostrado Ocultar YouTube Doodles Barra de búsqueda Doodles están ocultos @@ -374,32 +374,38 @@ Limitaciones Palabra clave ocultará todos los vídeos: %s - Ocultar anuncios generales - Los anuncios generales están ocultos - Se muestran anuncios generales + Ocultar estantes de la tienda del creador + Los estantes de la tienda debajo del reproductor y en la descripción del video están ocultos + Se muestran los estantes de la tienda debajo del reproductor y en la descripción del video + Ocultar banner de la tienda en la pantalla final + El banner de la tienda está oculto + El banner de la tienda está mostrado Ocultar anuncios a pantalla completa "Los anuncios a pantalla completa están ocultos Esta función solo está disponible para dispositivos antiguos" Se muestran anuncios a pantalla completa + + Ocultar anuncio solo con dispositivos viejos + Ocultar anuncios generales + Los anuncios generales están ocultos + Se muestran anuncios generales + Ocultar banners publicitarios + Los banners publicitarios están ocultos + Se muestran los banners publicitarios Ocultar etiqueta de promoción de pago Etiqueta de promoción pagada está oculta Etiqueta de promoción pagada se muestra + + Ocultar el banner \"Ver productos\" + El banner en la superposición del video está oculto + Se muestra el banner en la superposición del video Ocultar tarjetas autopatrocinadas Las tarjetas autopatrocinadas están ocultas Se muestran las tarjetas autopatrocinadas - Ocultar el banner \"Ver productos\" - Banner oculto - Banner mostrado - Ocultar banner de la tienda en la pantalla final - El banner de la tienda está oculto - El banner de la tienda está mostrado - Ocultar estampilla de compra del jugador - El armazón de compras está oculto - Se muestra el shelf de la compra - Ocultar enlaces de compras en la descripción de vídeo - Los enlaces de compra en la descripción del video están ocultos - Se muestran los enlaces de compra en la descripción del video + Ocultar productos etiquetados + Los productos etiquetados en la descripción del video están ocultos + Se muestran los productos etiquetados en la descripción del video Ocultar el botón \'Visitar tienda\' en las páginas del canal El botón en la página del canal está oculto @@ -407,11 +413,6 @@ Esta función solo está disponible para dispositivos antiguos" Ocultar resultados de búsqueda web Los resultados de búsqueda web están ocultos Se muestran los resultados de la búsqueda web - Ocultar banners publicitarios - Los banners publicitarios están ocultos - Se muestran los banners publicitarios - - Ocultar anuncio solo con dispositivos viejos Ocultar promociones de YouTube Premium @@ -823,7 +824,7 @@ Para mostrar el menú de la pista de audio, cambia \"Suplantar transmisiones de Ocultar etiqueta de metadatos de sonido Etiqueta de metadatos oculta Etiqueta de metadatos mostrada - Ocultar etiqueta de enlace de vídeo completo + Ocultar la etiqueta del enlace del video Etiqueta de enlace de vídeo oculto Etiqueta de enlace de vídeo mostrada Ocultar botón de sonido @@ -960,7 +961,7 @@ Esta función funciona mejor con una calidad de vídeo de 720p o inferior y cuan Duración del botón Omitir ¿Cuánto tiempo se muestran automáticamente los botones de omitir y omitir para resaltar? Mostrar mensaje emergente para deshacer omisión - Se muestra un mensaje emergente cuando un segmento se omite automáticamente. Toca la notificación de mensaje emergente para deshacer la omisión. + Se muestra un mensaje emergente cuando un segmento se omite automáticamente. Toca la notificación de mensaje emergente para deshacer la omisión El mensaje emergente no se muestra Duración del mensaje emergente al omitir ¿Cuánto tiempo se muestra la notificación de mensaje emergente de omisión? diff --git a/patches/src/main/resources/addresources/values-et-rEE/strings.xml b/patches/src/main/resources/addresources/values-et-rEE/strings.xml index 456557db2..97feccaf7 100644 --- a/patches/src/main/resources/addresources/values-et-rEE/strings.xml +++ b/patches/src/main/resources/addresources/values-et-rEE/strings.xml @@ -315,15 +315,15 @@ Teid ei teavitata ühestki ootamatust sündmusest." Peida nupp \"Loo lühis\" Nupp Loo lühivideo on peidetud Nupp Loo lühivideo on kuvatud - Peida ajatempli nupp - Ajatempli nupp on peidetud - Ajatempli nupp on nähtav Peida eelvaate kommentaar Eelvaate kommentaar on peidetud Eelvaate kommentaar on kuvatud Peida tänunupp Tänu nupp on peidetud Tänu nupp on kuvatud + Peida ajatempli nupp + Ajatempli nupp on peidetud + Ajatempli nupp on nähtav Peida YouTube Doodles Otsinguriba Doodled on peidetud @@ -377,32 +377,38 @@ Piirangud Võti sõna: %s peidab kõik videod - Peida üldine reklaamid - Üldine reklaamid on peidetud - Üldreklaamid kuvatakse + Peida looja poeriiulid + Mängija all ja videokirjelduses olevad poeriiulid on peidetud + Poeriiulid mängija all ja videokirjelduses on näha + Peida lõpuekraani poe bänner + Poebanner on peidetud + Poebanner on nähtav Peida täisekraanireklaamid "Täisekraani reklaamid on peidetud See funktsioon on saadaval ainult vanemates seadmetes" Täisekraanireklaamid kuvatakse + + Terveekraanireklaamide peitmine toimib ainult vanemate seadmetega + Peida üldine reklaamid + Üldine reklaamid on peidetud + Üldreklaamid kuvatakse + Peida reklaamipõhjad + Reklaamipõhjad on peidetud + Reklaamipõhjad on nähtavad Peida makstud edendamise silt Makstud edendamise silt on peidus Makstud edendamise silt on näidatud + + Peida bänner \"Vaata tooteid\" + Video ülekatte bänner on peidetud + Bänner videokatte all on näha Peida ise-sponsoritud kaardid Ise-sponsoritud kaardid on peidus Ise-sponsoritud kaardid on näidatud - Peida bänner „Vaata tooteid“ - Bänner on peidetud - Bänner on nähtav - Peida lõpuekraani poe bänner - Poebanner on peidetud - Poebanner on nähtav - Peida poes ostukorvi riiul - Ostukorvi riiul on peidetud - Ostukorvi riiul on nähtav - Peida ostulinkid video kirjelduses - Ostulinkid video kirjelduses on peidetud - Ostulinkid video kirjelduses on kuvatud + Peida märgistatud tooted + Videokirjelduses olevad märgistatud tooted on peidetud + Märgistatud tooted videokirjelduses on näha Peida kanali lehelt nuppu \"Külasta poodi\" Nupp kanali lehel on peidetud @@ -410,11 +416,6 @@ See funktsioon on saadaval ainult vanemates seadmetes" Peida veebiotsingu tulemused Veebiotsingu tulemused on peidetud Veebiotsingu tulemused on nähtavad - Peida reklaamipõhjad - Reklaamipõhjad on peidetud - Reklaamipõhjad on nähtavad - - Terveekraanireklaamide peitmine toimib ainult vanemate seadmetega Peida YouTube Premiumi reklaamid @@ -489,6 +490,7 @@ Helitugevuse reguleerimiseks pühkige ekraani paremal küljel vertikaalselt"Luba automaatse heleduse žest Pühkige alla heleduse žesti madalaima väärtuseni, et lubada automaatne heleduse Pühkimine alla madalaima väärtuseni ei luba automaatset heleduse + Automaatne Pühkimise katte aegumisaeg Katte näitamise millisekundite arv Pühkiva katte tausta läbipaistvus @@ -825,7 +827,7 @@ Heliriba menüü kuvamiseks muutke valikut „Võltsitud videovoogedastus“ vä Peida heli metaandmete silt Metaandmete silt on peidetud Metaandmete silt on nähtav - Peida täispika video lingi silt + Peida videolingi silt Video lingi silt on peidetud Video lingi silt on nähtav Peida heli nupp @@ -962,7 +964,7 @@ See funktsioon toimib kõige paremini 720p või madalama video kvaliteedi ja vä Vahelejätnud nupu kestus Kui kaua kuvatakse automaatselt peidetud nuppe \"jäta vahele\" ja \"jäta esiletõstmise juurde\" Kuva tühista vahelejätmise teavitus (toast) - Teavitus (toast) kuvatakse, kui segment jäetakse automaatselt vahele. Vahelejätmise tühistamiseks puudutage teavitust (toast). + Teavitus kuvatakse, kui segment jäetakse automaatselt vahele. Vahelejätmise tühistamiseks puudutage teavitust Hüpikut ei kuvata Vahelejätnud hüpiku kestus Kui kaua kuvatakse vahelejätmise teavitust (toast) @@ -1199,6 +1201,7 @@ Kui see hiljem välja lülitatakse, on soovitatav rakenduse andmed kustutada, et Teatised Esitusloendid Otsi + Ostlemine Sport Tellimused Trendikas @@ -1426,6 +1429,7 @@ Selle lubamine võib avada kõrgema video kvaliteedi" Vaikimisi [Shorts] kvaliteet WiFi võrgus Vaikimisi [Shorts] kvaliteet mobiilivõrgus mobiil + WiFi Vaikimisi %1$s kvaliteet muudeti: %2$s Muudetud Shorts %1$s kvaliteet: %2$s diff --git a/patches/src/main/resources/addresources/values-eu-rES/strings.xml b/patches/src/main/resources/addresources/values-eu-rES/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-eu-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-eu-rES/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-fa-rIR/strings.xml b/patches/src/main/resources/addresources/values-fa-rIR/strings.xml index dd001b6b9..dc7929b8a 100644 --- a/patches/src/main/resources/addresources/values-fa-rIR/strings.xml +++ b/patches/src/main/resources/addresources/values-fa-rIR/strings.xml @@ -108,8 +108,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml index 58be93e9b..df3d64b00 100644 --- a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml +++ b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml @@ -285,6 +285,13 @@ Et saa ilmoituksia odottamattomista tapahtumista." Videon kuvaus Piilota tai näytä videon kuvauksen osia Suodatinpalkki + Piilota tai näytä suodatinpalkki syötteissä, historiassa, hakutuloksissa ja liittyvissä videoissa + Piilota syötteissä + Piilotettu syötteissä + Näytetään syötteissä + Piilota historiassa + Piilotettu historiassa + Näytetään historiassa Piilota hakutuloksissa Piilotettu hakutuloksissa Näytetään hakutuloksissa @@ -308,15 +315,15 @@ Et saa ilmoituksia odottamattomista tapahtumista." Piilota \"Luo Shorts-video\" -painike Luo Shorts-video -painike on piilotettu Luo Shorts-video -painike näytetään - Piilota aikaleimapainike - Aikaleimapainike on piilotettu - Aikaleimapainike näytetään Piilota kommentin esikatselu Kommentin esikatselu on piilotettu Kommentin esikatselu näytetään Piilota Kiitos-painike Kiitos-painike on piilotettu Kiitos-painike näytetään + Piilota aikaleimapainike + Aikaleimapainike on piilotettu + Aikaleimapainike näytetään Piilota YouTube Doodlet Hakupalkin Doodlet on piilotettu @@ -370,32 +377,29 @@ Rajoitukset Avainsana piilottaa kaikki videot: %s - Piilota yleiset mainokset - Yleiset mainokset on piilotettu - Yleiset mainokset näytetään + Piilota loppunäytön kauppabanneri + Kauppabanneri on piilotettu + Kauppabanneri näytetään Piilota koko näytön mainokset "Koko näytön mainokset on piilotettu Tämä ominaisuus on käytettävissä vain vanhemmilla laitteilla" Koko näytön mainokset näytetään + + Koko näytön mainosten piilottaminen toimii vain vanhemmilla laitteilla + Piilota yleiset mainokset + Yleiset mainokset on piilotettu + Yleiset mainokset näytetään + Piilota tuotebannerit + Tuotebannerit on piilotettu + Tuotebannerit näytetään Piilota maksetun mainostuksen tunniste Maksetun mainostuksen tunniste on piilotettu Maksetun mainostuksen tunniste näytetään + Piilota itse-sponsoroidut kortit Itse-sponsoroidut kortit ovat piilotettu Itse-sponsoroidut kortit näytetään - Piilota \"Näytä tuotteet\" -banneri - Banneri on piilotettu - Banneri näytetään - Piilota loppunäytön kauppabanneri - Kauppabanneri on piilotettu - Kauppabanneri näytetään - Piilota soittimen tuotehylly - Tuotehylly on piilotettu - Tuotehylly näytetään - Piilota kauppalinkit - Shopping-linkit on piilotettu videoiden kuvauksissa - Shopping-linkit näytetään videoiden kuvauksissa Piilota \"Vieraile kaupassa\" -painike kanavasivuilla Painike on piilotettu kanavasivuilla @@ -403,11 +407,6 @@ Tämä ominaisuus on käytettävissä vain vanhemmilla laitteilla" Piilota verkkohakutulokset Verkkohakutulokset on piilotettu Verkkohakutulokset näytetään - Piilota tuotebannerit - Tuotebannerit on piilotettu - Tuotebannerit näytetään - - Koko näytön mainosten piilottaminen toimii vain vanhemmilla laitteilla Piilota YouTube Premium -mainokset @@ -816,7 +815,6 @@ Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi" Piilota äänen metadata-tunniste Metadata-tunniste on piilotettu Metadata-tunniste näytetään - Piilota koko videon linkin tunniste Videolinkin tunniste on piilotettu Videolinkin tunniste näytetään Piilota äänipainike @@ -950,7 +948,19 @@ Tämä ominaisuus toimii parhaiten, kun videon laatu on 720p tai alhaisempi ja k Piilota ohita-painike automaattisesti Ohita-painike piiloutuu muutaman sekunnin kuluttua Ohita-painike näytetään koko osion ajan + Ponnahdusilmoitusta ei näytetä + 1 sekunti + 2 sekuntia + 3 sekuntia + 4 sekuntia + 5 sekuntia + 6 sekuntia + 7 sekuntia + 8 sekuntia + 9 sekuntia + 10 sekuntia Näytä videon pituus ilman osioita + Videon pituus ilman kaikkia osioita näkyy etenemispalkissa Videon koko pituus näytetään Uusien osioiden luominen Näytä Luo uusi osio -painike diff --git a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml index eb345427e..5f73dcd76 100644 --- a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml +++ b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml @@ -315,15 +315,15 @@ Hindi ka aabisuhan ng anumang hindi inaasahang mga kaganapan." Itago ang butong \'Gumawa ng Short\' Nakatago ang button na Gumawa ng isang Short Ipinapakita ang button na Gumawa ng isang Short - Itago ang button na timestamp - Nakatago ang button na timestamp - Ipinapakita ang button na timestamp Itago ang preview na komento Nakatago ang preview ng komento Ang pag-preview ng komento ay ipinapakita Itago ang pindutang Salamat Nakatago ang buton ng salamat Ang pindutan ng salamat ay ipinapakita + Itago ang button na timestamp + Nakatago ang button na timestamp + Ipinapakita ang button na timestamp Itago ang mga Doodles ng YouTube Ang mga Doodles sa search bar ay nakatago @@ -377,32 +377,38 @@ Mga limitasyon Ang keyword ay magtatago ng lahat ng mga video: %s - Itago ang mga pangkalahatang ad - Nakatago ang mga pangkalahatang ad - Ipinapakita ang mga pangkalahatang ad + Itago ang mga istante ng tindahan ng tagalikha + Ang mga istante ng tindahan sa ibaba ng player at sa paglalarawan ng video ay nakatago + Ipinapakita ang mga istante ng tindahan sa ilalim ng player at sa paglalarawan ng video + Itago ang banner ng tindahan ng end screen + Nakatago ang banner ng tindahan + Ipinakita ang banner ng tindahan Itago ang mga fullscreen na ad "Ang mga fullscreen ad ay nakatago Ang tampok na ito ay magagamit lamang para sa mga mas lumang device" Ipinapakita ang mga fullscreen na ad + + Gumagana lang ang Itago ang mga fullscreen na ad sa mga mas lumang device + Itago ang mga pangkalahatang ad + Nakatago ang mga pangkalahatang ad + Ipinapakita ang mga pangkalahatang ad + Itago ang mga merchandise banner + Nakatago ang mga banner ng merchandise + Ipinapakita ang mga banner ng merchandise Itago ang may bayad na label ng promosyon Nakatago ang label ng bayad na promosyon Ipinapakita ang may bayad na label ng promosyon + + Itago ang banner na \"Tingnan ang mga produkto\" + Nakatago ang banner sa overlay ng video + Ipinapakita ang banner sa overlay ng video Itago ang mga self sponsored card Nakatago ang mga self sponsored card Ipinapakita ang mga self sponsored card - Itago ang banner na \'Tingnan ang mga produkto\' - Nakatago ang banner - Ipinakita ang banner - Itago ang banner ng tindahan ng end screen - Nakatago ang banner ng tindahan - Ipinakita ang banner ng tindahan - Itago ang istante ng pamimili ng player - Ang istante ng pamimili ay nakatago - Ang istante ng pamimili ay ipinapakita - Itago ang mga link sa pamimili sa paglalarawan ng video - Nakatago ang mga link sa pamimili sa paglalarawan ng video - Ipinapakita ang mga link sa pamimili sa paglalarawan ng video + Itago ang mga nakatag na produkto + Ang mga nakatag na produkto sa paglalarawan ng video ay nakatago + Ipinapakita ang mga naka-tag na produkto sa paglalarawan ng video Itago ang button na \"Bisitahin ang tindahan\" sa mga page ng channel Nakatago ang button sa page ng channel @@ -410,11 +416,6 @@ Ang tampok na ito ay magagamit lamang para sa mga mas lumang device" Itago ang mga resulta ng paghahanap sa web Nakatago ang mga resulta ng paghahanap sa web Ipinapakita ang mga resulta ng paghahanap sa web - Itago ang mga merchandise banner - Nakatago ang mga banner ng merchandise - Ipinapakita ang mga banner ng merchandise - - Gumagana lang ang Itago ang mga fullscreen na ad sa mga mas lumang device Itago ang mga promosyon sa YouTube Premium @@ -720,6 +721,7 @@ Upang ipakita ang menu ng Audio track, baguhin ang 'Spoof video streams' sa iOS Ipinapakita ang thumbnail seekbar + Shorts Manlalaro Itago o ipakita ang mga sangkap sa Shorts player Itago ang Shorts sa home feed @@ -823,7 +825,7 @@ Upang ipakita ang menu ng Audio track, baguhin ang 'Spoof video streams' sa iOS Itago ang sound metadata label Nakatago ang label ng metadata Ang label ng metadata ay ipinapakita - Itago ang buong label ng link ng video + Itago ang label ng link ng video Nakatago ang label ng link ng video Ipinapakita ang label ng link ng video Itago ang pindutan ng tunog @@ -859,6 +861,8 @@ Mga Setting → Pag-playback → I-autoplay ang susunod na video" Lumabas sa fullscreen mode sa katapusan ng video Na-disable + Patayo + Pahalang Portrait at landscape @@ -892,6 +896,7 @@ Limitasyon: Maaaring hindi lumabas ang mga Dislike sa incognito mode" Ipinapakita ang mga Dislike bilang isang porsyento Ipinapakita ang mga Dislike bilang isang numero + Siksik na Pindutan ng Like Like button na naka-istilong para sa minimum na lapad I-style na button para sa pinakamahusay na hitsura Ipakita ang tinantyang mga gusto @@ -1018,6 +1023,7 @@ Ang iyong user id ay parang isang password at hindi dapat ibahagi. " Huwag ipakitang muli Baguhin ang gawi ng segment + Sponsor Bayad na promosyon, bayad na referral at direktang advertisement. Hindi para sa self-promote o libreng shout-out sa mga sanhi/creator/website/produktong gusto nila Walang bayad/Pag-promote sa Sarili Katulad ng Sponsor maliban sa hindi bayad o self promotion. Kasama ang mga seksyon tungkol sa merchandise, donasyon, o impormasyon tungkol sa kung sino ang kanilang nakasama @@ -1086,6 +1092,7 @@ Umiiral na" Hindi makaboto para sa segment (nag-time out ang API) Hindi makaboto para sa segment (status: %1$d %2$s) Hindi makaboto para sa segment: %s + Itaas na Boto I-downvote Baguhin ang kategorya Walang mga segment na iboboto @@ -1128,6 +1135,7 @@ Isumite na ba?" Ang iyong reputasyon ay <b>%.2f</b> Nilikha mo ang <b>%s</b> mga segment Tapikin dito upang tingnan ang iyong mga segment + SponsorBlock Talaan ng mga Nangunguna Nailigtas mo ang mga tao mula sa <b>%s</b> mga segment Mag-tap dito para makita ang mga pandaigdigang istatistika at nangungunang contributor Iyon ay <b>%s</b> ng kanilang buhay.<br>Mag-tap dito para makita ang leaderboard @@ -1137,13 +1145,16 @@ Isumite na ba?" %1$s oras %2$s minuto %1$s minuto %2$s segundo %s segundo + Opacity: Kulay: Tungkol Ang data ay ibinibigay ng SponsorBlock API. Mag-tap dito para matuto pa at makakita ng mga download para sa iba pang platform + Kaayusan ng Form Factor Regular Telepono + Tablet Awtomatiko "Kasama sa mga pagbabago: @@ -1181,6 +1192,7 @@ Kung mamaya ay patayin, inirerekumenda na i-clear ang data ng app upang maiwasan Kasaysayan Aklatan Nagustuhan ang mga video + Live Mga Pelikula Musika Mga Balita @@ -1190,6 +1202,8 @@ Kung mamaya ay patayin, inirerekumenda na i-clear ang data ng app upang maiwasan Pamimili Isports Mga subscription + Uso + Birtuwal na Katotohanan Panoorin mamaya Mga clip mo Palaging baguhin ang panimulang pahina @@ -1205,6 +1219,9 @@ Limitasyon: Maaaring hindi gumana ang paggamit ng back button sa toolbar" Buksan ang Shorts gamit ang + Shorts player + Regular player + Regular player fullscreen Awtomatikong pag-play ng Shorts @@ -1215,10 +1232,12 @@ Limitasyon: Maaaring hindi gumana ang paggamit ng back button sa toolbar"Uulitin ang mga Shorts sa background + Miniplayer Baguhin ang estilo ng naka-minimize na in-app player Uri ng miniplayer Hindi Regular + Minimal Tableta Moderno 1 Moderno 2 @@ -1303,6 +1322,7 @@ Mag-tap dito upang matuto nang higit pa tungkol sa DeArrow" Magpakita ng toast kung hindi available ang API Ang toast ay ipinapakita kung hindi available ang DeArrow Hindi ipinapakita ang toast kung hindi available ang DeArrow + DeArrow API endpoint Ang URL ng DeArrow thumbnail cache endpoint Nakakuha pa rin ng video Kinukuha ang mga still capture mula sa simula/gitna/katapusan ng bawat video. Ang mga larawang ito ay binuo sa YouTube at walang panlabas na API na ginagamit @@ -1350,6 +1370,7 @@ Ang pagpapagana nito ay maaaring magbukas ng mas mataas na kalidad ng video"Mga setting para sa GmsCore + Haptic feedback Baguhin ang haptic feedback Huwag paganahin ang chapters haptics Hindi pinagana ang Chapters haptics @@ -1526,6 +1547,7 @@ Ang AVC ay may pinakamataas na resolusyon na 1080p, ang codec ng audio ng Opus a Tungkol sa ReVanced Mga ad Mga setting ng pag-block ng ad + Chat Mga setting ng chat Iba Pa Sari-saring mga setting diff --git a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml index daf87f89e..ab04cb169 100644 --- a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml +++ b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml @@ -315,15 +315,15 @@ Vous ne serez pas informé des événements inattendus." Masquer le bouton Créer un Short Le bouton \"Créer un Short\" est masqué Le bouton \"Créer un Short\" est affiché - Masquer le bouton d\'horodatage - Le bouton d\'horodatage est masqué - Le bouton d\'horodatage est affiché Masquer le commentaire servant d\'aperçu Le commentaire servant d\'aperçu est masqué Le commentaire servant d\'aperçu est affiché Masquer le bouton Merci Le bouton Merci est masqué Le bouton Merci est affiché + Masquer le bouton d\'horodatage + Le bouton d\'horodatage est masqué + Le bouton d\'horodatage est affiché Masquer les Doodles YouTube Les Doodles de la barre de recherche sont masqués @@ -377,32 +377,38 @@ Limitations Ce mot-clé va masquer toutes les vidéos : %s - Masquer les annonces générales - Les annonces générales sont masquées - Les annonces générales sont affichées + Masquer les étagères de la boutique du créateur + Les étagères de boutique sous le lecteur et dans la description de la vidéo sont masquées + Les étagères de boutique sous le lecteur et dans la description de la vidéo sont affichées + Masquer l\'écran de fin de bannière de boutique + La bannière de boutique est masquée + La bannière de boutique est affichée Masquer les annonces plein écran "Les annonces plein écran sont masquées Cette fonctionnalité est disponible uniquement pour les appareils anciens" Les annonces plein écran sont affichées + + Masquer les annonces plein écran ne fonctionne que sur les appareils anciens + Masquer les annonces générales + Les annonces générales sont masquées + Les annonces générales sont affichées + Masquer les bannières Produits dérivés + Les bannières Produits dérivés sont masquées + Les bannières Produits dérivés sont affichées Masquer la bannière de promotion rémunérée La bannière \"Inclut une promotion rémunérée\" est masquée La bannière \"Inclut une promotion rémunérée\" est affichée + + Masquer la bannière \"Afficher les produits\" + La bannière dans l\'overlay de la vidéo est masquée + La bannière dans l\'overlay de la vidéo est affichée Masquer les cartes d\'autopromotion Les cartes d\'autopromotion sont masquées Les cartes d\'autopromotion sont affichées - Masquer la bannière Afficher les produits - La bannière est masquée - La bannière est affichée - Masquer l\'écran de fin de bannière de boutique - La bannière de boutique est masquée - La bannière de boutique est affichée - Masquer l\'étagère Shopping dans le lecteur - L\'étagère Shopping est masquée - L\'étagère Shopping est affichée - Masquer les liens de shopping - Les liens de shopping dans la description des vidéos sont masqués - Les liens de shopping dans la description des vidéos sont affichés + Masquer les produits tagués + Les produits tagués dans la description de la vidéo sont masqués + Les produits tagués dans la description de la vidéo sont affichés Masquer le bouton Visiter la boutique Le bouton est masqué sur la page de chaîne @@ -410,11 +416,6 @@ Cette fonctionnalité est disponible uniquement pour les appareils anciens"Masquer les résultats Web Les résultats Web sont masqués Les résultats Web sont affichés - Masquer les bannières Produits dérivés - Les bannières Produits dérivés sont masquées - Les bannières Produits dérivés sont affichées - - Masquer les annonces plein écran ne fonctionne que sur les appareils anciens Masquer les publicités pour YouTube Premium @@ -826,7 +827,7 @@ Pour afficher le menu Piste audio, définissez \"Falsifier les flux vidéo\" sur Masquer le libellé des métadonnées audio Le libellé des métadonnées est masqué Le libellé des métadonnées est affiché - Masquer le libellé de lien vers la vidéo complète + Masquer le libellé du lien vidéo Le libellé de lien est masqué Le libellé de lien est affiché Masquer le bouton du son @@ -962,13 +963,13 @@ Cette fonctionnalité fonctionne de manière optimale avec une qualité vidéo d Masquer automatiquement le bouton Passer Le bouton Passer est masqué après quelques secondes Le bouton Passer est affiché pendant toute la durée du segment - Durée du bouton Ignorer - Durée d\'affichage des boutons de masquage automatique de saut et de saut vers le surlignage - Afficher le toast d\'annulation de saut - Un toast s\'affiche lorsqu\'un segment est automatiquement sauté. Touchez la notification toast pour annuler le saut. - Le message n\'est pas affiché - Durée du message Ignorer - Durée d\'affichage de la notification toast de saut + Durée du bouton Passer + Durée d\'affichage avant masquage automatique des boutons Passer et Passer au temps fort + Afficher le message toast d\'annulation de saut + Un message toast est affiché lorsqu\'un segment est automatiquement passé. Appuyez dessus pour annuler le saut. + Le message toast n\'est pas affiché + Durée du message toast de saut + Durée d\'affichage du message toast de saut 1 seconde 2 secondes 3 secondes @@ -981,7 +982,7 @@ Cette fonctionnalité fonctionne de manière optimale avec une qualité vidéo d 10 secondes Afficher la durée de la vidéo sans les segments La durée de la vidéo moins tous les segments est affichée sur la barre de progression - Affichage de la durée totale de la vidéo + La durée totale de la vidéo est affichée Création de nouveaux segments Afficher le bouton Créer un segment Le bouton de création de segment est affiché diff --git a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml index 2963249ae..22eb3a07a 100644 --- a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml +++ b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml @@ -315,15 +315,15 @@ Ní chuirfear ar an eolas thú faoi aon imeachtaí gan choinne." Folaigh an cnaipe \'Cruthaigh Short\' Tá cnaipe Cruthaigh gearrscéal i bhfolach Taispeántar cnaipe Cruthaigh gearrscéal - Folaigh cnaipe an stampa ama - Tá cnaipe an stampa ama i bhfolach - Taispeántar cnaipe an stampa ama Folaigh trácht réamhamharc Tá trácht réamhamhar i bhfolach Taispeántar trácht réamhamharc Folaigh cnaipe Buíochas Tá cnaipe buíochas i bhfolach Taispeántar cnaipe buíochas + Folaigh cnaipe an stampa ama + Tá cnaipe an stampa ama i bhfolach + Taispeántar cnaipe an stampa ama Folaigh YouTube Doodles Barra cuardaigh Tá Doodles i bhfolach @@ -377,32 +377,38 @@ Teorainneacha Folaigh eochairfhocal gach físeán: %s - Folaigh fógraí ginearálta - Tá fógraí ginearálta i bhfolach - Taispeántar fógraí ginearálta + Folaigh seilfeanna siopa an chruthaitheora + Tá seilfeanna siopa faoi bhun an imreora agus i gcur síos an fhíseáin folaithe + Taispeántar seilfeanna siopa faoin imreoir agus sa chur síos ar an bhfíseán + Folaigh brat bhranda siopa scáileáin deiridh + Tá an bhratach Siopa i bhfolach + Taispeántar an bhratach Siopa Folaigh fógraí lánscáileáin "Tá fógraí lána scáileáin i bhfolach Níl an ghné seo ar fáil ach do ghléasanna níos sine" Taispeántar fógraí lánscáileáin + + Ní oibríonn folaigh fógraí lánscáileáin ach le gléasanna níos sine + Folaigh fógraí ginearálta + Tá fógraí ginearálta i bhfolach + Taispeántar fógraí ginearálta + Folaigh meirgí marsantais + Tá meirgí marsantais i bhfolach + Taispeántar meirgí marsantais Folaigh lipéad chun cinn íoctha Tá an lipéad promóisin íoctha i bhfolach Taispeántar lipéad promóisin íoctha + + Folaigh an meirge \'Féach ar tháirgí\' + Tá meirge i bhforleagan físeáin folaithe + Taispeántar meirge san fhorleagan físeáin Folaigh cártaí féin-urraithe Tá cártaí féin-urraithe i bhfolach Taispeántar cártaí féin-urraithe - Folaigh an bhratach \'Féach ar tháirgí\' - Tá bratach i bhfolach - Taispeántar an bhratach - Folaigh brat bhranda siopa scáileáin deiridh - Tá an bhratach Siopa i bhfolach - Taispeántar an bhratach Siopa - Folaigh seilf siopadóireachta an t-imreoir - Tá seilf siopadóireachta i bhfolach - Taispeántar seilf siopadóireachta - Folaigh naisc siopadóireachta sa chur síos físeáin - Tá naisc siopadóireachta i dtuairisc an fhíseáin i bhfolach - Taispeántar naisc siopadóireachta i dtuairisc an fhíseáin + Folaigh táirgí clibáilte + Tá táirgí clibáilte i gcur síos an fhíseáin folaithe + Taispeántar táirgí clibáilte sa chur síos ar an bhfíseán Folaigh an cnaipe \'Tabhair cuairt ar an siopa\' ar leathanaigh chainéil Tá cnaipe i leathanach an chainéil i bhfolach @@ -410,11 +416,6 @@ Níl an ghné seo ar fáil ach do ghléasanna níos sine" Folaigh torthaí cuardaigh gréasáin Tá torthaí cuardaigh gréasáin i bhfolach Taispeántar torthaí cuardaigh gréasáin - Folaigh meirgí marsantais - Tá meirgí marsantais i bhfolach - Taispeántar meirgí marsantais - - Ní oibríonn folaigh fógraí lánscáileáin ach le gléasanna níos sine Folaigh cur chun cinn Préimhe YouTube @@ -826,7 +827,7 @@ Chun roghchlár na rian fuaime a thaispeáint, athraigh 'Srutháin físeáin bhr Folaigh lipéad meiteashonraí fuaime Tá lipéad meiteashonraí folach Léirítear lipéad meiteashonraí - Folaigh lipéad nasc físe iomlán + Folaigh lipéad nasc físeáin Tá lipéad nasc físe i bhfolach Taispeántar lipéad nasc físe Folaigh an cnaipe fuaime diff --git a/patches/src/main/resources/addresources/values-gl-rES/strings.xml b/patches/src/main/resources/addresources/values-gl-rES/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-gl-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-gl-rES/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-gu-rIN/strings.xml b/patches/src/main/resources/addresources/values-gu-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-gu-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-gu-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-hi-rIN/strings.xml b/patches/src/main/resources/addresources/values-hi-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-hi-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-hi-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-hr-rHR/strings.xml b/patches/src/main/resources/addresources/values-hr-rHR/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-hr-rHR/strings.xml +++ b/patches/src/main/resources/addresources/values-hr-rHR/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml index d0a920858..c8cc277cb 100644 --- a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml +++ b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml @@ -315,15 +315,15 @@ Nem fog értesülni semmilyen váratlan eseményről." A „Rövid létrehozása” gomb elrejtése A Rövidfilm létrehozása gomb rejtett A Rövidfilm létrehozása gomb látható - Az időbélyegző gomb elrejtése - Az időbélyegző gomb el van rejtve - Az időbélyegző gomb megjelenik Megjegyzés előnézet elrejtése A megjegyzés előnézet el van rejtve A megjegyzés előnézet megjelenik Köszönet gomb elrejtése A köszönet gomb el van rejtve A köszönet gomb látható + Az időbélyegző gomb elrejtése + Az időbélyegző gomb el van rejtve + Az időbélyegző gomb megjelenik YouTube Doodles elrejtése A Doodles Keresősáv el van rejtve @@ -377,32 +377,38 @@ Korlátozások A kulcsszó elrejti az összes videót: %s - Általános hirdetések elrejtése - Az általános hirdetések el vannak rejtve - Az általános hirdetések megjelennek + Alkotói bolti polcok elrejtése + A lejátszó alatti és a videó leírásában lévő bolti polcok elrejtve + A lejátszó alatt és a videó leírásában megjelennek az árupolcok + A befejező képernyőn lévő üzletbanner elrejtése + Az áruház banner rejtett + Az áruház banner megjelenik Teljes képernyős hirdetések elrejtése "A teljes képernyős hirdetések el vannak rejtve Ez a funkció csak régebbi eszközökön érhető el" A teljes képernyős hirdetések láthatók + + A teljes képernyős hirdetések elrejtése csak régebbi eszközökön működik + Általános hirdetések elrejtése + Az általános hirdetések el vannak rejtve + Az általános hirdetések megjelennek + Áruszalaghirdetések elrejtése + Az áruszalaghirdetések el vannak rejtve + Az áruszalaghirdetések megjelennek Fizetett promóció címke elrejtése A fizetett promóciós címke el van rejtve A fizetett promóciós címke meg van jelenítve + + A „Termékek megtekintése” szalaghirdetés elrejtése + A videóátfedésben lévő szalaghirdetés elrejtve + A szalaghirdetés megjelenik a videó átfedésében Önpromóciós kártyák elrejtése Az önpromóciós kártyák rejtve vannak Az önpromóciós kártyák megjelennek - \"View products\" szalagcím elrejtése - A szalagkép rejtett - A szalagkép megjelenik - A befejező képernyőn lévő üzletbanner elrejtése - Az áruház banner rejtett - Az áruház banner megjelenik - A lejátszó bevásárlópolcának elrejtése - A bevásárlópolc el van rejtve - Megjelenik a bevásárlópolc - Vásárlási linkek elrejtése a videó leírásában - A videóleírásban található vásárlási hivatkozások rejtettek - A videóleírásban található vásárlási hivatkozások láthatók + Címkézett termékek elrejtése + A videó leírásában lévő címkézett termékek elrejtve + A videó leírásában címkézett termékek jelennek meg \'Bolt meglátogatása\' gomb elrejtése a csatornák oldalán A gomb a csatornaoldalon rejtett @@ -410,11 +416,6 @@ Ez a funkció csak régebbi eszközökön érhető el" Webes keresési találatok elrejtése A webes keresési találatok rejtve vannak A webes keresési találatok megjelennek - Áruszalaghirdetések elrejtése - Az áruszalaghirdetések el vannak rejtve - Az áruszalaghirdetések megjelennek - - A teljes képernyős hirdetések elrejtése csak régebbi eszközökön működik YouTube Premium promóciók elrejtése @@ -826,7 +827,7 @@ Az audiosáv menü megjelenítéséhez módosítsa a \"Videófolyamok hamisítá Hang metaadatcímke elrejtése A hang metaadatcímke el van rejtve A hang metaadatcímke megjelenik - Teljes videólink címke elrejtése + Videóhivatkozás címkéjének elrejtése A teljes videólink címke el van rejtve A teljes videólink címke megjelenik Hang gomb elrejtése @@ -963,7 +964,7 @@ Ez a funkció a legjobban 720p vagy annál alacsonyabb videóminőség mellett Átugrás gomb időtartama Meddig láthatók az automatikus elrejtésű átugrás és kiemelés gombok Ugrás visszavonása felugró értesítés megjelenítése - Felugró értesítés jelenik meg, amikor egy szegmens automatikusan átugrásra kerül. Érintse meg a felugró értesítést az átugrás visszavonásához. + Felugró értesítés jelenik meg, amikor egy szegmens automatikusan átugrásra kerül. Érintse meg a felugró értesítést az átugrás visszavonásához A felugró üzenet nem jelenik meg Átugrási felugró üzenet időtartama Meddig látható az átugrás felugró értesítés diff --git a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml index b68a0accc..5e22d7748 100644 --- a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml +++ b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml @@ -315,15 +315,15 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել Թաքցնել \"Ստեղծել Shorts\" կոճակը \"Ստեղծել Short\" կոճակը թաքցված է \"Ստեղծել Short\" կոճակը ցուցադրվում է - Թաքցնել ժամանակային նշումով կոճակը - Ժամանակային նշումով կոճակը թաքցված է - Ժամանակային նշումով կոճակը ցուցադրվում է Թաքցնել նախադիտման մեկնաբանությունը Նախադիտման մեկնաբանությունը թաքցված է Նախադիտման մեկնաբանությունը երևում է Թաքցնել շնորհակալության կոճակը \"Շնորհակալություն\" կոճակը թաքցված է \"Շնորհակալություն\" կոճակը երևում է + Թաքցնել ժամանակային նշումով կոճակը + Ժամանակային նշումով կոճակը թաքցված է + Ժամանակային նշումով կոճակը ցուցադրվում է Թաքցնել YouTube-ի Doodles-ները Որոնման տողի Doodles-ները թաքցված են @@ -377,32 +377,38 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել Բանալի բառը կթաքցնի բոլոր տեսանյութերը։ %s - Թաքցնել ընդհանուր գովազդները - Ընդհանուր գովազդները թաքցված են - Ընդհանուր գովազդները երևում են + Թաքցնել ստեղծողի խանութի դարակները + Խանութի դարակները նվագարկչի տակ և տեսանյութի նկարագրության մեջ թաքնված են + Խանութի դարակները նվագարկչի տակ և տեսանյութի նկարագրության մեջ ցուցադրվում են + Թաքցնել վերջնական էկրանի խանութի բաները + Խանութի բանները թաքցված են + Խանութի բանները ցուցադրվում են Թաքցնել լի էկրանի գովազդները "«Լրիվ էկրան» գովազդները թաքցվում են Այս հատկությունը հասանելի է միայն հին սարքերի համար" Լի էկրանի գովազդները երևում են + + Լի էկրանի գովազդների թաքցումը գործում է միայն հին սարքերի համար + Թաքցնել ընդհանուր գովազդները + Ընդհանուր գովազդները թաքցված են + Ընդհանուր գովազդները երևում են + Թաքցնել ապրանքների բաները + Ապրանքների բաները թաքցված են + Ապրանքների բաները երևում են Թաքցնել վճարված խթանման նշանը Վճարված խթանման նշանը թաքցված է Վճարված խթանման նշանը երևում է + + Թաքցնել \"Դիտել ապրանքները\" պաստառը + Տեսանյութի ծածկույթում գտնվող դրոշակը թաքնված է + Տեսանյութի վերադիրում պաստառը ցուցադրվում է Թաքցնել ինքնահովանավորված քարտերը Ինքնահովանավորված քարտերը թաքցված են Ինքնահովանավորված քարտերը երևում են - Թաքցնել «Դիտել ապրանքները» պաստառը - Բաները թաքցված են - Բաները երևում են - Թաքցնել վերջնական էկրանի խանութի բաները - Խանութի բանները թաքցված են - Խանութի բանները ցուցադրվում են - Թաքցնել խաղացողի խանութի դարակը - Խանութի դարակը թաքցված է - Խանութի դարակը երևում է - Թաքցնել խանութի հղումները տեսանյութի նկարագրության մեջ - Տեսանյութի նկարագրության մեջ առկա գնումների հղումները թաքցված են - Տեսանյութի նկարագրության մեջ առկա գնումների հղումները ցուցադրվում են + Թաքցնել պիտակված ապրանքները + Տեսանյութի նկարագրության մեջ պիտակված ապրանքները թաքնված են + Նշված ապրանքները տեսանյութի նկարագրության մեջ ցուցադրվում են Թաքցնել \"Անցնել խանութ\" կոճակը ալիքների էջերում Ալիքի էջում գտնվող կոճակը թաքցված է @@ -410,11 +416,6 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել Թաքցնել վեբ-որոնման արդյունքները Վեբ-որոնման արդյունքները թաքցված են Վեբ-որոնման արդյունքները երևում են - Թաքցնել ապրանքների բաները - Ապրանքների բաները թաքցված են - Ապրանքների բաները երևում են - - Լի էկրանի գովազդների թաքցումը գործում է միայն հին սարքերի համար Թաքցնել YouTube Premium-ի խթանումները @@ -826,7 +827,7 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել Թաքցնել ձայնի մետատվությունների լեյբլը Մետատվությունների լեյբլը թաքցված է Մետատվությունների լեյբլը երևում է - Թաքցնել լիարժեք տեսանյութի հղման լեյբլը + Թաքցնել տեսանյութի հղման պիտակը Տեսանյութի հղման լեյբլը թաքցված է Տեսանյութի հղման լեյբլը երևում է Թաքցնել ձայնի կոճակը @@ -964,7 +965,7 @@ Seekbar thumbnails-ները կօգտագործեն նույն որակը, ինչ Բաց թողնելու կոճակի տևողությունը Ինչքան ժամանակ են ցուցադրվում ավտոմատ թաքնվող բաց թողնելու և առանձնացված մասին անցնելու կոճակները։ Ցուցադրել բաց թողնելը չեղարկելու ծանուցումը։ - Ծանուցում է ցուցադրվում, երբ հատվածն ավտոմատ կերպով բաց է թողնվում։ Հպեք ծանուցմանը՝ բացթողումը չեղարկելու համար։ + Ծանուցում է ցուցադրվում, երբ հատվածն ավտոմատ կերպով բաց է թողնվում։ Հպեք ծանուցմանը՝ բացթողումը չեղարկելու համար Ծանուցումը չի ցուցադրվում Բաց թողնելու ծանուցման տևողությունը Ինչքան ժամանակ է ցուցադրվում բաց թողնելու ծանուցումը։ diff --git a/patches/src/main/resources/addresources/values-in-rID/strings.xml b/patches/src/main/resources/addresources/values-in-rID/strings.xml index 2a4aef60e..6db5f8395 100644 --- a/patches/src/main/resources/addresources/values-in-rID/strings.xml +++ b/patches/src/main/resources/addresources/values-in-rID/strings.xml @@ -315,15 +315,15 @@ Anda tidak akan diberi tahu tentang kejadian yang tidak terduga." Sembunyikan tombol \'Buat Short\' Tombol Buat Short disembunyikan Tombol Buat Short ditampilkan - Sembunyikan tombol penanda waktu - Tombol penanda waktu disembunyikan - Tombol penanda waktu ditampilkan Sembunyikan pratinjau komentar Pratinjau komentar disembunyikan Pratinjau komentar ditampilkan Sembunyikan tombol Terima Kasih Tombol terima kasih disembunyikan Tombol terima kasih ditampilkan + Sembunyikan tombol penanda waktu + Tombol penanda waktu disembunyikan + Tombol penanda waktu ditampilkan Sembunyikan YouTube Doodles Bilah pencarian Doodle disembunyikan @@ -377,32 +377,38 @@ Keterbatasan Kata kunci akan menyembunyikan semua video: %s - Sembunyikan iklan umum - Iklan umum disembunyikan - Iklan umum ditampilkan + Sembunyikan rak toko kreator + Rak toko di bawah pemutar dan di deskripsi video disembunyikan + Rak toko di bawah pemutar dan di deskripsi video ditampilkan + Sembunyikan spanduk toko di layar akhir + Spanduk toko disembunyikan + Spanduk toko ditampilkan Sembunyikan iklan layar penuh "Iklan layar penuh disembunyikan Fitur ini hanya tersedia untuk perangkat yang lebih lama" Iklan layar penuh ditampilkan + + Menyembunyikan iklan layar penuh hanya berfungsi pada perangkat lama + Sembunyikan iklan umum + Iklan umum disembunyikan + Iklan umum ditampilkan + Sembunyikan spanduk merchandise + Banner merchandise disembunyikan + Spanduk merchandise ditampilkan Sembunyikan label promosi berbayar Label promosi berbayar disembunyikan Label promosi berbayar ditampilkan + + Sembunyikan banner \'Lihat produk\' + Spanduk di hamparan video disembunyikan + Banner di overlay video ditampilkan Sembunyikan kartu bersponsor pribadi Kartu bersponsor pribadi disembunyikan Kartu bersponsor pribadi ditampilkan - Sembunyikan spanduk \'Lihat produk\' - Spanduk disembunyikan - Spanduk ditampilkan - Sembunyikan spanduk toko di layar akhir - Spanduk toko disembunyikan - Spanduk toko ditampilkan - Sembunyikan rak belanja pemutar - Rak belanja disembunyikan - Rak belanja ditampilkan - Sembunyikan tautan belanja - Tautan belanja di deskripsi video disembunyikan - Tautan belanja di deskripsi video ditampilkan + Sembunyikan produk yang ditandai + Produk yang ditandai dalam deskripsi video disembunyikan + Produk yang ditandai di deskripsi video ditampilkan Sembunyikan tombol \'Kunjungi toko\' Tombol di halaman saluran disembunyikan @@ -410,11 +416,6 @@ Fitur ini hanya tersedia untuk perangkat yang lebih lama" Sembunyikan hasil pencarian web Hasil pencarian web disembunyikan Hasil pencarian web ditampilkan - Sembunyikan spanduk merchandise - Banner merchandise disembunyikan - Spanduk merchandise ditampilkan - - Menyembunyikan iklan layar penuh hanya berfungsi pada perangkat lama Sembunyikan promosi YouTube Premium @@ -826,7 +827,7 @@ Untuk menampilkan menu trek Audio, ubah 'Spoof aliran video' ke iOS TV" Sembunyikan label metadata suara Label metadata disembunyikan Label metadata ditampilkan - Sembunyikan label tautan video penuh + Sembunyikan label tautan video Label tautan video disembunyikan Label tautan video ditampilkan Sembunyikan tombol suara diff --git a/patches/src/main/resources/addresources/values-is-rIS/strings.xml b/patches/src/main/resources/addresources/values-is-rIS/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-is-rIS/strings.xml +++ b/patches/src/main/resources/addresources/values-is-rIS/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-it-rIT/strings.xml b/patches/src/main/resources/addresources/values-it-rIT/strings.xml index 732ba3793..fd424c768 100644 --- a/patches/src/main/resources/addresources/values-it-rIT/strings.xml +++ b/patches/src/main/resources/addresources/values-it-rIT/strings.xml @@ -315,15 +315,15 @@ Non sarai notificato di eventi imprevisti." Nascondi il pulsante \'Crea uno Short\' Il pulsante Crea uno Short è nascosto Il pulsante Crea uno Short è visibile - Nascondi pulsante timestamp - Il pulsante timestamp è nascosto - Il pulsante timestamp è visibile Nascondi il commento di anteprima Il commento di anteprima è nascosto Il commento di anteprima è visibile Nascondi il pulsante Grazie Il pulsante Grazie è nascosto Il pulsante Grazie è visibile + Nascondi pulsante timestamp + Il pulsante timestamp è nascosto + Il pulsante timestamp è visibile Nascondi Doodles di YouTube I Doodle nella barra di ricerca sono nascosti @@ -377,32 +377,38 @@ Note: La parola chiave nasconderà tutti i video: %s - Nascondi pubblicità generali - Le pubblicità generali sono nascoste - Le pubblicità generali sono visibili + Nascondi gli scaffali del negozio del creatore + Gli scaffali del negozio sotto il player e nella descrizione del video sono nascosti + Le scaffalature del negozio sotto il lettore e nella descrizione del video sono mostrate + Nascondi banner del negozio della schermata finale + Il banner del negozio è nascosto + Il banner del negozio è visibile Nascondi le pubblicità a schermo intero "Le pubblicità a schermo intero sono nascoste Questa funzione è disponibile solo per i dispositivi più vecchi" Le pubblicità a schermo intero sono visibili + + Nascondi gli annunci a schermo intero funziona solo con dispositivi più vecchi + Nascondi pubblicità generali + Le pubblicità generali sono nascoste + Le pubblicità generali sono visibili + Nascondi i banner sul merchandising + I banner sul merchandising sono nascosti + I banner sul merchandising sono visibili Nascondi l\'etichetta della promozione a pagamento L\'etichetta della promozione a pagamento è nascosta L\'etichetta della promozione a pagamento è visibile + + Nascondi il banner \'Visualizza prodotti\' + Il banner nella sovrapposizione del video è nascosto + Il banner nell\'overlay del video è mostrato Nascondi le schede autopromozionali Le schede autopromozionali sono nascoste Le schede autopromozionali sono visibili - Nascondi il banner \"Visualizza prodotti\" - Il banner è nascosto - Il banner è visibile - Nascondi banner del negozio della schermata finale - Il banner del negozio è nascosto - Il banner del negozio è visibile - Nascondi la sezione Negozio - La sezione negozio è nascosta - La sezione negozio è visibile - Nascondi link agli acquisti nella descrizione del video - I link di shopping nella descrizione del video sono nascosti - I link di shopping nella descrizione del video sono visibili + Nascondi prodotti taggati + I prodotti taggati nella descrizione del video sono nascosti + I prodotti taggati nella descrizione del video sono mostrati Nascondi il pulsante \'Visita negozio\' nelle pagine del canale Il pulsante nella pagina del canale è nascosto @@ -410,11 +416,6 @@ Questa funzione è disponibile solo per i dispositivi più vecchi" Nascondi i risultati della ricerca web I risultati della ricerca web sono nascosti I risultati della ricerca web sono visibili - Nascondi i banner sul merchandising - I banner sul merchandising sono nascosti - I banner sul merchandising sono visibili - - Nascondi gli annunci a schermo intero funziona solo con dispositivi più vecchi Nascondi la promozione di YouTube Premium @@ -826,7 +827,7 @@ Per mostrare il menu della traccia audio, cambia \"Spoof video streams\" in iOS Nascondi etichetta dei metadati sonori L\'etichetta dei metadati è nascosta L\'etichetta dei metadati è visibile - Nascondi l\'etichetta del link del video + Nascondi etichetta link video L\'etichetta del link del video è nascosta L\'etichetta del link del video è visibile Nascondi il pulsante Suono @@ -963,7 +964,7 @@ Questa funzione funziona meglio con una qualità video di 720p o inferiore e qua Durata pulsante Salta Per quanto tempo vengono mostrati i pulsanti di nascondimento automatico e di salto all\'evidenziazione Mostra toast annulla salto - Il toast viene mostrato quando un segmento viene automaticamente saltato. Tocca la notifica toast per annullare il salto. + Il toast viene mostrato quando un segmento viene automaticamente saltato. Tocca la notifica toast per annullare il salto Il toast non viene mostrato Durata toast Salta Per quanto tempo viene mostrata la notifica toast di salto diff --git a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml index eb34d34c9..43bfc541c 100644 --- a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml +++ b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml @@ -315,15 +315,15 @@ Second \"item\" text" הסתר לחצן \'יצירת Short\' לחצן יצירת Short מוסתר לחצן יצירת Short מוצג - הסתר לחצן חותם זמן - לחצן חותם זמן מוסתר - לחצן חותם זמן מוצג הסתר תצוגה מקדימה של תגובה תצוגה מקדימה של תגובה מוסתרת תצוגה מקדימה של תגובה מוצגת הסתר לחצן תודה לחצן תודה מוסתר לחצן תודה מוצג + הסתר לחצן חותם זמן + לחצן חותם זמן מוסתר + לחצן חותם זמן מוצג הסתר YouTube Doodles שרבוטים (Doodles) של סרגל חיפוש מוסתרים @@ -377,32 +377,38 @@ Second \"item\" text" מילת מפתח תסתיר את כל הסרטונים: %s - הסתר מודעות כלליות - מודעות כלליות מוסתרות - מודעות כלליות מוצגות + הסתר מדפי חנות של יוצר + מדפי החנות מתחת לנגן ובתיאור הסרטון מוסתרים + מדפי חנות מתחת לנגן ובתאור הסרטון מוצגים + הסתר כרזת חנות של מסך סיום + כרזת חנות מוסתרת + כרזת חנות מוצגת הסתר מודעות מסך מלא "מודעות במסך מלא מוסתרות תכונה זו זמינה רק עבור מכשירים ישנים יותר" מודעות מסך מלא מוצגות + + הסתר מודעות מסך מלא עובד רק עם מכשירים ישנים יותר + הסתר מודעות כלליות + מודעות כלליות מוסתרות + מודעות כלליות מוצגות + הסתר כרזות מרצ\'נדייז + כרזות מרצ\'נדייז מוסתרות + כרזות מרצ\'נדייז מוצגות הסתר תווית קידום מכירות בתשלום תווית קידום מכירות בתשלום מוסתרת תווית קידום מכירות בתשלום מוצגת + + הסתר באנר \'צפה במוצרים\' + הבאנר בשכבת העל של הסרטון מוסתר + הבאנר בשכבת העל של הסרטון מוצג הסתר כרטיסים בחסות עצמית כרטיסים בחסות עצמית מוסתרים כרטיסים בחסות עצמית מוצגים - הסתר כרזת \'ראה מוצרים\' - כרזה מוסתרת - כרזה מוצגת - הסתר כרזת חנות של מסך סיום - כרזת חנות מוסתרת - כרזת חנות מוצגת - הסתר מדף שופינג של נגן - מדף שופינג מוסתר - מדף שופינג מוצג - הסתר קישורי שופינג - קישורי שופינג בתיאור סרטון מוסתרים - קישורי שופינג בתיאור סרטון מוצגים + הסתר מוצרים מתויגים + מוצרים מתויגים בתיאור הסרטון מוסתרים + מוצרים מתויגים בתאור הסרטון מוצגים הסתר לחצן \'בקר בחנות\' לחצן בדף הערוץ מוסתר @@ -410,11 +416,6 @@ Second \"item\" text" הסתר תוצאות חיפוש באינטרנט תוצאות חיפוש באינטרנט מוסתרות תוצאות חיפוש באינטרנט מוצגות - הסתר כרזות מרצ\'נדייז - כרזות מרצ\'נדייז מוסתרות - כרזות מרצ\'נדייז מוצגות - - הסתר מודעות מסך מלא עובד רק עם מכשירים ישנים יותר הסתר קידומי YouTube Premium @@ -826,7 +827,7 @@ Second \"item\" text" הסתר תווית מטא-נתונים של סאונד תווית מטא-נתונים מוסתרת תווית מטא-נתונים מוצגת - הסתר תווית קישור סרטון מלא + הסתר תווית קישור לסרטון תווית קישור סרטון מוסתרת תווית קישור סרטון מוצגת הסתר לחצן סאונד diff --git a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml index 3162b5c8a..1f2690c4a 100644 --- a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml +++ b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml @@ -316,15 +316,15 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 「ショートを作成」ボタンを非表示 「ショートを作成」ボタンは表示されません 「ショートを作成」ボタンは表示されます - タイムスタンプ ボタンを非表示 - タイムスタンプ ボタンは表示されません - タイムスタンプ ボタンは表示されます コメントのプレビューを非表示 コメントのプレビューは表示されません コメントのプレビューは表示されます Thanks ボタンを非表示 Thanks ボタンは表示されません Thanks ボタンは表示されます + タイムスタンプ ボタンを非表示 + タイムスタンプ ボタンは表示されません + タイムスタンプ ボタンは表示されます YouTube Doodle を非表示 Doodle は検索バーに表示されません @@ -378,32 +378,38 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 全ての動画を除外するキーワード: %s - 一般的な広告を非表示 - 一般的な広告を非表示にします - 一般的な広告を非表示にします + クリエイターのストア棚を非表示にする + プレーヤーの下と動画の概要欄にあるストア棚は非表示になります + プレーヤーの下と動画の概要欄にストアシェルフが表示されます + 終了画面のストアバナーを非表示 + 終了画面のストアバナーを非表示にします + 終了画面のストアバナーを非表示にします 全画面広告を非表示 "アプリ起動時の全画面広告を非表示にします この機能は、古いデバイスでのみ利用できます" アプリ起動時の全画面広告を非表示にします\n\nこの機能は、古いデバイスでのみ利用できます + + 全画面広告の非表示は古いデバイス専用です + 一般的な広告を非表示 + 一般的な広告を非表示にします + 一般的な広告を非表示にします + 商品バナーを非表示 + 商品バナーを非表示にします + 商品バナーを非表示にします 「プロモーションを含みます」ボタンを非表示 プレーヤー画面の「プロモーションを含みます」ボタンを非表示にします プレーヤー画面の「プロモーションを含みます」ボタンを非表示にします + + \'商品を表示\'バナーを非表示にする + 動画オーバーレイのバナーは非表示になります + 動画オーバーレイにバナーが表示されます 自己スポンサー カードを非表示 自己スポンサー カードを非表示にします 自己スポンサー カードを非表示にします - 「商品を表示」ボタンを非表示 - プレーヤー画面の「商品を表示」ボタンや商品ボタンを非表示にします - プレーヤー画面の「商品を表示」ボタンや商品ボタンを非表示にします - 終了画面のストアバナーを非表示 - 終了画面のストアバナーを非表示にします - 終了画面のストアバナーを非表示にします - ストア広告を非表示 - ストア広告を非表示にします - ストア広告を非表示にします - 商品へのリンクを非表示 - 概要欄のタグ付けされた商品へのリンクを非表示にします - 概要欄のタグ付けされた商品へのリンクを非表示にします + タグ付けされた商品を非表示にする + 動画の概要欄にあるタグ付けされた商品は非表示になります + 動画の概要欄にタグ付けされた商品が表示されます 「ストアに移動」ボタンを非表示 チャンネル ページの「ストアに移動」ボタンを非表示にします @@ -411,11 +417,6 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に ウェブ検索結果を非表示 ウェブ検索結果を非表示にします ウェブ検索結果を非表示にします - 商品バナーを非表示 - 商品バナーを非表示にします - 商品バナーを非表示にします - - 全画面広告の非表示は古いデバイス専用です YouTube Premium の広告を非表示 @@ -827,7 +828,7 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に サウンド メタデータ ラベルを非表示 サウンド メタデータ ラベルは表示されません サウンド メタデータ ラベルは表示されます - 関連動画へのリンクを非表示 + 動画リンクのラベルを非表示にする 関連動画へのリンクは表示されません 関連動画へのリンクは表示されます サウンド ボタンを非表示 @@ -964,29 +965,29 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に スキップボタンは、表示された数秒後に自動的に非表示になります スキップボタンは、セグメントの開始から終了まで表示されます スキップボタンの表示時間 - 自動非表示のスキップボタンとハイライトへのスキップボタンがどれくらいの期間表示されるか - スキップの取り消しトーストを表示 - セグメントが自動的にスキップされたときにトーストが表示されます。スキップを取り消すには、トースト通知をタップします。 - トーストは表示されません - スキップトーストの表示時間 - スキップトースト通知がどれくらいの期間表示されるか - 1秒 - 2秒 - 3秒 - 4秒 - 5秒 - 6秒 - 7秒 - 8秒 - 9秒 - 10秒 - セグメントを除いた再生時間を表示する - すべてのセグメントを除いた動画の長さがシークバーに表示されます - 動画全体の再生時間のみが表示されます + 自動非表示設定のスキップボタンとハイライトへのスキップボタンが表示される時間 + スキップ取り消しのトーストを表示 + セグメントが自動的にスキップされた際にトーストを表示します。このトースト通知をタップすると、スキップが取り消されます + セグメントが自動的にスキップされた際にトーストを表示します。このトースト通知をタップすると、スキップが取り消されます + スキップ トーストの表示時間 + スキップのトースト通知が表示される時間 + 1 秒 + 2 秒 + 3 秒 + 4 秒 + 5 秒 + 6 秒 + 7 秒 + 8 秒 + 9 秒 + 10 秒 + セグメントを除いた再生時間を表示 + シークバーにすべてのセグメントを除いた再生時間を表示します + シークバーにすべてのセグメントを除いた再生時間を表示します セグメントの作成 - セグメント作成ボタンを表示する - セグメント作成ボタンはプレーヤー オーバーレイに表示されます - セグメント作成ボタンはプレーヤー オーバーレイに表示されません + セグメント作成ボタンを表示 + プレーヤー オーバーレイにセグメント作成ボタンを表示します + プレーヤー オーバーレイにセグメント作成ボタンを表示します セグメントの時間調整幅 セグメント作成メニュー内の早送り / 巻き戻しボタンで移動する時間 (ミリ秒) 値は正の整数でなければなりません @@ -1405,8 +1406,8 @@ Automotive レイアウト デフォルトでの吹き替え再生を無効化 - 動画を開いたとき、オリジナルの音声が再生されます - 動画を開いたとき、オリジナルの音声が再生されます + 動画を開いた際に強制的にオリジナルの音声トラックを再生します + 動画を開いた際に強制的にオリジナルの音声トラックを再生します この機能を使用するには、「動画ストリームを偽装する」のクライアントを iOS TV に変更してください @@ -1496,7 +1497,7 @@ AVC は、最大解像度が 1080p であり、Opus オーディオ コーデッ Android クライアントの副作用 "• 「音声トラック」がフライアウト メニューに表示されない • 「一定音量」が利用できない -• 「デフォルトでの吹き替え再生を無効にする」が利用できない" +• 「デフォルトでの吹き替え再生を無効化」が利用できない" • AV1 コーデックが利用できない • ログアウト時またはシークレット モード時に、子ども向け動画が再生されない可能性がある 統計情報に表示する diff --git a/patches/src/main/resources/addresources/values-ka-rGE/strings.xml b/patches/src/main/resources/addresources/values-ka-rGE/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-ka-rGE/strings.xml +++ b/patches/src/main/resources/addresources/values-ka-rGE/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-kk-rKZ/strings.xml b/patches/src/main/resources/addresources/values-kk-rKZ/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-kk-rKZ/strings.xml +++ b/patches/src/main/resources/addresources/values-kk-rKZ/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-km-rKH/strings.xml b/patches/src/main/resources/addresources/values-km-rKH/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-km-rKH/strings.xml +++ b/patches/src/main/resources/addresources/values-km-rKH/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-kn-rIN/strings.xml b/patches/src/main/resources/addresources/values-kn-rIN/strings.xml index 6bcbbaa7e..84cc40bcb 100644 --- a/patches/src/main/resources/addresources/values-kn-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-kn-rIN/strings.xml @@ -70,8 +70,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml index 0d72ce8e3..2fd70d1a3 100644 --- a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml +++ b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml @@ -199,9 +199,9 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 채널 가이드라인 숨기기 채널 가이드라인이 숨겨집니다 채널 가이드라인이 표시됩니다 - 더 많은 주제 탐색 선반 숨기기 - 더 많은 주제 탐색 선반이 숨겨집니다 - 더 많은 주제 탐색 선반이 표시됩니다 + \'다른 주제 더 살펴보기\' 선반 숨기기 + \'다른 주제 더 살펴보기\' 선반이 숨겨집니다 + \'다른 주제 더 살펴보기\' 선반이 표시됩니다 펼쳐볼 수 있는 정보 숨기기 썸네일 하단에서 다음 정보들이 숨겨집니다:\n동영상 설명, 챕터, 주요 순간, 스크립트,\n재생목록의 동영상, 이 동영상에 나온 제품, etc. 썸네일 하단에서 다음 정보들이 표시됩니다:\n동영상 설명, 챕터, 주요 순간, 스크립트,\n재생목록의 동영상, 이 동영상에 나온 제품, etc. @@ -319,15 +319,15 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 Shorts 만들기 버튼 숨기기 Shorts 만들기 버튼이 숨겨집니다 Shorts 만들기 버튼이 표시됩니다 - 타임스탬프 버튼 숨기기 - 타임스탬프 버튼이 숨겨집니다 - 타임스탬프 버튼이 표시됩니다 댓글 미리보기 숨기기 댓글 미리보기가 숨겨집니다 댓글 미리보기가 표시됩니다 Thanks 버튼 숨기기 Thanks 버튼이 숨겨집니다 Thanks 버튼이 표시됩니다 + 타임스탬프 버튼 숨기기 + 타임스탬프 버튼이 숨겨집니다 + 타임스탬프 버튼이 표시됩니다 YouTube Doodles 숨기기 YouTube Doodles가 숨겨집니다\n• Doodles: 기념일 로고 헤더 @@ -380,32 +380,38 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 키워드가 모든 동영상을 숨길 것입니다: %s - 일반 레이아웃 광고 숨기기 - 일반 레이아웃 광고가 숨겨집니다 - 일반 레이아웃 광고가 표시됩니다 + 판매자 스토어 선반 숨기기 + 플레이어 아래, 동영상 설명 그리고 채널 프로필에서 판매자(크리에이터) 스토어 선반이 숨겨집니다 + 플레이어 아래, 동영상 설명 그리고 채널 프로필에서 판매자(크리에어터) 스토어 선반이 표시됩니다 + 최종 화면에서 스토어 배너 숨기기 + 스토어 배너가 숨겨집니다 + 스토어 배너가 표시됩니다 전체 화면 광고 숨기기 "전체 화면 광고가 숨겨집니다 이 설정은 구형 기기에서만 사용할 수 있습니다" 전체 화면 광고가 표시됩니다 + + \'전체 화면 광고 숨기기\'는 구형 기기에서만 사용할 수 있습니다 + 일반 레이아웃 광고 숨기기 + 일반 레이아웃 광고가 숨겨집니다 + 일반 레이아웃 광고가 표시됩니다 + 매장 쇼핑 배너 숨기기 + 매장 쇼핑 배너가 숨겨집니다 + 매장 쇼핑 배너가 표시됩니다 유료 광고 포함 라벨 숨기기 유료 광고 포함 라벨이 숨겨집니다 유료 광고 포함 라벨이 표시됩니다 + + \'제품 보기\' 배너 숨기기 + 동영상 오버레이에서 \'제품 보기\' 배너가 숨겨집니다 + 동영상 오버레이에서 \'제품 보기\' 배너가 표시됩니다 셀프 스폰서 카드 숨기기 셀프 스폰서 카드가 숨겨집니다 셀프 스폰서 카드가 표시됩니다 - 플레이어에서 제품 보기 배너 숨기기 - 제품 보기 배너가 숨겨집니다 - 제품 보기 배너가 표시됩니다 - 최종 화면에서 스토어 배너 숨기기 - 스토어 배너가 숨겨집니다 - 스토어 배너가 표시됩니다 - 판매자 쇼핑 선반 숨기기 - 판매자 쇼핑 선반이 숨겨집니다\n• 판매자(크리에이터명) 선반 - 판매자 쇼핑 선반이 표시됩니다\n• 판매자(크리에이터명) 선반 - 동영상 설명에서 쇼핑 링크 숨기기 - 동영상 설명에서 쇼핑 링크가 숨겨집니다 - 동영상 설명에서 쇼핑 링크가 표시됩니다 + 태그된 제품 숨기기 + 동영상 설명에서 태그된 제품이 숨겨집니다 + 동영상 설명에서 태그된 제품이 표시됩니다 채널 프로필에서 스토어 방문 버튼 숨기기 스토어 방문 버튼이 숨겨집니다 @@ -413,11 +419,6 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 웹 검색 결과 숨기기 웹 검색 결과가 숨겨집니다 웹 검색 결과가 표시됩니다 - 매장 쇼핑 선반 숨기기 - 매장 쇼핑 선반이 숨겨집니다\n• 크리에이터명 매장 쇼핑 선반 - 매장 쇼핑 선반이 표시됩니다\n• 크리에이터명 매장 쇼핑 선반 - - \'전체 화면 광고 숨기기\'는 구형 기기에서만 사용할 수 있습니다 YouTube Premium 프로모션 숨기기 @@ -826,7 +827,7 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 사운드 메타데이터 라벨 숨기기 메타데이터 라벨이 숨겨집니다 메타데이터 라벨이 표시됩니다 - FULL 또는 관련 동영상 링크 라벨 숨기기 + 동영상 링크 라벨 숨기기 동영상 링크 라벨이 숨겨집니다 동영상 링크 라벨이 표시됩니다 사운드 버튼 숨기기 @@ -980,9 +981,9 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 8 초 9 초 10 초 - 건너뛸 구간을 제외한 시간 표시하기 - 건너뛸 구간을 제외한 동영상 길이를 재생바에 표시합니다 - 건너뛸 구간을 포함한 동영상 길이를 재생바에 표시합니다 + 건너뛸 구간이 제외된 시간 표시하기 + 건너뛸 구간이 제외된 동영상 길이를 재생바에 표시합니다 + 건너뛸 구간이 포함된 동영상 길이를 재생바에 표시합니다 새로운 구간 추가하기 구간 추가 버튼 표시하기 플레이어에서 구간 추가 버튼을 표시합니다 diff --git a/patches/src/main/resources/addresources/values-ky-rKG/strings.xml b/patches/src/main/resources/addresources/values-ky-rKG/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-ky-rKG/strings.xml +++ b/patches/src/main/resources/addresources/values-ky-rKG/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-lo-rLA/strings.xml b/patches/src/main/resources/addresources/values-lo-rLA/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-lo-rLA/strings.xml +++ b/patches/src/main/resources/addresources/values-lo-rLA/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml index f4051be84..ddc9141ec 100644 --- a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml +++ b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml @@ -315,15 +315,15 @@ Apie netikėtus įvykius nebus pranešta." Slėpti \"Kurti Short\" mygtuką Mygtukas „Sukurti Short“ paslėptas Mygtukas „Sukurti Short“ rodomas - Slėpti datos ir laiko žymos mygtuką - Datos ir laiko žymos mygtukas paslėptas - Datos ir laiko žymos mygtukas rodomas Slėpti peržiūros komentarą Peržiūros komentaras yra paslėptas Peržiūros komentaras yra rodomas PaslÄ—pti „Ačių“ mygtukÄ… \"Ačiū\" mygtukas yra paslėptas \"Ačiū\" mygtukas yra rodomas + Slėpti datos ir laiko žymos mygtuką + Datos ir laiko žymos mygtukas paslėptas + Datos ir laiko žymos mygtukas rodomas Slėpti YouTube Doodles Paieškos juostos Doodles yra paslėpti @@ -377,32 +377,38 @@ Apribojimai Raktiniu žodžiu bus paslėpti visi vaizdo įrašai: %s - Slėpti bendras reklamas - Bendros reklamos yra paslėptos - Bendros reklamos yra rodomos + Slėpti kūrėjo parduotuvės lentynas + Parduotuvės lentynos po grotuvu ir vaizdo įrašo aprašyme yra paslėptos + Parduotuvių lentynos po grotuvu ir vaizdo įrašo apraše yra rodomos + Paslˁpti pabaigos ekrano parduotuvÄ—s reklaminį juostelÄ™ + Parduotuvės reklaminis skydelis paslėptas + Parduotuvės reklaminis skydelis rodomas Slėpti viso ekrano reklamas "Pilno ekrano reklamos paslėptos Ši funkcija yra prieinama tik senesniuose įrenginiuose" Viso ekrano reklamos yra rodomos + + Slėpti viso ekrano reklamas veikia tik senesniuose įrenginiuose + Slėpti bendras reklamas + Bendros reklamos yra paslėptos + Bendros reklamos yra rodomos + Slėpti prekių banerius + Prekių baneriai yra paslėpti + Prekių baneriai yra rodomi Slėpti apmokėtos reklamos etiketę Apmokėtos reklamos etiketė yra paslėpta Apmokėtos reklamos etiketė yra rodoma + + Slėpti reklamjuostę „Žiūrėti produktus“ + Reklama vaizdo įrašo perdangoje paslėpta + Vaizdo įrašo perdangoje rodoma reklamjuostė Slėpti savarankiškus rėmėjų kortelės Savarankiški rėmėjų kortelės yra paslėpti Savarankiški rėmėjų kortelės yra rodomi - Slėpti „Peržiūrėti produktus“ reklamjuostę - Baneris yra paslėptas - Baneris yra rodomas - Paslˁpti pabaigos ekrano parduotuvÄ—s reklaminį juostelÄ™ - Parduotuvės reklaminis skydelis paslėptas - Parduotuvės reklaminis skydelis rodomas - Slėpti žaidėjo parduotuvės lentyną - Parduotuvės lentyna yra paslėpta - Parduotuvės lentyna yra rodoma - Slėpti apsipirkimo nuorodas vaizdo įrašo aprašyme - Apsipirkimo nuorodos vaizdo įrašo apraše paslėptos - Apsipirkimo nuorodos vaizdo įrašo apraše rodomos + Slėpti pažymėtus produktus + Pažymėti produktai vaizdo įrašo aprašyme yra paslėpti + Pažymėti produktai vaizdo įrašo apraše yra rodomi Slėpti \"Apsilankyti parduotuvėje\" mygtuką kanalo puslapiuose Mygtukas kanalo puslapyje paslėptas @@ -410,11 +416,6 @@ Apribojimai Slėpti žiniatinklio paieškos rezultatus Žiniatinklio paieškos rezultatai yra paslėpti Žiniatinklio paieškos rezultatai yra rodomi - Slėpti prekių banerius - Prekių baneriai yra paslėpti - Prekių baneriai yra rodomi - - Slėpti viso ekrano reklamas veikia tik senesniuose įrenginiuose Slėpti YouTube Premium reklamą @@ -824,7 +825,7 @@ Jei pakeitus šį nustatymą neįsigalioja, pabandykite perjungti į inkognito r Slėpti garso metaduomenų etiketę Metaduomenų etiketė paslėpta Metaduomenų etiketė rodoma - Slėpti pilno vaizdo įrašo nuorodos etiketę + Slėpti vaizdo įrašo nuorodos etiketę Vaizdo įrašo nuorodos etiketė paslėpta Vaizdo įrašo nuorodos etiketė rodoma Slėpti garso mygtuką @@ -1427,6 +1428,7 @@ Gali būti atrakinta aukštesnės vaizdo įrašų kokybės, bet galite patirti v Numatytoji „Shorts“ kokybė naudojant „Wi-Fi“ tinklą Numatytoji „Shorts“ kokybė mobiliųjų tinklų atveju mobilusis + Wi-Fi Pakeista numatytoji %1$s kokybė į: %2$s Pakeista \"Shorts\" %1$s kokybė į: %2$s diff --git a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml index 9237dda5f..20c203976 100644 --- a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml +++ b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml @@ -315,15 +315,15 @@ Jūs netiksit informēts par neparedzētiem notikumiem." Paslēpt \"Izveidot īso\" pogu Poga Izveidot Short ir paslēpta Poga Izveidot Short ir redzama - Paslēpt laika zīmoga pogu - Laika zīmoga poga ir paslēpta - Laika zīmoga poga ir redzama Paslēpt priekšskatījuma komentāru Priekšskatījuma komentārs ir paslēpts Priekšskatījuma komentārs ir redzams Paslēpt pateicības pogu Paldies poga ir paslēpta Paldies poga ir redzama + Paslēpt laika zīmoga pogu + Laika zīmoga poga ir paslēpta + Laika zīmoga poga ir redzama Paslēpt YouTube Doodles Meklēšanas joslas Doodles ir paslēpti @@ -377,32 +377,38 @@ Ierobežojumi Atslēgvārds paslēps visus video: %s - Paslēpt vispārējas reklāmas - Vispārējas reklāmas ir paslēptas - Vispārējas reklāmas ir redzamas + Slēpt satura veidotāja veikala plauktus + Veikala plaukti zem atskaņotāja un video aprakstā ir paslēpti + Veikalu plaukti zem atskaņotāja un video aprakstā tiek rādīti + Paslēpt veikala reklāmkarogu ekrāna beigās + Noslēguma ekrāna veikala baneris ir paslēpts + Noslēguma ekrāna veikala baneris ir parādīts Paslēpt pilnekrāna reklāmas "Pilnekrāna reklāmas ir paslēptas Šī funkcija ir pieejama tikai vecākiem ierīcēm" Pilnekrāna reklāmas ir redzamas + + Paslēpt pilnekrāna reklāmas darbojas tikai ar vecākām ierīcēm + Paslēpt vispārējas reklāmas + Vispārējas reklāmas ir paslēptas + Vispārējas reklāmas ir redzamas + Paslēpt preču reklāmas + Preču reklāmas ir paslēptas + Preču reklāmas ir redzamas Paslēpt apmaksātas reklāmas etiķeti Apmaksātas reklāmas etiķete ir paslēpta Apmaksātas reklāmas etiķete ir redzama + + Paslēpt reklāmkarogu \"Skatīt produktus\" + Baneris video pārklājumā ir paslēpts + Reklāmkarogs video pārklājumā tiek rādīts Paslēpt pašreklāmas kartītes Pašreklāmas kartītes ir paslēptas Pašreklāmas kartītes ir redzamas - Paslēpt reklāmjoslu \"Skatīt produktus\" - Reklāmas josla ir paslēpta - Reklāmas josla ir redzama - Paslēpt veikala reklāmkarogu ekrāna beigās - Noslēguma ekrāna veikala baneris ir paslēpts - Noslēguma ekrāna veikala baneris ir parādīts - Paslēpt spēlētāja iepirkšanās plauktu - Iepirkšanās plaukts ir paslēpts - Iepirkšanās plaukts ir redzams - Paslēpt iepirkšanās saites video aprakstā - Iepirkšanās saites video aprakstā ir paslēptas - Iepirkšanās saites video aprakstā ir redzamas + Slēpt atzīmētos produktus + Video aprakstā atzīmētie produkti ir paslēpti + Video aprakstā tiek rādīti atzīmētie produkti Paslēpt \"Apmeklēt veikalu\" pogu kanāla lapās Poga kanāla lapā ir paslēpta @@ -410,11 +416,6 @@ Ierobežojumi Paslēpt tīmekļa meklēšanas rezultātus Tīmekļa meklēšanas rezultāti ir paslēpti Tīmekļa meklēšanas rezultāti ir redzami - Paslēpt preču reklāmas - Preču reklāmas ir paslēptas - Preču reklāmas ir redzamas - - Paslēpt pilnekrāna reklāmas darbojas tikai ar vecākām ierīcēm Paslēpt YouTube Premium reklāmas @@ -826,7 +827,7 @@ Lai parādītu audio celiņu izvēlni, mainiet \"Video straumju viltošana\" uz Paslēpt skaņas metadatu nosaukumu Metadatu nosaukums ir paslēpts Metadatu nosaukums ir redzams - Paslēpt pilna video saites nosaukumu + Paslēpt video saites etiķeti Video saites nosaukums ir paslēpts Video saites nosaukums ir redzams Paslēpt skaņas pogu diff --git a/patches/src/main/resources/addresources/values-mk-rMK/strings.xml b/patches/src/main/resources/addresources/values-mk-rMK/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-mk-rMK/strings.xml +++ b/patches/src/main/resources/addresources/values-mk-rMK/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-ml-rIN/strings.xml b/patches/src/main/resources/addresources/values-ml-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-ml-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-ml-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-mn-rMN/strings.xml b/patches/src/main/resources/addresources/values-mn-rMN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-mn-rMN/strings.xml +++ b/patches/src/main/resources/addresources/values-mn-rMN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-mr-rIN/strings.xml b/patches/src/main/resources/addresources/values-mr-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-mr-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-mr-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-ms-rMY/strings.xml b/patches/src/main/resources/addresources/values-ms-rMY/strings.xml index d42c78a31..0fabb6fc7 100644 --- a/patches/src/main/resources/addresources/values-ms-rMY/strings.xml +++ b/patches/src/main/resources/addresources/values-ms-rMY/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-my-rMM/strings.xml b/patches/src/main/resources/addresources/values-my-rMM/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-my-rMM/strings.xml +++ b/patches/src/main/resources/addresources/values-my-rMM/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-nb-rNO/strings.xml b/patches/src/main/resources/addresources/values-nb-rNO/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-nb-rNO/strings.xml +++ b/patches/src/main/resources/addresources/values-nb-rNO/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-ne-rIN/strings.xml b/patches/src/main/resources/addresources/values-ne-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-ne-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-ne-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml index a89da6410..2046f826c 100644 --- a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml +++ b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml @@ -315,15 +315,15 @@ U wordt niet op de hoogte gesteld van onverwachte gebeurtenissen." Verberg \'Create a Short\' knop Knop \'Een Short maken\' is verborgen Knop \'Een Short maken\' wordt weergegeven - Knop voor tijdstempel verbergen - Knop voor tijdstempel is verborgen - Knop voor tijdstempel wordt weergegeven Reactie in preview verbergen Preview reactie is verborgen Preview reactie wordt getoond Verberg de knop \'Bedankt\' Bedankknop is verborgen De knop \'Bedankt\' wordt weergegeven + Knop voor tijdstempel verbergen + Knop voor tijdstempel is verborgen + Knop voor tijdstempel wordt weergegeven YouTube Doodles verbergen Doodles in de zoekbalk zijn verborgen @@ -377,32 +377,38 @@ Beperkingen Keyword verbergt alle video\'s: %s - Algemene advertenties verbergen - Algemene advertenties zijn verborgen - Algemene advertenties worden getoond + Verberg schappen van maker + Winkelplanken onder de speler en in de videobeschrijving zijn verborgen + Winkelplanken onder de speler en in de videobeschrijving worden getoond + Verberg de Store-banner op het eindscherm + De winkelbanner is verborgen + De winkelbanner is zichtbaar Volledig scherm advertenties verbergen "Volledig schermadvertenties zijn verborgen Deze functie is alleen beschikbaar voor oudere apparaten" Volledig scherm advertenties worden getoond + + Volledig scherm advertenties werkt alleen met oudere apparaten + Algemene advertenties verbergen + Algemene advertenties zijn verborgen + Algemene advertenties worden getoond + Merchandise banners verbergen + Merchandise banners zijn verborgen + Merchandise banners worden getoond Betaalde promotielabel verbergen Betaalde promotielabel is verborgen Betaalde promotielabel wordt getoond + + Banner \'Producten bekijken\' verbergen + Banner in video-overlay is verborgen + Banner in video-overlay wordt getoond Zelf gesponsorde kaarten verbergen Zelf gesponsorde kaarten zijn verborgen Zelf gesponsorde kaarten worden getoond - Verberg de banner \'Producten bekijken\' - Banner is verborgen - Banner wordt getoond - Verberg de Store-banner op het eindscherm - De winkelbanner is verborgen - De winkelbanner is zichtbaar - Winkelplank in de speler verbergen - Winkelplank is verborgen - Winkelplank wordt getoond - Winkelkoppelingen in de videobeschrijving verbergen - Winkelkoppelingen in videobeschrijving zijn verborgen - Winkelkoppelingen in videobeschrijving worden weergegeven + Verberg getagde producten + Getagde producten in de videobeschrijving zijn verborgen + Getagde producten in videobeschrijving worden getoond De knop \"Bezoek winkel\" op kanaalpagina\'s verbergen Knop op kanaalpagina is verborgen @@ -410,11 +416,6 @@ Deze functie is alleen beschikbaar voor oudere apparaten" Webzoekresultaten verbergen Webzoekresultaten zijn verborgen Webzoekresultaten worden getoond - Merchandise banners verbergen - Merchandise banners zijn verborgen - Merchandise banners worden getoond - - Volledig scherm advertenties werkt alleen met oudere apparaten YouTube Premium promoties verbergen @@ -826,7 +827,7 @@ Om het audiotrackmenu weer te geven, wijzigt u 'Videostreams vervalsen' in iOS T Verberg het label \"Geluidsinformatie\" Het label \"Geluidsinformatie\" is verborgen Het label \"Geluidsinformatie\" is zichtbaar - Verberg het label \"Volledige videolink\" + Videolinklabel verbergen Het label \"Volledige videolink\" is verborgen Het label \"Volledige videolink\" is zichtbaar Verberg de geluidsknop @@ -963,7 +964,7 @@ Deze functie werkt het beste met een videokwaliteit van 720p of lager en wanneer Duur van overslaan-knop Hoe lang de \"automatisch verbergen overslaan\"- en \"markeer\"-knoppen worden getoond Toon \"overslaan ongedaan maken\"-melding - Een melding wordt getoond wanneer een segment automatisch wordt overgeslagen. Tik op de melding om het overslaan ongedaan te maken. + Een melding wordt getoond wanneer een segment automatisch wordt overgeslagen. Tik op de melding om het overslaan ongedaan te maken Toast wordt niet getoond Duur van overslaan-toast Hoe lang de overslaan-melding wordt getoond diff --git a/patches/src/main/resources/addresources/values-or-rIN/strings.xml b/patches/src/main/resources/addresources/values-or-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-or-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-or-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-pa-rIN/strings.xml b/patches/src/main/resources/addresources/values-pa-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-pa-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-pa-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml index 41a438128..36ca06c0f 100644 --- a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml +++ b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml @@ -311,15 +311,15 @@ Nie będziesz informowany o żadnych nieoczekiwanych zdarzeniach." Przycisk od tworzenia Shortsów Przycisk Utwórz Short jest ukryty Przycisk Utwórz Short jest widoczny - Ukryj przycisk znacznika czasu - Przycisk znacznika czasu jest ukryty - Przycisk znacznika czasu jest widoczny Ukryj podgląd komentarzy Podgląd komentarzy jest ukryty Podgląd komentarzy jest widoczny Ukryj przycisk superpodziękowania Przycisk superpodziękowania jest ukryty Przycisk superpodziękowania jest widoczny + Ukryj przycisk znacznika czasu + Przycisk znacznika czasu jest ukryty + Przycisk znacznika czasu jest widoczny Ukryj YouTube Doodles Doodle w pasku wyszukiwania są ukryte @@ -373,32 +373,38 @@ Ograniczenia Słowo ukryje wszystkie filmy: %s - Reklamy ogólne - Ogólne reklamy są ukryte - Ogólne reklamy są widoczne + Ukryj półki sklepowe twórcy + Półki sklepowe pod odtwarzaczem i w opisie filmu są ukryte + Półki sklepu pod odtwarzaczem i w opisie filmu są widoczne + Ukryj baner sklepu na ekranie końcowym + Baner sklepu jest ukryty + Baner sklepu jest wyświetlany Reklamy pełnoekranowe "Reklamy pełnoekranowe są ukryte Ta funkcja jest dostępna tylko dla starszych urządzeń" Reklamy pełnoekranowe są widoczne + + Ukrycie pełnoekranowych reklam działa tylko na starszych urządzeniach + Reklamy ogólne + Ogólne reklamy są ukryte + Ogólne reklamy są widoczne + Banery towarowe + Banery z towarami są ukryte + Banery z towarami są widoczne Etykiety płatnej promocji Etykiety płatnej promocji są ukryte Etykiety płatnej promocji są widoczne + + Ukryj baner \'Zobacz produkty\' + Baner w nakładce wideo jest ukryty + Baner w nakładce wideo jest widoczny Karty z autopromocją Karty z autopromocją są ukryte Karty z autopromocją są widoczne - Ukryj baner „Zobacz produkty” - Banery są ukryte - Banery są widoczne - Ukryj baner sklepu na ekranie końcowym - Baner sklepu jest ukryty - Baner sklepu jest wyświetlany - Półki sklepowe w odtwarzaczu - Półki sklepowe są ukryte - Półki sklepowe są widoczne - Linki do zakupów w opisie filmu - Linki do zakupów w opisie filmu są ukryte - Linki do zakupów w opisie filmu są widoczne + Ukryj oznaczone produkty + Oznaczone produkty w opisie filmu są ukryte + Oznaczone produkty w opisie filmu są widoczne Przycisk do sklepu na stronach kanału Przycisk na stronie kanału jest ukryty @@ -406,11 +412,6 @@ Ta funkcja jest dostępna tylko dla starszych urządzeń" Wyniki wyszukiwania stron internetowych Wyniki wyszukiwania stron są ukryte Wyniki wyszukiwania stron są widoczne - Banery towarowe - Banery z towarami są ukryte - Banery z towarami są widoczne - - Ukrycie pełnoekranowych reklam działa tylko na starszych urządzeniach Promocje YouTube Premium @@ -822,7 +823,7 @@ Aby pokazać menu ścieżki audio, zmień opcję „Fałszuj strumienie wideo” Etykieta z metadanymi dźwięku Etykieta metadanych jest ukryta Etykieta metadanych jest widoczna - Etykieta z linkami do całych filmów + Ukryj etykietę linku do filmu Etykieta linku do filmu jest ukryta Etykieta linku do filmu jest widoczna Przycisk dźwięku diff --git a/patches/src/main/resources/addresources/values-pt-rBR/strings.xml b/patches/src/main/resources/addresources/values-pt-rBR/strings.xml index c52fe55e6..ce264cbfc 100644 --- a/patches/src/main/resources/addresources/values-pt-rBR/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rBR/strings.xml @@ -315,15 +315,15 @@ Você não será notificado sobre nenhum evento inesperado." Ocultar botão \'Criar um Short\' O botão Criar um Short está oculto O botão Criar um Short é mostrado - Ocultar o botão de carimbo de data/hora - O botão de carimbo de data/hora está oculto - O botão de carimbo de data/hora é mostrado Ocultar prévia de comentário Prévia de comentário está oculta A prévia de comentário é exibida Ocultar o botão \"Obrigado\" Botão valeu está oculto O botão valeu é mostrada + Ocultar o botão de carimbo de data/hora + O botão de carimbo de data/hora está oculto + O botão de carimbo de data/hora é mostrado Ocultar Doodles do YouTube Doodles na barra de pesquisa estão ocultos @@ -377,32 +377,38 @@ Linitações A palavra-chave irá ocultar todos os vídeos: %s - Ocultar anúncios gerais - Anúncios gerais estão ocultos - Os anúncios gerais são mostrados + Ocultar prateleiras da loja do criador + As prateleiras da loja abaixo do player e na descrição do vídeo estão ocultas + Prateleiras da loja abaixo do player e na descrição do vídeo são exibidas + Ocultar banners da loja na tela final + O banner da loja está oculto + O banner da loja está sendo exibido Ocultar anúncios em tela cheia "Os anúncios em tela cheia estão ocultos Este recurso está disponível apenas para dispositivos mais antigos" Anúncios em tela cheia não estão ocultos + + Ocultar anúncios em tela cheia só funciona com dispositivos antigos + Ocultar anúncios gerais + Anúncios gerais estão ocultos + Os anúncios gerais são mostrados + Ocultar banners de mercadoria + Os banners de mercadoria estão ocultos + Os banners de mercadorias são mostrados Ocultar o rótulo de promoção paga O rótulo de promoção paga está oculto O rótulo de promoção paga é mostrada + + Ocultar banner \"Ver produtos\" + O banner na sobreposição de vídeo está oculto + Banner na sobreposição do vídeo é exibido Ocultar cartões auto-patrocinados Cartões autopatrocinados estão ocultos Cartões autopatrocinados não estão ocultos - Ocultar banner \"Ver produtos\" - Banner está oculto - O banner é mostrado - Ocultar banners da loja na tela final - O banner da loja está oculto - O banner da loja está sendo exibido - Ocultar painel de compras do reprodutor - O painel de compras está oculto - O painel de compras vai ser mostrado - Ocultar links de compras na descrição do vídeo - Os links de compras na descrição do vídeo estão ocultos - Os links de compras na descrição do vídeo são mostrados + Ocultar produtos marcados + Os produtos marcados na descrição do vídeo estão ocultos + Produtos marcados na descrição do vídeo são exibidos Ocultar o botão \'Visitar loja\' nas páginas dos canais O botão na página do canal está oculto @@ -410,11 +416,6 @@ Este recurso está disponível apenas para dispositivos mais antigos" Ocultar resultados de busca web Resultados de busca web estão ocultos Os resultados de busca web são mostrados - Ocultar banners de mercadoria - Os banners de mercadoria estão ocultos - Os banners de mercadorias são mostrados - - Ocultar anúncios em tela cheia só funciona com dispositivos antigos Ocultar promoções do YouTube Premium @@ -826,7 +827,7 @@ Para exibir o menu da faixa de áudio, altere \"Spoof video streams\" para iOS T Ocultar rótulo de metadados de som Rótulo de metadados está oculto Rótulo de metadados não está oculto - Ocultar rótulo completo do link do vídeo + Ocultar rótulo do link do vídeo Rótulo do link do vídeo está oculto Rótulo do link do vídeo não está oculto Ocultar botão som diff --git a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml index 4c7141e43..c95439153 100644 --- a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml @@ -315,15 +315,15 @@ Não será notificado de quaisquer eventos inesperados." Ocultar o botão \'Criar um Short\' O botão Criar um Short está oculto O botão Criar um Short é mostrado - Ocultar o botão de carimbo de data/hora - O botão de carimbo de data/hora está oculto - O botão de carimbo de data/hora está visível Esconder comentário de pré-visualização Visualização do comentário está escondida Pré-visualização de comentário é exibida Ocultar botão Obrigado O botão de agradecimento está escondido O botão Obrigado é visível + Ocultar o botão de carimbo de data/hora + O botão de carimbo de data/hora está oculto + O botão de carimbo de data/hora está visível Ocultar Doodles do YouTube Doodles da barra de pesquisa estão escondidos @@ -377,32 +377,38 @@ Limitações Palavra-chave irá ocultar todos os vídeos: %s - Esconder anúncios gerais - Anúncios gerais estão escondidos - Anúncios gerais são mostrados + Ocultar prateleiras da loja do criador + Prateleiras da loja abaixo do reprodutor e na descrição do vídeo estão ocultas + As prateleiras da loja abaixo do reprodutor e na descrição do vídeo são exibidas + Ocultar banner da loja na tela final + Banner de Loja está ocultado + Banner de Loja está visível Esconder anúncios em ecrã cheio "Quảng cáo toàn màn hình bị ẩn Tính năng này chỉ khả dụng cho các thiết bị cũ" Os anúncios são visíveis em ecrã cheia + + Ocultar anúncios de ecrã cheio só em aparelhos antigos + Esconder anúncios gerais + Anúncios gerais estão escondidos + Anúncios gerais são mostrados + Esconder banner de mercadoria + Banners de mercadoria estão escondidos + Banners de mercadoria são visíveis Ocultar rótulo de promoção paga O rótulo de promoção pago está oculto Rótulo de promoção pago é mostrado + + Ocultar banner \'Ver produtos\' + Banner na sobreposição de vídeo está oculto + O banner na sobreposição do vídeo é exibido Esconder cartões autopatrocinados Cartões auto-patrocinados estão escondidos Cartões auto-patrocinados são visíveis - Ocultar banner \"Ver produtos\" - Banner está escondido - Banner é visível - Ocultar banner da loja na tela final - Banner de Loja está ocultado - Banner de Loja está visível - Ocultar prateleira de compras do jogador - Prateleira de compras está escondida - Prateleira de compras é mostrada - Esconder links de compras na descrição do vídeo - Os links de compras na descrição do vídeo estão ocultos - Os links de compras na descrição do vídeo são mostrados + Ocultar produtos marcados + Produtos marcados na descrição do vídeo estão ocultos + Os produtos marcados na descrição do vídeo são exibidos Ocultar o botão \'Visitar loja\' nas páginas do canal O botão na página do canal está oculto @@ -410,11 +416,6 @@ Tính năng này chỉ khả dụng cho các thiết bị cũ" Esconder resultados da pesquisa web Resultados de pesquisa web estão escondidos Resultados de pesquisa web são visíveis - Esconder banner de mercadoria - Banners de mercadoria estão escondidos - Banners de mercadoria são visíveis - - Ocultar anúncios de ecrã cheio só em aparelhos antigos Esconder promoções Premium do YouTube @@ -826,7 +827,7 @@ Para mostrar o menu da faixa de áudio, altere \"Spoof video streams\" para iOS Esconder rótulo de metadados de som Etiqueta de metadados está escondida Etiqueta de metadados é visível - Esconder o rótulo completo do link do vídeo + Ocultar rótulo de link do vídeo Rótulo de link do vídeo está escondido Rótulo do link do vídeo é visível Esconder botão de som @@ -1239,6 +1240,7 @@ Limitação: Usar o botão voltar na barra de ferramentas pode não funcionar"Desativado Padrão Mínimo + Tablet Moderno 1 Moderno 2 Moderno 3 @@ -1548,6 +1550,7 @@ A AVC tem resolução máxima de 1080p, Opus audio codec não está disponível, Sobre o ReVanced Anúncios Configurações de bloqueio de anúncios + Bate-papo Configurações do chat Diversos Configurações diversas diff --git a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml index dd65662b7..739769b70 100644 --- a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml +++ b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml @@ -315,15 +315,15 @@ Nu veți fi notificat de niciun eveniment neașteptat." Ascunde butonul \'Creare Short\' Butonul Creează un Short este ascuns Butonul Creează un Short este afișat - Ascunde butonul de marcaj temporal - Butonul de marcaj temporal este ascuns - Butonul de marcaj temporal este afișat Ascunde previzualizarea comentariului Previzualizarea comentariului este ascunsă Previzualizarea comentariului este afișată Ascunde butonul „Mulțumesc” Butonul de multumire este ascuns Butonul de multumire este afisat + Ascunde butonul de marcaj temporal + Butonul de marcaj temporal este ascuns + Butonul de marcaj temporal este afișat Ascunde Doodle-urile YouTube Doodles bară de căutare sunt ascunse @@ -377,32 +377,38 @@ Limitări Cuvântul cheie va ascunde toate videoclipurile: %s - Ascunde reclamele generale - Anunțurile generale sunt ascunse - Anunțurile generale sunt afișate + Ascunde rafturile magazinului creatorului + Rafturile magazinului de sub player și din descrierea videoclipului sunt ascunse + Rafturile magazinelor de sub player și din descrierea videoclipului sunt afișate + Ascunde bannerul magazinului de la finalul ecranului + Bannerul Magazin este ascuns + Bannerul Magazin este afișat Ascunde reclame pe tot ecranul "Reclamele pe tot ecranul sunt ascunse Această funcție este disponibilă numai pentru dispozitivele mai vechi" Reclame pe ecran complet sunt afișate + + Ascunde reclamele pe tot ecranul funcționează doar cu dispozitive mai vechi + Ascunde reclamele generale + Anunțurile generale sunt ascunse + Anunțurile generale sunt afișate + Ascunde bannere de produse + Bannerele de marfă sunt ascunse + Bannerele de marfă sunt afișate Ascunde eticheta promoției cu plată Eticheta promoției plătite este ascunsă Eticheta promoției plătite este afișată + + Ascunde bannerul \"Vezi produse\" + Bannerul din suprapunerea video este ascuns + Bannerul în suprapunerea video este afișat Ascunde cardurile auto-sponsorizate Cardurile sponsorizate automat sunt ascunse Cardurile sponsorizate automat sunt afișate - Ascunde bannerul \"Vezi produse\" - Banner-ul este ascuns - Banner-ul este afișat - Ascunde bannerul magazinului de la finalul ecranului - Bannerul Magazin este ascuns - Bannerul Magazin este afișat - Ascunde raftul jucătorului - Platforma de cumpărături este ascunsă - Platforma de cumpărături este afișată - Ascunde link-urile de cumpărături în descrierea video - Linkurile de cumpărături din descrierea videoclipului sunt ascunse - Linkurile de cumpărături din descrierea videoclipului sunt afișate + Ascunde produsele etichetate + Produsele etichetate din descrierea videoclipului sunt ascunse + Produsele etichetate din descrierea videoclipului sunt afișate Ascunde butonul \"Vizitează magazinul\" pe paginile canalului Butonul din pagina canalului este ascuns @@ -410,11 +416,6 @@ Această funcție este disponibilă numai pentru dispozitivele mai vechi"Ascunde rezultatele căutării web Rezultatele căutării pe web sunt ascunse Rezultatele căutării web sunt afișate - Ascunde bannere de produse - Bannerele de marfă sunt ascunse - Bannerele de marfă sunt afișate - - Ascunde reclamele pe tot ecranul funcționează doar cu dispozitive mai vechi Ascunde promoțiile YouTube Premium @@ -826,7 +827,7 @@ Pentru a afișa meniul pentru pista audio, schimbați opțiunea „Falsifică fl Ascunde eticheta metadata sunet Eticheta metadata este ascunsă Eticheta metadata este afișată - Ascunde eticheta completă a link-ului video + Ascunde eticheta linkului video Eticheta link-ului video este ascunsă Eticheta link-ului video este afișată Ascunde butonul de sunet @@ -963,7 +964,7 @@ Această caracteristică funcționează cel mai bine cu o calitate video de 720p Durata butonului de omitere Cât timp sunt afișate butoanele de ascundere automată a săriturii și de săritură la evidențiere Afișează notificare toast de anulare a săriturii - Notificarea toast este afișată când un segment este sărit automat. Atingeți notificarea toast pentru a anula săritura. + Notificarea toast este afișată când un segment este sărit automat. Atingeți notificarea toast pentru a anula săritura Notificarea pop-up nu este afișată Durata notificării pop-up de omitere Cât timp este afișată notificarea toast de săritură diff --git a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml index 7a6602ea6..0fa0cfdad 100644 --- a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml +++ b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml @@ -156,7 +156,7 @@ Second \"item\" text" Водяной знак канала в плеере скрыт Водяной знак канала в плеере показан Скрыть горизонтальные секции - "Горизонтальные секции скрыты, такие как: + "Данные горизонтальные секции скрыты: • Срочные новости • Продолжить просмотр • Исследовать больше каналов @@ -315,15 +315,15 @@ Second \"item\" text" Скрыть кнопку \"Создать Short\" Кнопка \"Создать Short\" при ответе на комментарий скрыта Кнопка \"Создать Short\" при ответе на комментарий показана - Скрыть кнопку метки времени - Кнопка метки времени скрыта - Кнопка метки времени показана Скрыть предпросмотр комментария Предпросмотр комментария под плеером скрыт Предпросмотр комментария под плеером показан Скрыть кнопку \"Спасибо\" Кнопка \"Спасибо\" в комментариях скрыта Кнопка \"Спасибо\" в комментариях показана + Скрыть кнопку метки времени + Кнопка метки времени скрыта + Кнопка метки времени показана Скрыть YouTube Doodles Doodles на панели поиска скрыты @@ -377,32 +377,38 @@ Second \"item\" text" Ключевое слово скроет все видео: %s - Скрыть общую рекламу - Общая реклама скрыта - Общая реклама показана + Скрыть секции магазина автора + Секции магазина автора под плеером и в описании видео скрыты + Секции магазина автора под плеером и в описании видео показаны + Скрыть баннер магазина + Баннер магазина в конце просмотра скрыт + Баннер магазина в конце просмотра показан Скрыть полноэкранную рекламу "Полноэкранная реклама при запуске приложения скрыта Данная опция доступна только для старых устройств" Полноэкранная реклама при запуске приложения показана + + Скрытие полноэкранной рекламы работает только для старых устройств + Скрыть общую рекламу + Общая реклама скрыта + Общая реклама показана + Скрыть баннеры торговли + Баннеры торговли в ленте скрыты + Баннеры торговли в ленте показаны Скрыть метку платной акции Метка платной акции в плеере скрыта Метка платной акции в плеере показана + + Скрыть баннер просмотра товаров + Баннер просмотра товаров в плеере скрыт + Баннер просмотра товаров в плеере показан Скрыть заставки саморекламы Заставки саморекламы под информацией о видео скрыты Заставки саморекламы под информацией о видео показаны - Скрыть баннер просмотра товаров - Баннер просмотра товаров в плеере скрыт - Баннер просмотра товаров в плеере показан - Скрыть баннер магазина - Баннер магазина в конце просмотра скрыт - Баннер магазина в конце просмотра показан - Скрыть секцию покупок - Секция покупок в плеере скрыта - Секция покупок в плеере показана - Скрыть ссылки на товары - Ссылки на товары в описании видео скрыты - Ссылки на товары в описании видео показаны + Скрыть товары с тегом + Товары с тегом в описании видео скрыты + Товары с тегом в описании видео показаны Скрыть кнопку \"Посетить магазин\" Кнопка \"Посетить магазин\" на странице канала скрыта @@ -410,11 +416,6 @@ Second \"item\" text" Скрыть результаты веб-поиска Результаты веб-поиска в ленте скрыты Результаты веб-поиска в ленте показаны - Скрыть баннеры торговли - Баннеры торговли в ленте скрыты - Баннеры торговли в ленте показаны - - Скрытие полноэкранной рекламы работает только для старых устройств Скрыть рекламу YouTube Premium @@ -826,7 +827,7 @@ Second \"item\" text" Скрыть метку звуковых метаданных Метка звуковых метаданных в Shorts скрыта Метка звуковых метаданных в Shorts показана - Скрыть ссылку на полное видео + Скрыть метку ссылки на видео Метка ссылки на полное видео в Shorts скрыта Метка ссылки на полное видео в Shorts показана Скрыть кнопку \"Со звуком\" @@ -963,12 +964,12 @@ Second \"item\" text" Кнопка пропуска автоматически скрывается через несколько секунд Кнопка пропуска показывается для всего сегмента Длительность кнопки пропуска - Длительность отображения кнопок автоматического скрытия \"Пропустить\" и \"Перейти к выделенному\" - Показывать тост отмены пропуска - Тост показывается, когда сегмент автоматически пропускается. Нажмите на уведомление-тост, чтобы отменить пропуск. - Всплывающее сообщение не показывается - Длительность всплывающего сообщения при пропуске - Как долго показывается уведомление-тост о пропуске + Длительность показа кнопок автоматического скрытия пропуска и перехода к основному моменту + Показывать уведомление отмены пропуска + Всплывающее уведомление показано при автоматическом пропуске сегмента. Нажмите на всплывающее уведомление для отмены пропуска + Всплывающее уведомление скрыто + Длительность всплывающего уведомления при пропуске + Длительность показа всплывающего уведомления при пропуске 1 секунда 2 секунды 3 секунды @@ -980,7 +981,7 @@ Second \"item\" text" 9 секунд 10 секунд Длительность видео без сегментов - Длина видео без учета всех сегментов отображается на полосе прокрутки + Длина видео без учета всех сегментов показана на полосе прогресса Полная длительность видео показана Создание новых сегментов Кнопка создания сегмента diff --git a/patches/src/main/resources/addresources/values-si-rLK/strings.xml b/patches/src/main/resources/addresources/values-si-rLK/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-si-rLK/strings.xml +++ b/patches/src/main/resources/addresources/values-si-rLK/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml index 47dbdc3a1..bb38229c5 100644 --- a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml +++ b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml @@ -313,15 +313,15 @@ Nebudete informovaní o žiadnych nepredvídaných udalostiach." Skryť tlačidlo „Vytvoriť krátke video“ Tlačidlo Vytvoriť Short je skryté Tlačidlo Vytvoriť Short je zobrazené - Skryť tlačidlo s časovou pečiatkou - Tlačidlo s časovou pečiatkou je skryté - Zobrazí sa tlačidlo s časovou pečiatkou Skryť ukážkový komentár Komentár ukážky je skrytý Zobrazí sa ukážka komentára Skryť tlačidlo Ďakujem Tlačidlo poďakovania je skryté Zobrazí sa tlačidlo Ďakujem + Skryť tlačidlo s časovou pečiatkou + Tlačidlo s časovou pečiatkou je skryté + Zobrazí sa tlačidlo s časovou pečiatkou Skryť YouTube Doodles Doodles vo vyhľadávacom paneli sú skryté @@ -370,32 +370,38 @@ Slová s veľkými písmenami v strede musia byť zadané s použitím veľkých Kľúčové slovo skryje všetky videá: %s - Skryť všeobecné reklamy - Všeobecné reklamy sú skryté - Zobrazujú sa všeobecné reklamy + Skryť regály obchodu tvorcu + Regály obchodu pod prehrávačom a v popise videa sú skryté + Regály obchodov pod prehrávačom a v popise videa sú zobrazené + Skryť banner obchodu na konci obrazovky + Banner obchodu je skrytý + Banner obchodu je zobrazený Skryť reklamy na celú obrazovku "Celoobrazovkové reklamy sú skryté Táto funkcia je dostupná len pre staršie zariadenia" Zobrazujú sa reklamy na celú obrazovku + + Skryť reklamy na celú obrazovku funguje iba na starších zariadeniach + Skryť všeobecné reklamy + Všeobecné reklamy sú skryté + Zobrazujú sa všeobecné reklamy + Skryť reklamné bannery + Tovarové bannery sú skryté + Zobrazujú sa reklamné bannery Skryť štítok platenej propagácie Štítok platenej propagácie je skrytý Zobrazuje sa štítok platenej propagácie + + Skryť banner „Zobraziť produkty“ + Banner vo videoprekrývke je skrytý + Banner v prekrytí videa je zobrazený Skryť vlastné sponzorované karty Vlastné sponzorované karty sú skryté Zobrazujú sa vlastné sponzorované karty - Skryť banner „Zobraziť produkty“ - Banner je skrytý - Zobrazuje sa banner - Skryť banner obchodu na konci obrazovky - Banner obchodu je skrytý - Banner obchodu je zobrazený - Skryť nákupnú poličku prehrávača - Nákupná polička je skrytá - Nákupná polička sa zobrazuje - Skryť odkazy na nákupy v popise videa - Odkazy na nákupy v popise videa sú skryté - Odkazy na nákupy v popise videa sú zobrazené + Skryť označené produkty + Označené produkty v popise videa sú skryté + Označené produkty v popise videa sú zobrazené Skryte tlačidlo \"Navštíviť obchod\" na stránkach kanála Tlačidlo na stránke kanála je skryté @@ -403,11 +409,6 @@ Táto funkcia je dostupná len pre staršie zariadenia" Skryť výsledky vyhľadávania na webe Výsledky vyhľadávania na webe sú skryté Zobrazia sa výsledky vyhľadávania na webe - Skryť reklamné bannery - Tovarové bannery sú skryté - Zobrazujú sa reklamné bannery - - Skryť reklamy na celú obrazovku funguje iba na starších zariadeniach Skryť promá YouTube Premium @@ -819,7 +820,7 @@ Ak chcete zobraziť ponuku zvukovej stopy, zmeňte možnosť „Oklamať videost Skryť označenie metadát zvuku Štítok metadát je skrytý Zobrazuje sa štítok metadát - Skryť celý štítok odkazu na video + Skryť štítok odkazu na video Označenie odkazu na video je skryté Zobrazí sa štítok odkazu na video Tlačidlo skryť zvuk @@ -956,7 +957,7 @@ Táto funkcia najlepšie funguje s kvalitou videa 720p alebo nižšou a pri pou Dĺžka trvania tlačidla preskočiť Ako dlho sú zobrazené tlačidlá pre automatické skrytie preskočenia a preskočenie na zvýraznenie Zobraziť hlásenie o vrátení preskočenia - Hlásenie sa zobrazí, keď je segment automaticky preskočený. Klepnutím na hlásenie preskočenie vrátite. + Hlásenie sa zobrazí, keď je segment automaticky preskočený. Klepnutím na hlásenie preskočenie vrátite Hlásenie sa nezobrazuje Dĺžka trvania hlásenia preskočenia Ako dlho je zobrazené hlásenie o preskočení diff --git a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml index cae198a91..fc8ad55e7 100644 --- a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml +++ b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml @@ -315,15 +315,15 @@ Ne boste obveščeni o nobenih nepričakovanih dogodkih." Skrij gumb \"Ustvari Shorts\" Gumb »Ustvari Short« je skrit Gumb »Ustvari Short« je prikazan - Skrij gumb časovnega žiga - Gumb časovnega žiga je skrit - Gumb časovnega žiga je prikazan Skrij predogled komentarja Predogled komentarja je skrit Predogled komentarja je prikazan Skrij gumb Hvala Gumb \"Hvala\" je skrit Gumb \"Hvala\" je prikazan + Skrij gumb časovnega žiga + Gumb časovnega žiga je skrit + Gumb časovnega žiga je prikazan Skrij YouTube Doodles Doodles v iskalni vrstici so skriti @@ -377,32 +377,38 @@ Omejitve Ključna beseda bo skrila vse videoposnetke: %s - Skrij splošne oglase - Splošni oglasi so skriti - Splošni oglasi so prikazani + Skrij police trgovine ustvarjalca + Police trgovine pod predvajalnikom in v opisu videa so skrite + Prikazane so police trgovine pod predvajalnikom in v opisu videoposnetka + Skrij pasico trgovine na koncu zaslona + Pasica trgovine je skrita + Pasica trgovine je prikazana Skrij oglase na celotnem zaslonu "Oglasi na celotnem zaslonu so skriti Ta funkcija je na voljo samo za starejše naprave" Oglasi na celotnem zaslonu so prikazani + + Skrivanje oglasov na celotnem zaslonu deluje samo s starejšimi napravami. + Skrij splošne oglase + Splošni oglasi so skriti + Splošni oglasi so prikazani + Skrij pasice s trgovino + Pasice s trgovino so skrite + Pasice s trgovino so prikazane Skrij nalepko plačane promocije Nalepka plačane promocije je skrita Nalepka plačane promocije je prikazana + + Skrij pasico \"Prikaži izdelke\" + Pasica v prekrivanju videa je skrita + Prikazana je pasica v prekrivanju videoposnetka Skrij samoproizvedene oglase Samoproizvedeni oglasi so skriti Samoproizvedeni oglasi so prikazani - Skrij pasico »Ogled izdelkov« - Pasica je skrita - Pasica je prikazana - Skrij pasico trgovine na koncu zaslona - Pasica trgovine je skrita - Pasica trgovine je prikazana - Skrij polico trgovine predvajalnika - Polica trgovine je skrita - Polica trgovine je prikazana - Skrij povezave v trgovino v opisu videoposnetka - Povezave do nakupovanja v opisu videoposnetka so skrite - Povezave do nakupovanja v opisu videoposnetka so prikazane + Skrij označene izdelke + Označeni izdelki v opisu videa so skriti + Prikazani so označeni izdelki v opisu videoposnetka Skrij gumb \"Obiščite trgovino\" na straneh kanalov Gumb na strani kanala je skrit @@ -410,11 +416,6 @@ Ta funkcija je na voljo samo za starejše naprave" Skrij rezultate spletnega iskanja Rezultati spletnega iskanja so skriti Rezultati spletnega iskanja so prikazani - Skrij pasice s trgovino - Pasice s trgovino so skrite - Pasice s trgovino so prikazane - - Skrivanje oglasov na celotnem zaslonu deluje samo s starejšimi napravami. Skrij promocije YouTube Premium @@ -826,7 +827,7 @@ Opomba: Omogočanje tega tudi prisilno skrije video oglase" Skrij nalepko s podatki o zvoku Nalepka s podatki je skrita Nalepka s podatki je prikazana - Skrij nalepko s povezavo do celotnega videoposnetka + Skrij oznako povezave do videoposnetka Nalepka s povezavo do videoposnetka je skrita Nalepka s povezavo do videoposnetka je prikazana Skrij gumb za zvok @@ -963,7 +964,7 @@ Ta funkcija deluje najbolje pri kakovosti videa 720p ali nižji in pri uporabi z Trajanje gumba za preskok Kako dolgo so prikazani gumbi za samodejno skrivanje preskakovanja in preskok na poudarek Prikaži obvestilo za razveljavitev preskakovanja - Obvestilo se prikaže, ko je segment samodejno preskočen. Dotaknite se obvestila, da razveljavite preskok. + Obvestilo se prikaže, ko je segment samodejno preskočen. Dotaknite se obvestila, da razveljavite preskok Obvestilo ni prikazano Trajanje obvestila o preskoku Kako dolgo je prikazano obvestilo o preskakovanju. diff --git a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml index 0aaba3f36..ea7e683bd 100644 --- a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml +++ b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml @@ -315,15 +315,15 @@ Ju nuk do të njoftoheni për ndonjë ngjarje të papritur." Fsheh butonin \"Krijo një Short\" Butoni Krijo një Short është i fshehur Butoni Krijo një Short është i shfaqur - Fshih butonin e kohëshënimit - Butoni i kohëshënimit është i fshehur - Butoni i kohëshënimit është shfaqur Fsheh komentin e parashikimit Komenti i parashikimit është i fshehur Komenti i parashikimit është i dukshëm Fsheh butonin Faleminderit Butoni i falënderimit është i fshehur Butoni i falënderimit është i dukshëm + Fshih butonin e kohëshënimit + Butoni i kohëshënimit është i fshehur + Butoni i kohëshënimit është shfaqur Fsheh YouTube Doodles Doodles në shiritin e kërkimit janë të fshehur @@ -377,32 +377,38 @@ Kufizime Fjala kyçe do të fshehë të gjitha videot: %s - Fsheh reklamimet e përgjithshme - Reklamimet e përgjithshme janë të fshehur - Reklamimet e përgjithshme janë të dukshme + Fshih raftet e dyqanit të krijuesit + Raftet e dyqanit poshtë luajtësit dhe në përshkrimin e videos janë fshehur + Raftet e dyqanit poshtë luajtësit dhe në përshkrimin e videos janë shfaqur + Fsheh bannerin e dyqanit të ekranit përfundimtar + Fletë banneri e dyqanit është fshehur + Fletë banneri e dyqanit është shfaqur Fsheh reklamimet me ekran të plotë "Reklamat në ekran të plotë janë të fshehura Kjo veçori është e disponueshme vetëm për pajisje më të vjetra" Reklamimet me ekran të plotë janë të dukshme + + Fshehja e reklamave me ekran të plotë funksionon vetëm me pajisje më të vjetra + Fsheh reklamimet e përgjithshme + Reklamimet e përgjithshme janë të fshehur + Reklamimet e përgjithshme janë të dukshme + Fsheh bannerat e mallrave + Bannerat e mallrave janë të fshehur + Bannerat e mallrave janë të dukshme Fsheh etiketën e promovimit të paguar Etiketë e promovimit të paguar është e fshehur Etiketë e promovimit të paguar është e dukshme + + Fshih banerin \'Shiko produkte\' + Baneri në mbivendosjen e videos është fshehur + Baneri në mbivendosjen e videos është shfaqur Fsheh kartat e sponsorizuara vetë Kartat e sponsorizuara vetë janë të fshehur Kartat e sponsorizuara vetë janë të dukshme - Fshih banerin \'Shiko produktet\' - Banneri është i fshehur - Banneri është i dukshëm - Fsheh bannerin e dyqanit të ekranit përfundimtar - Fletë banneri e dyqanit është fshehur - Fletë banneri e dyqanit është shfaqur - Fsheh raftin e dyqanit të lojtarit - Rafti i dyqanit është i fshehur - Rafti i dyqanit është i dukshëm - Fsheh lidhjet e blerjeve në përshkrimin e videos - Lidhjet e blerjeve në përshkrimin e videos janë të fshehura - Lidhjet e blerjeve në përshkrimin e videos janë të shfaqura + Fshih produktet e etiketuara + Produktet e etiketuara në përshkrimin e videos janë fshehur + Produktet e etiketuara në përshkrimin e videos janë shfaqur Fsheh butonin \"Vizito dyqanin\" në faqet e kanaleve Butoni në faqen e kanalit është i fshehur @@ -410,11 +416,6 @@ Kjo veçori është e disponueshme vetëm për pajisje më të vjetra" Fsheh rezultatet e kërkimit në ueb Rezultatet e kërkimit në ueb janë të fshehur Rezultatet e kërkimit në ueb janë të dukshme - Fsheh bannerat e mallrave - Bannerat e mallrave janë të fshehur - Bannerat e mallrave janë të dukshme - - Fshehja e reklamave me ekran të plotë funksionon vetëm me pajisje më të vjetra Fsheh promovimet e YouTube Premium @@ -826,7 +827,7 @@ Për të shfaqur menunë e pistës audio, ndryshoni 'Falsifiko transmetimet vide Fsheh etiketën e metadatave të zërit Etiketë metadata është e fshehur Etiketë metadata është e dukshme - Fsheh etiketën e lidhjes së videos së plotë + Fshih etiketën e lidhjes së videos Etiketë lidhje video është e fshehur Etiketë lidhje video është e dukshme Fsheh butonin \"Zëri\" diff --git a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml index 9d2d6a254..645eb2b87 100644 --- a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml @@ -315,15 +315,15 @@ Nećete biti obavešteni ni o kakvim neočekivanim događajima." Sakrij dugme „Napravi Short” Dugme „Napravi Short” je skriveno Dugme „Napravi Short” je prikazano - Sakrij dugme vremenske oznake - Dugme vremenske oznake je skriveno - Dugme vremenske oznake je prikazano Sakrij komentar za pregled Komentar za pregled je skriven Komentar za pregled je prikazan Sakrij dugme „Hvala” Dugme „Hvala” je skriveno Dugme „Hvala” je prikazano + Sakrij dugme vremenske oznake + Dugme vremenske oznake je skriveno + Dugme vremenske oznake je prikazano Sakrij YouTube Doodles Doodles na traci za pretragu je skriven @@ -377,32 +377,38 @@ Ograničenja Ključna reč će sakriti sve videe: %s - Sakrij opšte oglase - Opšti oglasi su skriveni - Opšti oglasi su prikazani + Sakrij police prodavnice kreatora + Police prodavnice ispod plejera i u opisu videa su skrivene + Prikazuju se police prodavnice ispod plejera i u opisu video snimka + Sakrij baner prodavnice na završnom ekranu + Baner prodavnice na završnom ekranu je skriven + Baner prodavnice na završnom ekranu je prikazan Sakrij oglase preko celog ekrana "Oglasi preko celog ekrana su skriveni Ova funkcija je dostupna samo za starije uređaje" Oglasi preko celog ekrana su prikazani + + Sakrivanje oglasa preko celog ekrana radi samo sa starijim uređajima + Sakrij opšte oglase + Opšti oglasi su skriveni + Opšti oglasi su prikazani + Sakrij banere za robu + Baneri za robu su skriveni + Baneri za robu su prikazani Sakrij oznaku plaćene promocije Oznaka plaćeme promocije je skrivena Oznaka plaćene promocije je prikazana + + Sakrij baner „Pregledaj proizvode” + Baner u video preklapanju je skriven + Prikazan je baner u preklapanju video snimka Sakrij kartice samosponzorstva Kartice samosponzorstva su skrivene Kartice samosponzorstva su prikazane - Sakrij baner „Pogledajte proizvode” - Baner za gledanje proizvoda je skriven - Baner za gledanje proizvoda je prikazan - Sakrij baner prodavnice na završnom ekranu - Baner prodavnice na završnom ekranu je skriven - Baner prodavnice na završnom ekranu je prikazan - Sakrij policu „Kupovina” u plejeru - Polica „Kupovina” u plejeru je skrivena - Polica „Kupovina” u plejeru je prikazana - Sakrij linkove za kupovinu u opisu videa - Linkovi za kupovinu u opisu videa su skriveni - Linkovi za kupovinu u opisu videa su prikazani + Sakrij označene proizvode + Označeni proizvodi u opisu videa su skriveni + Označeini proizvodi u opisu video snimka su prikazani Sakrij dugme „Poseti prodavnicu” na stranicama kanala Dugme „Poseti prodavnicu” na stranici kanala je skriveno @@ -410,11 +416,6 @@ Ova funkcija je dostupna samo za starije uređaje" Sakrij rezultate veb-pretrage Rezultati veb-pretrage su skriveni Rezultati veb-pretrage su prikazani - Sakrij banere za robu - Baneri za robu su skriveni - Baneri za robu su prikazani - - Sakrivanje oglasa preko celog ekrana radi samo sa starijim uređajima Sakrij promocije za YouTube Premium @@ -826,7 +827,7 @@ Da biste prikazali meni „Audio snimak”, promenite opciju „Lažirani video Sakrij oznaku metapodataka zvuka Oznaka metapodataka zvuka je skrivena Oznaka metapodataka zvuka je prikazana - Sakrij oznaku linka Shorts videa + Sakrij oznaku veze video snimka Oznaka linka Shorts videa je skrivena Oznaka linka Shorts videa je prikazana Sakrij dugme „Zvuk” @@ -961,12 +962,12 @@ Ova funkcija najbolje radi sa kvalitetom videa od 720p ili nižim i kada koristi Dugme za preskakanje će biti skriveno nakon nekoliko sekundi Dugme za preskakanje je prikazano za ceo segment Trajanje dugmeta za preskakanje - Koliko dugo se prikazuju dugmad za automatsko sakrivanje preskakanja i preskakanje do isticanja - Prikaži obaveštenje o poništavanju preskakanja - Obaveštenje se prikazuje kada se segment automatski preskoči. Dodirnite obaveštenje da biste poništili preskakanje - Toast se ne prikazuje - Trajanje toasta prilikom preskakanja - Koliko dugo se prikazuje obaveštenje o preskakanju + Koliko dugo se prikazuju dugmad za automatsko skrivanje preskakanja i preskakanje do isticanja + Prikaži iskačuće obaveštenje o poništavanju preskakanja + Iskačuće obaveštenje se prikazuje, kada se segment automatski preskoči. Dodirnite iskačuće obaveštenje da biste poništili preskakanje + Iskačuće obaveštenje se ne prikazuje + Trajanje iskačućeg obaveštenja pri preskakanju + Koliko dugo se prikazuje iskačuće obaveštenje o preskakanju 1 sekunda 2 sekunde 3 sekunde @@ -978,7 +979,7 @@ Ova funkcija najbolje radi sa kvalitetom videa od 720p ili nižim i kada koristi 9 sekundi 10 sekundi Prikaži dužinu videa bez segmenata - Dužina video snimka minus svi segmenti prikazuje se na traci za pretragu + Dužina videa bez svih segmenata prikazana je na traci za premotavanje Puna dužina videa je prikazana Pravljenje novih segmenata Prikaži dugme za pravljenje novog segmenta @@ -1154,6 +1155,7 @@ Spreman za podnošenje?" Faktor forme izgleda Podrazumevani Telefon + Tablet Automobilski "Promene uključuju: @@ -1237,6 +1239,7 @@ Ograničenje: Korišćenje dugmeta „Nazad” na traci sa alatkama možda neće Onemogućen Podrazumevan Minimalan + Tablet Moderan 1 Moderan 2 Moderan 3 diff --git a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml index 66f039939..44bdeafe3 100644 --- a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml @@ -315,15 +315,15 @@ Second \"item\" text" Сакриј дугме „Направи Short” Дугме „Направи Short” је скривено Дугме „Направи Short” је приказано - Сакриј дугме временске ознаке - Дугме временске ознаке је скривено - Дугме временске ознаке је приказано Сакриј коментар за преглед Коментар за преглед је скривен Коментар за преглед је приказан Сакриј дугме „Хвала” Дугме „Хвала” је скривено Дугме „Хвала” је приказано + Сакриј дугме временске ознаке + Дугме временске ознаке је скривено + Дугме временске ознаке је приказано Сакриј YouTube Doodles Doodles на траци за претрагу је скривен @@ -377,32 +377,38 @@ Second \"item\" text" Кључна реч ће сакрити све видее: %s - Сакриј опште огласе - Општи огласи су скривени - Општи огласи су приказани + Сакриј полице продавница креатора + Полице продавница испод плејера и у опису видеа су скривене + Полице продавнице испод плејера и у опису видеа су приказане + Сакриј банер продавнице на завршном екрану + Банер продавнице на завршном екрану је скривен + Банер продавнице на завршном екрану је приказан Сакриј огласе преко целог екрана "Огласи преко целог екрана су скривени Ова функција је доступна само за старије уређаје" Огласи преко целог екрана су приказани + + Сакривање огласа преко целог екрана ради само са старијим уређајима + Сакриј опште огласе + Општи огласи су скривени + Општи огласи су приказани + Сакриј банере за робу + Банери за робу су скривени + Банери за робу су приказани Сакриј ознаку плаћене промоције Ознака плаћене промоције је скривена Ознака плаћене промоције је приказана + + Сакриј банер \'Прегледај производе\' + Банер у преклапању видеа је скривен + Банер у преклапању видеа је приказан Сакриј картице самоспонзорства Картице самоспонзорства су скривене Картице самоспонзорства су приказане - Сакриј банер „Погледајте производе” - Банер за гледање производа је скривен - Банер за гледање производа је приказан - Сакриј банер продавнице на завршном екрану - Банер продавнице на завршном екрану је скривен - Банер продавнице на завршном екрану је приказан - Сакриј полицу „Куповина” у плејеру - Полица „Куповина” у плејеру је скривена - Полица „Куповина” у плејеру је приказана - Сакриј линкове за куповину у опису видеа - Линкови за куповину у опису видеа су скривени - Линкови за куповину у опису видеа су приказани + Сакриј означене производе + Означени производи у опису видеа су скривени + Означени производи у опису видеа су приказани Сакриј дугме „Посети продавницу” на страницама канала Дугме „Посети продавницу” на страници канала је скривено @@ -410,11 +416,6 @@ Second \"item\" text" Сакриј резултате веб-претраге Резултати веб-претраге су скривени Резултати веб-претраге су приказани - Сакриј банере за робу - Банери за робу су скривени - Банери за робу су приказани - - Сакривање огласа преко целог екрана ради само са старијим уређајима Сакриј промоције за YouTube Premium @@ -826,7 +827,7 @@ Second \"item\" text" Сакриј ознаку метаподатака звука Ознака метаподатака звука је скривена Ознака метаподатака звука је приказана - Сакриј ознаку линка Shorts видеа + Сакриј ознаку везе видеа Ознака линка Shorts видеа је скривена Ознака линка Shorts видеа је приказана Сакриј дугме „Звук” @@ -962,11 +963,11 @@ Second \"item\" text" Дугме за прескакање је приказано за цео сегмент Трајање дугмета за прескакање Колико дуго се приказују дугмад за аутоматско скривање прескакања и прескакање до истакнутог - Прикажи искачућу поруку за поништавање прескакања - Искачућа порука се приказује када се сегмент аутоматски прескочи. Додирните искачућу поруку да бисте поништили прескакање - Тост није приказан - Трајање тост поруке при прескакању - Колико дуго се приказује искачућа порука о прескакању + Прикажи искачуће обавештење о поништавању прескакања + Искачуће обавештење се приказује, када се сегмент аутоматски прескочи. Додирните искачуће обавештење да бисте поништили прескакање + Искачуће обавештење се не приказује + Трајање искачућег обавештења при прескакању + Колико дуго се приказује искачуће обавештење о прескакању 1 секунда 2 секунде 3 секунде @@ -978,7 +979,7 @@ Second \"item\" text" 9 секунди 10 секунди Прикажи дужину видеа без сегмената - Дужина видеа без свих сегмената приказана је на траци напретка + Дужина видеа без свих сегмената приказана је на траци за премотавање Пуна дужина видеа је приказана Прављење нових сегмената Прикажи дугме за прављење новог сегмента diff --git a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml index a36344b42..41e138085 100644 --- a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml +++ b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml @@ -315,15 +315,15 @@ Du kommer inte att bli meddelad om oväntade händelser." Dölj knappen \'Skapa en kort\' Knappen Skapa en Short är dold Knappen Skapa en Short visas - Dölj tidsstämpelknappen - Tidsstämpelknappen är dold - Tidsstämpelknappen är synlig Dölj förhandsgranskningskommentar Förhandsgranskningskommentaren är dold Förhandsgranskningskommentaren visas Dölj knappen \"Tack\" Tack-knappen är dold Tackknappen är synlig + Dölj tidsstämpelknappen + Tidsstämpelknappen är dold + Tidsstämpelknappen är synlig Dölj YouTube Doodles Sökfältet Doodles är dolda @@ -377,32 +377,38 @@ Begränsningar Nyckelord döljer alla videor: %s - Dölj allmänna annonser - Allmänna annonser är dolda - Allmänna annonser är synliga + Dölj skaparens butikshyllor + Butikshyllor under spelaren och i videobeskrivningen är dolda + Butikshyllor under spelaren och i videobeskrivningen visas + Dölj butiksbannern på slutskärmen + Butiksbannern är dold + Butiksbannern visas Dölj helskärmsannonser "Helskärmsannonser är dolda Den här funktionen är endast tillgänglig för äldre enheter" Helskärmsannonser visas + + Helskärmsannonser kan döljas bara på äldre enheter + Dölj allmänna annonser + Allmänna annonser är dolda + Allmänna annonser är synliga + Dölj banners för varor + Banners för varor är dolda + Banners för varor visas Dölj etikett för betald marknadsföring Etiketten för betald marknadsföring är dold Etiketten för betald marknadsföring visas + + Dölj bannern \"Visa produkter\" + Banner i videoöverlägg är dold + Banner i videoöverlägg visas Dölj självsponsrade kort Självsponsrade kort är dolda Självsponsrade kort är synliga - Dölj \"Visa produkter\"-banner - Banner är dold - Banner är synlig - Dölj butiksbannern på slutskärmen - Butiksbannern är dold - Butiksbannern visas - Dölj butikshyllan i spelaren - Butikshyllan är dold - Butikshyllan visas - Dölj butikslänkar - Butikslänkar i videobeskrivningen är dolda - Butikslänkar i videobeskrivningen visas + Dölj taggade produkter + Taggade produkter i videobeskrivningen är dolda + Taggade produkter i videobeskrivningen visas Dölj knappen Besök butiken Knappen på kanalsidan är dold @@ -410,11 +416,6 @@ Den här funktionen är endast tillgänglig för äldre enheter" Dölj sökresultat på webben Sökresultat på webben är dolda Sökresultat på webben är synliga - Dölj banners för varor - Banners för varor är dolda - Banners för varor visas - - Helskärmsannonser kan döljas bara på äldre enheter Dölj YouTube Premium-kampanjer @@ -826,7 +827,7 @@ För att visa ljudspårsmenyn, ändra \"Spoof video streams\" till iOS TV"Dölj ljudmetadata-etikett Metadata-etikett är dold Metadata etikett visas - Dölj full videolänk-etikett + Dölj etikett för videolänk Etiketten för videolänk är dold Etikett för videolänk visas Dölj ljudknapp diff --git a/patches/src/main/resources/addresources/values-sw-rKE/strings.xml b/patches/src/main/resources/addresources/values-sw-rKE/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-sw-rKE/strings.xml +++ b/patches/src/main/resources/addresources/values-sw-rKE/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-ta-rIN/strings.xml b/patches/src/main/resources/addresources/values-ta-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-ta-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-ta-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-te-rIN/strings.xml b/patches/src/main/resources/addresources/values-te-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-te-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-te-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-th-rTH/strings.xml b/patches/src/main/resources/addresources/values-th-rTH/strings.xml index f4c478c92..3ce72e21f 100644 --- a/patches/src/main/resources/addresources/values-th-rTH/strings.xml +++ b/patches/src/main/resources/addresources/values-th-rTH/strings.xml @@ -315,15 +315,15 @@ Second \"item\" text" ซ่อนปุ่ม \'สร้าง Shorts\' ปุ่มสร้าง Short ถูกซ่อน ปุ่มสร้าง Short แสดงอยู่ - ซ่อนปุ่มประทับเวลา - ปุ่มประทับเวลาถูกซ่อน - ปุ่มประทับเวลาแสดงอยู่ ซ่อนความคิดเห็นตัวอย่าง ความคิดเห็นตัวอย่างถูกซ่อนไว้ ความคิดเห็นตัวอย่างแสดงอยู่ ซ่อนปุ่มขอบคุณ ปุ่มขอบคุณถูกซ่อนไว้ ปุ่มขอบคุณจะแสดง + ซ่อนปุ่มประทับเวลา + ปุ่มประทับเวลาถูกซ่อน + ปุ่มประทับเวลาแสดงอยู่ ซ่อน Doodles ของ YouTube Doodles แถบค้นหาถูกซ่อน @@ -377,32 +377,38 @@ Second \"item\" text" คำสำคัญจะซ่อนวิดีโอทั้งหมด: %s - ซ่อนโฆษณาโดยทั่วไป - โฆษณาโดยทั่วไปถูกซ่อน - โฆษณาโดยทั่วไปจะแสดง + ซ่อนชั้นวางสินค้าของครีเอเตอร์ + ซ่อนชั้นวางสินค้าใต้เครื่องเล่นและในคำอธิบายวิดีโอ + ชั้นวางสินค้าใต้เครื่องเล่นและในคำอธิบายวิดีโอจะแสดงขึ้น + ซ่อนแบนเนอร์ร้านค้าท้ายจอ + แบนเนอร์ร้านค้าถูกซ่อนไว้ + แบนเนอร์ร้านค้าปรากฏ ซ่อนโฆษณาแบบเต็มหน้าจอ "โฆษณาแบบเต็มจอถูกซ่อน คุณสมบัตินี้มีเฉพาะสําหรับอุปกรณ์รุ่นเก่า" โฆษณาแบบเต็มหน้าจอจะแสดง + + ซ่อนโฆษณาแบบเต็มหน้าจอใช้งานได้กับอุปกรณ์รุ่นเก่าเท่านั้น + ซ่อนโฆษณาโดยทั่วไป + โฆษณาโดยทั่วไปถูกซ่อน + โฆษณาโดยทั่วไปจะแสดง + ซ่อนแบนเนอร์สินค้า + แบนเนอร์สินค้าถูกซ่อน + แบนเนอร์สินค้าจะแสดง ซ่อนป้ายโฆษณาที่จ่ายเงิน ป้ายโฆษณาที่จ่ายเงินถูกซ่อน ป้ายโฆษณาที่จ่ายเงินจะแสดง + + ซ่อนแบนเนอร์ \'ดูสินค้า\' + ซ่อนแบนเนอร์ในโอเวอร์เลย์วิดีโอ + แบนเนอร์ในการวางซ้อนวิดีโอจะแสดงขึ้น ซ่อนการ์ดที่สนับสนุนตัวเอง การ์ดที่สนับสนุนตัวเองถูกซ่อน การ์ดที่สนับสนุนตัวเองจะแสดง - ซ่อนแบนเนอร์ \'ดูผลิตภัณฑ์\' - แบนเนอร์ถูกซ่อน - แบนเนอร์จะแสดง - ซ่อนแบนเนอร์ร้านค้าท้ายจอ - แบนเนอร์ร้านค้าถูกซ่อนไว้ - แบนเนอร์ร้านค้าปรากฏ - ซ่อนชั้นวางสินค้าในเครื่องเล่น - ชั้นวางสินค้าถูกซ่อน - ชั้นวางสินค้าจะแสดง - ซ่อนลิงก์การช็อปปิ้งในคำอธิบายวิดีโอ - ลิงก์ช้อปปิ้งในรายละเอียดวิดีโอถูกซ่อน - ลิงก์ช้อปปิ้งในรายละเอียดวิดีโอแสดงอยู่ + ซ่อนสินค้าที่แท็กไว้ + ซ่อนสินค้าที่แท็กไว้ในคำอธิบายวิดีโอ + สินค้าที่ติดแท็กในคำอธิบายวิดีโอจะแสดงขึ้น ซ่อนปุ่ม \'ไปที่ร้านค้า\' บนหน้าช่อง ปุ่มในหน้าแชนเนลถูกซ่อน @@ -410,11 +416,6 @@ Second \"item\" text" ซ่อนผลลัพธ์การค้นหาบนเว็บ ผลลัพธ์การค้นหาบนเว็บถูกซ่อน ผลลัพธ์การค้นหาบนเว็บจะแสดง - ซ่อนแบนเนอร์สินค้า - แบนเนอร์สินค้าถูกซ่อน - แบนเนอร์สินค้าจะแสดง - - ซ่อนโฆษณาแบบเต็มหน้าจอใช้งานได้กับอุปกรณ์รุ่นเก่าเท่านั้น ซ่อนการโปรโมต YouTube Premium @@ -824,7 +825,7 @@ Second \"item\" text" ซ่อนป้ายเมตามีเดียเสียง ซ่อนป้ายเมตามีเดีย แสดงป้ายชื่อเมทาดาต้า - ซ่อนป้ายชื่อลิงก์วิดีโอเต็ม + ซ่อนป้ายกำกับลิงก์วิดีโอ ซ่อนป้ายชื่อลิงก์วิดีโอเต็ม แสดงป้ายชื่อลิงก์วิดีโอเต็ม ซ่อนปุ่มเสียง diff --git a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml index c4a73f49c..c2fb6795e 100644 --- a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml +++ b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml @@ -315,15 +315,15 @@ Beklenmedik olaylar hakkında bilgilendirilmeyeceksiniz." \'Short oluştur\' düğmesini gizle Short oluştur düğmesi gizli Short oluştur düğmesi görünür - Zaman damgası düğmesini gizle - Zaman damgası düğmesi gizli - Zaman damgası düğmesi görünür Ön izlenen yorumu gizle Ön izlenen yorum gizli Ön izlenen yorum görünür Teşekkürler düğmesini gizle Teşekkürler düğmesi gizli Teşekkürler düğmesi görünür + Zaman damgası düğmesini gizle + Zaman damgası düğmesi gizli + Zaman damgası düğmesi görünür YouTube Doodle\'larını gizle Arama çubuğu Doodle\'ları gizli @@ -377,32 +377,38 @@ Sınırlamalar Kelime bütün videoları gizler: %s - Genel reklamları gizle - Genel reklamlar gizli - Genel reklamlar görünür + İçerik oluşturucu mağaza raflarını gizle + Oynatıcının altındaki ve video açıklamasındaki mağaza rafları gizlendi + Oynatıcının altındaki ve video açıklamasındaki mağaza rafları gösteriliyor + Bitiş ekranındaki mağaza afişini gizle + Mağaza afişi gizli + Mağaza afişi görünür Tam ekran reklamları gizle "Tam ekran reklamlar gizli Bu özellik yalnızca eski cihazlarda kullanılabilir" Tam ekran reklamlar görünür + + Tam ekran reklamlar sadece eski cihazlarda gizlenebilir + Genel reklamları gizle + Genel reklamlar gizli + Genel reklamlar görünür + Ürün afişlerini gizle + Ürün afişleri gizli + Ürün afişleri görünür Ücretli tanıtım etiketini gizle Ücretli tanıtım etiketi gizli Ücretli tanıtım etiketi görünür + + \"Ürünleri görüntüle\" afişini gizle + Video yer paylaşımındaki banner gizlendi + Video yer paylaşımındaki afiş gösteriliyor Kendine sponsor kartları gizle Kendine sponsor kartlar gizli Kendine sponsor kartlar görünür - \'Ürünleri görüntüle\' başlığını gizle - Afiş gizli - Afiş görünür - Bitiş ekranındaki mağaza afişini gizle - Mağaza afişi gizli - Mağaza afişi görünür - Oynatıcı alışveriş rafını gizle - Alışveriş rafı gizli - Alışveriş rafı görünür - Alışveriş bağlantılarını gizle - Video açıklamasındaki alışveriş bağlantıları gizli - Video açıklamasındaki alışveriş bağlantıları görünür + Etiketli ürünleri gizle + Video açıklamasındaki etiketli ürünler gizlendi + Video açıklamasındaki etiketli ürünler gösteriliyor Kanal sayfalarındaki \'Mağazayı ziyaret et\' düğmesini gizle Kanal sayfasındaki düğme gizli @@ -410,11 +416,6 @@ Bu özellik yalnızca eski cihazlarda kullanılabilir" Web arama sonuçlarını gizle Web arama sonuçları gizli Web arama sonuçları görünür - Ürün afişlerini gizle - Ürün afişleri gizli - Ürün afişleri görünür - - Tam ekran reklamlar sadece eski cihazlarda gizlenebilir YouTube Premium promosyonlarını gizle @@ -826,7 +827,7 @@ Ses parçası menüsünü göstermek için \"Video akışlarını taklit et\" ay Ses bilgisi etiketini gizle Bilgi etiketi gizli Bilgi etiketi görünür - Tam video bağlantısı etiketini gizle + Video bağlantı etiketini gizle Video bağlantısı etiketi gizli Video bağlantısı etiketi görünür Ses düğmesini gizle @@ -965,7 +966,7 @@ Bu özellik, 720p veya daha düşük video kalitesi ve çok hızlı bir internet Atla düğmesi süresi Otomatik gizlenen atla ve vurgulaya atla düğmelerinin ne kadar süreyle gösterildiği Atlamayı geri al bildirimini göster - Bildirim, bir segment otomatik olarak atlandığında gösterilir. Atlamayı geri almak için bildirimine dokunun. + Bildirim, bir segment otomatik olarak atlandığında gösterilir. Atlamayı geri almak için bildirimine dokunun Toast gösterilmiyor Atlama toast süresi Atlama bildiriminin ne kadar süreyle gösterildiği diff --git a/patches/src/main/resources/addresources/values-uk-rUA/strings.xml b/patches/src/main/resources/addresources/values-uk-rUA/strings.xml index 6fc5f6b94..40b9fbdb0 100644 --- a/patches/src/main/resources/addresources/values-uk-rUA/strings.xml +++ b/patches/src/main/resources/addresources/values-uk-rUA/strings.xml @@ -316,15 +316,15 @@ Second \"item\" text" Приховати кнопку \"Створити Short\" Кнопку \"Створити Short\" приховано Кнопка \"Створити Short\" показується - Приховати кнопку позначки часу - Кнопку позначки часу приховано - Кнопка позначки часу показується Приховати прев\'ю коментар Прев\'ю коментар в секції коментарів приховано Прев\'ю коментар в секції коментарів показується Приховати \"Дякую\" Кнопку \"Дякую\" приховано Кнопка \"Дякую\" показується + Приховати кнопку позначки часу + Кнопку позначки часу приховано + Кнопка позначки часу показується Приховати YouTube Doodles Doodles у пошуковій панелі приховано @@ -378,32 +378,38 @@ Second \"item\" text" Ключове слово приховає всі відео: %s - Приховати загальну рекламу - Загальну рекламу приховано - Загальна реклама показується + Приховати полиці магазину автора + Полиці магазину під плеєром та в описі відео приховані + Полиці магазину під плеєром та в описі відео показуються + Приховати банер магазину на кінцевому екрані + Рекламний банер магазину на кінцевому екрані приховано + Рекламний банер магазину на кінцевому екрані показується Приховати повноекранну рекламу "Повноекранну рекламу приховано Ця функція доступна тільки для старих пристроїв" Повноекранна реклама показується + + Приховувати повноекранну рекламу працює тільки зі старими пристроями + Приховати загальну рекламу + Загальну рекламу приховано + Загальна реклама показується + Приховати товарні банери + Товарні банери приховано + Товарні банери показуються Приховати \"Містить пряму рекламу\" Мітку \"Містить пряму рекламу\" приховано Мітка \"Містить пряму рекламу\" показується + + Приховати банер \"Перегляд товарів\" + Банер в інтерфейсі відео приховано + Банер в інтерфейсі відео показується Приховати картки само спонсорства Картки само спонсорства приховано Картки само спонсорства показуються - Приховати банер \"Перегляд товарів\" - Банер перегляду товарів приховано - Банер перегляду товарів показується - Приховати банер магазину на кінцевому екрані - Рекламний банер магазину на кінцевому екрані приховано - Рекламний банер магазину на кінцевому екрані показується - Приховати полицю покупок в плеєрі - Полицю покупок в плеєрі приховано - Полиця покупок в плеєрі показується - Приховати посилання на покупки - Посилання на покупки в описі відео приховано - Посилання на покупки в описі відео показуються + Приховати відмічені товари + Позначені продукти в описі відео приховані + Позначені товари в описі відео відображаються Приховати \"Відвідати магазин\" Кнопку на сторінці каналу приховано @@ -411,11 +417,6 @@ Second \"item\" text" Приховати результати вебпошуку Результати вебпошуку приховано Результати вебпошуку показуються - Приховати товарні банери - Товарні банери приховано - Товарні банери показуються - - Приховувати повноекранну рекламу працює тільки зі старими пристроями Приховати рекламу YouTube Premium @@ -827,7 +828,7 @@ Second \"item\" text" Приховати мітку метаданих звуку Мітку метаданих звуку приховано Мітка метаданих звуку показується - Приховати посилання на повне відео + Приховати посилання на відео Мітка посилання на повне відео приховано Мітка посилання на повне відео показується Приховати \"Зі звуком\" @@ -979,7 +980,7 @@ Second \"item\" text" 9 секунд 10 секунд Показувати тривалість відео без сегментів - Показується тривалість відео без урахування всіх сегментів, які показуються на панелі прогресу + Показується тривалість відео без урахування всіх сегментів, які присутні на панелі прогресу Показується повна тривалість відео Створення нових сегментів Показувати кнопку створення нового сегмента diff --git a/patches/src/main/resources/addresources/values-ur-rIN/strings.xml b/patches/src/main/resources/addresources/values-ur-rIN/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-ur-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-ur-rIN/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-uz-rUZ/strings.xml b/patches/src/main/resources/addresources/values-uz-rUZ/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-uz-rUZ/strings.xml +++ b/patches/src/main/resources/addresources/values-uz-rUZ/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + diff --git a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml index 164ef2f8d..7aaeea325 100644 --- a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml +++ b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml @@ -315,15 +315,15 @@ Bạn sẽ không được thông báo về bất kỳ sự kiện bất ngờ n Ẩn nút \'Tạo video ngắn\' Nút Tạo video ngắn đã bị ẩn Nút Tạo video ngắn được hiển thị - Ẩn nút dấu thời gian - Nút dấu thời gian đã bị ẩn - Nút dấu thời gian được hiện Ẩn xem trước bình luận Xem trước bình luận đã bị ẩn Xem trước bình luận được hiển thị Ẩn nút Cảm ơn Nút cảm ơn đã bị ẩn Nút cảm ơn được hiển thị + Ẩn nút dấu thời gian + Nút dấu thời gian đã bị ẩn + Nút dấu thời gian được hiện Ẩn YouTube Doodles Thanh tìm kiếm Doodles đã bị ẩn @@ -377,32 +377,38 @@ Hạn chế Từ khóa sẽ ẩn tất cả video: %s - Ẩn quảng cáo chung - Quảng cáo chung đã bị ẩn - Quảng cáo chung được hiển thị + Ẩn kệ cửa hàng của nhà sáng tạo + Kệ cửa hàng bên dưới trình phát và trong mô tả video đã bị ẩn + Kệ cửa hàng bên dưới trình phát và trong mô tả video được hiển thị + Ẩn biểu ngữ cửa hàng ở cuối màn hình + Biểu ngữ cửa hàng đã bị ẩn + Biểu ngữ cửa hàng được hiển thị Ẩn quảng cáo toàn màn hình "Quảng cáo toàn màn hình đã bị ẩn Tính năng này chỉ khả dụng trên các thiết bị cũ" Quảng cáo toàn màn hình được hiển thị + + Ẩn QC toàn màn hình chỉ hoạt động trên thiết bị cũ + Ẩn quảng cáo chung + Quảng cáo chung đã bị ẩn + Quảng cáo chung được hiển thị + Ẩn biểu ngữ sản phẩm + Biểu ngữ sản phẩm đã bị ẩn + Biểu ngữ sản phẩm được hiển thị Ẩn nhãn quảng cáo trả phí Nhãn quảng cáo trả phí đã bị ẩn Nhãn quảng cáo trả phí được hiển thị + + Ẩn biểu ngữ \"Xem sản phẩm\" + Biểu ngữ trong lớp phủ video đã bị ẩn + Biểu ngữ trong lớp phủ video được hiển thị Ẩn thẻ tự tài trợ Các thẻ tự tài trợ đã bị ẩn Các thẻ tự tài trợ được hiển thị - Ẩn biểu ngữ \'Xem sản phẩm\' - Biểu ngữ đã bị ẩn - Biểu ngữ được hiển thị - Ẩn biểu ngữ cửa hàng ở cuối màn hình - Biểu ngữ cửa hàng đã bị ẩn - Biểu ngữ cửa hàng được hiển thị - Ẩn kệ cửa hàng của trình phát - Kệ cửa hàng đã bị ẩn - Kệ cửa hàng được hiển thị - Ẩn các liên kết mua sắm - Liên kết mua sắm trong mô tả video đã bị ẩn - Liên kết mua sắm trong mô tả video được hiển thị + Ẩn sản phẩm được gắn thẻ + Các sản phẩm được gắn thẻ trong mô tả video đã bị ẩn + Sản phẩm được gắn thẻ trong mô tả video được hiển thị Ẩn nút \'Chuyển đến cửa hàng\' Nút trên trang kênh đã bị ẩn @@ -410,11 +416,6 @@ Tính năng này chỉ khả dụng trên các thiết bị cũ" Ẩn kết quả tìm kiếm trên web Kết quả tìm kiếm trên web đã bị ẩn Kết quả tìm kiếm trên web được hiển thị - Ẩn biểu ngữ sản phẩm - Biểu ngữ sản phẩm đã bị ẩn - Biểu ngữ sản phẩm được hiển thị - - Ẩn QC toàn màn hình chỉ hoạt động trên thiết bị cũ Ẩn quảng cáo YouTube Premium @@ -826,7 +827,7 @@ Nếu thay đổi cài đặt này không có hiệu lực, hãy thử chuyển Ẩn nhãn siêu dữ liệu âm thanh Nhãn siêu dữ liệu đã bị ẩn Nhãn siêu dữ liệu được hiển thị - Ẩn nhãn liên kết tới video đầy đủ + Ẩn nhãn liên kết video Nhãn liên kết tới video đầy đủ đã bị ẩn Nhãn liên kết tới video đầy đủ được hiển thị Ẩn nút âm thanh @@ -960,14 +961,14 @@ Tính năng này hoạt động tốt nhất với chất lượng video 720p tr Nút Bỏ qua được thiết kế để tối ưu độ rộng Nút bỏ qua phân đoạn được thiết kế để tối ưu ngoại hình tốt nhất Tự động ẩn nút Bỏ qua - Nút bỏ qua ẩn sau vài giây + Nút bỏ qua sẽ ẩn sau vài giây Nút bỏ qua được hiển thị cho toàn bộ phân đoạn - Thời lượng nút bỏ qua - Thời gian hiển thị các nút tự động ẩn bỏ qua và bỏ qua đến điểm nổi bật + Thời gian hiển thị nút bỏ qua + Thời gian tự động ẩn nút bỏ qua và nút bỏ qua đến phần nổi bật Hiện thông báo nổi hoàn tác bỏ qua - Thông báo nổi được hiển thị mỗi khi tự động bỏ qua một phân đoạn. Chạm vào thông báo nổi để hoàn tác bỏ qua - Toast không được hiển thị - Thời lượng toast bỏ qua + Thông báo nổi được hiển thị mỗi khi tự động bỏ qua một phân đoạn. Chạm vào thông báo nổi để hoàn tác bỏ qua phân đoạn vừa rồi + Thông báo nổi không được hiển thị + Thời gian hiển thị thông báo nổi bỏ qua Thời gian hiển thị thông báo nổi bỏ qua 1 giây 2 giây @@ -980,7 +981,7 @@ Tính năng này hoạt động tốt nhất với chất lượng video 720p tr 9 giây 10 giây Hiện thời lượng video không có phân đoạn - Thời lượng video trừ tất cả các phân đoạn được hiển thị trên thanh tua + Thời lượng video đã trừ đi tất cả các phân đoạn được hiển thị trên thanh tiến trình Thời lượng đầy đủ của video được hiển thị Tạo phân đoạn mới Hiện nút Tạo phân đoạn mới @@ -1026,23 +1027,23 @@ ID người dùng của bạn giống như mật khẩu và không bao giờ đ Không hiện lại Thay đổi hành vi phân đoạn Nhà tài trợ - Quảng cáo trả phí, giới thiệu trả phí và quảng cáo trực tiếp. Không dùng cho mục đích tự quảng cáo hoặc quảng bá miễn phí cho các tổ chức/nhà sáng tạo/trang web/sản phẩm mà họ yêu thích + Quảng cáo trả phí, giới thiệu trả phí và quảng cáo trực tiếp. Không phải tự quảng cáo hoặc quảng bá miễn phí cho các tổ chức/nhà sáng tạo/trang web/sản phẩm mà họ yêu thích Không được trả phí / Tự quảng cáo Tương tự như \"Nhà tài trợ\" nhưng không có lợi nhuận hoặc tự quảng bá. Bao gồm các phần về sản phẩm, quyên góp hoặc thông tin về những người họ đã hợp tác cùng - Lời nhắc tương tác (Đăng ký) - Một lời nhắc ngắn về thích, đăng ký hoặc theo dõi họ ở giữa nội dung. Nếu nó dài hoặc về một điều gì đó cụ thể, nó nên phân loại vào tự quảng cáo + Nhắc nhở tương tác (Đăng ký) + Một lời nhắc ngắn rằng hãy thích, đăng ký hoặc theo dõi họ ở giữa nội dung. Nếu nó dài hoặc về một điều gì đó cụ thể, nó nên phân loại vào Tự quảng cáo Nổi bật Phần video mà hầu hết mọi người đang tìm kiếm Gián đoạn / Giới thiệu - Một khoảng thời gian không có nội dung thực tế. Có thể là tạm dừng, khung hình tĩnh hoặc hoạt ảnh lặp lại. Không bao gồm các phần chuyển tiếp chứa thông tin + Một khoảng thời gian không có nội dung thực tế. Có thể là tạm dừng, khung hình tĩnh hoặc hoạt ảnh lặp lại. Không bao gồm các phần chuyển cảnh chứa thông tin Màn hình kết thúc / Danh đề Danh đề hoặc khi màn hình kết thúc của YouTube xuất hiện. Không dành cho phần kết có chứa thông tin Xem trước / Tóm tắt / Gây chú ý Tuyển tập các đoạn cắt cho thấy những gì sắp diễn ra hoặc đã xảy ra trong video hoặc trong các video khác của một sê-ri, trong đó tất cả thông tin được lặp lại ở nơi khác Nội dung thừa / Lạc đề / Câu đùa - Các cảnh phụ chỉ được thêm vào để làm đầy thời lượng hoặc gây hài, không cần thiết để hiểu nội dung chính của video. Không bao gồm các phân đoạn cung cấp bối cảnh hoặc chi tiết nền + Các cảnh phụ chỉ được thêm vào để kéo dài thời lượng hoặc gây hài, không cần thiết để hiểu nội dung chính của video. Không bao gồm các phân đoạn cung cấp bối cảnh hoặc chi tiết nền Âm nhạc: Phần không phải âm nhạc - Chỉ dành cho video âm nhạc. Các đoạn video âm nhạc không có nhạc, chưa được phân loại vào danh mục khác + Chỉ dành cho video âm nhạc. Phần của video âm nhạc nhưng không có nhạc, mà cũng không được phân loại vào danh mục khác Bỏ qua Nổi bật Bỏ qua nhà tài trợ diff --git a/patches/src/main/resources/addresources/values-zh-rCN/strings.xml b/patches/src/main/resources/addresources/values-zh-rCN/strings.xml index df7c03a8d..327386d1a 100644 --- a/patches/src/main/resources/addresources/values-zh-rCN/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rCN/strings.xml @@ -315,15 +315,15 @@ Second \"item\" text" 隐藏「创建 Short」按钮 “创建Shorts”按钮已隐藏 “创建Shorts”按钮已显示 - 隐藏时间戳按钮 - 时间戳按钮已隐藏 - 时间戳按钮已显示 隐藏评论预览 评论预览已隐藏 评论预览已显示 隐藏感谢按钮 感谢按钮已隐藏 感谢按钮已显示 + 隐藏时间戳按钮 + 时间戳按钮已隐藏 + 时间戳按钮已显示 隐藏 YouTube 涂鸦 搜索栏涂鸦已隐藏 @@ -377,32 +377,38 @@ Second \"item\" text" 关键词将隐藏所有影片:%s - 隐藏一般广告 - 一般广告已隐藏 - 一般广告已显示 + 隐藏创作者商店货架 + 播放器下方和视频描述中的商店货架已隐藏 + 播放器下方和视频描述中会显示商店货架 + 商店横幅已隐藏 + 隐藏商店横幅 + 商店横幅已显示 隐藏全屏广告 "全屏广告已隐藏 此功能仅适用于旧设备" 全屏广告已显示 + + 隐藏全屏广告只适用于旧设备 + 隐藏一般广告 + 一般广告已隐藏 + 一般广告已显示 + 隐藏商品广告横幅 + 已隐藏商品横幅 + 已显示商品横幅 隐藏付费推广标签 付费推广标签已隐藏 付费推广标签已显示 + + 隐藏“查看商品”横幅 + 视频叠加层中的横幅已隐藏 + 视频叠加层中会显示横幅 隐藏自我推广卡片 自我推广卡片已隐藏 自我推广卡片已显示 - 隐藏“查看商品”横幅 - 横幅已隐藏 - 横幅已显示 - 商店横幅已隐藏 - 隐藏商店横幅 - 商店横幅已显示 - 隐藏播放器购物栏 - 购物展示栏已隐藏 - 购物展示栏已显示 - 在视频描述中隐藏购物链接 - 已隐藏视频说明中的购物链接 - 已显示视频说明中的购物链接 + 隐藏带标签的商品 + 视频描述中的带标签商品已隐藏 + 视频描述中会显示已标记商品 隐藏频道页面上的“访问商店”按钮 频道页面中的按钮已隐藏 @@ -410,11 +416,6 @@ Second \"item\" text" 隐藏网页搜索结果 网页搜索结果已隐藏 网页搜索结果已显示 - 隐藏商品广告横幅 - 已隐藏商品横幅 - 已显示商品横幅 - - 隐藏全屏广告只适用于旧设备 隐藏 YouTube Premium 促销推广 @@ -826,7 +827,7 @@ Second \"item\" text" 隐藏声音元数据标签 元数据标签已隐藏 元数据标签已显示 - 隐藏完整视频链接标签 + 隐藏视频链接标签 视频链接标签已隐藏 视频链接标签已显示 隐藏声音按钮 diff --git a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml index 8a9d00d90..55a85c299 100644 --- a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml @@ -315,15 +315,15 @@ Second \"item\" text" 隱藏「建立 Short」按鈕 已隱藏「建立 Short」按鈕 已顯示「建立 Short」按鈕 - 隱藏時間戳記按鈕 - 時間戳記按鈕已隱藏 - 時間戳記按鈕已顯示 隱藏留言預覽 已隱藏留言預覽 已顯示留言預覽 隱藏「感謝」按鈕 已隱藏「感謝」按鈕 已顯示「感謝」按鈕 + 隱藏時間戳記按鈕 + 時間戳記按鈕已隱藏 + 時間戳記按鈕已顯示 隱藏 YouTube Doodles 已隱藏位於搜尋列的 Doodles @@ -377,32 +377,29 @@ Second \"item\" text" 關鍵字將隱藏所有影片:%s - 隱藏一般廣告 - 已隱藏一般廣告 - 已顯示一般廣告 + 隱藏片尾商店橫幅 + 已隱藏商店橫幅 + 已顯示商店橫幅 隱藏全螢幕廣告 "已隱藏全螢幕廣告 此功能僅適用於舊版裝置" 已顯示全螢幕廣告 + + 只能在舊裝置上使用隱藏全螢幕廣告 + 隱藏一般廣告 + 已隱藏一般廣告 + 已顯示一般廣告 + 隱藏商品橫幅 + 已隱藏商品橫幅 + 已顯示商品橫幅 隱藏付費推廣標籤 已隱藏付費推廣標籤 已顯示付費推廣標籤 + 隱藏自我贊助資訊卡 已隱藏自我贊助資訊卡 已顯示自我贊助資訊卡 - 隱藏「查看商品」橫幅 - 已隱藏橫幅 - 已顯示橫幅 - 隱藏片尾商店橫幅 - 已隱藏商店橫幅 - 已顯示商店橫幅 - 隱藏播放器購物區塊 - 已隱藏購物區塊 - 已顯示購物區塊 - 隱藏購物連結 - 已隱藏影片說明中的購物連結 - 已顯示影片說明中的購物連結 隱藏「造訪商店」按鈕 已隱藏頻道頁面中的按鈕 @@ -410,11 +407,6 @@ Second \"item\" text" 隱藏網頁搜尋結果 已隱藏網頁搜尋結果 已顯示網頁搜尋結果 - 隱藏商品橫幅 - 已隱藏商品橫幅 - 已顯示商品橫幅 - - 只能在舊裝置上使用隱藏全螢幕廣告 隱藏 YouTube Premium 促銷內容 @@ -826,7 +818,6 @@ Second \"item\" text" 隱藏聲音中繼資料標籤 已隱藏中繼資料標籤 已顯示中繼資料標籤 - 隱藏完整影片連結標籤 已隱藏影片連結標籤 已顯示影片連結標籤 隱藏「音效」按鈕 diff --git a/patches/src/main/resources/addresources/values-zu-rZA/strings.xml b/patches/src/main/resources/addresources/values-zu-rZA/strings.xml index af2c63ca8..f35ee40ba 100644 --- a/patches/src/main/resources/addresources/values-zu-rZA/strings.xml +++ b/patches/src/main/resources/addresources/values-zu-rZA/strings.xml @@ -55,8 +55,9 @@ Second \"item\" text" - + + From 209a3a36265880436cc3729d9775b5f7dabb7597 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:36:08 +0400 Subject: [PATCH 22/33] fix(YouTube - SponsorBlock): Do not show undo skip if PiP is active (#5314) --- .../SegmentPlaybackController.java | 42 +++++++++++++++---- .../resources/addresources/values/strings.xml | 4 +- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SegmentPlaybackController.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SegmentPlaybackController.java index b279de71b..86a7d200e 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SegmentPlaybackController.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/SegmentPlaybackController.java @@ -44,6 +44,7 @@ import app.revanced.extension.youtube.sponsorblock.objects.SegmentCategory; import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment; import app.revanced.extension.youtube.sponsorblock.requests.SBRequester; import app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockViewController; +import kotlin.Unit; /** * Handles showing, scheduling, and skipping of all {@link SponsorSegment} for the current video. @@ -167,6 +168,30 @@ public class SegmentPlaybackController { */ private static WeakReference toastDialogRef = new WeakReference<>(null); + static { + // Dismiss toast if app changes to PiP while undo skip is shown. + PlayerType.getOnChange().addObserver((PlayerType type) -> { + if (type == PlayerType.WATCH_WHILE_PICTURE_IN_PICTURE && dismissUndoToast()) { + Logger.printDebug(() -> "Dismissed undo toast as playback is PiP"); + } + + return Unit.INSTANCE; + }); + } + + /** + * @return If the toast was on screen and is now dismissed. + */ + private static boolean dismissUndoToast() { + Dialog toastDialog = toastDialogRef.get(); + if (toastDialog != null && toastDialog.isShowing()) { + toastDialog.dismiss(); + return true; + } + + return false; + } + /** * @return The adjusted duration to show the skip button, in milliseconds. */ @@ -700,6 +725,11 @@ public class SegmentPlaybackController { return; } + if (PlayerType.getCurrent() == PlayerType.WATCH_WHILE_PICTURE_IN_PICTURE) { + Logger.printDebug(() -> "Not showing autoskip toast as playback is PiP"); + return; + } + if (toastSegmentSkipped == null || undoAutoSkipRangeToast == null) { // Video was changed immediately after skipping segment. Logger.printDebug(() -> "Ignoring old scheduled show toast"); @@ -709,9 +739,7 @@ public class SegmentPlaybackController { ? toastSegmentSkipped.getSkippedToastText() : str("revanced_sb_skipped_multiple_segments"); - showToastShortWithTapAction(message, undoAutoSkipRangeToast); - } catch (Exception ex) { - Logger.printException(() -> "showSkippedSegmentToast failure", ex); + showAutoSkipToast(message, undoAutoSkipRangeToast); } finally { toastNumberOfSegmentsSkipped = 0; toastSegmentSkipped = null; @@ -719,7 +747,7 @@ public class SegmentPlaybackController { }, delayToToastMilliseconds); } - private static void showToastShortWithTapAction(String messageToToast, Range rangeToUndo) { + private static void showAutoSkipToast(String messageToToast, Range rangeToUndo) { Objects.requireNonNull(messageToToast); Utils.verifyOnMainThread(); @@ -816,10 +844,8 @@ public class SegmentPlaybackController { window.addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH); } - Dialog priorDialog = toastDialogRef.get(); - if (priorDialog != null && priorDialog.isShowing()) { - Logger.printDebug(() -> "Removing previous skip toast that is still on screen: " + priorDialog); - priorDialog.dismiss(); + if (dismissUndoToast()) { + Logger.printDebug(() -> "Dismissed previous skip toast that was still on screen"); } toastDialogRef = new WeakReference<>(dialog); diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index d8c18f4b1..722bb5192 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1029,12 +1029,12 @@ This feature works best with a video quality of 720p or lower and when using a v Skip button hides after a few seconds Skip button is shown for the entire segment Skip button duration - How long the auto hide skip and skip to highlight buttons are shown + How long to show the skip and skip to highlight buttons before automatically hiding Show undo skip toast Toast is shown when a segment is automatically skipped. Tap the toast notification to undo the skip Toast is not shown Skip toast duration - How long the skip toast notification is shown + How long to show the undo skip toast 1 second 2 seconds 3 seconds From 5ed07d4aaad3ccb21d5932ef836a7103f5fdd2b3 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 1 Jul 2025 17:40:13 +0000 Subject: [PATCH 23/33] chore: Release v5.30.0-dev.6 [skip ci] # [5.30.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.5...v5.30.0-dev.6) (2025-07-01) ### Bug Fixes * **YouTube - SponsorBlock:** Do not show undo skip if PiP is active ([#5314](https://github.com/ReVanced/revanced-patches/issues/5314)) ([209a3a3](https://github.com/ReVanced/revanced-patches/commit/209a3a36265880436cc3729d9775b5f7dabb7597)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5be45fb4..10863bcf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.5...v5.30.0-dev.6) (2025-07-01) + + +### Bug Fixes + +* **YouTube - SponsorBlock:** Do not show undo skip if PiP is active ([#5314](https://github.com/ReVanced/revanced-patches/issues/5314)) ([18af8de](https://github.com/ReVanced/revanced-patches/commit/18af8dead2c6c7f0d99cd75b69948240e0bcd12c)) + # [5.30.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.4...v5.30.0-dev.5) (2025-06-30) diff --git a/gradle.properties b/gradle.properties index 46b74feb0..db37c4fbc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.5 +version = 5.30.0-dev.6 From d3ec219a29b7fe60f60bbd6397812d45b51b96af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 22:54:09 +0400 Subject: [PATCH 24/33] chore(deps-dev): bump semantic-release from 24.2.5 to 24.2.6 (#5317) --- package-lock.json | 1318 ++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 717 insertions(+), 603 deletions(-) diff --git a/package-lock.json b/package-lock.json index 80bae02a9..326563459 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", "gradle-semantic-release-plugin": "^1.10.1", - "semantic-release": "^24.2.5" + "semantic-release": "^24.2.6" } }, "node_modules/@babel/code-frame": { @@ -1485,11 +1485,10 @@ } }, "node_modules/@semantic-release/npm": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.1.tgz", - "integrity": "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.2.tgz", + "integrity": "sha512-+M9/Lb35IgnlUO6OSJ40Ie+hUsZLuph2fqXC/qrKn0fMvUU/jiCjpoL6zEm69vzcmaZJ8yNKtMBEKHWN49WBbQ==", "dev": true, - "license": "MIT", "dependencies": { "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", @@ -1498,7 +1497,7 @@ "lodash-es": "^4.17.21", "nerf-dart": "^1.0.0", "normalize-url": "^8.0.0", - "npm": "^10.5.0", + "npm": "^10.9.3", "rc": "^1.2.8", "read-pkg": "^9.0.0", "registry-auth-token": "^5.0.0", @@ -1517,7 +1516,6 @@ "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" } @@ -1527,7 +1525,6 @@ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -1540,7 +1537,6 @@ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, - "license": "MIT", "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" @@ -1557,7 +1553,6 @@ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, - "license": "MIT", "dependencies": { "escape-string-regexp": "5.0.0" }, @@ -1573,7 +1568,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -1582,24 +1576,23 @@ } }, "node_modules/@semantic-release/npm/node_modules/execa": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.4.0.tgz", - "integrity": "sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", + "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", "dev": true, - "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", - "human-signals": "^8.0.0", + "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", - "pretty-ms": "^9.0.0", + "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.0.0" + "yoctocolors": "^2.1.1" }, "engines": { "node": "^18.19.0 || >=20.5.0" @@ -1613,7 +1606,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, - "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" @@ -1626,11 +1618,10 @@ } }, "node_modules/@semantic-release/npm/node_modules/human-signals": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", - "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=18.18.0" } @@ -1640,7 +1631,6 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -1653,7 +1643,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -1666,7 +1655,6 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" @@ -1683,7 +1671,6 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -1696,7 +1683,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "ISC", "engines": { "node": ">=14" }, @@ -1709,7 +1695,6 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -1722,7 +1707,6 @@ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -2256,11 +2240,10 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3678,9 +3661,9 @@ } }, "node_modules/npm": { - "version": "10.8.3", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.3.tgz", - "integrity": "sha512-0IQlyAYvVtQ7uOhDFYZCGK8kkut2nh8cpAdA9E6FvRSJaTgtZRZgNjlC5ZCct//L73ygrpY93CxXpRJDtNqPVg==", + "version": "10.9.3", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.3.tgz", + "integrity": "sha512-6Eh1u5Q+kIVXeA8e7l2c/HpnFFcwrkt37xDMujD5be1gloWa9p6j3Fsv3mByXXmqJHy+2cElRMML8opNT7xIJQ==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -3752,83 +3735,75 @@ "write-file-atomic" ], "dev": true, - "license": "Artistic-2.0", - "workspaces": [ - "docs", - "smoke-tests", - "mock-globals", - "mock-registry", - "workspaces/*" - ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.5.4", - "@npmcli/config": "^8.3.4", - "@npmcli/fs": "^3.1.1", - "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.2.0", - "@npmcli/promise-spawn": "^7.0.2", - "@npmcli/redact": "^2.0.1", - "@npmcli/run-script": "^8.1.0", - "@sigstore/tuf": "^2.3.4", - "abbrev": "^2.0.0", + "@npmcli/arborist": "^8.0.1", + "@npmcli/config": "^9.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/map-workspaces": "^4.0.2", + "@npmcli/package-json": "^6.2.0", + "@npmcli/promise-spawn": "^8.0.2", + "@npmcli/redact": "^3.2.2", + "@npmcli/run-script": "^9.1.0", + "@sigstore/tuf": "^3.1.1", + "abbrev": "^3.0.1", "archy": "~1.0.0", - "cacache": "^18.0.4", - "chalk": "^5.3.0", - "ci-info": "^4.0.0", + "cacache": "^19.0.1", + "chalk": "^5.4.1", + "ci-info": "^4.2.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^10.4.5", "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.2", - "ini": "^4.1.3", - "init-package-json": "^6.0.3", - "is-cidr": "^5.1.0", - "json-parse-even-better-errors": "^3.0.2", - "libnpmaccess": "^8.0.6", - "libnpmdiff": "^6.1.4", - "libnpmexec": "^8.1.4", - "libnpmfund": "^5.0.12", - "libnpmhook": "^10.0.5", - "libnpmorg": "^6.0.6", - "libnpmpack": "^7.0.4", - "libnpmpublish": "^9.0.9", - "libnpmsearch": "^7.0.6", - "libnpmteam": "^6.0.5", - "libnpmversion": "^6.0.3", - "make-fetch-happen": "^13.0.1", + "hosted-git-info": "^8.1.0", + "ini": "^5.0.0", + "init-package-json": "^7.0.2", + "is-cidr": "^5.1.1", + "json-parse-even-better-errors": "^4.0.0", + "libnpmaccess": "^9.0.0", + "libnpmdiff": "^7.0.1", + "libnpmexec": "^9.0.1", + "libnpmfund": "^6.0.1", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.1", + "libnpmpublish": "^10.0.1", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.3", "minimatch": "^9.0.5", "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.2.0", - "nopt": "^7.2.1", - "normalize-package-data": "^6.0.2", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.3", - "npm-pick-manifest": "^9.1.0", - "npm-profile": "^10.0.0", - "npm-registry-fetch": "^17.1.0", - "npm-user-validate": "^2.0.1", - "p-map": "^4.0.0", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.1", - "proc-log": "^4.2.0", + "node-gyp": "^11.2.0", + "nopt": "^8.1.0", + "normalize-package-data": "^7.0.0", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.1", + "npm-package-arg": "^12.0.2", + "npm-pick-manifest": "^10.0.0", + "npm-profile": "^11.0.1", + "npm-registry-fetch": "^18.0.2", + "npm-user-validate": "^3.0.0", + "p-map": "^7.0.3", + "pacote": "^19.0.1", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", - "read": "^3.0.1", - "semver": "^7.6.3", + "read": "^4.1.0", + "semver": "^7.7.2", "spdx-expression-parse": "^4.0.0", - "ssri": "^10.0.6", + "ssri": "^12.0.0", "supports-color": "^9.4.0", "tar": "^6.2.1", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.1", - "which": "^4.0.0", - "write-file-atomic": "^5.0.1" + "validate-npm-package-name": "^6.0.1", + "which": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "bin": { "npm": "bin/npm-cli.js", @@ -3869,7 +3844,7 @@ } }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -3918,6 +3893,18 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { "version": "1.1.0", "dev": true, @@ -3925,7 +3912,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.2", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -3937,48 +3924,48 @@ "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.5.4", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.1", - "@npmcli/installed-package-contents": "^2.1.0", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.1.1", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.1.0", - "@npmcli/query": "^3.1.0", - "@npmcli/redact": "^2.0.0", - "@npmcli/run-script": "^8.1.0", - "bin-links": "^4.0.4", - "cacache": "^18.0.3", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^8.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.2", - "json-parse-even-better-errors": "^3.0.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", "json-stringify-nice": "^1.1.4", "lru-cache": "^10.2.2", "minimatch": "^9.0.4", - "nopt": "^7.2.1", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.2", - "npm-pick-manifest": "^9.0.1", - "npm-registry-fetch": "^17.0.1", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.0", - "proc-log": "^4.2.0", - "proggy": "^2.0.0", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", - "ssri": "^10.0.6", + "ssri": "^12.0.0", "treeverse": "^3.0.0", "walk-up-path": "^3.0.1" }, @@ -3986,30 +3973,30 @@ "arborist": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.3.4", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/package-json": "^5.1.1", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", "ci-info": "^4.0.0", - "ini": "^4.1.2", - "nopt": "^7.2.1", - "proc-log": "^4.2.0", + "ini": "^5.0.0", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", "walk-up-path": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/fs": { - "version": "3.1.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -4017,160 +4004,190 @@ "semver": "^7.3.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.8", + "version": "6.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "ini": "^4.1.3", + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^4.0.0", - "promise-inflight": "^1.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "semver": "^7.3.5", - "which": "^4.0.0" + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.1.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "bin": { "installed-package-contents": "bin/index.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.6", + "version": "4.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" + "minimatch": "^9.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.1.1", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^18.0.0", - "proc-log": "^4.1.0", + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^20.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", + "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { + "version": "20.0.0", "dev": true, "inBundle": true, "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@npmcli/node-gyp": { + "node_modules/npm/node_modules/@npmcli/name-from-folder": { "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.2.0", + "version": "6.2.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", + "@npmcli/git": "^6.0.0", "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^4.0.0", - "semver": "^7.5.3" + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "7.0.2", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "which": "^4.0.0" + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.1.0", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "2.0.1", + "version": "3.2.2", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "8.1.0", + "version": "9.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "proc-log": "^4.0.0", - "which": "^4.0.0" + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@pkgjs/parseargs": { @@ -4183,78 +4200,26 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.3.2", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/core": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.3.2", + "version": "0.4.3", "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.3.2", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^13.0.1", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.3.4", + "version": "3.1.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2", - "tuf-js": "^2.2.1" + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/verify": { - "version": "1.2.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@tufjs/canonical-json": { @@ -4266,53 +4231,24 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/@tufjs/models": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/abbrev": { - "version": "2.0.0", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/agent-base": { - "version": "7.1.1", + "version": "7.1.3", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, "engines": { "node": ">= 14" } }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/ansi-regex": { "version": "5.0.1", "dev": true, @@ -4353,18 +4289,19 @@ "license": "MIT" }, "node_modules/npm/node_modules/bin-links": { - "version": "4.0.4", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/binary-extensions": { @@ -4380,7 +4317,7 @@ } }, "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "MIT", @@ -4389,12 +4326,12 @@ } }, "node_modules/npm/node_modules/cacache": { - "version": "18.0.4", + "version": "19.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/fs": "^3.1.0", + "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", @@ -4402,17 +4339,67 @@ "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, "node_modules/npm/node_modules/chalk": { - "version": "5.3.0", + "version": "5.4.1", "dev": true, "inBundle": true, "license": "MIT", @@ -4433,7 +4420,7 @@ } }, "node_modules/npm/node_modules/ci-info": { - "version": "4.0.0", + "version": "4.2.0", "dev": true, "funding": [ { @@ -4448,7 +4435,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.1.1", + "version": "4.1.3", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -4459,15 +4446,6 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/npm/node_modules/cli-columns": { "version": "4.0.0", "dev": true, @@ -4482,12 +4460,12 @@ } }, "node_modules/npm/node_modules/cmd-shim": { - "version": "6.0.3", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/color-convert": { @@ -4515,7 +4493,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", @@ -4556,12 +4534,12 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.6", + "version": "4.4.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -4572,12 +4550,6 @@ } } }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/diff": { "version": "5.2.0", "dev": true, @@ -4625,7 +4597,7 @@ "license": "MIT" }, "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.1", + "version": "3.1.2", "dev": true, "inBundle": true, "license": "Apache-2.0" @@ -4640,12 +4612,12 @@ } }, "node_modules/npm/node_modules/foreground-child": { - "version": "3.3.0", + "version": "3.3.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -4694,7 +4666,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "7.0.2", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -4702,11 +4674,11 @@ "lru-cache": "^10.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", + "version": "4.2.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause" @@ -4725,12 +4697,12 @@ } }, "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.5", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -4751,7 +4723,7 @@ } }, "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.5", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -4759,7 +4731,7 @@ "minimatch": "^9.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/imurmurhash": { @@ -4771,40 +4743,31 @@ "node": ">=0.8.19" } }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/ini": { - "version": "4.1.3", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.3", + "version": "7.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/package-json": "^5.0.0", - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^3.0.1", + "@npmcli/package-json": "^6.0.0", + "npm-package-arg": "^12.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/ip-address": { @@ -4833,7 +4796,7 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "5.1.0", + "version": "5.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -4853,12 +4816,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/isexe": { "version": "2.0.0", "dev": true, @@ -4887,12 +4844,12 @@ "license": "MIT" }, "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.2", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/json-stringify-nice": { @@ -4926,169 +4883,169 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.6", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1" + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.1.4", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/installed-package-contents": "^2.1.0", + "@npmcli/arborist": "^8.0.1", + "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", "tar": "^6.2.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "8.1.4", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/run-script": "^8.1.0", + "@npmcli/arborist": "^8.0.1", + "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6", - "proc-log": "^4.2.0", - "read": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "walk-up-path": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.12", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4" + "@npmcli/arborist": "^8.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.5", + "version": "11.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.6", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "7.0.4", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/run-script": "^8.1.0", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6" + "@npmcli/arborist": "^8.0.1", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.9", + "version": "10.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.1", - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.2.0", + "normalize-package-data": "^7.0.0", + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1", + "proc-log": "^5.0.0", "semver": "^7.3.7", - "sigstore": "^2.2.0", - "ssri": "^10.0.6" + "sigstore": "^3.0.0", + "ssri": "^12.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.6", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.5", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "6.0.3", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.7", - "@npmcli/run-script": "^8.1.0", - "json-parse-even-better-errors": "^3.0.2", - "proc-log": "^4.2.0", + "@npmcli/git": "^6.0.1", + "@npmcli/run-script": "^9.0.1", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.7" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/lru-cache": { @@ -5098,26 +5055,34 @@ "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.1", + "version": "14.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", + "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "ssri": "^10.0.0" + "ssri": "^12.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, "node_modules/npm/node_modules/minimatch": { @@ -5157,17 +5122,17 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "3.0.5", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "minizlib": "^3.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" }, "optionalDependencies": { "encoding": "^0.1.13" @@ -5246,28 +5211,15 @@ } }, "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": ">= 18" } }, "node_modules/npm/node_modules/mkdirp": { @@ -5289,99 +5241,140 @@ "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { - "version": "1.0.0", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.2.0", + "version": "11.2.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^4.1.0", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", - "tar": "^6.2.1", - "which": "^4.0.0" + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/nopt": { - "version": "7.2.1", + "node_modules/npm/node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "abbrev": "^2.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "8.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/normalize-package-data": { - "version": "6.0.2", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "hosted-git-info": "^7.0.0", + "hosted-git-info": "^8.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-audit-report": { - "version": "5.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-bundled": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-normalize-package-bin": "^3.0.0" + "npm-normalize-package-bin": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-install-checks": { - "version": "6.3.0", + "version": "7.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -5389,165 +5382,162 @@ "semver": "^7.1.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.3", + "version": "12.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.2", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^6.0.4" + "ignore-walk": "^7.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "9.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-profile": { "version": "10.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.0.0" + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" }, "engines": { - "node": ">=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "17.1.0", + "node_modules/npm/node_modules/npm-profile": { + "version": "11.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/redact": "^2.0.0", - "jsonparse": "^1.3.1", - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^4.0.0" + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "18.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-user-validate": { - "version": "2.0.1", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", + "version": "7.0.3", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm/node_modules/package-json-from-dist": { - "version": "1.0.0", + "version": "1.0.1", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0" }, "node_modules/npm/node_modules/pacote": { - "version": "18.0.6", + "version": "19.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/package-json": "^5.1.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^8.0.0", - "cacache": "^18.0.0", + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^17.0.0", - "proc-log": "^4.0.0", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "sigstore": "^2.2.0", - "ssri": "^10.0.0", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", "tar": "^6.1.11" }, "bin": { "pacote": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/parse-conflict-json": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", + "json-parse-even-better-errors": "^4.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/path-key": { @@ -5576,7 +5566,7 @@ } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "version": "7.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -5589,21 +5579,21 @@ } }, "node_modules/npm/node_modules/proc-log": { - "version": "4.2.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/proggy": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/promise-all-reject-late": { @@ -5616,7 +5606,7 @@ } }, "node_modules/npm/node_modules/promise-call-limit": { - "version": "3.0.1", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -5624,12 +5614,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/promise-retry": { "version": "2.0.1", "dev": true, @@ -5644,15 +5628,15 @@ } }, "node_modules/npm/node_modules/promzard": { - "version": "1.0.2", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "read": "^3.0.1" + "read": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/qrcode-terminal": { @@ -5664,37 +5648,37 @@ } }, "node_modules/npm/node_modules/read": { - "version": "3.0.1", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "mute-stream": "^1.0.0" + "mute-stream": "^2.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/read-cmd-shim": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/read-package-json-fast": { "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json-fast": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/retry": { @@ -5714,7 +5698,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.6.3", + "version": "7.7.2", "dev": true, "inBundle": true, "license": "ISC", @@ -5759,20 +5743,72 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "2.3.1", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^2.3.2", - "@sigstore/tuf": "^2.3.4", - "@sigstore/verify": "^1.2.1" + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/smart-buffer": { @@ -5786,7 +5822,7 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.3", + "version": "2.8.5", "dev": true, "inBundle": true, "license": "MIT", @@ -5800,12 +5836,12 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.4", + "version": "8.0.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -5850,7 +5886,7 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.18", + "version": "3.0.21", "dev": true, "inBundle": true, "license": "CC0-1.0" @@ -5862,7 +5898,7 @@ "license": "BSD-3-Clause" }, "node_modules/npm/node_modules/ssri": { - "version": "10.0.6", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -5870,7 +5906,7 @@ "minipass": "^7.0.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/string-width": { @@ -5989,6 +6025,31 @@ "node": ">=8" } }, + "node_modules/npm/node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/npm/node_modules/text-table": { "version": "0.2.0", "dev": true, @@ -6001,6 +6062,48 @@ "inBundle": true, "license": "MIT" }, + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.14", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/npm/node_modules/treeverse": { "version": "3.0.0", "dev": true, @@ -6011,33 +6114,46 @@ } }, "node_modules/npm/node_modules/tuf-js": { - "version": "2.2.1", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-filename": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "unique-slug": "^4.0.0" + "unique-slug": "^5.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-slug": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6045,7 +6161,7 @@ "imurmurhash": "^0.1.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/util-deprecate": { @@ -6075,12 +6191,12 @@ } }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "5.0.1", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/walk-up-path": { @@ -6090,7 +6206,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/which": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6101,7 +6217,7 @@ "node-which": "bin/which.js" }, "engines": { - "node": "^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/which/node_modules/isexe": { @@ -6164,7 +6280,7 @@ } }, "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -6214,7 +6330,7 @@ } }, "node_modules/npm/node_modules/write-file-atomic": { - "version": "5.0.1", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6223,7 +6339,7 @@ "signal-exit": "^4.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/yallist": { @@ -6517,11 +6633,10 @@ } }, "node_modules/pretty-ms": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz", - "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", "dev": true, - "license": "MIT", "dependencies": { "parse-ms": "^4.0.0" }, @@ -6774,16 +6889,15 @@ "license": "MIT" }, "node_modules/semantic-release": { - "version": "24.2.5", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.5.tgz", - "integrity": "sha512-9xV49HNY8C0/WmPWxTlaNleiXhWb//qfMzG2c5X8/k7tuWcu8RssbuS+sujb/h7PiWSXv53mrQvV9hrO9b7vuQ==", + "version": "24.2.6", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.6.tgz", + "integrity": "sha512-D0cwjlO5RZzHHxAcsoF1HxiRLfC3ehw+ay+zntzFs6PNX6aV0JzKNG15mpxPipBYa/l4fHly88dHvgDyqwb1Ww==", "dev": true, - "license": "MIT", "dependencies": { "@semantic-release/commit-analyzer": "^13.0.0-beta.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^11.0.0", - "@semantic-release/npm": "^12.0.0", + "@semantic-release/npm": "^12.0.2", "@semantic-release/release-notes-generator": "^14.0.0-beta.1", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", diff --git a/package.json b/package.json index 5c21bb60c..51374afe0 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,6 @@ "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", "gradle-semantic-release-plugin": "^1.10.1", - "semantic-release": "^24.2.5" + "semantic-release": "^24.2.6" } } From b2e601f0f08f6e1f2984cffe0ca912e56aaeb23d Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 1 Jul 2025 23:11:05 +0200 Subject: [PATCH 25/33] fix(Spotify - Spoof client): Handle remaining edge cases to obtain a session (#5285) Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com> --- .../misc/fix/LoginRequestListener.java | 61 ++--- .../extension/spotify/misc/fix/Session.java | 12 + .../spotify/misc/fix/SpoofClientPatch.java | 15 +- .../extension/spotify/misc/fix/WebApp.java | 213 ++++++++++-------- .../revanced/extension/spotify/UserAgent.g4 | 2 +- patches/api/patches.api | 8 +- .../misc/extension/SharedExtensionPatch.kt | 14 +- .../spotify/misc/extension/ExtensionPatch.kt | 6 +- .../spotify/misc/extension/Fingerprints.kt | 7 + .../patches/spotify/misc/extension/Hooks.kt | 20 ++ .../patches/spotify/misc/fix/Fingerprints.kt | 28 ++- .../spotify/misc/fix/SpoofClientPatch.kt | 29 ++- .../patches/spotify/shared/Fingerprints.kt | 16 +- 13 files changed, 262 insertions(+), 169 deletions(-) create mode 100644 patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/LoginRequestListener.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/LoginRequestListener.java index 613d82bbb..2a6107c31 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/LoginRequestListener.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/LoginRequestListener.java @@ -14,11 +14,19 @@ import java.io.IOException; import java.io.InputStream; import java.util.Objects; +import static app.revanced.extension.spotify.misc.fix.Session.FAILED_TO_RENEW_SESSION; import static fi.iki.elonen.NanoHTTPD.Response.Status.INTERNAL_ERROR; class LoginRequestListener extends NanoHTTPD { LoginRequestListener(int port) { super(port); + + try { + start(); + } catch (IOException ex) { + Logger.printException(() -> "Failed to start login request listener on port " + port, ex); + throw new RuntimeException(ex); + } } @NonNull @@ -31,8 +39,8 @@ class LoginRequestListener extends NanoHTTPD { LoginRequest loginRequest; try { loginRequest = LoginRequest.parseFrom(requestBodyInputStream); - } catch (IOException e) { - Logger.printException(() -> "Failed to parse LoginRequest", e); + } catch (IOException ex) { + Logger.printException(() -> "Failed to parse LoginRequest", ex); return newResponse(INTERNAL_ERROR); } @@ -42,52 +50,49 @@ class LoginRequestListener extends NanoHTTPD { // however a webview can only handle one request at a time due to singleton cookie manager. // Therefore, synchronize to ensure that only one webview handles the request at a time. synchronized (this) { - loginResponse = getLoginResponse(loginRequest); + try { + loginResponse = getLoginResponse(loginRequest); + } catch (Exception ex) { + Logger.printException(() -> "Failed to get login response", ex); + return newResponse(INTERNAL_ERROR); + } } - if (loginResponse != null) { - return newResponse(Response.Status.OK, loginResponse); - } - - return newResponse(INTERNAL_ERROR); + return newResponse(Response.Status.OK, loginResponse); } - @Nullable private static LoginResponse getLoginResponse(@NonNull LoginRequest loginRequest) { Session session; - boolean isInitialLogin = !loginRequest.hasStoredCredential(); - if (isInitialLogin) { + if (!loginRequest.hasStoredCredential()) { Logger.printInfo(() -> "Received request for initial login"); - session = WebApp.currentSession; // Session obtained from WebApp.login. + session = WebApp.currentSession; // Session obtained from WebApp.launchLogin, can be null if still in progress. } else { Logger.printInfo(() -> "Received request to restore saved session"); session = Session.read(loginRequest.getStoredCredential().getUsername()); } - return toLoginResponse(session, isInitialLogin); + return toLoginResponse(session); } - - private static LoginResponse toLoginResponse(Session session, boolean isInitialLogin) { + private static LoginResponse toLoginResponse(@Nullable Session session) { LoginResponse.Builder builder = LoginResponse.newBuilder(); if (session == null) { - if (isInitialLogin) { - Logger.printInfo(() -> "Session is null, returning try again later error for initial login"); - builder.setError(LoginError.TRY_AGAIN_LATER); - } else { - Logger.printInfo(() -> "Session is null, returning invalid credentials error for stored credential login"); - builder.setError(LoginError.INVALID_CREDENTIALS); - } - } else if (session.username == null) { - Logger.printInfo(() -> "Session username is null, returning invalid credentials error"); - builder.setError(LoginError.INVALID_CREDENTIALS); + Logger.printException(() -> "Session is null. An initial login may still be in progress, returning try again later error"); + builder.setError(LoginError.TRY_AGAIN_LATER); } else if (session.accessTokenExpired()) { - Logger.printInfo(() -> "Access token has expired, renewing session"); - WebApp.renewSession(session.cookies); - return toLoginResponse(WebApp.currentSession, isInitialLogin); + Logger.printInfo(() -> "Access token expired, renewing session"); + WebApp.renewSessionBlocking(session.cookies); + return toLoginResponse(WebApp.currentSession); + } else if (session.username == null) { + Logger.printException(() -> "Session username is null, likely caused by invalid cookies, returning invalid credentials error"); + session.delete(); + builder.setError(LoginError.INVALID_CREDENTIALS); + } else if (session == FAILED_TO_RENEW_SESSION) { + Logger.printException(() -> "Failed to renew session, likely caused by a timeout, returning try again later error"); + builder.setError(LoginError.TRY_AGAIN_LATER); } else { session.save(); Logger.printInfo(() -> "Returning session for username: " + session.username); diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/Session.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/Session.java index 6e7f38cde..0860253f6 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/Session.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/Session.java @@ -29,6 +29,11 @@ class Session { */ final String cookies; + /** + * Session that represents a failed attempt to renew the session. + */ + static final Session FAILED_TO_RENEW_SESSION = new Session("", "", ""); + /** * @param username Username of the account. Empty if this session does not have an authenticated user. * @param accessToken Access token for this session. @@ -87,6 +92,13 @@ class Session { editor.apply(); } + void delete() { + Logger.printInfo(() -> "Deleting saved session for username: " + username); + SharedPreferences.Editor editor = Utils.getContext().getSharedPreferences("revanced", MODE_PRIVATE).edit(); + editor.remove("session_" + username); + editor.apply(); + } + @Nullable static Session read(String username) { Logger.printInfo(() -> "Reading saved session for username: " + username); diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java index 8d01edaf7..28f0f0320 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java @@ -10,20 +10,19 @@ public class SpoofClientPatch { /** * Injection point. *
- * Start login server. + * Launch login server. */ - public static void listen(int port) { + public static void launchListener(int port) { if (listener != null) { Logger.printInfo(() -> "Listener already running on port " + port); return; } try { + Logger.printInfo(() -> "Launching listener on port " + port); listener = new LoginRequestListener(port); - listener.start(); - Logger.printInfo(() -> "Listener running on port " + port); } catch (Exception ex) { - Logger.printException(() -> "listen failure", ex); + Logger.printException(() -> "launchListener failure", ex); } } @@ -32,11 +31,11 @@ public class SpoofClientPatch { *
* Launch login web view. */ - public static void login(LayoutInflater inflater) { + public static void launchLogin(LayoutInflater inflater) { try { - WebApp.login(inflater.getContext()); + WebApp.launchLogin(inflater.getContext()); } catch (Exception ex) { - Logger.printException(() -> "login failure", ex); + Logger.printException(() -> "launchLogin failure", ex); } } } diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java index 082c7833f..3b78f75f2 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java @@ -5,135 +5,125 @@ import android.app.Dialog; import android.content.Context; import android.graphics.Bitmap; import android.os.Build; -import android.view.*; +import android.view.Window; +import android.view.WindowInsets; import android.webkit.*; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import app.revanced.extension.spotify.UserAgent; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import app.revanced.extension.shared.Logger; -import app.revanced.extension.shared.Utils; -import app.revanced.extension.spotify.UserAgent; +import static app.revanced.extension.spotify.misc.fix.Session.FAILED_TO_RENEW_SESSION; class WebApp { private static final String OPEN_SPOTIFY_COM = "open.spotify.com"; private static final String OPEN_SPOTIFY_COM_URL = "https://" + OPEN_SPOTIFY_COM; private static final String OPEN_SPOTIFY_COM_PREFERENCES_URL = OPEN_SPOTIFY_COM_URL + "/preferences"; - private static final String ACCOUNTS_SPOTIFY_COM_LOGIN_URL = "https://accounts.spotify.com/login?continue=" + - "https%3A%2F%2Fopen.spotify.com%2Fpreferences"; + private static final String ACCOUNTS_SPOTIFY_COM_LOGIN_URL = "https://accounts.spotify.com/login?allow_password=1" + + "&continue=https%3A%2F%2Fopen.spotify.com%2Fpreferences"; private static final int GET_SESSION_TIMEOUT_SECONDS = 10; private static final String JAVASCRIPT_INTERFACE_NAME = "androidInterface"; private static final String USER_AGENT = getWebUserAgent(); + /** + * A session obtained from the webview after logging in. + */ + @Nullable + static volatile Session currentSession = null; + /** * Current webview in use. Any use of the object must be done on the main thread. */ @SuppressLint("StaticFieldLeak") private static volatile WebView currentWebView; - /** - * A session obtained from the webview after logging in or renewing the session. - */ - @Nullable - static volatile Session currentSession; + static void launchLogin(Context context) { + final Dialog dialog = newDialog(context); - static void login(Context context) { - Logger.printInfo(() -> "Starting login"); + Utils.runOnBackgroundThread(() -> { + Logger.printInfo(() -> "Launching login"); - Dialog dialog = new Dialog(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen); - // Ensure that the keyboard does not cover the webview content. - Window window = dialog.getWindow(); - //noinspection StatementWithEmptyBody - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - window.getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { - v.setPadding(0, 0, 0, insets.getInsets(WindowInsets.Type.ime()).bottom); + // A session must be obtained from a login. Repeat until a session is acquired. + boolean isAcquired = false; + do { + CountDownLatch onLoggedInLatch = new CountDownLatch(1); + CountDownLatch getSessionLatch = new CountDownLatch(1); - return WindowInsets.CONSUMED; - }); - } else { - // TODO: Implement for lower Android versions. - } - - newWebView( // Can't use Utils.getContext() here, because autofill won't work. // See https://stackoverflow.com/a/79182053/11213244. - context, - new WebViewCallback() { + launchWebView(context, ACCOUNTS_SPOTIFY_COM_LOGIN_URL, new WebViewCallback() { @Override void onInitialized(WebView webView) { - // Ensure that cookies are cleared before loading the login page. - CookieManager.getInstance().removeAllCookies((anyRemoved) -> { - Logger.printInfo(() -> "Loading URL: " + ACCOUNTS_SPOTIFY_COM_LOGIN_URL); - webView.loadUrl(ACCOUNTS_SPOTIFY_COM_LOGIN_URL); - }); + super.onInitialized(webView); - dialog.setCancelable(false); dialog.setContentView(webView); dialog.show(); } @Override void onLoggedIn(String cookies) { - dialog.dismiss(); + onLoggedInLatch.countDown(); } @Override - void onReceivedSession(WebView webView, Session session) { - Logger.printInfo(() -> "Received session from login: " + session); - currentSession = session; - currentWebView = null; - webView.stopLoading(); - webView.destroy(); + void onReceivedSession(Session session) { + super.onReceivedSession(session); + + getSessionLatch.countDown(); + dialog.dismiss(); } + }); + + try { + // Wait indefinitely until the user logs in. + onLoggedInLatch.await(); + // Wait until the session is received, or timeout. + isAcquired = getSessionLatch.await(GET_SESSION_TIMEOUT_SECONDS, TimeUnit.SECONDS); + } catch (InterruptedException ex) { + Logger.printException(() -> "Login interrupted", ex); + Thread.currentThread().interrupt(); } - ); + } while (!isAcquired); + }); } - static void renewSession(String cookies) { + static void renewSessionBlocking(String cookies) { Logger.printInfo(() -> "Renewing session with cookies: " + cookies); CountDownLatch getSessionLatch = new CountDownLatch(1); - newWebView( - Utils.getContext(), - new WebViewCallback() { - @Override - public void onInitialized(WebView webView) { - Logger.printInfo(() -> "Loading URL: " + OPEN_SPOTIFY_COM_PREFERENCES_URL + - " with cookies: " + cookies); - setCookies(cookies); - webView.loadUrl(OPEN_SPOTIFY_COM_PREFERENCES_URL); - } - - @Override - public void onReceivedSession(WebView webView, Session session) { - Logger.printInfo(() -> "Received session: " + session); - currentSession = session; - getSessionLatch.countDown(); - currentWebView = null; - webView.stopLoading(); - webView.destroy(); - } - } - ); - - try { - final boolean isAcquired = getSessionLatch.await(GET_SESSION_TIMEOUT_SECONDS, TimeUnit.SECONDS); - if (!isAcquired) { - Logger.printException(() -> "Failed to retrieve session within " + GET_SESSION_TIMEOUT_SECONDS + " seconds"); + launchWebView(Utils.getContext(), OPEN_SPOTIFY_COM_PREFERENCES_URL, new WebViewCallback() { + @Override + public void onInitialized(WebView webView) { + setCookies(cookies); + super.onInitialized(webView); } - } catch (InterruptedException e) { - Logger.printException(() -> "Interrupted while waiting to retrieve session", e); + + public void onReceivedSession(Session session) { + super.onReceivedSession(session); + getSessionLatch.countDown(); + } + }); + + boolean isAcquired = false; + try { + isAcquired = getSessionLatch.await(GET_SESSION_TIMEOUT_SECONDS, TimeUnit.SECONDS); + } catch (InterruptedException ex) { + Logger.printException(() -> "Session renewal interrupted", ex); Thread.currentThread().interrupt(); } - // Cleanup. - currentWebView = null; + if (!isAcquired) { + Logger.printException(() -> "Failed to retrieve session within " + GET_SESSION_TIMEOUT_SECONDS + " seconds"); + currentSession = FAILED_TO_RENEW_SESSION; + destructWebView(); + } } /** @@ -141,36 +131,34 @@ class WebApp { */ abstract static class WebViewCallback { void onInitialized(WebView webView) { + currentWebView = webView; + currentSession = null; // Reset current session. } void onLoggedIn(String cookies) { } - void onReceivedSession(WebView webView, Session session) { + void onReceivedSession(Session session) { + Logger.printInfo(() -> "Received session: " + session); + currentSession = session; + + destructWebView(); } } @SuppressLint("SetJavaScriptEnabled") - private static void newWebView( + private static void launchWebView( Context context, + String initialUrl, WebViewCallback webViewCallback ) { Utils.runOnMainThreadNowOrLater(() -> { - WebView webView = currentWebView; - if (webView != null) { - // Old webview is still hanging around. - // Could happen if the network request failed and thus no callback is made. - // But in practice this never happens. - Logger.printException(() -> "Cleaning up prior webview"); - webView.stopLoading(); - webView.destroy(); - } - - webView = new WebView(context); + WebView webView = new WebView(context); WebSettings settings = webView.getSettings(); settings.setDomStorageEnabled(true); settings.setJavaScriptEnabled(true); settings.setUserAgentString(USER_AGENT); + // WebViewClient is always called off the main thread, // but callback interface methods are called on the main thread. webView.setWebViewClient(new WebViewClient() { @@ -209,31 +197,42 @@ class WebApp { " })" + " " + " }" + - "});"; + "});" + + "if (new URLSearchParams(window.location.search).get('_authfailed') != null) {" + + " " + JAVASCRIPT_INTERFACE_NAME + ".getSession(null, null);" + + "}"; view.evaluateJavascript(getSessionScript, null); } }); - final WebView callbackWebView = webView; webView.addJavascriptInterface(new Object() { @SuppressWarnings("unused") @JavascriptInterface public void getSession(String username, String accessToken) { Session session = new Session(username, accessToken, getCurrentCookies()); - Utils.runOnMainThread(() -> webViewCallback.onReceivedSession(callbackWebView, session)); + Utils.runOnMainThread(() -> webViewCallback.onReceivedSession(session)); } }, JAVASCRIPT_INTERFACE_NAME); - currentWebView = webView; - CookieManager.getInstance().removeAllCookies((anyRemoved) -> { + Logger.printInfo(() -> "Loading URL: " + initialUrl); + webView.loadUrl(initialUrl); + Logger.printInfo(() -> "WebView initialized with user agent: " + USER_AGENT); - webViewCallback.onInitialized(currentWebView); + webViewCallback.onInitialized(webView); }); }); } + private static void destructWebView() { + Utils.runOnMainThreadNowOrLater(() -> { + currentWebView.stopLoading(); + currentWebView.destroy(); + currentWebView = null; + }); + } + private static String getWebUserAgent() { String userAgentString = WebSettings.getDefaultUserAgent(Utils.getContext()); try { @@ -241,16 +240,36 @@ class WebApp { .withCommentReplaced("Android", "Windows NT 10.0; Win64; x64") .withoutProduct("Mobile") .toString(); - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException ex) { userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edge/137.0.0.0"; String fallback = userAgentString; - Logger.printException(() -> "Failed to get user agent, falling back to " + fallback, e); + Logger.printException(() -> "Failed to get user agent, falling back to " + fallback, ex); } return userAgentString; } + @NonNull + private static Dialog newDialog(Context context) { + Dialog dialog = new Dialog(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen); + dialog.setCancelable(false); + + // Ensure that the keyboard does not cover the webview content. + Window window = dialog.getWindow(); + //noinspection StatementWithEmptyBody + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + window.getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { + v.setPadding(0, 0, 0, insets.getInsets(WindowInsets.Type.ime()).bottom); + + return WindowInsets.CONSUMED; + }); + } else { + // TODO: Implement for lower Android versions. + } + return dialog; + } + private static String getCurrentCookies() { CookieManager cookieManager = CookieManager.getInstance(); return cookieManager.getCookie(OPEN_SPOTIFY_COM_URL); diff --git a/extensions/spotify/utils/src/main/antlr/app/revanced/extension/spotify/UserAgent.g4 b/extensions/spotify/utils/src/main/antlr/app/revanced/extension/spotify/UserAgent.g4 index afd3ba3f9..b46799359 100644 --- a/extensions/spotify/utils/src/main/antlr/app/revanced/extension/spotify/UserAgent.g4 +++ b/extensions/spotify/utils/src/main/antlr/app/revanced/extension/spotify/UserAgent.g4 @@ -32,4 +32,4 @@ STRING WS : [ \r\n]+ - ; \ No newline at end of file + ; diff --git a/patches/api/patches.api b/patches/api/patches.api index bbb98099c..aa2e2ece2 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -645,10 +645,10 @@ public final class app/revanced/patches/shared/misc/extension/ExtensionHook { } public final class app/revanced/patches/shared/misc/extension/SharedExtensionPatchKt { - public static final fun extensionHook (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lapp/revanced/patcher/Fingerprint;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; - public static final fun extensionHook (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; - public static synthetic fun extensionHook$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lapp/revanced/patcher/Fingerprint;ILjava/lang/Object;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; - public static synthetic fun extensionHook$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; + public static final fun extensionHook (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lapp/revanced/patcher/Fingerprint;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; + public static final fun extensionHook (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; + public static synthetic fun extensionHook$default (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lapp/revanced/patcher/Fingerprint;ILjava/lang/Object;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; + public static synthetic fun extensionHook$default (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; public static final fun sharedExtensionPatch (Ljava/lang/String;[Lapp/revanced/patches/shared/misc/extension/ExtensionHook;)Lapp/revanced/patcher/patch/BytecodePatch; public static final fun sharedExtensionPatch ([Lapp/revanced/patches/shared/misc/extension/ExtensionHook;)Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt index 129073b7d..e6d78b777 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt @@ -87,8 +87,8 @@ fun sharedExtensionPatch( class ExtensionHook internal constructor( internal val fingerprint: Fingerprint, - private val insertIndexResolver: ((Method) -> Int), - private val contextRegisterResolver: (Method) -> String, + private val insertIndexResolver: BytecodePatchContext.(Method) -> Int, + private val contextRegisterResolver: BytecodePatchContext.(Method) -> String, ) { context(BytecodePatchContext) operator fun invoke(extensionClassDescriptor: String) { @@ -98,19 +98,19 @@ class ExtensionHook internal constructor( fingerprint.method.addInstruction( insertIndex, "invoke-static/range { $contextRegister .. $contextRegister }, " + - "$extensionClassDescriptor->setContext(Landroid/content/Context;)V", + "$extensionClassDescriptor->setContext(Landroid/content/Context;)V", ) } } fun extensionHook( - insertIndexResolver: ((Method) -> Int) = { 0 }, - contextRegisterResolver: (Method) -> String = { "p0" }, + insertIndexResolver: BytecodePatchContext.(Method) -> Int = { 0 }, + contextRegisterResolver: BytecodePatchContext.(Method) -> String = { "p0" }, fingerprint: Fingerprint, ) = ExtensionHook(fingerprint, insertIndexResolver, contextRegisterResolver) fun extensionHook( - insertIndexResolver: ((Method) -> Int) = { 0 }, - contextRegisterResolver: (Method) -> String = { "p0" }, + insertIndexResolver: BytecodePatchContext.(Method) -> Int = { 0 }, + contextRegisterResolver: BytecodePatchContext.(Method) -> String = { "p0" }, fingerprintBuilderBlock: FingerprintBuilder.() -> Unit, ) = extensionHook(insertIndexResolver, contextRegisterResolver, fingerprint(block = fingerprintBuilderBlock)) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt index 048228871..070190a03 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt @@ -2,4 +2,8 @@ package app.revanced.patches.spotify.misc.extension import app.revanced.patches.shared.misc.extension.sharedExtensionPatch -val sharedExtensionPatch = sharedExtensionPatch("spotify", mainActivityOnCreateHook) +val sharedExtensionPatch = sharedExtensionPatch( + "spotify", + mainActivityOnCreateHook, + loadOrbitLibraryHook +) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt new file mode 100644 index 000000000..13b6094d3 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt @@ -0,0 +1,7 @@ +package app.revanced.patches.spotify.misc.extension + +import app.revanced.patcher.fingerprint + +internal val loadOrbitLibraryFingerprint = fingerprint { + strings("OrbitLibraryLoader", "cst") +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt index 6153f4b60..4bddc43b8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt @@ -1,6 +1,26 @@ package app.revanced.patches.spotify.misc.extension +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patches.shared.misc.extension.extensionHook import app.revanced.patches.spotify.shared.mainActivityOnCreateFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference internal val mainActivityOnCreateHook = extensionHook(fingerprint = mainActivityOnCreateFingerprint) + +internal val loadOrbitLibraryHook = extensionHook( + insertIndexResolver = { + loadOrbitLibraryFingerprint.stringMatches!!.last().index + }, + contextRegisterResolver = { method -> + val contextReferenceIndex = method.indexOfFirstInstruction { + getReference()?.type == "Landroid/content/Context;" + } + val contextRegister = method.getInstruction(contextReferenceIndex).registerA + + "v$contextRegister" + }, + fingerprint = loadOrbitLibraryFingerprint, +) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt index dff859cfb..c0eb72f62 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt @@ -1,7 +1,11 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.fingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val getPackageInfoFingerprint = fingerprint { strings( @@ -9,7 +13,7 @@ internal val getPackageInfoFingerprint = fingerprint { ) } -internal val startLiborbitFingerprint = fingerprint { +internal val loadOrbitLibraryFingerprint = fingerprint { strings("/liborbit-jni-spotify.so") } @@ -20,10 +24,22 @@ internal val startupPageLayoutInflateFingerprint = fingerprint { strings("blueprintContainer", "gradient", "valuePropositionTextView") } -internal val standardIntegrityTokenProviderBuilderFingerprint = fingerprint { - strings( - "standard_pi_init", - "outcome", - "success" +internal val runIntegrityVerificationFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + opcodes( + Opcode.CHECK_CAST, + Opcode.INVOKE_VIRTUAL, + Opcode.INVOKE_STATIC, // Calendar.getInstance() + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, // instance.get(6) + Opcode.MOVE_RESULT, + Opcode.IF_EQ, // if (x == instance.get(6)) return ) + custom { method, _ -> + method.indexOfFirstInstruction { + val reference = getReference() + reference?.definingClass == "Ljava/util/Calendar;" && reference.name == "get" + } >= 0 + } } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt index e34bcebaa..e476c8f5e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt @@ -24,8 +24,8 @@ val spoofClientPatch = bytecodePatch( name = "Spoof client", description = "Spoofs the client to fix various functions of the app.", ) { - val port by intOption( - key = "port", + val requestListenerPort by intOption( + key = "requestListenerPort", default = 4345, title = " Login request listener port", description = "The port to use for the listener that intercepts and handles login requests. " + @@ -46,10 +46,10 @@ val spoofClientPatch = bytecodePatch( "x86", "x86_64" ).forEach { architecture -> - "https://login5.spotify.com/v3/login" to "http://127.0.0.1:$port/v3/login" inFile + "https://login5.spotify.com/v3/login" to "http://127.0.0.1:$requestListenerPort/v3/login" inFile "lib/$architecture/liborbit-jni-spotify.so" - "https://login5.spotify.com/v4/login" to "http://127.0.0.1:$port/v4/login" inFile + "https://login5.spotify.com/v4/login" to "http://127.0.0.1:$requestListenerPort/v4/login" inFile "lib/$architecture/liborbit-jni-spotify.so" } }) @@ -58,6 +58,8 @@ val spoofClientPatch = bytecodePatch( compatibleWith("com.spotify.music") execute { + // region Spoof package info. + getPackageInfoFingerprint.method.apply { // region Spoof signature. @@ -99,28 +101,33 @@ val spoofClientPatch = bytecodePatch( // endregion } - startLiborbitFingerprint.method.addInstructions( + // endregion + + // region Spoof client. + + loadOrbitLibraryFingerprint.method.addInstructions( 0, """ - const/16 v0, $port - invoke-static { v0 }, $EXTENSION_CLASS_DESCRIPTOR->listen(I)V + const/16 v0, $requestListenerPort + invoke-static { v0 }, $EXTENSION_CLASS_DESCRIPTOR->launchListener(I)V """ ) startupPageLayoutInflateFingerprint.method.apply { val openLoginWebViewDescriptor = - "$EXTENSION_CLASS_DESCRIPTOR->login(Landroid/view/LayoutInflater;)V" + "$EXTENSION_CLASS_DESCRIPTOR->launchLogin(Landroid/view/LayoutInflater;)V" addInstructions( 0, """ - move-object/from16 v3, p1 - invoke-static { v3 }, $openLoginWebViewDescriptor + invoke-static/range { p1 .. p1 }, $openLoginWebViewDescriptor """ ) } // Early return to block sending bad verdicts to the API. - standardIntegrityTokenProviderBuilderFingerprint.method.returnEarly() + runIntegrityVerificationFingerprint.method.returnEarly() + + // endregion } } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt index b107fd267..cd3e3cf6b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.spotify.shared import app.revanced.patcher.fingerprint import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patches.spotify.misc.extension.mainActivityOnCreateHook +import com.android.tools.smali.dexlib2.AccessFlags private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivity;" @@ -12,6 +12,9 @@ private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivit internal const val SPOTIFY_MAIN_ACTIVITY_LEGACY = "Lcom/spotify/music/MainActivity;" internal val mainActivityOnCreateFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + parameters("Landroid/os/Bundle;") custom { method, classDef -> method.name == "onCreate" && (classDef.type == SPOTIFY_MAIN_ACTIVITY || classDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY) @@ -26,9 +29,10 @@ private var isLegacyAppTarget: Boolean? = null * supports Spotify integration on Kenwood/Pioneer car stereos. */ context(BytecodePatchContext) -internal val IS_SPOTIFY_LEGACY_APP_TARGET get(): Boolean { - if (isLegacyAppTarget == null) { - isLegacyAppTarget = mainActivityOnCreateHook.fingerprint.originalClassDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY +internal val IS_SPOTIFY_LEGACY_APP_TARGET + get(): Boolean { + if (isLegacyAppTarget == null) { + isLegacyAppTarget = mainActivityOnCreateFingerprint.originalClassDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY + } + return isLegacyAppTarget!! } - return isLegacyAppTarget!! -} From d3935f03c00e54e6c29ae645eeafe1ff26aa3a0d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 1 Jul 2025 21:15:22 +0000 Subject: [PATCH 26/33] chore: Release v5.30.0-dev.7 [skip ci] # [5.30.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.6...v5.30.0-dev.7) (2025-07-01) ### Bug Fixes * **Spotify - Spoof client:** Handle remaining edge cases to obtain a session ([#5285](https://github.com/ReVanced/revanced-patches/issues/5285)) ([b2e601f](https://github.com/ReVanced/revanced-patches/commit/b2e601f0f08f6e1f2984cffe0ca912e56aaeb23d)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10863bcf3..b5d95705e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.6...v5.30.0-dev.7) (2025-07-01) + + +### Bug Fixes + +* **Spotify - Spoof client:** Handle remaining edge cases to obtain a session ([#5285](https://github.com/ReVanced/revanced-patches/issues/5285)) ([2bb2d59](https://github.com/ReVanced/revanced-patches/commit/2bb2d594936093774e232ad8b274c81e805c5bf6)) + # [5.30.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.5...v5.30.0-dev.6) (2025-07-01) diff --git a/gradle.properties b/gradle.properties index db37c4fbc..0d69cb81a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.6 +version = 5.30.0-dev.7 From d7ed32571f9ad8eab77f49f683004583502ba41f Mon Sep 17 00:00:00 2001 From: brosssh <44944126+brosssh@users.noreply.github.com> Date: Wed, 2 Jul 2025 12:19:20 +0200 Subject: [PATCH 27/33] fix(Spotify - Spoof client): Skip native login screens (#5228) Co-authored-by: oSumAtrIX Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Co-authored-by: Dawid Krajcarz <80264606+drobotk@users.noreply.github.com> Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> --- .../spotify/misc/fix/SpoofClientPatch.java | 13 ++++ .../extension/spotify/misc/fix/WebApp.java | 15 +++- .../patches/spotify/misc/fix/Fingerprints.kt | 16 +++++ .../spotify/misc/fix/SpoofClientPatch.kt | 68 +++++++++++++++++-- 4 files changed, 105 insertions(+), 7 deletions(-) diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java index 28f0f0320..fb5e08113 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/SpoofClientPatch.java @@ -1,6 +1,7 @@ package app.revanced.extension.spotify.misc.fix; import android.view.LayoutInflater; +import android.view.View; import app.revanced.extension.shared.Logger; @SuppressWarnings("unused") @@ -38,4 +39,16 @@ public class SpoofClientPatch { Logger.printException(() -> "launchLogin failure", ex); } } + + /** + * Injection point. + *
+ * Set handler to call the native login after the webview login. + */ + public static void setNativeLoginHandler(View startLoginButton) { + WebApp.nativeLoginHandler = (() -> { + startLoginButton.setSoundEffectsEnabled(false); + startLoginButton.performClick(); + }); + } } diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java index 3b78f75f2..fd11ae7a8 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/fix/WebApp.java @@ -37,18 +37,23 @@ class WebApp { static volatile Session currentSession = null; /** - * Current webview in use. Any use of the object must be done on the main thread. + * Current webview in use. Any use of the object must be done on the main thread. */ @SuppressLint("StaticFieldLeak") private static volatile WebView currentWebView; + interface NativeLoginHandler { + void login(); + } + + static NativeLoginHandler nativeLoginHandler; + static void launchLogin(Context context) { final Dialog dialog = newDialog(context); Utils.runOnBackgroundThread(() -> { Logger.printInfo(() -> "Launching login"); - // A session must be obtained from a login. Repeat until a session is acquired. boolean isAcquired = false; do { @@ -77,6 +82,12 @@ class WebApp { getSessionLatch.countDown(); dialog.dismiss(); + + try { + nativeLoginHandler.login(); + } catch (Exception ex) { + Logger.printException(() -> "nativeLoginHandler failure", ex); + } } }); diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt index c0eb72f62..3cc57181b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt @@ -24,6 +24,22 @@ internal val startupPageLayoutInflateFingerprint = fingerprint { strings("blueprintContainer", "gradient", "valuePropositionTextView") } +internal val renderStartLoginScreenFingerprint = fingerprint { + strings("authenticationButtonFactory", "MORE_OPTIONS") +} + +internal val renderSecondLoginScreenFingerprint = fingerprint { + strings("authenticationButtonFactory", "intent_login") +} + +internal val renderThirdLoginScreenFingerprint = fingerprint { + strings("EMAIL_OR_USERNAME", "listener") +} + +internal val thirdLoginScreenLoginOnClickFingerprint = fingerprint { + strings("login", "listener", "none") +} + internal val runIntegrityVerificationFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt index e476c8f5e..c35dc1346 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofClientPatch.kt @@ -9,11 +9,9 @@ import app.revanced.patcher.patch.intOption import app.revanced.patches.shared.misc.hex.HexPatchBuilder import app.revanced.patches.shared.misc.hex.hexPatch import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch -import app.revanced.util.findInstructionIndicesReversedOrThrow -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionReversedOrThrow -import app.revanced.util.returnEarly +import app.revanced.util.* import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference @@ -119,12 +117,72 @@ val spoofClientPatch = bytecodePatch( addInstructions( 0, + "invoke-static/range { p1 .. p1 }, $openLoginWebViewDescriptor" + ) + } + + renderStartLoginScreenFingerprint.method.apply { + val onEventIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.INVOKE_INTERFACE && getReference()?.name == "getView" + } + + val buttonRegister = getInstruction(onEventIndex + 1).registerA + + addInstruction( + onEventIndex + 2, + "invoke-static { v$buttonRegister }, $EXTENSION_CLASS_DESCRIPTOR->setNativeLoginHandler(Landroid/view/View;)V" + ) + } + + renderSecondLoginScreenFingerprint.method.apply { + val getViewIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.INVOKE_INTERFACE && getReference()?.name == "getView" + } + + val buttonRegister = getInstruction(getViewIndex + 1).registerA + + // Early return the render for loop since the first item of the loop is the login button. + addInstructions( + getViewIndex + 2, """ - invoke-static/range { p1 .. p1 }, $openLoginWebViewDescriptor + invoke-virtual { v$buttonRegister }, Landroid/view/View;->performClick()Z + return-void """ ) } + renderThirdLoginScreenFingerprint.method.apply { + val invokeSetListenerIndex = indexOfFirstInstructionOrThrow { + val reference = getReference() + reference?.definingClass == "Landroid/view/View;" && reference.name == "setOnClickListener" + } + + val buttonRegister = getInstruction(invokeSetListenerIndex).registerC + + addInstruction( + invokeSetListenerIndex + 1, + "invoke-virtual { v$buttonRegister }, Landroid/view/View;->performClick()Z" + ) + } + + thirdLoginScreenLoginOnClickFingerprint.method.apply { + // Use placeholder credentials to pass the login screen. + val loginActionIndex = indexOfFirstInstructionOrThrow(Opcode.RETURN_VOID) - 1 + val loginActionInstruction = getInstruction(loginActionIndex) + + addInstructions( + loginActionIndex, + """ + const-string v${loginActionInstruction.registerD}, "placeholder" + const-string v${loginActionInstruction.registerE}, "placeholder" + """ + ) + } + + // endregion + + // region Disable verdicts. + // Early return to block sending bad verdicts to the API. runIntegrityVerificationFingerprint.method.returnEarly() From d3c9dc6ed732e06dfebae75da3241c799c0258ac Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 2 Jul 2025 10:23:13 +0000 Subject: [PATCH 28/33] chore: Release v5.30.0-dev.8 [skip ci] # [5.30.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.7...v5.30.0-dev.8) (2025-07-02) ### Bug Fixes * **Spotify - Spoof client:** Skip native login screens ([#5228](https://github.com/ReVanced/revanced-patches/issues/5228)) ([d7ed325](https://github.com/ReVanced/revanced-patches/commit/d7ed32571f9ad8eab77f49f683004583502ba41f)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d95705e..9cbcc92e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.7...v5.30.0-dev.8) (2025-07-02) + + +### Bug Fixes + +* **Spotify - Spoof client:** Skip native login screens ([#5228](https://github.com/ReVanced/revanced-patches/issues/5228)) ([c5ebc63](https://github.com/ReVanced/revanced-patches/commit/c5ebc6336ed17cc9cc7f1348282a2aa3c173fb95)) + # [5.30.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.6...v5.30.0-dev.7) (2025-07-01) diff --git a/gradle.properties b/gradle.properties index 0d69cb81a..a1ea8564b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.7 +version = 5.30.0-dev.8 From 8b9e04475d68cdba5e5cc80edba0833baf932584 Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Wed, 2 Jul 2025 09:08:11 -0300 Subject: [PATCH 29/33] fix(Spotify - Unlock Premium): Fix hiding context menu ads on newest versions (#5318) Co-authored-by: oSumAtrIX --- .../revanced/ContextMenuItemPlaceholder.java | 5 ++++ .../patches/spotify/misc/Fingerprints.kt | 29 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 extensions/spotify/stub/src/main/java/app/revanced/ContextMenuItemPlaceholder.java diff --git a/extensions/spotify/stub/src/main/java/app/revanced/ContextMenuItemPlaceholder.java b/extensions/spotify/stub/src/main/java/app/revanced/ContextMenuItemPlaceholder.java new file mode 100644 index 000000000..404be907c --- /dev/null +++ b/extensions/spotify/stub/src/main/java/app/revanced/ContextMenuItemPlaceholder.java @@ -0,0 +1,5 @@ +package app.revanced; + +public interface ContextMenuItemPlaceholder { + Object getViewModel(); +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt index 3ac589fc8..1d42c29de 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt @@ -42,7 +42,10 @@ internal val contextMenuViewModelClassFingerprint = fingerprint { strings("ContextMenuViewModel(header=") } -internal val contextMenuViewModelAddItemFingerprint = fingerprint { +/** + * Used in versions older than "9.0.60.128". + */ +internal val oldContextMenuViewModelAddItemFingerprint = fingerprint { parameters("L") returns("V") custom { method, _ -> @@ -52,6 +55,28 @@ internal val contextMenuViewModelAddItemFingerprint = fingerprint { } } +internal val contextMenuViewModelConstructorFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) + parameters("L", "Z", "Ljava/util/List;") +} + +/** + * Used to find the interface name of a context menu item. + */ +internal val browsePodcastsContextMenuItemClassFingerprint = fingerprint { + strings("browse_podcast_item", "ui_navigate") +} + +internal const val CONTEXT_MENU_ITEM_PLACEHOLDER_CLASS_NAME = "Lapp/revanced/ContextMenuItemPlaceholder;" +internal val extensionFilterContextMenuItemsFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) + returns("Ljava/util/List;") + parameters("Ljava/util/List;") + custom { method, classDef -> + method.name == "filterContextMenuItems" && classDef.type == EXTENSION_CLASS_DESCRIPTOR + } +} + internal val getViewModelFingerprint = fingerprint { custom { method, _ -> method.name == "getViewModel" } } @@ -93,7 +118,7 @@ internal val abstractProtobufListEnsureIsMutableFingerprint = fingerprint { } } -private fun structureGetSectionsFingerprint(className: String) = fingerprint { +internal fun structureGetSectionsFingerprint(className: String) = fingerprint { custom { method, classDef -> classDef.endsWith(className) && method.indexOfFirstInstruction { opcode == Opcode.IGET_OBJECT && getReference()?.name == "sections_" From 11338008c694926998191413662c9eb970be1f27 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 2 Jul 2025 12:12:04 +0000 Subject: [PATCH 30/33] chore: Release v5.30.0-dev.9 [skip ci] # [5.30.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.8...v5.30.0-dev.9) (2025-07-02) ### Bug Fixes * **Spotify - Unlock Premium:** Fix hiding context menu ads on newest versions ([#5318](https://github.com/ReVanced/revanced-patches/issues/5318)) ([8b9e044](https://github.com/ReVanced/revanced-patches/commit/8b9e04475d68cdba5e5cc80edba0833baf932584)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cbcc92e0..e17175f9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.8...v5.30.0-dev.9) (2025-07-02) + + +### Bug Fixes + +* **Spotify - Unlock Premium:** Fix hiding context menu ads on newest versions ([#5318](https://github.com/ReVanced/revanced-patches/issues/5318)) ([73fd832](https://github.com/ReVanced/revanced-patches/commit/73fd83222e089a5fd6e1526e5c12f5a1e9893a35)) + # [5.30.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.7...v5.30.0-dev.8) (2025-07-02) diff --git a/gradle.properties b/gradle.properties index a1ea8564b..5464ef07d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.8 +version = 5.30.0-dev.9 From d1313e3ea14c834c8d4114d9bab44d8de76fd37f Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Wed, 2 Jul 2025 16:04:26 +0200 Subject: [PATCH 31/33] fix(Spotify - Unlock Premium): Fix hiding context menu ads on newest versions by simplifying fingerprint (#5318) --- .../kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt index 1d42c29de..54cc0c661 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt @@ -57,7 +57,6 @@ internal val oldContextMenuViewModelAddItemFingerprint = fingerprint { internal val contextMenuViewModelConstructorFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - parameters("L", "Z", "Ljava/util/List;") } /** @@ -67,7 +66,7 @@ internal val browsePodcastsContextMenuItemClassFingerprint = fingerprint { strings("browse_podcast_item", "ui_navigate") } -internal const val CONTEXT_MENU_ITEM_PLACEHOLDER_CLASS_NAME = "Lapp/revanced/ContextMenuItemPlaceholder;" +internal const val CONTEXT_MENU_ITEM_CLASS_DESCRIPTOR_PLACEHOLDER = "Lapp/revanced/ContextMenuItemPlaceholder;" internal val extensionFilterContextMenuItemsFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Ljava/util/List;") @@ -134,7 +133,7 @@ internal val homeStructureGetSectionsFingerprint = structureGetSectionsFingerprint("homeapi/proto/HomeStructure;") internal val browseSectionFingerprint = fingerprint { - custom { _, classDef -> classDef.endsWith("browsita/v1/resolved/Section;") } + custom { _, classDef-> classDef.endsWith("browsita/v1/resolved/Section;") } } internal val browseStructureGetSectionsFingerprint = From a354c443ad8ce7d4f25af83a2a1e898d59a11882 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 2 Jul 2025 14:08:17 +0000 Subject: [PATCH 32/33] chore: Release v5.30.0-dev.10 [skip ci] # [5.30.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.9...v5.30.0-dev.10) (2025-07-02) ### Bug Fixes * **Spotify - Unlock Premium:** Fix hiding context menu ads on newest versions by simplifying fingerprint ([#5318](https://github.com/ReVanced/revanced-patches/issues/5318)) ([d1313e3](https://github.com/ReVanced/revanced-patches/commit/d1313e3ea14c834c8d4114d9bab44d8de76fd37f)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e17175f9e..64d296261 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.30.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.9...v5.30.0-dev.10) (2025-07-02) + + +### Bug Fixes + +* **Spotify - Unlock Premium:** Fix hiding context menu ads on newest versions by simplifying fingerprint ([#5318](https://github.com/ReVanced/revanced-patches/issues/5318)) ([dad0ff4](https://github.com/ReVanced/revanced-patches/commit/dad0ff4fba74c2b020fbde6c6d5eb66e10e6f1f7)) + # [5.30.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.30.0-dev.8...v5.30.0-dev.9) (2025-07-02) diff --git a/gradle.properties b/gradle.properties index 5464ef07d..d18a5bd51 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.30.0-dev.9 +version = 5.30.0-dev.10 From b4005079e3cc2c2309c9d624134b998d5b3cdda4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Jul 2025 18:21:04 +0400 Subject: [PATCH 33/33] chore: Sync translations (#5322) --- .../addresources/values-ar-rSA/strings.xml | 4 +-- .../addresources/values-be-rBY/strings.xml | 4 +-- .../addresources/values-bg-rBG/strings.xml | 4 +-- .../addresources/values-bn-rBD/strings.xml | 4 +-- .../addresources/values-cs-rCZ/strings.xml | 4 +-- .../addresources/values-da-rDK/strings.xml | 4 +-- .../addresources/values-de-rDE/strings.xml | 4 +-- .../addresources/values-el-rGR/strings.xml | 2 +- .../addresources/values-es-rES/strings.xml | 4 +-- .../addresources/values-et-rEE/strings.xml | 4 +-- .../addresources/values-fi-rFI/strings.xml | 10 +++++-- .../addresources/values-fil-rPH/strings.xml | 4 +-- .../addresources/values-fr-rFR/strings.xml | 4 +-- .../addresources/values-ga-rIE/strings.xml | 4 +-- .../addresources/values-hu-rHU/strings.xml | 4 +-- .../addresources/values-hy-rAM/strings.xml | 4 +-- .../addresources/values-in-rID/strings.xml | 8 ++--- .../addresources/values-it-rIT/strings.xml | 4 +-- .../addresources/values-iw-rIL/strings.xml | 4 +-- .../addresources/values-ja-rJP/strings.xml | 30 +++++++++---------- .../addresources/values-ko-rKR/strings.xml | 10 +++---- .../addresources/values-lt-rLT/strings.xml | 4 +-- .../addresources/values-lv-rLV/strings.xml | 4 +-- .../addresources/values-nl-rNL/strings.xml | 4 +-- .../addresources/values-pl-rPL/strings.xml | 4 +-- .../addresources/values-pt-rPT/strings.xml | 4 +-- .../addresources/values-ro-rRO/strings.xml | 4 +-- .../addresources/values-ru-rRU/strings.xml | 4 +-- .../addresources/values-sk-rSK/strings.xml | 4 +-- .../addresources/values-sl-rSI/strings.xml | 4 +-- .../addresources/values-sq-rAL/strings.xml | 4 +-- .../addresources/values-sr-rCS/strings.xml | 4 +-- .../addresources/values-sr-rSP/strings.xml | 4 +-- .../addresources/values-sv-rSE/strings.xml | 4 +-- .../addresources/values-th-rTH/strings.xml | 4 +-- .../addresources/values-tr-rTR/strings.xml | 4 +-- .../addresources/values-vi-rVN/strings.xml | 4 +-- 37 files changed, 97 insertions(+), 91 deletions(-) diff --git a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml index 58591e121..8eb1e4945 100644 --- a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml +++ b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml @@ -962,12 +962,12 @@ Second \"item\" text" إخفاء زر التخطي بعد بضع ثوانٍ يتم عرض زر التخطي للمقطع بأكمله مدة زر التخطي - المدة التي تظهر فيها أزرار التخطي والتخطي إلى التمييز المخفية تلقائيًا + كم المدة لعرض أزرار التخطي والتخطي إلى التمييز قبل الإخفاء التلقائي إظهار إشعار التراجع عن التخطي يظهر إشعار عند تخطي مقطع تلقائيًا. انقر على الإشعار للتراجع عن التخطي لا يتم عرض التوست مدة توست التخطي - المدة التي يظهر فيها إشعار التخطي + كم المدة لعرض رسالة التراجع عن التخطي المنبثقة ثانية واحدة ثانيتان 3 ثوانٍ diff --git a/patches/src/main/resources/addresources/values-be-rBY/strings.xml b/patches/src/main/resources/addresources/values-be-rBY/strings.xml index 12fef4cf6..3e3f03eeb 100644 --- a/patches/src/main/resources/addresources/values-be-rBY/strings.xml +++ b/patches/src/main/resources/addresources/values-be-rBY/strings.xml @@ -962,12 +962,12 @@ Second \"item\" text" Кнопка \"Прапусціць\" скрываецца праз некалькі секунд Кнопка «Прапусціць» паказана для ўсяго сегмента Працягласць кнопкі пропуску - Як доўга адлюстроўваюцца кнопкі аўтаматычнага хавання прапуску і пераходу да вылучэння + Як доўга паказваць кнопкі прапусціць і прапусціць да асноўнага моманту перад аўтаматычным схаваннем Паказаць усплываючае паведамленне для адмены прапуску Усплываючае паведамленне паказваецца, калі сегмент аўтаматычна прапускаецца. Націсніце на ўсплываючае паведамленне, каб адмяніць прапуск Усплывальнае апавяшчэнне не паказваецца Працягласць усплывальнага апавяшчэння пра пропуск - Як доўга адлюстроўваецца ўсплываючае паведамленне пра прапуск + Як доўга паказваць паведамленне пра адмену пропуску 1 секунда 2 секунды 3 секунды diff --git a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml index 9175dc42a..936833a42 100644 --- a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml +++ b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml @@ -962,12 +962,12 @@ Second \"item\" text" Бутона за пропускане се скрива след няколко секунди Бутонът \"Пропускане\" е показан за целия сегмент Продължителност на бутона за пропускане - Колко дълго се показват бутоните за автоматично скриване на пропускане и за пропускане до акцент + Колко дълго да се показват бутоните за пропускане и преминаване към акцент, преди да се скрият автоматично Показване на известие за отмяна на пропускането Показва се известие, когато сегмент е автоматично пропуснат. Докоснете известието, за да отмените пропускането Изскачащо съобщение не се показва Продължителност на изскачащото съобщение за пропускане - Колко дълго се показва известието за пропускане + Колко дълго да се показва известието за отмяна на пропускането 1 секунда 2 секунди 3 секунди diff --git a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml index a39605cb3..414e4f546 100644 --- a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml +++ b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml @@ -958,12 +958,12 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন কয়েক সেকেন্ড পরে স্কিপ বোতাম লুকিয়ে যায় পুরো অংশের জন্য Skip বোতাম দেখানো হয়েছে স্কিপ বোতামের সময়কাল - অটো হাইড স্কিপ এবং হাইলাইট বোতাম কতক্ষণ দেখানো হয় + স্বয়ংক্রিয়ভাবে লুকানোর আগে এড়িয়ে যাওয়া এবং হাইলাইট করা বোতামগুলি কতক্ষণ দেখানো হবে স্কিপ পূর্বাবস্থায় ফিরিয়ে আনার টোস্ট দেখান যখন একটি সেগমেন্ট স্বয়ংক্রিয়ভাবে এড়িয়ে যাওয়া হয় তখন টোস্ট দেখানো হয়। স্কিপ পূর্বাবস্থায় ফিরিয়ে আনতে টোস্ট বিজ্ঞপ্তিতে ট্যাপ করুন টোস্ট দেখানো হয়নি টোস্ট এড়িয়ে যাওয়ার সময়কাল - স্কিপ টোস্ট বিজ্ঞপ্তি কতক্ষণ দেখানো হয় + এড়িয়ে যাওয়া বাতিল করার টোস্ট কতক্ষণ দেখানো হবে ১ সেকেন্ড ২ সেকেন্ড ৩ সেকেন্ড diff --git a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml index 2cf8cfcd4..4f6463412 100644 --- a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml +++ b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml @@ -963,12 +963,12 @@ Tato funkce funguje nejlépe s kvalitou videa 720p nebo nižší a při použit Tlačítko pro přeskočení se skrývá po několika sekundách Tlačítko Přeskočit se zobrazuje pro celý segment Doba trvání tlačítka přeskočení - Jak dlouho se zobrazují tlačítka pro automatické skrytí přeskočení a přeskočení na zvýraznění + Jak dlouho zobrazovat tlačítka přeskočit a přeskočit na zvýraznění před automatickým skrytím Zobrazit hlásku pro zrušení přeskočení Hláska se zobrazí, když je segment automaticky přeskočen. Klepněte na hlásku pro zrušení přeskočení Toast se nezobrazuje Doba trvání toastu přeskočení - Jak dlouho se zobrazuje hláska pro přeskočení + Jak dlouho zobrazovat hlášení o zrušení přeskočení 1 sekunda 2 sekundy 3 sekundy diff --git a/patches/src/main/resources/addresources/values-da-rDK/strings.xml b/patches/src/main/resources/addresources/values-da-rDK/strings.xml index 7e65b1b02..940735fde 100644 --- a/patches/src/main/resources/addresources/values-da-rDK/strings.xml +++ b/patches/src/main/resources/addresources/values-da-rDK/strings.xml @@ -964,12 +964,12 @@ Denne funktion fungerer bedst med en videokvalitet på 720p eller lavere og ved Skip knap skjuler efter et par sekunder Spring over-knappen vises for hele segmentet Spring over-knap varighed - Hvor længe knapperne til automatisk skjuling af overspring og spring til højdepunkt vises + Hvor længe skal knapperne til at springe over og springe til højdepunkt vises, før de automatisk skjules Vis fortryd oversprings-toast Toast vises, når et segment automatisk springes over. Tryk på toast-meddelelsen for at fortryde overspringelsen Toast vises ikke Spring over-toast varighed - Hvor længe toast-meddelelsen ved overspringelse vises + Hvor længe skal fortryd spring over-meddelelsen vises 1 sekund 2 sekunder 3 sekunder diff --git a/patches/src/main/resources/addresources/values-de-rDE/strings.xml b/patches/src/main/resources/addresources/values-de-rDE/strings.xml index ff567ee1f..d57c76e17 100644 --- a/patches/src/main/resources/addresources/values-de-rDE/strings.xml +++ b/patches/src/main/resources/addresources/values-de-rDE/strings.xml @@ -955,12 +955,12 @@ Diese Funktion funktioniert am besten mit einer Videoqualität von 720p oder nie Überspringe Taste verbirgt sich nach ein paar Sekunden Die Schaltfläche \"Überspringen\" wird für das gesamte Segment angezeigt Dauer des Überspringen-Buttons - Wie lange die automatisch ausgeblendeten Schaltflächen zum Überspringen und zum Springen zur Markierung angezeigt werden + Wie lange die Schaltflächen zum Überspringen und zum Hervorheben angezeigt werden sollen, bevor sie automatisch ausgeblendet werden Toast zum Rückgängigmachen des Überspringens anzeigen Ein Toast wird angezeigt, wenn ein Segment automatisch übersprungen wird. Tippen Sie auf die Toast-Benachrichtigung, um das Überspringen rückgängig zu machen Toast-Nachricht wird nicht angezeigt Dauer der Überspring-Toastmeldung - Wie lange die Überspringen-Toast-Benachrichtigung angezeigt wird + Wie lange der Hinweis zum Rückgängigmachen des Überspringens angezeigt werden soll 1 Sekunde 2 Sekunden 3 Sekunden diff --git a/patches/src/main/resources/addresources/values-el-rGR/strings.xml b/patches/src/main/resources/addresources/values-el-rGR/strings.xml index 410e45ce0..e65d1f210 100644 --- a/patches/src/main/resources/addresources/values-el-rGR/strings.xml +++ b/patches/src/main/resources/addresources/values-el-rGR/strings.xml @@ -969,7 +969,7 @@ Second \"item\" text" Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης όταν ένα τμήμα παραλείπεται αυτόματα. Πατήστε το μήνυμα για αναίρεση της παράλειψης Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης όταν ένα τμήμα παραλείπεται αυτόματα Διάρκεια μηνύματος παράλειψης - Διάρκεια εμφάνισης μηνύματος παράλειψης + Διάρκεια εμφάνισης του μηνύματος αναίρεσης παράλειψης 1 δευτερόλεπτο 2 δευτερόλεπτα 3 δευτερόλεπτα diff --git a/patches/src/main/resources/addresources/values-es-rES/strings.xml b/patches/src/main/resources/addresources/values-es-rES/strings.xml index 0d7d3e4cd..6933a01a2 100644 --- a/patches/src/main/resources/addresources/values-es-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-es-rES/strings.xml @@ -959,12 +959,12 @@ Esta función funciona mejor con una calidad de vídeo de 720p o inferior y cuan Omitir botón se oculta después de unos segundos Se muestra el botón Saltar para todo el segmento Duración del botón Omitir - ¿Cuánto tiempo se muestran automáticamente los botones de omitir y omitir para resaltar? + Cuánto tiempo se deben mostrar los botones de \"saltar\" y \"saltar al momento destacado\" antes de ocultarse automáticamente Mostrar mensaje emergente para deshacer omisión Se muestra un mensaje emergente cuando un segmento se omite automáticamente. Toca la notificación de mensaje emergente para deshacer la omisión El mensaje emergente no se muestra Duración del mensaje emergente al omitir - ¿Cuánto tiempo se muestra la notificación de mensaje emergente de omisión? + Cuánto tiempo se debe mostrar el mensaje emergente de \"deshacer salto\" 1 segundo 2 segundos 3 segundos diff --git a/patches/src/main/resources/addresources/values-et-rEE/strings.xml b/patches/src/main/resources/addresources/values-et-rEE/strings.xml index 97feccaf7..11a7fede4 100644 --- a/patches/src/main/resources/addresources/values-et-rEE/strings.xml +++ b/patches/src/main/resources/addresources/values-et-rEE/strings.xml @@ -962,12 +962,12 @@ See funktsioon toimib kõige paremini 720p või madalama video kvaliteedi ja vä Vahelejätmisnupp peitub mõne sekundi pärast Vahelejätmise nupp on kuvatud kogu segmendi jaoks Vahelejätnud nupu kestus - Kui kaua kuvatakse automaatselt peidetud nuppe \"jäta vahele\" ja \"jäta esiletõstmise juurde\" + Kui kaua näidata vahelejätmise ja esiletõstmise nuppe enne automaatset peitmist Kuva tühista vahelejätmise teavitus (toast) Teavitus kuvatakse, kui segment jäetakse automaatselt vahele. Vahelejätmise tühistamiseks puudutage teavitust Hüpikut ei kuvata Vahelejätnud hüpiku kestus - Kui kaua kuvatakse vahelejätmise teavitust (toast) + Kui kaua näidata vahelejätmise tagasivõtmise hüpikut 1 sekund 2 sekundit 3 sekundit diff --git a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml index df3d64b00..ef5d1740b 100644 --- a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml +++ b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml @@ -377,6 +377,9 @@ Rajoitukset Avainsana piilottaa kaikki videot: %s + Piilota sisällöntuottajien kauppojen hyllyt + Kauppahyllyt soittimen alla ja videon kuvauksessa on piilotettu + Kauppahyllyt soittimen alla ja videon kuvauksessa näytetään Piilota loppunäytön kauppabanneri Kauppabanneri on piilotettu Kauppabanneri näytetään @@ -400,6 +403,9 @@ Tämä ominaisuus on käytettävissä vain vanhemmilla laitteilla" Piilota itse-sponsoroidut kortit Itse-sponsoroidut kortit ovat piilotettu Itse-sponsoroidut kortit näytetään + Piilota tagatut tuotteet + Tagatut tuotteet videon kuvauksessa on piilotettu + Tagatut tuotteet videon kuvauksessa näytetään Piilota \"Vieraile kaupassa\" -painike kanavasivuilla Painike on piilotettu kanavasivuilla @@ -665,7 +671,7 @@ Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi" Videolaatuvalikon alatunniste näytetään - Piilota Edellinen ja Seuraava -painikkeeet + Piilota Edellinen & Seuraava -painikkeet Painikkeet on piilotettu Painikkeet näytetään Piilota Cast-painike @@ -1007,7 +1013,7 @@ UserID on kuin salasana, eikä sitä pidä jakaa kenellekään. Älä näytä uudelleen Muuta osion käyttäytymistä Sponsori - Maksettu mainostus, maksetut viittaukset ja suorat mainokset. Ei itsensä mainostukselle tai ilmaisille maininnoille kampanjoista/luojista/nettisivuista/tuotteista, joista he pitävät + Maksettu mainostus, maksetut viittaukset ja suorat mainokset. Ei itsensä mainostukselle tai ilmaisille maininnoille kampanjoista/sisällöntuottajista/nettisivuista/tuotteista, joista he pitävät Maksamaton/Itsensä mainostus Samankaltainen \"Sponsorin\" kanssa, mutta maksamattomalle tai itsensä mainostukselle. Tämä sisältää osioita kauppatavarasta, lahjoituksista tai tietoa siitä, kenen kanssa he ovat tehneet yhteistyötä Vuorovaikutusmuistutus (tilaaminen) diff --git a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml index 5f73dcd76..1f025cb91 100644 --- a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml +++ b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml @@ -960,12 +960,12 @@ Ang tampok na ito ay pinakamahusay na gumagana sa kalidad ng video na 720p o mas Tinatago ang pindutan ng skip pagkatapos ng ilang segundo Ipinapakita ang button na Laktawan para sa buong segment Tagal ng pindutan ng Paglaktaw - Gaano katagal ipinapakita ang mga pindutan ng awtomatikong pagtago ng laktaw at laktaw upang i-highlight + Gaano katagal ipakita ang mga pindutan ng paglaktaw at paglaktaw sa highlight bago awtomatikong itago Ipakita ang undo skip toast Ipinapakita ang toast kapag awtomatikong nilaktawan ang isang segment. Tapikin ang notipikasyon ng toast upang i-undo ang paglaktaw Hindi ipinapakita ang toast Tagal ng toast sa paglaktaw - Gaano katagal ipinapakita ang notipikasyon ng skip toast + Gaano katagal ipakita ang paalala ng pag-undo ng paglaktaw 1 segundo 2 segundo 3 segundo diff --git a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml index ab04cb169..b6299327a 100644 --- a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml +++ b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml @@ -964,12 +964,12 @@ Cette fonctionnalité fonctionne de manière optimale avec une qualité vidéo d Le bouton Passer est masqué après quelques secondes Le bouton Passer est affiché pendant toute la durée du segment Durée du bouton Passer - Durée d\'affichage avant masquage automatique des boutons Passer et Passer au temps fort + Durée d\'affichage des boutons \"Passer\" et \"Passer au temps fort\" avant masquage automatique Afficher le message toast d\'annulation de saut Un message toast est affiché lorsqu\'un segment est automatiquement passé. Appuyez dessus pour annuler le saut. Le message toast n\'est pas affiché Durée du message toast de saut - Durée d\'affichage du message toast de saut + Durée d\'affichage du message toast d\'annulation de saut 1 seconde 2 secondes 3 secondes diff --git a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml index 22eb3a07a..2c547463f 100644 --- a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml +++ b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml @@ -962,12 +962,12 @@ Oibríonn an ghné seo is fearr le caighdeán físeáin 720p nó níos ísle agu Folaíonn cnaipe scipeáil tar éis cúpla soicindí Taispeántar cnaipe Scipeála don deighleog iomlán Fad an chnaipe scipeála - Cé chomh fada a thaispeántar na cnaipí uathfholaigh scipeála agus scipeála go buaicphointe + Cá fhad chun na cnaipí scipeála agus scipeála go dtí an aibhsigh a thaispeáint sula bhfolóidh siad go huathoibríoch Taispeáin teast cealaigh scipeála Taispeántar teast nuair a scipeáiltear deighleog go huathoibríoch. Tapáil an fógra teast chun an scipeáil a chealú Ní thaispeántar an tóstas Fad an tóstais scipeála - Cé chomh fada a thaispeántar an fógra teast scipeála + Cá fhad chun an fógra dísciption a thaispeáint 1 soicind 2 soicind 3 soicind diff --git a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml index c8cc277cb..2cd1c46fd 100644 --- a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml +++ b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml @@ -962,12 +962,12 @@ Ez a funkció a legjobban 720p vagy annál alacsonyabb videóminőség mellett A kihagyás gomb néhány másodperc után eltűnik Az Átugrás gomb a teljes szegmenshez megjelenik Átugrás gomb időtartama - Meddig láthatók az automatikus elrejtésű átugrás és kiemelés gombok + Mennyi ideig jelenjenek meg az átugrás és az átugrás kiemeléshez gombok az automatikus elrejtés előtt Ugrás visszavonása felugró értesítés megjelenítése Felugró értesítés jelenik meg, amikor egy szegmens automatikusan átugrásra kerül. Érintse meg a felugró értesítést az átugrás visszavonásához A felugró üzenet nem jelenik meg Átugrási felugró üzenet időtartama - Meddig látható az átugrás felugró értesítés + Mennyi ideig jelenjen meg az átugrás visszavonása felugró üzenet 1 másodperc 2 másodperc 3 másodperc diff --git a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml index 5e22d7748..97db99a7c 100644 --- a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml +++ b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml @@ -963,12 +963,12 @@ Seekbar thumbnails-ները կօգտագործեն նույն որակը, ինչ Բաց թողնել կոճակը թաքնվում է մի քանի վայրկյանից հետո Skip կոճակը ցուցադրվում է ամբողջ հատվածի համար Բաց թողնելու կոճակի տևողությունը - Ինչքան ժամանակ են ցուցադրվում ավտոմատ թաքնվող բաց թողնելու և առանձնացված մասին անցնելու կոճակները։ + Որքան ժամանակ ցուցադրել բացթողում և բացթողում՝ ընդգծելու կոճակները մինչև ավտոմատ թաքնվելը Ցուցադրել բաց թողնելը չեղարկելու ծանուցումը։ Ծանուցում է ցուցադրվում, երբ հատվածն ավտոմատ կերպով բաց է թողնվում։ Հպեք ծանուցմանը՝ բացթողումը չեղարկելու համար Ծանուցումը չի ցուցադրվում Բաց թողնելու ծանուցման տևողությունը - Ինչքան ժամանակ է ցուցադրվում բաց թողնելու ծանուցումը։ + Որքան ժամանակ ցուցադրել բացթողումը հետարկելու ծանուցումը 1 վայրկյան 2 վայրկյան 3 վայրկյան diff --git a/patches/src/main/resources/addresources/values-in-rID/strings.xml b/patches/src/main/resources/addresources/values-in-rID/strings.xml index 6db5f8395..3a79bc788 100644 --- a/patches/src/main/resources/addresources/values-in-rID/strings.xml +++ b/patches/src/main/resources/addresources/values-in-rID/strings.xml @@ -400,9 +400,9 @@ Fitur ini hanya tersedia untuk perangkat yang lebih lama" Label promosi berbayar disembunyikan Label promosi berbayar ditampilkan - Sembunyikan banner \'Lihat produk\' + Sembunyikan spanduk \'Lihat produk\' Spanduk di hamparan video disembunyikan - Banner di overlay video ditampilkan + Spanduk di hamparan video ditampilkan Sembunyikan kartu bersponsor pribadi Kartu bersponsor pribadi disembunyikan Kartu bersponsor pribadi ditampilkan @@ -962,12 +962,12 @@ Fitur ini bekerja paling baik dengan kualitas video 720p atau lebih rendah dan s Tombol lewati disembunyikan setelah beberapa detik Tombol Lewati ditampilkan untuk seluruh segmen Durasi tombol Lewati - Berapa lama tombol sembunyikan otomatis lewati dan lewati ke sorotan ditampilkan + Berapa lama untuk menampilkan tombol lewati dan lewati ke sorotan sebelum bersembunyi secara otomatis Tampilkan pembatalan pesan timbul lewati Pesan timbul ditampilkan saat segmen dilewati secara otomatis. Ketuk notifikasi pesan timbul untuk membatalkan lewati Pesan timbul tidak ditampilkan Durasi pesan timbul lewati - Berapa lama notifikasi pesan timbul lewati ditampilkan + Berapa lama waktu yang dibutuhkan untuk menampilkan pembatalan pesan timbul 1 detik 2 detik 3 detik diff --git a/patches/src/main/resources/addresources/values-it-rIT/strings.xml b/patches/src/main/resources/addresources/values-it-rIT/strings.xml index fd424c768..d21f61954 100644 --- a/patches/src/main/resources/addresources/values-it-rIT/strings.xml +++ b/patches/src/main/resources/addresources/values-it-rIT/strings.xml @@ -962,12 +962,12 @@ Questa funzione funziona meglio con una qualità video di 720p o inferiore e qua Il pulsante Salta si nasconde dopo alcuni secondi Il pulsante Salta è mostrato per l\'intero segmento Durata pulsante Salta - Per quanto tempo vengono mostrati i pulsanti di nascondimento automatico e di salto all\'evidenziazione + Per quanto tempo mostrare i pulsanti Salta e Salta a evidenziazione prima che si nascondano automaticamente Mostra toast annulla salto Il toast viene mostrato quando un segmento viene automaticamente saltato. Tocca la notifica toast per annullare il salto Il toast non viene mostrato Durata toast Salta - Per quanto tempo viene mostrata la notifica toast di salto + Per quanto tempo mostrare il toast annulla salto 1 secondo 2 secondi 3 secondi diff --git a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml index 43bfc541c..d874e44e0 100644 --- a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml +++ b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml @@ -965,12 +965,12 @@ Second \"item\" text" לחצן דילוג נעלם לאחר כמה שניות לחצן דילוג מוצג עבור כל המקטע משך לחצן הדילוג - כמה זמן מוצגים כפתורי הדילוג והדילוג לסימון בהסתרה אוטומטית + כמה זמן להציג את כפתורי הדילוג ודילוג לסימון לפני הסתרה אוטומטית הצג הודעה קופצת לביטול דילוג הודעה קופצת מוצגת כאשר קטע מדולג אוטומטית. הקש על ההודעה הקופצת כדי לבטל את הדילוג הטוסט לא מוצג משך טוסט הדילוג - כמה זמן מוצגת ההודעה הקופצת של הדילוג + כמה זמן להציג את הודעת \"טוסט\" ביטול הדילוג שנייה אחת שתי שניות 3 שניות diff --git a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml index 1f2690c4a..088d09602 100644 --- a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml +++ b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml @@ -378,9 +378,9 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 全ての動画を除外するキーワード: %s - クリエイターのストア棚を非表示にする - プレーヤーの下と動画の概要欄にあるストア棚は非表示になります - プレーヤーの下と動画の概要欄にストアシェルフが表示されます + ストア広告を非表示 + プレーヤー下および概要欄のストア広告を非表示にします + プレーヤー下および概要欄のストア広告を非表示にします 終了画面のストアバナーを非表示 終了画面のストアバナーを非表示にします 終了画面のストアバナーを非表示にします @@ -401,15 +401,15 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に プレーヤー画面の「プロモーションを含みます」ボタンを非表示にします プレーヤー画面の「プロモーションを含みます」ボタンを非表示にします - \'商品を表示\'バナーを非表示にする - 動画オーバーレイのバナーは非表示になります - 動画オーバーレイにバナーが表示されます + 「商品を表示」ボタンを非表示 + プレーヤー画面の「商品を表示」ボタンおよび商品ボタンを非表示にします + プレーヤー画面の「商品を表示」ボタンおよび商品ボタンを非表示にします 自己スポンサー カードを非表示 自己スポンサー カードを非表示にします 自己スポンサー カードを非表示にします - タグ付けされた商品を非表示にする - 動画の概要欄にあるタグ付けされた商品は非表示になります - 動画の概要欄にタグ付けされた商品が表示されます + タグ付けされた商品へのリンクを非表示 + 概要欄のタグ付けされた商品へのリンクを非表示にします + 概要欄のタグ付けされた商品へのリンクを非表示にします 「ストアに移動」ボタンを非表示 チャンネル ページの「ストアに移動」ボタンを非表示にします @@ -521,9 +521,9 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 全画面表示でスワイプしても、次 / 前の動画に切り替わりません - デフォルトでの字幕表示を無効にする - 字幕がオフの状態で動画を開きます - 字幕がオンの状態で動画を開く場合があります + デフォルトでの字幕表示を無効化 + 動画を開いた際に字幕を表示しません + 動画を開いた際に字幕を表示しません アクション ボタン @@ -828,7 +828,7 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に サウンド メタデータ ラベルを非表示 サウンド メタデータ ラベルは表示されません サウンド メタデータ ラベルは表示されます - 動画リンクのラベルを非表示にする + 関連動画へのリンクを非表示 関連動画へのリンクは表示されません 関連動画へのリンクは表示されます サウンド ボタンを非表示 @@ -966,11 +966,11 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に スキップボタンは、セグメントの開始から終了まで表示されます スキップボタンの表示時間 自動非表示設定のスキップボタンとハイライトへのスキップボタンが表示される時間 - スキップ取り消しのトーストを表示 + スキップ取り消しトーストを表示 セグメントが自動的にスキップされた際にトーストを表示します。このトースト通知をタップすると、スキップが取り消されます セグメントが自動的にスキップされた際にトーストを表示します。このトースト通知をタップすると、スキップが取り消されます スキップ トーストの表示時間 - スキップのトースト通知が表示される時間 + スキップ取り消しトーストの表示時間 1 秒 2 秒 3 秒 diff --git a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml index 2fd70d1a3..6de3bf85d 100644 --- a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml +++ b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml @@ -24,7 +24,7 @@ Second \"item\" text" 환경 검사에 실패하였습니다 공식 홈페이지 열기 닫기 - <h5>이 앱은 사용자가 패치하지 않은 것 같습니다.</h5><br>이 앱은 제대로 작동하지 않을 수 있으며, <b>사용 시 해롭거나 심지어 위험할 수도 있습니다</b>.<br><br>이러한 검사는 이 앱이 사전에 패치되었거나 다른 사람으로부터 받은 것임을 의미합니다:<br><br><small>%1$s</small><br>검증되고 안전한 앱을 사용하고 있는지 확인하려면 <b>이 앱을 삭제하고 직접 패치하는 것</b>을 강력히 권장합니다.<p><br>이 경고는 두 번만 표시됩니다. + <h5>이 앱은 사용자가 패치하지 않은 것 같습니다.</h5><br>이 앱은 제대로 작동하지 않을 수 있으며, <b>사용 시 해롭거나 심지어 위험할 수도 있습니다</b>.<br><br>이러한 검사는 이 앱이 다른 사람이 패치했거나 다른 사람으로부터 받은 것임을 의미합니다:<br><br><small>%1$s</small><br>검증되고 안전한 앱을 사용하고 있는지 확인하려면 <b>이 앱을 삭제하고 직접 패치하는 것</b>을 강력히 권장합니다.<p><br>이 경고는 두 번만 표시됩니다. 다른 기기에서 패치되었습니다 ReVanced Manager에 의해 설치되지 않았습니다 10분 이상 전에 패치되었습니다 @@ -962,15 +962,15 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 최소화된 건너뛰기 버튼을 표시합니다 일반적인 건너뛰기 버튼을 표시합니다 자동으로 건너뛰기 버튼 숨기기 - 건너뛰기 버튼이 몇 초 후에 사라집니다 + 건너뛰기 버튼이 몇 초 후에 숨겨집니다 건너뛰기 버튼이 해당 구간이 끝날 때까지 표시됩니다 건너뛰기 버튼 표시 시간 - 자동으로 숨겨지는 \'건너뛰기\' 및 \'하이라이트로 건너뛰기\' 버튼이 표시되는 시간을 설정할 수 있습니다 + 건너뛰기 및 하이라이트로 건너뛰기 버튼이 자동으로 숨겨지기 전까지 표시되는 시간을 설정할 수 있습니다 건너뛰기 취소 메시지 표시하기 구간을 자동으로 건너뛰는 경우에 팝업 메시지를 표시합니다\n\n팝업 메시지를 눌러서 건너뛰기를 취소할 수 있습니다 팝업 메시지를 표시하지 않습니다 - 건너뛰기 팝업 메시지 표시 시간 - 건너뛰기 팝업 메시지가 표시되는 시간을 설정할 수 있습니다 + 건너뛰기 취소 메시지 표시 시간 + 건너뛰기 취소 팝업 메시지가 표시되는 시간을 설정할 수 있습니다 1 초 2 초 3 초 diff --git a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml index ddc9141ec..0fcf65185 100644 --- a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml +++ b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml @@ -960,12 +960,12 @@ Paieškos juostos miniatiūros bus naudojamos tos pačios kokybės kaip dabartin Praleidimo mygtukas pasislėps po kelių sekundžių Praleidimo mygtukas rodomas visam segmentui Praleidimo mygtuko trukmė - Kiek laiko rodomi automatinio paslėpimo praleidimo ir praleidimo iki paryškinimo mygtukai + Kiek laiko rodyti praleidimo ir praleidimo iki paryškinimo mygtukus prieš juos automatiškai paslepiant Rodyti praleidimo anuliavimo pranešimą Pranešimas rodomas, kai segmentas automatiškai praleidžiamas. Bakstelėkite pranešimą, norėdami anuliuoti praleidimą Pranešimas nerodomas Praleidimo pranešimo trukmė - Kiek laiko rodomas praleidimo pranešimas + Kiek laiko rodyti pranešimą apie praleidimo atšaukimą 1 sekundė 2 sekundės 3 sekundės diff --git a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml index 20c203976..20111b15f 100644 --- a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml +++ b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml @@ -964,12 +964,12 @@ Laika skalas miniatūras izmantos tādu pašu kvalitāti kā pašreizējais vide Izlaides poga paslēpjas pēc dažām sekundēm Poga Izlaist ir redzama visam segmentam Izlaišanas pogas ilgums - Cik ilgi tiek rādītas automātiskās paslēpšanas izlaišanas un pārejas uz izcēlumu pogas + Cik ilgi rādīt pogas \"Izlaist\" un \"Izlaist uz izcelt\", pirms tās automātiski paslēpjas Rādīt atsaukt izlaišanas paziņojumu Paziņojums tiek rādīts, kad segments tiek automātiski izlaists. Pieskarieties paziņojumam, lai atsauktu izlaišanu Paziņojums netiek rādīts Izlaišanas paziņojuma ilgums - Cik ilgi tiek rādīts izlaišanas paziņojums + Cik ilgi rādīt paziņojumu par izlaišanas atcelšanu 1 sekunde 2 sekundes 3 sekundes diff --git a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml index 2046f826c..f58bf65cc 100644 --- a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml +++ b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml @@ -962,12 +962,12 @@ Deze functie werkt het beste met een videokwaliteit van 720p of lager en wanneer Oversla-knop wordt na een paar seconden verborgen Skip-knop wordt weergegeven voor het hele segment Duur van overslaan-knop - Hoe lang de \"automatisch verbergen overslaan\"- en \"markeer\"-knoppen worden getoond + Hoe lang de knoppen \"overslaan\" en \"overslaan naar hoogtepunt\" moeten worden weergegeven voordat ze automatisch worden verborgen Toon \"overslaan ongedaan maken\"-melding Een melding wordt getoond wanneer een segment automatisch wordt overgeslagen. Tik op de melding om het overslaan ongedaan te maken Toast wordt niet getoond Duur van overslaan-toast - Hoe lang de overslaan-melding wordt getoond + Hoe lang de \"overslaan ongedaan maken\"-melding moet worden weergegeven 1 seconde 2 seconden 3 seconden diff --git a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml index 36ca06c0f..205f7eaf1 100644 --- a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml +++ b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml @@ -958,12 +958,12 @@ Ta funkcja działa najlepiej przy jakości wideo 720p lub niższej i przy korzys Przycisk od pomijania ukrywa się po kilku sekundach Przycisk pomijania jest wyświetlany dla całego segmentu Czas trwania przycisku pominięcia - Jak długo wyświetlane są przyciski automatycznego ukrywania pomijania i przechodzenia do wyróżnienia + Jak długo wyświetlać przyciski pomijania i przechodzenia do wyróżnienia przed automatycznym ukryciem Pokaż komunikat o cofnięciu pominięcia Komunikat jest wyświetlany, gdy segment zostanie automatycznie pominięty. Dotknij powiadomienia, aby cofnąć pominięcie Komunikat nie jest wyświetlany Czas trwania komunikatu pominięcia - Jak długo wyświetlane jest powiadomienie o pominięciu + Jak długo wyświetlać komunikat wyskakujący o cofnięciu pominięcia 1 sekunda 2 sekundy 3 sekundy diff --git a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml index c95439153..4aa1504ea 100644 --- a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml @@ -962,12 +962,12 @@ Tính năng này hoạt động tốt nhất với chất lg video là 720p tr Pular botão esconde após alguns segundos O botão \"Ignorar\" é mostrado para todo o segmento Duração do botão de pular - Por quanto tempo os botões de ocultar automaticamente pular e pular para destacar são exibidos + Quanto tempo para mostrar os botões de pular e pular para destaque antes de ocultar automaticamente Mostrar notificação de desfazer pular Uma notificação é exibida quando um segmento é pulado automaticamente. Toque na notificação para desfazer o pulo Notificação não é exibida Duração da notificação de pular - Por quanto tempo a notificação de pular é exibida + Quanto tempo para mostrar o aviso de desfazer pular 1 segundo 2 segundos 3 segundos diff --git a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml index 739769b70..9ad9026f6 100644 --- a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml +++ b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml @@ -962,12 +962,12 @@ Această caracteristică funcționează cel mai bine cu o calitate video de 720p Omite ascunderea butonului după câteva secunde Butonul Skip este afișat pentru întregul segment Durata butonului de omitere - Cât timp sunt afișate butoanele de ascundere automată a săriturii și de săritură la evidențiere + Cât timp să se afișeze butoanele „Omite” și „Omite la momentul cheie” înainte de a se ascunde automat Afișează notificare toast de anulare a săriturii Notificarea toast este afișată când un segment este sărit automat. Atingeți notificarea toast pentru a anula săritura Notificarea pop-up nu este afișată Durata notificării pop-up de omitere - Cât timp este afișată notificarea toast de săritură + Cât timp să se afișeze notificarea de anulare a omisiunii 1 secundă 2 secunde 3 secunde diff --git a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml index 0fa0cfdad..c07239c89 100644 --- a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml +++ b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml @@ -964,12 +964,12 @@ Second \"item\" text" Кнопка пропуска автоматически скрывается через несколько секунд Кнопка пропуска показывается для всего сегмента Длительность кнопки пропуска - Длительность показа кнопок автоматического скрытия пропуска и перехода к основному моменту + Длительность показа кнопок пропуска и перехода к основному моменту до автоматического скрытия Показывать уведомление отмены пропуска Всплывающее уведомление показано при автоматическом пропуске сегмента. Нажмите на всплывающее уведомление для отмены пропуска Всплывающее уведомление скрыто Длительность всплывающего уведомления при пропуске - Длительность показа всплывающего уведомления при пропуске + Как долго показывать всплывающее сообщение об отмене пропуска 1 секунда 2 секунды 3 секунды diff --git a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml index bb38229c5..564041493 100644 --- a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml +++ b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml @@ -955,12 +955,12 @@ Táto funkcia najlepšie funguje s kvalitou videa 720p alebo nižšou a pri pou Tlačidlo preskočenia sa po niekoľkých sekundách skryje Tlačidlo Preskočiť sa zobrazuje pre celý segment Dĺžka trvania tlačidla preskočiť - Ako dlho sú zobrazené tlačidlá pre automatické skrytie preskočenia a preskočenie na zvýraznenie + Ako dlho zobrazovať tlačidlá preskočiť a preskočiť na zvýraznenie pred automatickým skrytím Zobraziť hlásenie o vrátení preskočenia Hlásenie sa zobrazí, keď je segment automaticky preskočený. Klepnutím na hlásenie preskočenie vrátite Hlásenie sa nezobrazuje Dĺžka trvania hlásenia preskočenia - Ako dlho je zobrazené hlásenie o preskočení + Ako dlho zobrazovať správu o zrušení preskočenia 1 sekunda 2 sekundy 3 sekundy diff --git a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml index fc8ad55e7..f08a45ea6 100644 --- a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml +++ b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml @@ -962,12 +962,12 @@ Ta funkcija deluje najbolje pri kakovosti videa 720p ali nižji in pri uporabi z Gumb za preskakovanje se po nekaj sekundah skrije Gumb za preskok je prikazan za celoten segment Trajanje gumba za preskok - Kako dolgo so prikazani gumbi za samodejno skrivanje preskakovanja in preskok na poudarek + Kako dolgo prikazovati gumbe za preskok in preskok do označevalca, preden se samodejno skrijejo Prikaži obvestilo za razveljavitev preskakovanja Obvestilo se prikaže, ko je segment samodejno preskočen. Dotaknite se obvestila, da razveljavite preskok Obvestilo ni prikazano Trajanje obvestila o preskoku - Kako dolgo je prikazano obvestilo o preskakovanju. + Kako dolgo prikazovati obvestilo o razveljavitvi preskoka 1 sekunda 2 sekundi 3 sekunde diff --git a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml index ea7e683bd..9ce00ba85 100644 --- a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml +++ b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml @@ -962,12 +962,12 @@ Kjo veçori funksionon më mirë me një cilësi video prej 720p ose më të ul Butoni i kalimit fshihet pas disa sekondash Butoni Kalo është i shfaqur për të gjithë segmentin Kohëzgjatja e butonit të kapërcimit - Sa gjatë shfaqen butonat e fshehjes automatike të anashkalimit dhe anashkalimit te theksimi + Sa gjatë të shfaqen butonat \"kapërce\" dhe \"kapërce te pika kryesore\" përpara fshehjes automatike Shfaq njoftimin e zhbërjes së anashkalimit Njoftimi shfaqet kur një segment anashkalohet automatikisht. Prek njoftimin për të zhbërë anashkalimin Njoftimi i shkurtër nuk shfaqet Kohëzgjatja e njoftimit të kapërcimit - Sa gjatë shfaqet njoftimi i anashkalimit + Sa gjatë të shfaqet njoftimi i përkohshëm për zhbërjen e kapërcimit 1 sekondë 2 sekonda 3 sekonda diff --git a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml index 645eb2b87..dddfb72d2 100644 --- a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml @@ -962,12 +962,12 @@ Ova funkcija najbolje radi sa kvalitetom videa od 720p ili nižim i kada koristi Dugme za preskakanje će biti skriveno nakon nekoliko sekundi Dugme za preskakanje je prikazano za ceo segment Trajanje dugmeta za preskakanje - Koliko dugo se prikazuju dugmad za automatsko skrivanje preskakanja i preskakanje do isticanja + Koliko dugo prikazivati dugmad za preskakanje i preskakanje do isticanja pre automatskog skrivanja Prikaži iskačuće obaveštenje o poništavanju preskakanja Iskačuće obaveštenje se prikazuje, kada se segment automatski preskoči. Dodirnite iskačuće obaveštenje da biste poništili preskakanje Iskačuće obaveštenje se ne prikazuje Trajanje iskačućeg obaveštenja pri preskakanju - Koliko dugo se prikazuje iskačuće obaveštenje o preskakanju + Koliko dugo prikazivati poruku za opoziv preskakanja 1 sekunda 2 sekunde 3 sekunde diff --git a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml index 44bdeafe3..ffb33f845 100644 --- a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml @@ -962,12 +962,12 @@ Second \"item\" text" Дугме за прескакање ће бити скривено након неколико секунди Дугме за прескакање је приказано за цео сегмент Трајање дугмета за прескакање - Колико дуго се приказују дугмад за аутоматско скривање прескакања и прескакање до истакнутог + Колико дуго да се приказују дугмад за прескакање и прескакање до истакнутог дела пре аутоматског скривања Прикажи искачуће обавештење о поништавању прескакања Искачуће обавештење се приказује, када се сегмент аутоматски прескочи. Додирните искачуће обавештење да бисте поништили прескакање Искачуће обавештење се не приказује Трајање искачућег обавештења при прескакању - Колико дуго се приказује искачуће обавештење о прескакању + Колико дуго да се приказује тост за поништавање прескакања 1 секунда 2 секунде 3 секунде diff --git a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml index 41e138085..2d9297354 100644 --- a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml +++ b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml @@ -962,12 +962,12 @@ Den här funktionen fungerar bäst med en videokvalitet på 720p eller lägre oc Hoppa över-knappen döljs efter några sekunder Hoppa över-knappen visas för hela segmentet Varaktighet för Hoppa över-knappen - Hur länge knapparna för automatisk döljning av överhoppning och hoppa till markering visas + Hur länge knappen för att hoppa över och hoppa till höjdpunkt ska visas innan den döljs automatiskt Visa toastmeddelande för ångra överhoppning Meddelande visas när ett segment hoppas över automatiskt. Tryck på toastmeddelandet för att ångra överhoppningen Toastmeddelande visas inte Varaktighet för överhoppningstoastmeddelande - Hur länge toastmeddelandet för överhoppning visas + Hur länge toast-meddelandet för ångra överhoppning ska visas 1 sekund 2 sekunder 3 sekunder diff --git a/patches/src/main/resources/addresources/values-th-rTH/strings.xml b/patches/src/main/resources/addresources/values-th-rTH/strings.xml index 3ce72e21f..1e7c6f3a1 100644 --- a/patches/src/main/resources/addresources/values-th-rTH/strings.xml +++ b/patches/src/main/resources/addresources/values-th-rTH/strings.xml @@ -961,12 +961,12 @@ Second \"item\" text" ปุ่มข้ามซ่อนหลังจากผ่านไปไม่กี่วินาที ปุ่มข้ามจะแสดงสำหรับทั้งส่วน ระยะเวลาปุ่มข้าม - ระยะเวลาที่ปุ่มซ่อนอัตโนมัติสำหรับข้ามและข้ามไปยังไฮไลต์จะแสดง + นานแค่ไหนที่จะแสดงปุ่มข้ามและปุ่มข้ามไปยังไฮไลต์ก่อนที่จะซ่อนโดยอัตโนมัติ แสดงการแจ้งเตือนยกเลิกการข้าม จะมีการแจ้งเตือนแสดงขึ้นเมื่อมีการข้ามส่วนโดยอัตโนมัติ แตะการแจ้งเตือนแบบชั่วคราวเพื่อยกเลิกการข้าม ไม่แสดงข้อความแจ้งเตือน ระยะเวลาข้อความแจ้งเตือนการข้าม - ระยะเวลาที่แสดงการแจ้งเตือนข้ามแบบชั่วคราว + นานแค่ไหนที่จะแสดงแจ้งเตือนยกเลิกการข้าม 1 วินาที 2 วินาที 3 วินาที diff --git a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml index c2fb6795e..9f53aa5e8 100644 --- a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml +++ b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml @@ -964,12 +964,12 @@ Bu özellik, 720p veya daha düşük video kalitesi ve çok hızlı bir internet Atlama düğmesi birkaç saniye sonra gizlenir Atlama düğmesi bütün kısım boyunca gösterilir Atla düğmesi süresi - Otomatik gizlenen atla ve vurgulaya atla düğmelerinin ne kadar süreyle gösterildiği + Atla ve öne çıkanlara atla düğmelerini otomatik olarak gizlemeden önce ne kadar süreyle göster Atlamayı geri al bildirimini göster Bildirim, bir segment otomatik olarak atlandığında gösterilir. Atlamayı geri almak için bildirimine dokunun Toast gösterilmiyor Atlama toast süresi - Atlama bildiriminin ne kadar süreyle gösterildiği + Geri al atla bildirimini ne kadar süreyle göster 1 saniye 2 saniye 3 saniye diff --git a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml index 7aaeea325..11ffe2b6a 100644 --- a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml +++ b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml @@ -964,12 +964,12 @@ Tính năng này hoạt động tốt nhất với chất lượng video 720p tr Nút bỏ qua sẽ ẩn sau vài giây Nút bỏ qua được hiển thị cho toàn bộ phân đoạn Thời gian hiển thị nút bỏ qua - Thời gian tự động ẩn nút bỏ qua và nút bỏ qua đến phần nổi bật + Thời gian hiển thị nút bỏ qua và nút bỏ qua đến phần nổi bật trước khi tự động ẩn Hiện thông báo nổi hoàn tác bỏ qua Thông báo nổi được hiển thị mỗi khi tự động bỏ qua một phân đoạn. Chạm vào thông báo nổi để hoàn tác bỏ qua phân đoạn vừa rồi Thông báo nổi không được hiển thị Thời gian hiển thị thông báo nổi bỏ qua - Thời gian hiển thị thông báo nổi bỏ qua + Thời gian hiển thị thông báo nổi hoàn tác bỏ qua 1 giây 2 giây 3 giây