Compare commits

...

18 Commits

Author SHA1 Message Date
semantic-release-bot
46ba0d8a2e chore: Release v5.24.0-dev.2 [skip ci]
# [5.24.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.24.0-dev.1...v5.24.0-dev.2) (2025-05-14)

### Features

* **GmsCore support:** Open vendor specific DontKillMyApp if available ([#4952](https://github.com/ReVanced/revanced-patches/issues/4952)) ([d2b440d](d2b440d800))
* **YouTube - Hide player components:** Hide related video overlay in fullscreen ([#4938](https://github.com/ReVanced/revanced-patches/issues/4938)) ([f454183](f454183646))
2025-05-14 07:07:03 +00:00
MarcaD
f454183646 feat(YouTube - Hide player components): Hide related video overlay in fullscreen (#4938) 2025-05-14 11:03:33 +04:00
LisoUseInAIKyrios
d2b440d800 feat(GmsCore support): Open vendor specific DontKillMyApp if available (#4952) 2025-05-14 11:01:32 +04:00
hoodles
494c5f04a4 fix(Instagram) - Fix hide ads fingerprint and add bypass check signature (#4901)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-05-13 10:58:07 +04:00
semantic-release-bot
48d5fdf7e1 chore: Release v5.24.0-dev.1 [skip ci]
# [5.24.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.23.0...v5.24.0-dev.1) (2025-05-12)

### Features

* **NU.nl:** Support version `11.3.0` ([#4925](https://github.com/ReVanced/revanced-patches/issues/4925)) ([887c9f0](887c9f0d75))
2025-05-12 22:40:55 +00:00
Jasper Abbink
887c9f0d75 feat(NU.nl): Support version 11.3.0 (#4925) 2025-05-13 02:37:41 +04:00
github-actions[bot]
7de4c9d41d chore: Sync translations (#4946) 2025-05-13 02:36:53 +04:00
semantic-release-bot
7d3b8d9c42 chore: Release v5.23.0 [skip ci]
# [5.23.0](https://github.com/ReVanced/revanced-patches/compare/v5.22.0...v5.23.0) (2025-05-10)

### Bug Fixes

* Correct incorrect fingerprint ([5f05414](5f0541407c))
* Fix incorrect fingerprints ([#4917](https://github.com/ReVanced/revanced-patches/issues/4917)) ([796c118](796c118fe1))
* **Spotify - Unlock Spotify Premium:** Remove pop up premium ads ([#4842](https://github.com/ReVanced/revanced-patches/issues/4842)) ([5028c1a](5028c1acb3))
* **YouTube:** Improve litho filtering performance ([#4904](https://github.com/ReVanced/revanced-patches/issues/4904)) ([60fdf4c](60fdf4c44c))
* **YouTube:** Simplify litho filtering patch ([#4910](https://github.com/ReVanced/revanced-patches/issues/4910)) ([23fd720](23fd720fa7))

### Features

* **Lightroom:** Constrain patches to last working version ([858c59d](858c59d728))
* **Pandora:** Add `Disable audio ads` and `Unlimited skips` patch ([#4841](https://github.com/ReVanced/revanced-patches/issues/4841)) ([f4f36ff](f4f36ff273))
* **Prime Video:** Add `Skip ads` patch ([#4824](https://github.com/ReVanced/revanced-patches/issues/4824)) ([f8bdf74](f8bdf744ab))
* **Spotify:** Add `Sanitize sharing links` patch ([#4829](https://github.com/ReVanced/revanced-patches/issues/4829)) ([777957e](777957e2d0))
2025-05-10 09:02:41 +00:00
LisoUseInAIKyrios
25e1a965d6 chore: Merge branch dev to main (#4899) 2025-05-10 12:58:55 +04:00
github-actions[bot]
b29c01cee1 chore: Sync translations (#4933) 2025-05-10 12:39:30 +04:00
semantic-release-bot
639850471b chore: Release v5.23.0-dev.7 [skip ci]
# [5.23.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.23.0-dev.6...v5.23.0-dev.7) (2025-05-06)

### Bug Fixes

* Fix incorrect fingerprints ([#4917](https://github.com/ReVanced/revanced-patches/issues/4917)) ([796c118](796c118fe1))
2025-05-06 12:13:29 +00:00
Nuckyz
796c118fe1 fix: Fix incorrect fingerprints (#4917) 2025-05-06 16:09:54 +04:00
semantic-release-bot
edf20e397d chore: Release v5.23.0-dev.6 [skip ci]
# [5.23.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.23.0-dev.5...v5.23.0-dev.6) (2025-05-06)

### Bug Fixes

* Correct incorrect fingerprint ([5f05414](5f0541407c))
2025-05-06 10:50:54 +00:00
oSumAtrIX
5f0541407c fix: Correct incorrect fingerprint 2025-05-06 12:47:06 +02:00
semantic-release-bot
56b7ba9ba7 chore: Release v5.23.0-dev.5 [skip ci]
# [5.23.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.23.0-dev.4...v5.23.0-dev.5) (2025-05-06)

### Bug Fixes

* **Spotify - Unlock Spotify Premium:** Remove pop up premium ads ([#4842](https://github.com/ReVanced/revanced-patches/issues/4842)) ([5028c1a](5028c1acb3))

### Features

* **Pandora:** Add `Disable audio ads` and `Unlimited skips` patch ([#4841](https://github.com/ReVanced/revanced-patches/issues/4841)) ([f4f36ff](f4f36ff273))
* **Prime Video:** Add `Skip ads` patch ([#4824](https://github.com/ReVanced/revanced-patches/issues/4824)) ([f8bdf74](f8bdf744ab))
2025-05-06 07:44:30 +00:00
hoodles
f8bdf744ab feat(Prime Video): Add Skip ads patch (#4824) 2025-05-06 11:40:45 +04:00
hoodles
f4f36ff273 feat(Pandora): Add Disable audio ads and Unlimited skips patch (#4841)
Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com>
2025-05-06 11:39:07 +04:00
Nuckyz
5028c1acb3 fix(Spotify - Unlock Spotify Premium): Remove pop up premium ads (#4842) 2025-05-06 11:35:47 +04:00
50 changed files with 759 additions and 117 deletions

View File

@@ -1,3 +1,64 @@
# [5.24.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.24.0-dev.1...v5.24.0-dev.2) (2025-05-14)
### Features
* **GmsCore support:** Open vendor specific DontKillMyApp if available ([#4952](https://github.com/ReVanced/revanced-patches/issues/4952)) ([b89927a](https://github.com/ReVanced/revanced-patches/commit/b89927a10e3b909a3c37fbb75c16a7abbce44560))
* **YouTube - Hide player components:** Hide related video overlay in fullscreen ([#4938](https://github.com/ReVanced/revanced-patches/issues/4938)) ([ac9be97](https://github.com/ReVanced/revanced-patches/commit/ac9be9760c9965e54df196b227a310d64ead4bf5))
# [5.24.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.23.0...v5.24.0-dev.1) (2025-05-12)
### Features
* **NU.nl:** Support version `11.3.0` ([#4925](https://github.com/ReVanced/revanced-patches/issues/4925)) ([bedde60](https://github.com/ReVanced/revanced-patches/commit/bedde60fc1a52b0fd491174b3b5b887435eb621a))
# [5.23.0](https://github.com/ReVanced/revanced-patches/compare/v5.22.0...v5.23.0) (2025-05-10)
### Bug Fixes
* Correct incorrect fingerprint ([c3bab89](https://github.com/ReVanced/revanced-patches/commit/c3bab89fc4189e38c10eee0caa36289de7e29dfa))
* Fix incorrect fingerprints ([#4917](https://github.com/ReVanced/revanced-patches/issues/4917)) ([49ca329](https://github.com/ReVanced/revanced-patches/commit/49ca3290a726cdba7bc9b62ffcd8d46e6f04778e))
* **Spotify - Unlock Spotify Premium:** Remove pop up premium ads ([#4842](https://github.com/ReVanced/revanced-patches/issues/4842)) ([00aa200](https://github.com/ReVanced/revanced-patches/commit/00aa2000ba2eef15a0dd827c2bd84c2e85c412e0))
* **YouTube:** Improve litho filtering performance ([#4904](https://github.com/ReVanced/revanced-patches/issues/4904)) ([7b43986](https://github.com/ReVanced/revanced-patches/commit/7b43986871a68e5cb43331d2fb2fdb9ef67438ad))
* **YouTube:** Simplify litho filtering patch ([#4910](https://github.com/ReVanced/revanced-patches/issues/4910)) ([bd53955](https://github.com/ReVanced/revanced-patches/commit/bd53955df738bb7b819eb91a3e776e9d2ca5c74a))
### Features
* **Lightroom:** Constrain patches to last working version ([efef03b](https://github.com/ReVanced/revanced-patches/commit/efef03b80da21552d0d8be6913faba64e4fb5ed1))
* **Pandora:** Add `Disable audio ads` and `Unlimited skips` patch ([#4841](https://github.com/ReVanced/revanced-patches/issues/4841)) ([0cf7a4c](https://github.com/ReVanced/revanced-patches/commit/0cf7a4c6be615ed0a52a6bacf87592f5f43ff575))
* **Prime Video:** Add `Skip ads` patch ([#4824](https://github.com/ReVanced/revanced-patches/issues/4824)) ([bb672c4](https://github.com/ReVanced/revanced-patches/commit/bb672c4674ddc201b8b2648c3906cfc31ef43f10))
* **Spotify:** Add `Sanitize sharing links` patch ([#4829](https://github.com/ReVanced/revanced-patches/issues/4829)) ([2e3511d](https://github.com/ReVanced/revanced-patches/commit/2e3511d03c8198bbdb9336888df038a33fb3ab8c))
# [5.23.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.23.0-dev.6...v5.23.0-dev.7) (2025-05-06)
### Bug Fixes
* Fix incorrect fingerprints ([#4917](https://github.com/ReVanced/revanced-patches/issues/4917)) ([49ca329](https://github.com/ReVanced/revanced-patches/commit/49ca3290a726cdba7bc9b62ffcd8d46e6f04778e))
# [5.23.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.23.0-dev.5...v5.23.0-dev.6) (2025-05-06)
### Bug Fixes
* Correct incorrect fingerprint ([c3bab89](https://github.com/ReVanced/revanced-patches/commit/c3bab89fc4189e38c10eee0caa36289de7e29dfa))
# [5.23.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.23.0-dev.4...v5.23.0-dev.5) (2025-05-06)
### Bug Fixes
* **Spotify - Unlock Spotify Premium:** Remove pop up premium ads ([#4842](https://github.com/ReVanced/revanced-patches/issues/4842)) ([00aa200](https://github.com/ReVanced/revanced-patches/commit/00aa2000ba2eef15a0dd827c2bd84c2e85c412e0))
### Features
* **Pandora:** Add `Disable audio ads` and `Unlimited skips` patch ([#4841](https://github.com/ReVanced/revanced-patches/issues/4841)) ([0cf7a4c](https://github.com/ReVanced/revanced-patches/commit/0cf7a4c6be615ed0a52a6bacf87592f5f43ff575))
* **Prime Video:** Add `Skip ads` patch ([#4824](https://github.com/ReVanced/revanced-patches/issues/4824)) ([bb672c4](https://github.com/ReVanced/revanced-patches/commit/bb672c4674ddc201b8b2648c3906cfc31ef43f10))
# [5.23.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.23.0-dev.3...v5.23.0-dev.4) (2025-05-06)

View File

@@ -82,7 +82,7 @@ public class HideAdsPatch {
// Filter HeaderBlock with known ads until next HeaderBlock.
if (currentBlock instanceof HeaderBlock headerBlock) {
StyledText headerText = headerBlock.component20();
StyledText headerText = headerBlock.getTitle();
if (headerText != null) {
skipFullHeader = false;
for (String blockedHeaderBlock : blockedHeaderBlocks) {

View File

@@ -3,8 +3,7 @@ package nl.nu.performance.api.client.objects;
import nl.nu.performance.api.client.interfaces.Block;
public class HeaderBlock extends Block {
// returns title
public final StyledText component20() {
public final StyledText getTitle() {
throw new UnsupportedOperationException("Stub");
}
}

View File

@@ -0,0 +1,4 @@
dependencies {
compileOnly(project(":extensions:shared:library"))
compileOnly(project(":extensions:primevideo:stub"))
}

View File

@@ -0,0 +1 @@
<manifest/>

View File

@@ -0,0 +1,36 @@
package app.revanced.extension.primevideo.ads;
import com.amazon.avod.fsm.SimpleTrigger;
import com.amazon.avod.media.ads.AdBreak;
import com.amazon.avod.media.ads.internal.state.AdBreakTrigger;
import com.amazon.avod.media.ads.internal.state.AdEnabledPlayerTriggerType;
import com.amazon.avod.media.playback.VideoPlayer;
import com.amazon.avod.media.ads.internal.state.ServerInsertedAdBreakState;
import app.revanced.extension.shared.Logger;
@SuppressWarnings("unused")
public final class SkipAdsPatch {
public static void enterServerInsertedAdBreakState(ServerInsertedAdBreakState state, AdBreakTrigger trigger, VideoPlayer player) {
try {
AdBreak adBreak = trigger.getBreak();
// There are two scenarios when entering the original method:
// 1. Player naturally entered an ad break while watching a video.
// 2. User is skipped/scrubbed to a position on the timeline. If seek position is past an ad break,
// user is forced to watch an ad before continuing.
//
// Scenario 2 is indicated by trigger.getSeekStartPosition() != null, so skip directly to the scrubbing
// target. Otherwise, just calculate when the ad break should end and skip to there.
if (trigger.getSeekStartPosition() != null)
player.seekTo(trigger.getSeekTarget().getTotalMilliseconds());
else
player.seekTo(player.getCurrentPosition() + adBreak.getDurationExcludingAux().getTotalMilliseconds());
// Send "end of ads" trigger to state machine so everything doesn't get whacky.
state.doTrigger(new SimpleTrigger(AdEnabledPlayerTriggerType.NO_MORE_ADS_SKIP_TRANSITION));
} catch (Exception ex) {
Logger.printException(() -> "Failed skipping ads", ex);
}
}
}

View File

@@ -0,0 +1,17 @@
plugins {
id(libs.plugins.android.library.get().pluginId)
}
android {
namespace = "app.revanced.extension"
compileSdk = 34
defaultConfig {
minSdk = 21
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}

View File

@@ -0,0 +1 @@
<manifest/>

View File

@@ -0,0 +1,6 @@
package com.amazon.avod.fsm;
public final class SimpleTrigger<T> implements Trigger<T> {
public SimpleTrigger(T triggerType) {
}
}

View File

@@ -0,0 +1,7 @@
package com.amazon.avod.fsm;
public abstract class StateBase<S, T> {
// This method orginally has protected access (modified in patch code).
public void doTrigger(Trigger<T> trigger) {
}
}

View File

@@ -0,0 +1,4 @@
package com.amazon.avod.fsm;
public interface Trigger<T> {
}

View File

@@ -0,0 +1,7 @@
package com.amazon.avod.media;
public final class TimeSpan {
public long getTotalMilliseconds() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,7 @@
package com.amazon.avod.media.ads;
import com.amazon.avod.media.TimeSpan;
public interface AdBreak {
TimeSpan getDurationExcludingAux();
}

View File

@@ -0,0 +1,4 @@
package com.amazon.avod.media.ads.internal.state;
public abstract class AdBreakState extends AdEnabledPlaybackState {
}

View File

@@ -0,0 +1,18 @@
package com.amazon.avod.media.ads.internal.state;
import com.amazon.avod.media.ads.AdBreak;
import com.amazon.avod.media.TimeSpan;
public class AdBreakTrigger {
public AdBreak getBreak() {
throw new UnsupportedOperationException();
}
public TimeSpan getSeekTarget() {
throw new UnsupportedOperationException();
}
public TimeSpan getSeekStartPosition() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,8 @@
package com.amazon.avod.media.ads.internal.state;
import com.amazon.avod.fsm.StateBase;
import com.amazon.avod.media.playback.state.PlayerStateType;
import com.amazon.avod.media.playback.state.trigger.PlayerTriggerType;
public class AdEnabledPlaybackState extends StateBase<PlayerStateType, PlayerTriggerType> {
}

View File

@@ -0,0 +1,5 @@
package com.amazon.avod.media.ads.internal.state;
public enum AdEnabledPlayerTriggerType {
NO_MORE_ADS_SKIP_TRANSITION
}

View File

@@ -0,0 +1,4 @@
package com.amazon.avod.media.ads.internal.state;
public class ServerInsertedAdBreakState extends AdBreakState {
}

View File

@@ -0,0 +1,7 @@
package com.amazon.avod.media.playback;
public interface VideoPlayer {
long getCurrentPosition();
void seekTo(long positionMs);
}

View File

@@ -0,0 +1,4 @@
package com.amazon.avod.media.playback.state;
public interface PlayerStateType {
}

View File

@@ -0,0 +1,4 @@
package com.amazon.avod.media.playback.state.trigger;
public interface PlayerTriggerType {
}

View File

@@ -1,6 +1,7 @@
package app.revanced.extension.shared;
import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.shared.requests.Route.Method.GET;
import android.annotation.SuppressLint;
import android.app.Activity;
@@ -15,10 +16,16 @@ import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;
import app.revanced.extension.shared.requests.Requester;
import app.revanced.extension.shared.requests.Route;
@SuppressWarnings("unused")
public class GmsCoreSupport {
@@ -29,10 +36,24 @@ public class GmsCoreSupport {
= getGmsCoreVendorGroupId() + ".android.gms";
private static final Uri GMS_CORE_PROVIDER
= Uri.parse("content://" + getGmsCoreVendorGroupId() + ".android.gsf.gservices/prefix");
private static final String DONT_KILL_MY_APP_LINK
= "https://dontkillmyapp.com";
private static final String DONT_KILL_MY_APP_URL
= "https://dontkillmyapp.com/";
private static final Route DONT_KILL_MY_APP_MANUFACTURER_API
= new Route(GET, "/api/v2/{manufacturer}.json");
private static final String DONT_KILL_MY_APP_NAME_PARAMETER
= "?app=MicroG";
private static final String BUILD_MANUFACTURER
= Build.MANUFACTURER.toLowerCase(Locale.ROOT).replace(" ", "-");
/**
* If a manufacturer specific page exists on DontKillMyApp.
*/
@Nullable
private static volatile Boolean DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED;
private static void open(String queryOrLink) {
Logger.printInfo(() -> "Opening link: " + queryOrLink);
Intent intent;
try {
// Check if queryOrLink is a valid URL.
@@ -86,7 +107,7 @@ public class GmsCoreSupport {
// Do not exit. If the app exits before launch completes (and without
// opening another activity), then on some devices such as Pixel phone Android 10
// no toast will be shown and the app will continually be relaunched
// no toast will be shown and the app will continually relaunch
// with the appearance of a hung app.
}
@@ -122,11 +143,12 @@ public class GmsCoreSupport {
try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) {
if (client == null) {
Logger.printInfo(() -> "GmsCore is not running in the background");
checkIfDontKillMyAppSupportsManufacturer();
showBatteryOptimizationDialog(context,
"gms_core_dialog_not_whitelisted_not_allowed_in_background_message",
"gms_core_dialog_open_website_text",
(dialog, id) -> open(DONT_KILL_MY_APP_LINK));
(dialog, id) -> openDontKillMyApp());
}
}
} catch (Exception ex) {
@@ -141,6 +163,48 @@ public class GmsCoreSupport {
activity.startActivityForResult(intent, 0);
}
private static void checkIfDontKillMyAppSupportsManufacturer() {
Utils.runOnBackgroundThread(() -> {
try {
final long start = System.currentTimeMillis();
HttpURLConnection connection = Requester.getConnectionFromRoute(
DONT_KILL_MY_APP_URL, DONT_KILL_MY_APP_MANUFACTURER_API, BUILD_MANUFACTURER);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
final boolean supported = connection.getResponseCode() == 200;
Logger.printInfo(() -> "Manufacturer is " + (supported ? "" : "NOT ")
+ "listed on DontKillMyApp: " + BUILD_MANUFACTURER
+ " fetch took: " + (System.currentTimeMillis() - start) + "ms");
DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED = supported;
} catch (Exception ex) {
Logger.printInfo(() -> "Could not check if manufacturer is listed on DontKillMyApp: "
+ BUILD_MANUFACTURER, ex);
DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED = null;
}
});
}
private static void openDontKillMyApp() {
final Boolean manufacturerSupported = DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED;
String manufacturerPageToOpen;
if (manufacturerSupported == null) {
// Fetch has not completed yet. Only happens on extremely slow internet connections
// and the user spends less than 1 second reading what's on screen.
// Instead of waiting for the fetch (which may timeout),
// open the website without a vendor.
manufacturerPageToOpen = "";
} else if (manufacturerSupported) {
manufacturerPageToOpen = BUILD_MANUFACTURER;
} else {
// No manufacturer specific page exists. Open the general page.
manufacturerPageToOpen = "general";
}
open(DONT_KILL_MY_APP_URL + manufacturerPageToOpen + DONT_KILL_MY_APP_NAME_PARAMETER);
}
/**
* @return If GmsCore is not whitelisted from battery optimizations.
*/

View File

@@ -0,0 +1,13 @@
package app.revanced.extension.youtube.patches;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public final class HideRelatedVideoOverlayPatch {
/**
* Injection point.
*/
public static boolean hideRelatedVideoOverlay() {
return Settings.HIDE_RELATED_VIDEO_OVERLAY.get();
}
}

View File

@@ -139,6 +139,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("revanced_hide_emergency_box", TRUE);
public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("revanced_hide_endscreen_cards", FALSE);
public static final BooleanSetting HIDE_END_SCREEN_SUGGESTED_VIDEO = new BooleanSetting("revanced_end_screen_suggested_video", FALSE, true);
public static final BooleanSetting HIDE_RELATED_VIDEO_OVERLAY = new BooleanSetting("revanced_hide_related_video_overlay", FALSE, true);
public static final BooleanSetting HIDE_HIDE_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_channel_guidelines", TRUE);
public static final BooleanSetting HIDE_INFO_PANELS = new BooleanSetting("revanced_hide_info_panels", TRUE);
public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", FALSE);
@@ -478,4 +479,3 @@ public class Settings extends BaseSettings {
// endregion
}
}

View File

@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true
android.useAndroidX = true
kotlin.code.style = official
version = 5.23.0-dev.4
version = 5.24.0-dev.2

View File

@@ -240,6 +240,10 @@ public final class app/revanced/patches/instagram/ads/HideAdsPatchKt {
public static final fun getHideAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/instagram/misc/signature/SignatureCheckPatchKt {
public static final fun getSignatureCheckPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/irplus/ad/RemoveAdsPatchKt {
public static final fun getRemoveAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -380,6 +384,14 @@ public final class app/revanced/patches/openinghours/misc/fix/crash/FixCrashPatc
public static final fun getFixCrashPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/pandora/ads/DisableAudioAdsPatchKt {
public static final fun getDisableAudioAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/pandora/misc/EnableUnlimitedSkipsPatchKt {
public static final fun getEnableUnlimitedSkipsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/photomath/detection/deviceid/SpoofDeviceIdPatchKt {
public static final fun getGetDeviceIdPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -412,6 +424,14 @@ public final class app/revanced/patches/pixiv/ads/HideAdsPatchKt {
public static final fun getHideAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/primevideo/ads/SkipAdsPatchKt {
public static final fun getSkipAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/primevideo/misc/extension/ExtensionPatchKt {
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/protonmail/signature/RemoveSentFromSignaturePatchKt {
public static final fun getRemoveSentFromSignaturePatch ()Lapp/revanced/patcher/patch/ResourcePatch;
}
@@ -1200,6 +1220,10 @@ public final class app/revanced/patches/youtube/layout/hide/player/flyoutmenupan
public static final fun getHidePlayerFlyoutMenuPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/layout/hide/relatedvideooverlay/HideRelatedVideoOverlayPatchKt {
public static final fun getHideRelatedVideoOverlayPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatchKt {
public static final fun getDisableRollingNumberAnimationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}

View File

@@ -9,6 +9,5 @@ internal val adInjectorFingerprint = fingerprint {
parameters("L", "L")
strings(
"SponsoredContentController.insertItem",
"SponsoredContentController::Delivery",
)
}

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.instagram.misc.signature
import app.revanced.patcher.fingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal val isValidSignatureClassFingerprint = fingerprint {
strings("The provider for uri '", "' is not trusted: ")
}
internal val isValidSignatureMethodFingerprint = fingerprint {
parameters("L", "Z")
returns("Z")
custom { method, _ ->
method.indexOfFirstInstruction {
getReference<MethodReference>()?.name == "keySet"
} >= 0
}
}

View File

@@ -0,0 +1,19 @@
package app.revanced.patches.instagram.misc.signature
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.returnEarly
@Suppress("unused")
val signatureCheckPatch = bytecodePatch(
name = "Disable signature check",
description = "Disables the signature check that causes the app to crash on startup."
) {
compatibleWith("com.instagram.android"("378.0.0.52.68"))
execute {
isValidSignatureMethodFingerprint
.match(isValidSignatureClassFingerprint.classDef)
.method
.returnEarly(true)
}
}

View File

@@ -4,10 +4,10 @@ import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val jwUtilCreateAdvertisementFingerprint = fingerprint {
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
internal val jwPlayerConfigFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC)
custom { methodDef, classDef ->
classDef.type == "Lnl/sanomamedia/android/nu/video/util/JWUtil;" && methodDef.name == "createAdvertising"
classDef.type == "Lcom/jwplayer/pub/api/configuration/PlayerConfig${'$'}Builder;" && methodDef.name == "advertisingConfig"
}
}

View File

@@ -2,8 +2,11 @@ package app.revanced.patches.nunl.ads
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
@@ -11,23 +14,15 @@ val hideAdsPatch = bytecodePatch(
name = "Hide ads",
description = "Hide ads and sponsored articles in list pages and remove pre-roll ads on videos.",
) {
compatibleWith("nl.sanomamedia.android.nu"("11.0.0", "11.0.1", "11.1.0"))
compatibleWith("nl.sanomamedia.android.nu"("11.3.0"))
dependsOn(sharedExtensionPatch("nunl", mainActivityOnCreateHook))
execute {
// Disable video pre-roll ads.
// Whenever the app tries to create an ad via JWUtils.createAdvertising, don't actually tell the underlying JWPlayer library to do so => JWPlayer will not display ads.
jwUtilCreateAdvertisementFingerprint.method.addInstructions(
0,
"""
new-instance v0, Lcom/jwplayer/pub/api/configuration/ads/VastAdvertisingConfig${'$'}Builder;
invoke-direct { v0 }, Lcom/jwplayer/pub/api/configuration/ads/VastAdvertisingConfig${'$'}Builder;-><init>()V
invoke-virtual { v0 }, Lcom/jwplayer/pub/api/configuration/ads/VastAdvertisingConfig${'$'}Builder;->build()Lcom/jwplayer/pub/api/configuration/ads/VastAdvertisingConfig;
move-result-object v0
return-object v0
""",
)
// Whenever the app tries to define the advertising config for JWPlayer, don't set the advertising config and directly return.
val iputInstructionIndex = jwPlayerConfigFingerprint.method.indexOfFirstInstructionOrThrow(Opcode.IPUT_OBJECT)
jwPlayerConfigFingerprint.method.removeInstructions(iputInstructionIndex, 1)
// Filter injected content from API calls out of lists.
arrayOf(screenMapperFingerprint, nextPageRepositoryImplFingerprint).forEach {

View File

@@ -0,0 +1,30 @@
package app.revanced.patches.pandora.ads
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.pandora.shared.constructUserDataFingerprint
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
val disableAudioAdsPatch = bytecodePatch(
name = "Disable audio ads",
) {
compatibleWith("com.pandora.android")
execute {
constructUserDataFingerprint.method.apply {
// First match is "hasAudioAds".
val hasAudioAdsStringIndex = constructUserDataFingerprint.stringMatches!!.first().index
val moveResultIndex = indexOfFirstInstructionOrThrow(hasAudioAdsStringIndex, Opcode.MOVE_RESULT)
val hasAudioAdsRegister = getInstruction<OneRegisterInstruction>(moveResultIndex).registerA
addInstruction(
moveResultIndex + 1,
"const/4 v$hasAudioAdsRegister, 0"
)
}
}
}

View File

@@ -0,0 +1,31 @@
package app.revanced.patches.pandora.misc
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.pandora.shared.constructUserDataFingerprint
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
val enableUnlimitedSkipsPatch = bytecodePatch(
name = "Enable unlimited skips",
) {
compatibleWith("com.pandora.android")
execute {
constructUserDataFingerprint.method.apply {
// Last match is "skipLimitBehavior".
val skipLimitBehaviorStringIndex = constructUserDataFingerprint.stringMatches!!.last().index
val moveResultObjectIndex =
indexOfFirstInstructionOrThrow(skipLimitBehaviorStringIndex, Opcode.MOVE_RESULT_OBJECT)
val skipLimitBehaviorRegister = getInstruction<OneRegisterInstruction>(moveResultObjectIndex).registerA
addInstruction(
moveResultObjectIndex + 1,
"const-string v$skipLimitBehaviorRegister, \"unlimited\""
)
}
}
}

View File

@@ -0,0 +1,7 @@
package app.revanced.patches.pandora.shared
import app.revanced.patcher.fingerprint
internal val constructUserDataFingerprint = fingerprint {
strings("hasAudioAds", "skipLimitBehavior")
}

View File

@@ -0,0 +1,33 @@
package app.revanced.patches.primevideo.ads
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val enterServerInsertedAdBreakStateFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC)
parameters("Lcom/amazon/avod/fsm/Trigger;")
returns("V")
opcodes(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.CONST_4
)
custom { method, classDef ->
method.name == "enter" && classDef.type == "Lcom/amazon/avod/media/ads/internal/state/ServerInsertedAdBreakState;"
}
}
internal val doTriggerFingerprint = fingerprint {
accessFlags(AccessFlags.PROTECTED)
returns("V")
opcodes(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.RETURN_VOID
)
custom { method, classDef ->
method.name == "doTrigger" && classDef.type == "Lcom/amazon/avod/fsm/StateBase;"
}
}

View File

@@ -0,0 +1,45 @@
package app.revanced.patches.primevideo.ads
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.primevideo.misc.extension.sharedExtensionPatch
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
val skipAdsPatch = bytecodePatch(
name = "Skip ads",
description = "Automatically skips video stream ads.",
) {
compatibleWith("com.amazon.avod.thirdpartyclient"("3.0.403.257"))
dependsOn(sharedExtensionPatch)
// Skip all the logic in ServerInsertedAdBreakState.enter(), which plays all the ad clips in this
// ad break. Instead, force the video player to seek over the entire break and reset the state machine.
execute {
// Force doTrigger() access to public so we can call it from our extension.
doTriggerFingerprint.method.accessFlags = AccessFlags.PUBLIC.value;
val getPlayerIndex = enterServerInsertedAdBreakStateFingerprint.patternMatch!!.startIndex
enterServerInsertedAdBreakStateFingerprint.method.apply {
// Get register that stores VideoPlayer:
// invoke-virtual ->getPrimaryPlayer()
// move-result-object { playerRegister }
val playerRegister = getInstruction<OneRegisterInstruction>(getPlayerIndex + 1).registerA
// Reuse the params from the original method:
// p0 = ServerInsertedAdBreakState
// p1 = AdBreakTrigger
addInstructions(
getPlayerIndex + 2,
"""
invoke-static { p0, p1, v$playerRegister }, Lapp/revanced/extension/primevideo/ads/SkipAdsPatch;->enterServerInsertedAdBreakState(Lcom/amazon/avod/media/ads/internal/state/ServerInsertedAdBreakState;Lcom/amazon/avod/media/ads/internal/state/AdBreakTrigger;Lcom/amazon/avod/media/playback/VideoPlayer;)V
return-void
"""
)
}
}
}

View File

@@ -0,0 +1,5 @@
package app.revanced.patches.primevideo.misc.extension
import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
val sharedExtensionPatch = sharedExtensionPatch("primevideo", applicationInitHook)

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.primevideo.misc.extension
import app.revanced.patches.shared.misc.extension.extensionHook
internal val applicationInitHook = extensionHook {
custom { method, classDef ->
method.name == "onCreate" && classDef.endsWith("/SplashScreenActivity;")
}
}

View File

@@ -2,8 +2,12 @@ package app.revanced.patches.spotify.misc
import app.revanced.patcher.fingerprint
import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET
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.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
internal val accountAttributeFingerprint = fingerprint {
custom { _, classDef ->
@@ -15,7 +19,7 @@ internal val accountAttributeFingerprint = fingerprint {
}
}
internal val productStateProtoFingerprint = fingerprint {
internal val productStateProtoGetMapFingerprint = fingerprint {
returns("Ljava/util/Map;")
custom { _, classDef ->
classDef.type == if (IS_SPOTIFY_LEGACY_APP_TARGET) {
@@ -56,16 +60,40 @@ internal val readPlayerOptionOverridesFingerprint = fingerprint {
}
}
internal val homeSectionFingerprint = fingerprint {
custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") }
}
internal val protobufListsFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
custom { method, _ -> method.name == "emptyProtobufList" }
}
internal val homeStructureFingerprint = fingerprint {
opcodes(Opcode.IGET_OBJECT, Opcode.RETURN_OBJECT)
custom { _, classDef -> classDef.endsWith("homeapi/proto/HomeStructure;") }
internal val protobufListRemoveFingerprint = fingerprint {
custom { method, _ -> method.name == "remove" }
}
internal val homeSectionFingerprint = fingerprint {
custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") }
}
internal val homeStructureGetSectionsFingerprint = fingerprint {
custom { method, classDef ->
classDef.endsWith("homeapi/proto/HomeStructure;") && method.indexOfFirstInstruction {
opcode == Opcode.IGET_OBJECT && getReference<FieldReference>()?.name == "sections_"
} >= 0
}
}
internal fun reactivexFunctionApplyWithClassInitFingerprint(className: String) = fingerprint {
returns("Ljava/lang/Object;")
parameters("Ljava/lang/Object;")
custom { method, _ -> method.name == "apply" && method.indexOfFirstInstruction {
opcode == Opcode.NEW_INSTANCE && getReference<TypeReference>()?.type?.endsWith(className) == true
} >= 0
}
}
internal const val PENDRAGON_JSON_FETCH_MESSAGE_REQUEST_CLASS_NAME = "FetchMessageRequest;"
internal val pendragonJsonFetchMessageRequestFingerprint =
reactivexFunctionApplyWithClassInitFingerprint(PENDRAGON_JSON_FETCH_MESSAGE_REQUEST_CLASS_NAME)
internal const val PENDRAGON_PROTO_FETCH_MESSAGE_LIST_REQUEST_CLASS_NAME = "FetchMessageListRequest;"
internal val pendragonProtoFetchMessageListRequestFingerprint =
reactivexFunctionApplyWithClassInitFingerprint(PENDRAGON_PROTO_FETCH_MESSAGE_LIST_REQUEST_CLASS_NAME)

View File

@@ -60,4 +60,4 @@ val spoofPackageInfoPatch = bytecodePatch(
// endregion
}
}
}
}

View File

@@ -14,4 +14,4 @@ internal val mainActivityOnCreateFingerprint = fingerprint {
method.name == "onCreate" && (classDef.type == SPOTIFY_MAIN_ACTIVITY
|| classDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY)
}
}
}

View File

@@ -0,0 +1,18 @@
package app.revanced.patches.youtube.layout.hide.relatedvideooverlay
import app.revanced.patcher.fingerprint
import app.revanced.util.literal
internal val relatedEndScreenResultsParentFingerprint = fingerprint {
returns("V")
literal{ appRelatedEndScreenResults }
}
internal val relatedEndScreenResultsFingerprint = fingerprint {
returns("V")
parameters(
"I",
"Z",
"I",
)
}

View File

@@ -0,0 +1,83 @@
package app.revanced.patches.youtube.layout.hide.relatedvideooverlay
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.mapping.get
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patcher.util.smali.ExternalLabel
internal var appRelatedEndScreenResults = -1L
private set
private val hideRelatedVideoOverlayResourcePatch = resourcePatch {
dependsOn(
resourceMappingPatch,
)
execute {
appRelatedEndScreenResults = resourceMappings[
"layout",
"app_related_endscreen_results",
]
}
}
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/HideRelatedVideoOverlayPatch;"
@Suppress("unused")
val hideRelatedVideoOverlayPatch = bytecodePatch(
name = "Hide related video overlay",
description = "Adds an option to hide the related video overlay shown when swiping up in fullscreen.",
) {
dependsOn(
settingsPatch,
sharedExtensionPatch,
addResourcesPatch,
hideRelatedVideoOverlayResourcePatch,
)
compatibleWith(
"com.google.android.youtube"(
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
"19.47.53",
"20.07.39",
"20.12.46",
)
)
execute {
addResources("youtube", "layout.hide.relatedvideooverlay.hideRelatedVideoOverlayPatch")
PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_related_video_overlay")
)
relatedEndScreenResultsFingerprint.match(
relatedEndScreenResultsParentFingerprint.originalClassDef
).method.apply {
addInstructionsWithLabels(
0,
"""
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->hideRelatedVideoOverlay()Z
move-result v0
if-eqz v0, :show
return-void
""",
ExternalLabel("show", getInstruction(0))
)
}
}
}

View File

@@ -18,6 +18,7 @@ import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.util.InstructionUtils.Companion.branchOpcodes
import app.revanced.util.InstructionUtils.Companion.returnOpcodes
import app.revanced.util.InstructionUtils.Companion.writeOpcodes
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.Opcode.*
import com.android.tools.smali.dexlib2.iface.Method
@@ -169,6 +170,15 @@ internal val Instruction.isBranchInstruction: Boolean
internal val Instruction.isReturnInstruction: Boolean
get() = this.opcode in returnOpcodes
/**
* Adds public [AccessFlags] and removes private and protected flags (if present).
*/
internal fun Int.toPublicAccessFlags() : Int {
return this.or(AccessFlags.PUBLIC.value)
.and(AccessFlags.PROTECTED.value.inv())
.and(AccessFlags.PRIVATE.value.inv())
}
/**
* Find the [MutableMethod] from a given [Method] in a [MutableClass].
*
@@ -494,7 +504,7 @@ fun Method.indexOfFirstInstruction(startIndex: Int = 0, targetOpcode: Opcode): I
* @see indexOfFirstInstructionOrThrow
*/
fun Method.indexOfFirstInstruction(startIndex: Int = 0, filter: Instruction.() -> Boolean): Int {
var instructions = this.implementation!!.instructions
var instructions = this.implementation?.instructions ?: return -1
if (startIndex != 0) {
instructions = instructions.drop(startIndex)
}
@@ -560,7 +570,7 @@ fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, targetOpcode
* @see indexOfFirstInstructionReversedOrThrow
*/
fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, filter: Instruction.() -> Boolean): Int {
var instructions = this.implementation!!.instructions
var instructions = this.implementation?.instructions ?: return -1
if (startIndex != null) {
instructions = instructions.take(startIndex + 1)
}

View File

@@ -851,8 +851,8 @@ Second \"item\" text"</string>
<string name="revanced_ryd_estimated_like_summary_on">Τα βίντεο με απενεργοποιημένα «Μου αρέσει» εμφανίζουν έναν εκτιμώμενο αριθμό «Μου αρέσει»</string>
<string name="revanced_ryd_estimated_like_summary_off">Τα εκτιμώμενα «Μου αρέσει» δεν εμφανίζονται</string>
<string name="revanced_ryd_toast_on_connection_error_title">Εμφάνιση μηνύματος αν το API δεν είναι διαθέσιμο</string>
<string name="revanced_ryd_toast_on_connection_error_summary_on">Να εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το Return YouTube Dislike δεν είναι διαθέσιμο</string>
<string name="revanced_ryd_toast_on_connection_error_summary_off">Να μην εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το Return YouTube Dislike δεν είναι διαθέσιμο</string>
<string name="revanced_ryd_toast_on_connection_error_summary_on">Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το Return YouTube Dislike δεν είναι διαθέσιμο</string>
<string name="revanced_ryd_toast_on_connection_error_summary_off">Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το Return YouTube Dislike δεν είναι διαθέσιμο</string>
<string name="revanced_ryd_about">Σχετικά με</string>
<string name="revanced_ryd_attribution_summary">Τα δεδομένα Dislike παρέχονται από το API του Return YouTube Dislike. Πατήστε εδώ για να μάθετε περισσότερα</string>
<!-- Statistic strings are shown in the settings only when ReVanced debug mode is enabled. Typical users will never see these. -->
@@ -911,8 +911,8 @@ Second \"item\" text"</string>
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_on">Το κουμπί παράλειψης κρύβεται μετά από μερικά δευτερόλεπτα</string>
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_off">Το κουμπί παράλειψης εμφανίζεται σε όλο το τμήμα</string>
<string name="revanced_sb_general_skiptoast">Εμφάνιση μηνύματος κατά την παράλειψη</string>
<string name="revanced_sb_general_skiptoast_sum_on">Να εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης όταν ένα τμήμα παραλείπεται αυτόματα. Πατήστε για να δείτε ένα παράδειγμα</string>
<string name="revanced_sb_general_skiptoast_sum_off">Να μην εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης. Πατήστε για να δείτε ένα παράδειγμα</string>
<string name="revanced_sb_general_skiptoast_sum_on">Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης όταν ένα τμήμα παραλείπεται αυτόματα. Πατήστε για να δείτε ένα παράδειγμα</string>
<string name="revanced_sb_general_skiptoast_sum_off">Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης. Πατήστε για να δείτε ένα παράδειγμα</string>
<string name="revanced_sb_general_time_without">Εμφάνιση μήκους βίντεο χωρίς τα τμήματα</string>
<string name="revanced_sb_general_time_without_sum_on">Εμφανίζεται το μήκος βίντεο μείον όλα τα τμήματα, σε παρένθεση δίπλα στο πλήρες μήκος βίντεο</string>
<string name="revanced_sb_general_time_without_sum_off">Εμφανίζεται το πλήρες μήκος του βίντεο</string>
@@ -931,8 +931,8 @@ Second \"item\" text"</string>
<string name="revanced_sb_guidelines_popup_open">Δείξτε μου</string>
<string name="revanced_sb_general">Γενικά</string>
<string name="revanced_sb_toast_on_connection_error_title">Εμφάνιση μηνύματος αν το API δεν είναι διαθέσιμο</string>
<string name="revanced_sb_toast_on_connection_error_summary_on">Να εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το SponsorBlock δεν είναι διαθέσιμο</string>
<string name="revanced_sb_toast_on_connection_error_summary_off">Να μην εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το SponsorBlock δεν είναι διαθέσιμο</string>
<string name="revanced_sb_toast_on_connection_error_summary_on">Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το SponsorBlock δεν είναι διαθέσιμο</string>
<string name="revanced_sb_toast_on_connection_error_summary_off">Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το SponsorBlock δεν είναι διαθέσιμο</string>
<string name="revanced_sb_general_skipcount">Mετρητής παραλείψεων τμημάτων</string>
<string name="revanced_sb_general_skipcount_sum_on">Επιτρέπει στον πίνακα κατάταξης SponsorBlock να γνωρίζει πόσος χρόνος εξοικονομήθηκε. Αποστέλλεται ένα μήνυμα στον πίνακα κατάταξης κάθε φορά που παραλείπεται ένα τμήμα</string>
<string name="revanced_sb_general_skipcount_sum_off">Ο μετρητής παραλείψεων δεν είναι ενεργός</string>
@@ -1261,8 +1261,8 @@ Second \"item\" text"</string>
Πατήστε για να μάθετε περισσότερα για το DeArrow"</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_title">Εμφάνιση μηνύματος αν το API δεν είναι διαθέσιμο</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">Να εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το DeArrow δεν είναι διαθέσιμο</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">Να μην εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το DeArrow δεν είναι διαθέσιμο</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το DeArrow δεν είναι διαθέσιμο</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης αν το DeArrow δεν είναι διαθέσιμο</string>
<string name="revanced_alt_thumbnail_dearrow_api_url_title">Διεύθυνση API του DeArrow</string>
<string name="revanced_alt_thumbnail_dearrow_api_url_summary">Η διεύθυνση URL του τελικού σημείου αποθήκευσης μικρογραφιών DeArrow</string>
<string name="revanced_alt_thumbnail_stills_about_title">Λήψεις ακίνητων καρέ</string>

View File

@@ -114,9 +114,9 @@ Brúigh an cnaipe leanúnaí agus ligean athruithe optúimíochta."</string>
<string name="revanced_debug_toast_on_error_title">Taispeáin tósta ar earráid ReVanced</string>
<string name="revanced_debug_toast_on_error_summary_on">Taispeántar toast má tharlaíonn earráid</string>
<string name="revanced_debug_toast_on_error_summary_off">Ní thaispeántar toast má tharlaíonn earráid</string>
<string name="revanced_debug_toast_on_error_user_dialog_message">"Díchumasaíonn an rogha toasts earráide fógraí earráide ReVanced go léir.
<string name="revanced_debug_toast_on_error_user_dialog_message">"Má mhúchtar tóstaí earráide, folaítear gach fógra earráide ReVanced.
bheidh a fhios agat faoi aon imeachtaí neamhghnácha."</string>
chuirfear ar an eolas thú faoi aon imeachtaí gan choinne."</string>
</patch>
<patch id="layout.hide.general.hideLayoutComponentsPatch">
<string name="revanced_hide_album_cards_title">Folaigh cártaí albam</string>
@@ -205,11 +205,11 @@ Ní bheidh a fhios agat faoi aon imeachtaí neamhghnácha."</string>
<string name="revanced_hide_medical_panels_summary_on">Tá painéil leighis i bhfolach</string>
<string name="revanced_hide_medical_panels_summary_off">Taispeántar painéil leighis</string>
<string name="revanced_hide_channel_bar_title">Folaigh barra cainéal</string>
<string name="revanced_hide_channel_bar_summary_on">Tá barra cainéal i bhfolach</string>
<string name="revanced_hide_channel_bar_summary_off">Taispeántar barra cainéal</string>
<string name="revanced_hide_playables_title">Folaigh Rudaí Inimeartha</string>
<string name="revanced_hide_playables_summary_on">rudaí inimeartha i bhfolach</string>
<string name="revanced_hide_playables_summary_off">Taispeántar rudaí inimeartha</string>
<string name="revanced_hide_channel_bar_summary_on"> an barra Cainéal i bhfolach</string>
<string name="revanced_hide_channel_bar_summary_off">Taispeántar barra an chainéil</string>
<string name="revanced_hide_playables_title">Folaigh na heilimintí inseinnte</string>
<string name="revanced_hide_playables_summary_on">na heilimintí inseinnte i bhfolach</string>
<string name="revanced_hide_playables_summary_off">Taispeántar na heilimintí inseinnte</string>
<string name="revanced_hide_quick_actions_title">Folaigh gníomhartha gasta i lánscáileán</string>
<string name="revanced_hide_quick_actions_summary_on">Tá gníomhartha gasta i bhfolach</string>
<string name="revanced_hide_quick_actions_summary_off">Taispeántar gníomhartha tapa</string>

View File

@@ -333,9 +333,9 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ
<string name="revanced_hide_keyword_content_about_summary">"ホーム / 登録チャンネル / 検索結果からキーワードに合致する動画を除外します
制限事項
• ショート動画はチャンネル名で除外できません
• 一部の UI コンポーネントが残ってしまう場合があります
• キーワードを検索しても、結果が表示されない場合があります"</string>
• ショート動画はチャンネル名で除外されない
• 一部の UI コンポーネントが残ってしまう場合があ
• キーワードを検索したとき、結果が表示されない場合があ"</string>
<string name="revanced_hide_keyword_content_about_whole_words_title">単語全体で合致させる</string>
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
<string name="revanced_hide_keyword_content_about_whole_words_summary">キーワードを二重引用符で囲むことで、動画のタイトルやチャンネル名の単語の一部とキーワードが合致しないようにできます&lt;br&gt;&lt;br&gt;例えば、&lt;br&gt;&lt;b&gt;\"ai\"&lt;/b&gt;は、次の動画を除外します:&lt;b&gt;How does AI work?&lt;/b&gt;&lt;br&gt;しかし、次の動画は除外しません:&lt;b&gt;What does fair use mean?&lt;/b&gt;</string>
@@ -1099,11 +1099,11 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ
<string name="revanced_change_form_factor_user_dialog_message">"変更点は以下のとおりです:
タブレット レイアウト
• コミュニティ投稿が表示されません
• コミュニティ投稿が表示されない
Automotive レイアウト
• ショート動画を通常のプレーヤーで開きます
• フィードがトピックとチャンネルで分類されます"</string>
• ショート動画を通常のプレーヤーで開
• フィードがトピックとチャンネルで分類され"</string>
</patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">アプリのバージョンを偽装する</string>
@@ -1189,8 +1189,8 @@ Automotive レイアウト
<string name="revanced_miniplayer_double_tap_action_title">「ダブルタップとピンチでサイズ変更」を有効にする</string>
<string name="revanced_miniplayer_double_tap_action_summary_on">"「ダブルタップとピンチでサイズ変更」は有効です
• ダブルタップミニプレーヤーのサイズ大きくします
• もう一度ダブルタップすると、元のサイズに戻ります"</string>
• ダブルタップすると、ミニプレーヤーのサイズ大きくなる
• もう一度ダブルタップすると、元のサイズに戻"</string>
<string name="revanced_miniplayer_double_tap_action_summary_off">「 ダブルタップとピンチでサイズ変更」は無効です</string>
<string name="revanced_miniplayer_drag_and_drop_title">ドラッグ&ドロップを有効にする</string>
<string name="revanced_miniplayer_drag_and_drop_summary_on">"ドラッグ&ドロップは有効です
@@ -1399,13 +1399,13 @@ Automotive レイアウト
</patch>
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
<string name="revanced_spoof_video_streams_screen_title">動画ストリームを偽装する</string>
<string name="revanced_spoof_video_streams_screen_summary">再生不能問題を回避するために、クライアントの動画ストリームを偽装します</string>
<string name="revanced_spoof_video_streams_screen_summary">動画の再生に失敗しないために、クライアントの動画ストリームを偽装します</string>
<string name="revanced_spoof_video_streams_title">動画ストリームを偽装する</string>
<string name="revanced_spoof_video_streams_summary_on">動画ストリームは偽装されます</string>
<string name="revanced_spoof_video_streams_summary_off">"動画ストリームは偽装されません
動画再生されない可能性があります"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">この設定をオフにすると、動画再生されなくなる可能性があります。</string>
動画再生に失敗する可能性があります"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">この設定をオフにすると、動画再生に失敗するようになる可能性があります。</string>
<string name="revanced_spoof_video_streams_client_type_title">デフォルトのクライアント</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">iOS クライアントで AVC (H.264) を強制的に使用する</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">ビデオ コーデックは強制的に AVC (H.264) が使用されます</string>
@@ -1414,15 +1414,15 @@ Automotive レイアウト
AVC は、最大解像度が 1080p であり、Opus オーディオ コーデックが利用できず、動画再生時の通信量が VP9 や AV1 より多くなります。"</string>
<string name="revanced_spoof_video_streams_about_ios_tv_title">iOS クライアントの副作用</string>
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• 映画や有料動画が再生されない可能性があります
•「 一定音量」が利用できません
• 動画が 1 秒早く終了します"</string>
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• 映画や有料動画が再生されない可能性があ
•「 一定音量」が利用できない
• 動画が 1 秒早く終了す"</string>
<string name="revanced_spoof_video_streams_about_android_title">Android クライアントの副作用</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• 「音声トラック」がフライアウト メニューに表示されません
• 「一定音量」が利用できません
• 「デフォルトの吹き替えを無効にする」が利用できません"</string>
<string name="revanced_spoof_video_streams_about_no_av1">• AV1 コーデックが利用できません</string>
<string name="revanced_spoof_video_streams_about_kids_videos">• ログアウト時またはシークレット モード時に、子ども向け動画が再生されない可能性があります</string>
<string name="revanced_spoof_video_streams_about_android_summary">"• 「音声トラック」がフライアウト メニューに表示されない
• 「一定音量」が利用できない
• 「デフォルトの吹き替えを無効にする」が利用できない"</string>
<string name="revanced_spoof_video_streams_about_no_av1">• AV1 コーデックが利用できない</string>
<string name="revanced_spoof_video_streams_about_kids_videos">• ログアウト時またはシークレット モード時に、子ども向け動画が再生されない可能性があ</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">統計情報に表示する</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">現在のクライアントが統計情報に表示されます</string>
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">現在のクライアントは統計情報に表示されません</string>

View File

@@ -55,7 +55,7 @@ Second \"item\" text"</string>
<!-- Settings about dialog. -->
<string name="revanced_settings_about_links_body">ReVanced Patches &lt;i&gt;%s&lt;/i&gt;&lt;br&gt;버전을 사용 중입니다</string>
<string name="revanced_settings_about_links_dev_header">알림</string>
<string name="revanced_settings_about_links_dev_body">개발자 버전이므로&lt;br&gt;알려지지 않은 문제점이&lt;br&gt;발생할 수 있습니다</string>
<string name="revanced_settings_about_links_dev_body">Pre-Release 버전이므로&lt;br&gt;알려지지 않은 문제점이&lt;br&gt;발생할 수 있습니다</string>
<string name="revanced_settings_about_links_header">공식 링크</string>
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
and changes made here must also be made there. -->
@@ -975,7 +975,7 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배
<string name="revanced_sb_segments_filler">주제와 관련 없는 구간</string>
<string name="revanced_sb_segments_filler_sum">전반적인 동영상의 주제를 이해하는 데 필요 없는 내용을 포함하고 있습니다</string>
<string name="revanced_sb_segments_nomusic">음악이 아닌 구간</string>
<string name="revanced_sb_segments_nomusic_sum">뮤직 비디오에서 음악이 아닌 구간이 해당됩니다</string>
<string name="revanced_sb_segments_nomusic_sum">음악 동영상에서 음악이 아닌 구간이 해당됩니다</string>
<string name="revanced_sb_skip_button_compact">건너뛰기</string>
<string name="revanced_sb_skip_button_compact_highlight">하이라이트</string>
<string name="revanced_sb_skip_button_sponsor">스폰서 광고 건너뛰기</string>
@@ -1035,7 +1035,7 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배
<string name="revanced_sb_vote_segment_time_to_from">%1$s ~ %2$s</string>
<string name="revanced_sb_new_segment_choose_category">구간 카테고리를 선택하세요</string>
<string name="revanced_sb_new_segment_disabled_category">이 카테고리는 비활성화되어 있습니다. 제출하려면 설정에서 활성화해야 합니다.</string>
<string name="revanced_sb_new_segment_title">새 SponsorBlock 구간</string>
<string name="revanced_sb_new_segment_title">로운 SponsorBlock 구간</string>
<string name="revanced_sb_new_segment_mark_time_as_question">%s 을 구간의 시작 또는 끝으로 설정하시겠습니까?</string>
<string name="revanced_sb_new_segment_mark_start">시작</string>
<string name="revanced_sb_new_segment_mark_end"></string>

View File

@@ -495,12 +495,12 @@ Second \"item\" text"</string>
<patch id="layout.buttons.action.hideButtonsPatch">
<string name="revanced_hide_buttons_screen_title">Кнопки дій</string>
<string name="revanced_hide_buttons_screen_summary">Приховати або показувати кнопки дій під відео</string>
<string name="revanced_disable_like_subscribe_glow_title">Вимкнути відблиск кнопок \"Подобається\" та \"Підписати\"</string>
<string name="revanced_disable_like_subscribe_glow_summary_on">Кнопки \"Подобається\" та \"Підписатися\" не відблискуватимуть при згадуванні</string>
<string name="revanced_disable_like_subscribe_glow_summary_off">Кнопки \"Подобається\" та \"Підписатися\" не відблискуватимуть при згадуванні</string>
<string name="revanced_hide_like_dislike_button_title">Приховати \"Подобається\" та \"Не подобається\"</string>
<string name="revanced_hide_like_dislike_button_summary_on">Кнопки \"Подобається\" та \"Не подобається\" приховано</string>
<string name="revanced_hide_like_dislike_button_summary_off">Кнопки \"Подобається\" та \"Не подобається\" показуються</string>
<string name="revanced_disable_like_subscribe_glow_title">Вимкнути блимання кнопок \"Лайк\" та \"Підписатися\"</string>
<string name="revanced_disable_like_subscribe_glow_summary_on">Кнопки \"Лайк\" та \"Підписатися\" не будуть блимати при згадуванні</string>
<string name="revanced_disable_like_subscribe_glow_summary_off">Кнопки \"Лайк\" та \"Підписатися\" не будуть блимати при згадуванні</string>
<string name="revanced_hide_like_dislike_button_title">Приховати \"Лайк\" та \"Дизлайк\"</string>
<string name="revanced_hide_like_dislike_button_summary_on">Кнопки \"Лайк\" та \"Дизлайк\" приховано</string>
<string name="revanced_hide_like_dislike_button_summary_off">Кнопки \"Лайк\" та \"Дизлайк\" показуються</string>
<!-- 'Share' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_share_button_title">Приховати \"Поділитися\"</string>
<string name="revanced_hide_share_button_summary_on">Кнопку \"Поділитися\" приховано</string>
@@ -745,14 +745,14 @@ Second \"item\" text"</string>
<string name="revanced_hide_shorts_stickers_summary_on">Стікери приховано</string>
<string name="revanced_hide_shorts_stickers_summary_off">Стікери показуються</string>
<string name="revanced_hide_shorts_like_fountain_title">Приховати анімацію фонтану</string>
<string name="revanced_hide_shorts_like_fountain_summary_on">Анімацію фонтану біля кнопки \"Подобається\" приховано</string>
<string name="revanced_hide_shorts_like_fountain_summary_off">Анімація фонтану біля кнопки \"Подобається\" показується</string>
<string name="revanced_hide_shorts_like_button_title">Приховати \"Подобається\"</string>
<string name="revanced_hide_shorts_like_button_summary_on">Кнопку \"Подобається\" приховано</string>
<string name="revanced_hide_shorts_like_button_summary_off">Кнопка \"Подобається\" показується</string>
<string name="revanced_hide_shorts_dislike_button_title">Приховати \"Не подобається\"</string>
<string name="revanced_hide_shorts_dislike_button_summary_on">Кнопку \"Не подобається\" приховано</string>
<string name="revanced_hide_shorts_dislike_button_summary_off">Кнопка \"Не подобається\" показується</string>
<string name="revanced_hide_shorts_like_fountain_summary_on">Анімацію фонтану біля кнопки \"Лайк\" приховано</string>
<string name="revanced_hide_shorts_like_fountain_summary_off">Анімація фонтану біля кнопки \"Лайк\" показується</string>
<string name="revanced_hide_shorts_like_button_title">Приховати \"Лайк\"</string>
<string name="revanced_hide_shorts_like_button_summary_on">Кнопку \"Лайк\" приховано</string>
<string name="revanced_hide_shorts_like_button_summary_off">Кнопка \"Лайк\" показується</string>
<string name="revanced_hide_shorts_dislike_button_title">Приховати \"Дизлайк\"</string>
<string name="revanced_hide_shorts_dislike_button_summary_on">Кнопку \"Дизлайк\" приховано</string>
<string name="revanced_hide_shorts_dislike_button_summary_off">Кнопка \"Дизлайк\" показується</string>
<string name="revanced_hide_shorts_comments_button_title">Приховати \"Коментарі\"</string>
<string name="revanced_hide_shorts_comments_button_summary_on">Кнопку \"Коментарі\" приховано</string>
<string name="revanced_hide_shorts_comments_button_summary_off">Кнопка \"Коментарі\" показується</string>
@@ -823,43 +823,43 @@ Second \"item\" text"</string>
</patch>
<patch id="layout.returnyoutubedislike.returnYouTubeDislikePatch">
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
<string name="revanced_ryd_failure_connection_timeout">Відмітки \"Не подобається\" тимчасово недоступні (тайм-аут API)</string>
<string name="revanced_ryd_failure_connection_status_code">Відмітки \"Не подобається\" недоступні (статус %d)</string>
<string name="revanced_ryd_failure_client_rate_limit_requested">Відмітки \"Не подобається\" недоступні (ліміт клієнтів API)</string>
<string name="revanced_ryd_failure_generic">Відмітки \"Не подобається\" недоступні (%s)</string>
<string name="revanced_ryd_failure_connection_timeout">Дизлайки тимчасово недоступні (тайм-аут API)</string>
<string name="revanced_ryd_failure_connection_status_code">Дизлайки недоступні (статус %d)</string>
<string name="revanced_ryd_failure_client_rate_limit_requested">Дизлайки недоступні (ліміт клієнтів API)</string>
<string name="revanced_ryd_failure_generic">Дизлайки недоступні (%s)</string>
<!-- Toast shown if the user enables RYD while a video is opened, and then tries to vote for the video. -->
<string name="revanced_ryd_failure_ryd_enabled_while_playing_video_then_user_voted">Оновіть відео, щоб проголосувати за допомогою ReturnYouTubeDislike</string>
<string name="revanced_ryd_failure_ryd_enabled_while_playing_video_then_user_voted">Оновіть відео, щоб проголосувати за допомогою Return YouTube Dislike</string>
<!-- Video likes have been set to hidden by the video uploader. -->
<string name="revanced_ryd_video_likes_hidden_by_video_owner">Приховано власником</string>
<string name="revanced_ryd_enable_summary_on">Відмітки \"Не подобається\" показуються</string>
<string name="revanced_ryd_enable_summary_off">Відмітки \"Не подобається\" не показуються</string>
<string name="revanced_ryd_shorts_title">Відмітки \"Не подобається\" в Shorts</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Відмітки \"Не подобається\" в Shorts показуються
<string name="revanced_ryd_enable_summary_on">Дизлайки показуються</string>
<string name="revanced_ryd_enable_summary_off">Дизлайки не показуються</string>
<string name="revanced_ryd_shorts_title">Показувати дизлайки в Shorts</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Дизлайки в Shorts показуються
Обмеження: Відмітки \"Не подобається\" не можуть показуватися в анонімному режимі"</string>
<string name="revanced_ryd_shorts_summary_off">Відмітки \"Не подобається\" в Shorts не показуються</string>
<string name="revanced_ryd_dislike_percentage_title">Відмітки \"Не подобається\" у відсотках</string>
<string name="revanced_ryd_dislike_percentage_summary_on">Відмітки \"Не подобається\" показуються у відсотках</string>
<string name="revanced_ryd_dislike_percentage_summary_off">Відмітки \"Не подобається\" показуються як число</string>
Обмеження: Дизлайки не можуть показуватися в анонімному режимі"</string>
<string name="revanced_ryd_shorts_summary_off">Дизлайки в Shorts не показуються</string>
<string name="revanced_ryd_dislike_percentage_title">Дизлайки у відсотках</string>
<string name="revanced_ryd_dislike_percentage_summary_on">Дизлайки показуються у відсотках</string>
<string name="revanced_ryd_dislike_percentage_summary_off">Дизлайки показуються як число</string>
<!-- Translations should use language similar to 'revanced_sb_enable_compact_skip_button' -->
<string name="revanced_ryd_compact_layout_title">Компактна кнопка \"Подобається\"</string>
<string name="revanced_ryd_compact_layout_summary_on">Кнопку \"Подобається\" стилізовано під мінімальну ширину</string>
<string name="revanced_ryd_compact_layout_summary_off">Кнопку \"Подобається\" стилізовано для кращого вигляду</string>
<string name="revanced_ryd_estimated_like_title">Показувати приблизну кількість вподобань</string>
<string name="revanced_ryd_estimated_like_summary_on">На відео з вимкненими відмітками \"Подобається\" показується приблизна кількість вподобань</string>
<string name="revanced_ryd_estimated_like_summary_off">Приблизна кількість вподобань не показується</string>
<string name="revanced_ryd_compact_layout_title">Компактна кнопка \"Лайк\"</string>
<string name="revanced_ryd_compact_layout_summary_on">Кнопку \"Лайк\" стилізовано під мінімальну ширину</string>
<string name="revanced_ryd_compact_layout_summary_off">Кнопку \"Лайк\" стилізовано для кращого вигляду</string>
<string name="revanced_ryd_estimated_like_title">Показувати приблизну кількість лайків</string>
<string name="revanced_ryd_estimated_like_summary_on">Для відео з вимкненими лайками показується приблизна кількість лайків</string>
<string name="revanced_ryd_estimated_like_summary_off">Приблизна кількість лайків не показується</string>
<string name="revanced_ryd_toast_on_connection_error_title">Показувати тост, якщо API не доступний</string>
<string name="revanced_ryd_toast_on_connection_error_summary_on">Тост показується, якщо Return YouTube Dislike не доступний</string>
<string name="revanced_ryd_toast_on_connection_error_summary_off">Тост не показується, якщо Return YouTube Dislike не доступний</string>
<string name="revanced_ryd_about">Про інтеграцію</string>
<string name="revanced_ryd_attribution_summary">Дані надаються Return YouTube Dislike API. Натисніть тут, щоб дізнатися більше</string>
<string name="revanced_ryd_attribution_summary">Дані надаються через API Return YouTube Dislike. Натисніть тут, щоб дізнатися більше</string>
<!-- Statistic strings are shown in the settings only when ReVanced debug mode is enabled. Typical users will never see these. -->
<string name="revanced_ryd_statistics_category_title">Статистика ReturnYouTubeDislike API цього пристрою</string>
<string name="revanced_ryd_statistics_category_title">Статистика API ReturnYouTubeDislike цього пристрою</string>
<string name="revanced_ryd_statistics_getFetchCallResponseTimeAverage_title">Час відповіді API, середній</string>
<string name="revanced_ryd_statistics_getFetchCallResponseTimeMin_title">Час відповіді API, мінімальний</string>
<string name="revanced_ryd_statistics_getFetchCallResponseTimeMax_title">Час відповіді API, максимальний</string>
<string name="revanced_ryd_statistics_getFetchCallResponseTimeLast_title">Час відповіді API, останнє відео</string>
<string name="revanced_ryd_statistics_getFetchCallResponseTimeLast_rate_limit_summary">Відмітки \"Не подобається\" тимчасово недоступні - діє обмеження швидкості клієнта API</string>
<string name="revanced_ryd_statistics_getFetchCallResponseTimeLast_rate_limit_summary">Дизлайки тимчасово недоступні - діє обмеження швидкості для клієнта API</string>
<string name="revanced_ryd_statistics_getFetchCallCount_title">Отримання голосів API, кількість запитів</string>
<string name="revanced_ryd_statistics_getFetchCallCount_zero_summary">Мережевих запитів не здійснено </string>
<string name="revanced_ryd_statistics_getFetchCallCount_non_zero_summary">Здійснено %d мережевих запитів</string>
@@ -948,13 +948,13 @@ Second \"item\" text"</string>
<string name="revanced_sb_settings_ie">Імпорт / Експорт налаштувань</string>
<string name="revanced_sb_settings_copy">Копіювати</string>
<string name="revanced_sb_settings_ie_sum">Ваші налаштування SponsorBlock, які можуть бути імпортовані чи експортовані у ReVanced та до інших платформ SponsorBlock</string>
<string name="revanced_sb_settings_ie_sum_warning">Ваші налаштування SponsorBlock, які можуть бути імпортовані чи експортовані у ReVanced та до інших платформ SponsorBlock. Вони також містять Ваш особистий ідентифікатор користувача. Діліться ним розумно</string>
<string name="revanced_sb_settings_ie_sum_warning">Ваші налаштування SponsorBlock, які можуть бути імпортовані чи експортовані у ReVanced та до інших платформ SponsorBlock. Вони також містять Ваш особистий ідентифікатор користувача. Діліться ними розумно</string>
<string name="revanced_sb_settings_import_successful">Налаштування успішно імпортовано</string>
<string name="revanced_sb_settings_import_failed">Не вдалося імпортувати: %s</string>
<string name="revanced_sb_settings_export_failed">Не вдалося експортувати: %s</string>
<string name="revanced_sb_settings_revanced_export_user_id_warning">"Ваші налаштування містять особистий ID користувача SponsorBlock.
<string name="revanced_sb_settings_revanced_export_user_id_warning">"Ваші налаштування містять особистий ідентифікатор користувача SponsorBlock.
Ваш ID користувача це як пароль і його не можна поширювати."</string>
Ваш ідентифікатор користувача це як пароль і його не можна поширювати."</string>
<string name="revanced_sb_settings_revanced_export_user_id_warning_dismiss">Більше не показувати</string>
<string name="revanced_sb_diff_segments">Змінити поведінку сегмента</string>
<string name="revanced_sb_segments_sponsor">Спонсор</string>
@@ -1020,10 +1020,10 @@ Second \"item\" text"</string>
Він вже існує"</string>
<string name="revanced_sb_submit_succeeded">Сегмент успішно надіслано</string>
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
<string name="revanced_sb_sponsorblock_connection_failure_timeout">SponsorBlock тимчасово недоступний (закінчився час API)</string>
<string name="revanced_sb_sponsorblock_connection_failure_timeout">SponsorBlock тимчасово недоступний (тайм-аут API)</string>
<string name="revanced_sb_sponsorblock_connection_failure_status">SponsorBlock тимчасово недоступний (статус %d)</string>
<string name="revanced_sb_sponsorblock_connection_failure_generic">SponsorBlock тимчасово не доступний</string>
<string name="revanced_sb_vote_failed_timeout">Не вдалося проголосувати за сегмент (закінчився час API)</string>
<string name="revanced_sb_vote_failed_timeout">Не вдалося проголосувати за сегмент (тайм-аут API)</string>
<string name="revanced_sb_vote_failed_unknown_error">Не вдалося проголосувати за сегмент (статус: %1$d %2$s)</string>
<string name="revanced_sb_vote_failed_forbidden">Не вдалося проголосувати за сегмент: %s</string>
<string name="revanced_sb_vote_upvote">Проголосувати \"за\"</string>
@@ -1087,7 +1087,7 @@ Second \"item\" text"</string>
<string name="revanced_sb_reset_color">Скинути колір</string>
<string name="revanced_sb_reset">Скинути</string>
<string name="revanced_sb_about">Про інтеграцію</string>
<string name="revanced_sb_about_api_sum">Дані надаються SponsorBlock API. Натисніть тут, щоб дізнатися більше та побачити завантаження для інших платформ</string>
<string name="revanced_sb_about_api_sum">Дані надаються через API SponsorBlock. Натисніть тут, щоб дізнатися більше та побачити завантаження для інших платформ</string>
</patch>
<patch id="layout.formfactor.changeFormFactorPatch">
<string name="revanced_change_form_factor_title">Макет інтерфейсу</string>

View File

@@ -855,6 +855,11 @@ Autoplay can be changed in YouTube settings:
Settings → Playback → Autoplay next video"</string>
<string name="revanced_end_screen_suggested_video_summary_off">End screen suggested video is shown</string>
</patch>
<patch id="layout.hide.relatedvideooverlay.hideRelatedVideoOverlayPatch">
<string name="revanced_hide_related_video_overlay_title">Hide related video overlay in fullscreen</string>
<string name="revanced_hide_related_video_overlay_summary_on">Related video overlay is hidden</string>
<string name="revanced_hide_related_video_overlay_summary_off">Related video overlay is shown</string>
</patch>
<patch id="layout.hide.time.hideTimestampPatch">
<string name="revanced_hide_timestamp_title">Hide video timestamp</string>
<string name="revanced_hide_timestamp_summary_on">Timestamp is hidden</string>