mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-08 18:33:57 +01:00
Compare commits
36 Commits
v5.1.0-dev
...
v5.2.1-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
064be93ee2 | ||
|
|
f74fd7113f | ||
|
|
628afc22bc | ||
|
|
8686bd9f20 | ||
|
|
534996f251 | ||
|
|
ca4a16dbd8 | ||
|
|
e33082f765 | ||
|
|
18360464a9 | ||
|
|
968e6e9b69 | ||
|
|
02732ab432 | ||
|
|
77aea074a9 | ||
|
|
fe15213cf9 | ||
|
|
046bd3ec88 | ||
|
|
d6bc998365 | ||
|
|
545e16913a | ||
|
|
fafed099c5 | ||
|
|
a65bbebfdb | ||
|
|
1a910a2cf6 | ||
|
|
6d23a4e000 | ||
|
|
5c3c68406e | ||
|
|
b0c3709be7 | ||
|
|
cd19f976e7 | ||
|
|
c181135cc1 | ||
|
|
7f6775950e | ||
|
|
4b2abaf17e | ||
|
|
677b18c41a | ||
|
|
736b6a96b8 | ||
|
|
8c371d8579 | ||
|
|
abcaa6336a | ||
|
|
11537526a4 | ||
|
|
403116f591 | ||
|
|
a1d14cffe9 | ||
|
|
10f221f374 | ||
|
|
ba1aab6d4d | ||
|
|
01cc8e0abf | ||
|
|
518958350d |
120
CHANGELOG.md
120
CHANGELOG.md
@@ -1,3 +1,123 @@
|
|||||||
|
## [5.2.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.2.0...v5.2.1-dev.1) (2024-11-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof app version:** Update spoof target to resolve library tab crashes ([#4014](https://github.com/ReVanced/revanced-patches/issues/4014)) ([c8eced5](https://github.com/ReVanced/revanced-patches/commit/c8eced54704017df4e91e536dbef1e9514306f67))
|
||||||
|
|
||||||
|
# [5.2.0](https://github.com/ReVanced/revanced-patches/compare/v5.1.0...v5.2.0) (2024-11-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **My Expenses - Unlock pro:** Constrain compatible version to working version ([#3974](https://github.com/ReVanced/revanced-patches/issues/3974)) ([ba3bf69](https://github.com/ReVanced/revanced-patches/commit/ba3bf69df07ec8dab46868c3940ebd56db0cd137))
|
||||||
|
* **YouTube - Hide Shorts components:** Add missing options to patch ([65f62fc](https://github.com/ReVanced/revanced-patches/commit/65f62fcd5ac340616a96542c64faf2af2a60df28))
|
||||||
|
* **YouTube - Playback speed:** Allow long press 2x speed when using custom playback speeds ([#3990](https://github.com/ReVanced/revanced-patches/issues/3990)) ([79a543a](https://github.com/ReVanced/revanced-patches/commit/79a543a57470638f983862c61270e046f3ac5cb7))
|
||||||
|
* **YouTube - Settings:** Do not clip settings menus when using an Android 15 device ([#3999](https://github.com/ReVanced/revanced-patches/issues/3999)) ([7382a02](https://github.com/ReVanced/revanced-patches/commit/7382a020b8322a7abc016a4569bc15f9caf05546))
|
||||||
|
* **YouTube - Settings:** Show navigation back button in setting sub menus ([#3991](https://github.com/ReVanced/revanced-patches/issues/3991)) ([e61686c](https://github.com/ReVanced/revanced-patches/commit/e61686c1039ae29e443273e4da4ec63956216841))
|
||||||
|
* **YouTube - Spoof video streams:** Log out the iOS client to restore kids videos playback ([#4000](https://github.com/ReVanced/revanced-patches/issues/4000)) ([cc2ac4e](https://github.com/ReVanced/revanced-patches/commit/cc2ac4e4cd15ca2a23d60abd160d915bc98f99b4))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **TikTok:** Add ReVanced settings about screen ([#4009](https://github.com/ReVanced/revanced-patches/issues/4009)) ([12ea26b](https://github.com/ReVanced/revanced-patches/commit/12ea26b10ddea5ad39da1d35e2b8fd0b48c15d88))
|
||||||
|
* **VSCO:** Remove non functional `Unlock pro` patch ([4fddb19](https://github.com/ReVanced/revanced-patches/commit/4fddb1930bc7adeee3b60ae9cd346b143e88bd42))
|
||||||
|
* **YouTube - Theme:** Apply custom seekbar color to splash screen animation ([#3978](https://github.com/ReVanced/revanced-patches/issues/3978)) ([98d57e2](https://github.com/ReVanced/revanced-patches/commit/98d57e28af7206099867474b7aa3760cd4fe333f))
|
||||||
|
* **YouTube:** Support version `19.46.42` ([#4010](https://github.com/ReVanced/revanced-patches/issues/4010)) ([122aac6](https://github.com/ReVanced/revanced-patches/commit/122aac6aee8ef0737f18564f11bbc2a6addf4a6b))
|
||||||
|
|
||||||
|
# [5.2.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.6...v5.2.0-dev.7) (2024-11-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Settings:** Do not clip settings menus when using an Android 15 device ([#3999](https://github.com/ReVanced/revanced-patches/issues/3999)) ([7382a02](https://github.com/ReVanced/revanced-patches/commit/7382a020b8322a7abc016a4569bc15f9caf05546))
|
||||||
|
|
||||||
|
# [5.2.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.5...v5.2.0-dev.6) (2024-11-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube:** Support version `19.46.42` ([#4010](https://github.com/ReVanced/revanced-patches/issues/4010)) ([122aac6](https://github.com/ReVanced/revanced-patches/commit/122aac6aee8ef0737f18564f11bbc2a6addf4a6b))
|
||||||
|
|
||||||
|
# [5.2.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.4...v5.2.0-dev.5) (2024-11-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Log out the iOS client to restore kids videos playback ([#4000](https://github.com/ReVanced/revanced-patches/issues/4000)) ([cc2ac4e](https://github.com/ReVanced/revanced-patches/commit/cc2ac4e4cd15ca2a23d60abd160d915bc98f99b4))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **TikTok:** Add ReVanced settings about screen ([#4009](https://github.com/ReVanced/revanced-patches/issues/4009)) ([12ea26b](https://github.com/ReVanced/revanced-patches/commit/12ea26b10ddea5ad39da1d35e2b8fd0b48c15d88))
|
||||||
|
|
||||||
|
# [5.2.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.3...v5.2.0-dev.4) (2024-11-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Playback speed:** Allow long press 2x speed when using custom playback speeds ([#3990](https://github.com/ReVanced/revanced-patches/issues/3990)) ([79a543a](https://github.com/ReVanced/revanced-patches/commit/79a543a57470638f983862c61270e046f3ac5cb7))
|
||||||
|
|
||||||
|
# [5.2.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.2...v5.2.0-dev.3) (2024-11-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **VSCO:** Remove non functional `Unlock pro` patch ([4fddb19](https://github.com/ReVanced/revanced-patches/commit/4fddb1930bc7adeee3b60ae9cd346b143e88bd42))
|
||||||
|
|
||||||
|
# [5.2.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.1...v5.2.0-dev.2) (2024-11-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Settings:** Show navigation back button in setting sub menus ([#3991](https://github.com/ReVanced/revanced-patches/issues/3991)) ([e61686c](https://github.com/ReVanced/revanced-patches/commit/e61686c1039ae29e443273e4da4ec63956216841))
|
||||||
|
|
||||||
|
# [5.2.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.2...v5.2.0-dev.1) (2024-11-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Theme:** Apply custom seekbar color to splash screen animation ([#3978](https://github.com/ReVanced/revanced-patches/issues/3978)) ([98d57e2](https://github.com/ReVanced/revanced-patches/commit/98d57e28af7206099867474b7aa3760cd4fe333f))
|
||||||
|
|
||||||
|
## [5.1.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.1...v5.1.1-dev.2) (2024-11-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide Shorts components:** Add missing options to patch ([65f62fc](https://github.com/ReVanced/revanced-patches/commit/65f62fcd5ac340616a96542c64faf2af2a60df28))
|
||||||
|
|
||||||
|
## [5.1.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.0...v5.1.1-dev.1) (2024-11-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **My Expenses - Unlock pro:** Constrain compatible version to working version ([#3974](https://github.com/ReVanced/revanced-patches/issues/3974)) ([ba3bf69](https://github.com/ReVanced/revanced-patches/commit/ba3bf69df07ec8dab46868c3940ebd56db0cd137))
|
||||||
|
|
||||||
|
# [5.1.0](https://github.com/ReVanced/revanced-patches/compare/v5.0.2...v5.1.0) (2024-11-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Change header:** Apply header changes to A/B layout ([#3907](https://github.com/ReVanced/revanced-patches/issues/3907)) ([6ccf114](https://github.com/ReVanced/revanced-patches/commit/6ccf11426ec9e9cd9c8e89a2443f0d0645cc78b1))
|
||||||
|
* **YouTube - Hide Shorts components:** Do not hide Shorts action buttons on app first launch ([#3933](https://github.com/ReVanced/revanced-patches/issues/3933)) ([0d78815](https://github.com/ReVanced/revanced-patches/commit/0d78815e33bf2ae216e519f067fb773df0f2084e))
|
||||||
|
* **YouTube - Playback speed:** Add 'Auto' speed. Always override speed if default is set to 1.0x ([#3914](https://github.com/ReVanced/revanced-patches/issues/3914)) ([497739e](https://github.com/ReVanced/revanced-patches/commit/497739e8ce6933c1f1ea46edffc102e56b985623))
|
||||||
|
* **YouTube - SponsorBlock:** Fix create new segment crash on tablet custom roms ([#3946](https://github.com/ReVanced/revanced-patches/issues/3946)) ([a0da377](https://github.com/ReVanced/revanced-patches/commit/a0da377ba8f90ba39e905ed9730b3e819633bd50))
|
||||||
|
* **YouTube - Spoof app version:** Adjust legacy spoof targets ([#3934](https://github.com/ReVanced/revanced-patches/issues/3934)) ([f5794c1](https://github.com/ReVanced/revanced-patches/commit/f5794c1f896c331d76fdfc299e31a2773f2209ca))
|
||||||
|
* **YouTube - Spoof app version:** Remove broken spoof targets when patching 19.25+ ([#3915](https://github.com/ReVanced/revanced-patches/issues/3915)) ([9e18eca](https://github.com/ReVanced/revanced-patches/commit/9e18ecab1877dd33a3ad0fe216e6b91a8daaf1f8))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Miniplayer:** Add option to disable miniplayer ([#3961](https://github.com/ReVanced/revanced-patches/issues/3961)) ([e565cdb](https://github.com/ReVanced/revanced-patches/commit/e565cdb583aacfc0052d12c430f56fd9abd5bf00))
|
||||||
|
* **YouTube:** Support version `19.45.38` ([#3938](https://github.com/ReVanced/revanced-patches/issues/3938)) ([7c4e3fe](https://github.com/ReVanced/revanced-patches/commit/7c4e3fe97e8cbbb8cf16a2fb95f64223ca2bd7ef))
|
||||||
|
|
||||||
|
# [5.1.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.1.0-dev.2...v5.1.0-dev.3) (2024-11-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Miniplayer:** Add option to disable miniplayer ([#3961](https://github.com/ReVanced/revanced-patches/issues/3961)) ([e565cdb](https://github.com/ReVanced/revanced-patches/commit/e565cdb583aacfc0052d12c430f56fd9abd5bf00))
|
||||||
|
|
||||||
# [5.1.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.1.0-dev.1...v5.1.0-dev.2) (2024-11-21)
|
# [5.1.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.1.0-dev.1...v5.1.0-dev.2) (2024-11-21)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,35 @@
|
|||||||
package app.revanced.extension.shared.settings.preference;
|
package app.revanced.extension.shared.settings.preference;
|
||||||
|
|
||||||
|
import static app.revanced.extension.shared.StringRef.str;
|
||||||
|
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.Insets;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.*;
|
import android.preference.*;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowInsets;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toolbar;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
import app.revanced.extension.shared.Utils;
|
import app.revanced.extension.shared.Utils;
|
||||||
import app.revanced.extension.shared.settings.BaseSettings;
|
import app.revanced.extension.shared.settings.BaseSettings;
|
||||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||||
import app.revanced.extension.shared.settings.Setting;
|
import app.revanced.extension.shared.settings.Setting;
|
||||||
|
import app.revanced.extension.youtube.ThemeHelper;
|
||||||
import static app.revanced.extension.shared.StringRef.str;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||||
@@ -71,6 +85,15 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@SuppressLint("UseCompatLoadingForDrawables")
|
||||||
|
public static Drawable getBackButtonDrawable() {
|
||||||
|
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme()
|
||||||
|
? "yt_outline_arrow_left_white_24"
|
||||||
|
: "yt_outline_arrow_left_black_24",
|
||||||
|
"drawable");
|
||||||
|
return Utils.getContext().getResources().getDrawable(backButtonResource);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize this instance, and do any custom behavior.
|
* Initialize this instance, and do any custom behavior.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -98,7 +121,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
showingUserDialogMessage = true;
|
showingUserDialogMessage = true;
|
||||||
new AlertDialog.Builder(context)
|
new AlertDialog.Builder(context)
|
||||||
.setTitle(confirmDialogTitle)
|
.setTitle(confirmDialogTitle)
|
||||||
.setMessage(setting.userDialogMessage.toString())
|
.setMessage(Objects.requireNonNull(setting.userDialogMessage).toString())
|
||||||
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
|
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
|
||||||
if (setting.rebootApp) {
|
if (setting.rebootApp) {
|
||||||
showRestartDialog(context);
|
showRestartDialog(context);
|
||||||
@@ -261,6 +284,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
// causes a callback to the listener even though nothing changed.
|
// causes a callback to the listener even though nothing changed.
|
||||||
initialize();
|
initialize();
|
||||||
updateUIToSettingValues();
|
updateUIToSettingValues();
|
||||||
|
setPreferenceScreenToolbar(getPreferenceScreen());
|
||||||
|
|
||||||
preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
|
preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@@ -273,4 +297,56 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener);
|
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener);
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) {
|
||||||
|
for (int i = 0, preferenceCount = parentScreen.getPreferenceCount(); i < preferenceCount; i++) {
|
||||||
|
Preference childPreference = parentScreen.getPreference(i);
|
||||||
|
if (childPreference instanceof PreferenceScreen) {
|
||||||
|
// Recursively set sub preferences.
|
||||||
|
setPreferenceScreenToolbar((PreferenceScreen) childPreference);
|
||||||
|
|
||||||
|
childPreference.setOnPreferenceClickListener(
|
||||||
|
childScreen -> {
|
||||||
|
Dialog preferenceScreenDialog = ((PreferenceScreen) childScreen).getDialog();
|
||||||
|
ViewGroup rootView = (ViewGroup) preferenceScreenDialog
|
||||||
|
.findViewById(android.R.id.content)
|
||||||
|
.getParent();
|
||||||
|
|
||||||
|
// Fix required for Android 15 and YT 19.45+
|
||||||
|
// FIXME:
|
||||||
|
// On Android 15 the text layout is not aligned the same as the parent
|
||||||
|
// screen and it looks a little off. Otherwise this works.
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
rootView.setOnApplyWindowInsetsListener((v, insets) -> {
|
||||||
|
Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars());
|
||||||
|
v.setPadding(0, statusInsets.top, 0, 0);
|
||||||
|
return insets;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Toolbar toolbar = new Toolbar(childScreen.getContext());
|
||||||
|
toolbar.setTitle(childScreen.getTitle());
|
||||||
|
toolbar.setNavigationIcon(getBackButtonDrawable());
|
||||||
|
toolbar.setNavigationOnClickListener(view -> preferenceScreenDialog.dismiss());
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
final int margin = (int) TypedValue.applyDimension(
|
||||||
|
TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()
|
||||||
|
);
|
||||||
|
toolbar.setTitleMargin(margin, 0, margin, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextView toolbarTextView = Utils.getChildView(toolbar,
|
||||||
|
true, TextView.class::isInstance);
|
||||||
|
if (toolbarTextView != null) {
|
||||||
|
toolbarTextView.setTextColor(ThemeHelper.getForegroundColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
rootView.addView(toolbar, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package app.revanced.extension.shared.settings.preference;
|
package app.revanced.extension.shared.settings.preference;
|
||||||
|
|
||||||
import static app.revanced.extension.shared.StringRef.sf;
|
|
||||||
import static app.revanced.extension.shared.StringRef.str;
|
import static app.revanced.extension.shared.StringRef.str;
|
||||||
import static app.revanced.extension.youtube.requests.Route.Method.GET;
|
import static app.revanced.extension.youtube.requests.Route.Method.GET;
|
||||||
|
|
||||||
@@ -13,6 +12,8 @@ import android.content.res.Configuration;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
@@ -37,7 +38,7 @@ import app.revanced.extension.youtube.requests.Requester;
|
|||||||
import app.revanced.extension.youtube.requests.Route;
|
import app.revanced.extension.youtube.requests.Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a dialog showing the links from {@link SocialLinksRoutes}.
|
* Opens a dialog showing official links.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unused", "deprecation"})
|
@SuppressWarnings({"unused", "deprecation"})
|
||||||
public class ReVancedAboutPreference extends Preference {
|
public class ReVancedAboutPreference extends Preference {
|
||||||
@@ -72,7 +73,16 @@ public class ReVancedAboutPreference extends Preference {
|
|||||||
return Color.BLACK;
|
return Color.BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createDialogHtml(WebLink[] socialLinks) {
|
/**
|
||||||
|
* Apps that do not support bundling resources must override this.
|
||||||
|
*
|
||||||
|
* @return A localized string to display for the key.
|
||||||
|
*/
|
||||||
|
protected String getString(String key, Object ... args) {
|
||||||
|
return str(key, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createDialogHtml(WebLink[] aboutLinks) {
|
||||||
final boolean isNetworkConnected = Utils.isNetworkConnected();
|
final boolean isNetworkConnected = Utils.isNetworkConnected();
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
@@ -91,7 +101,7 @@ public class ReVancedAboutPreference extends Preference {
|
|||||||
builder.append("<img style=\"width: 100px; height: 100px;\" "
|
builder.append("<img style=\"width: 100px; height: 100px;\" "
|
||||||
// Hide the image if it does not load.
|
// Hide the image if it does not load.
|
||||||
+ "onerror=\"this.style.display='none';\" "
|
+ "onerror=\"this.style.display='none';\" "
|
||||||
+ "src=\"https://revanced.app/favicon.ico\" />");
|
+ "src=\"").append(AboutLinksRoutes.aboutLogoUrl).append("\" />");
|
||||||
}
|
}
|
||||||
|
|
||||||
String patchesVersion = Utils.getPatchesReleaseVersion();
|
String patchesVersion = Utils.getPatchesReleaseVersion();
|
||||||
@@ -103,29 +113,29 @@ public class ReVancedAboutPreference extends Preference {
|
|||||||
|
|
||||||
builder.append("<p>")
|
builder.append("<p>")
|
||||||
// Replace hyphens with non breaking dashes so the version number does not break lines.
|
// Replace hyphens with non breaking dashes so the version number does not break lines.
|
||||||
.append(useNonBreakingHyphens(str("revanced_settings_about_links_body", patchesVersion)))
|
.append(useNonBreakingHyphens(getString("revanced_settings_about_links_body", patchesVersion)))
|
||||||
.append("</p>");
|
.append("</p>");
|
||||||
|
|
||||||
// Add a disclaimer if using a dev release.
|
// Add a disclaimer if using a dev release.
|
||||||
if (patchesVersion.contains("dev")) {
|
if (patchesVersion.contains("dev")) {
|
||||||
builder.append("<h3>")
|
builder.append("<h3>")
|
||||||
// English text 'Pre-release' can break lines.
|
// English text 'Pre-release' can break lines.
|
||||||
.append(useNonBreakingHyphens(str("revanced_settings_about_links_dev_header")))
|
.append(useNonBreakingHyphens(getString("revanced_settings_about_links_dev_header")))
|
||||||
.append("</h3>");
|
.append("</h3>");
|
||||||
|
|
||||||
builder.append("<p>")
|
builder.append("<p>")
|
||||||
.append(str("revanced_settings_about_links_dev_body"))
|
.append(getString("revanced_settings_about_links_dev_body"))
|
||||||
.append("</p>");
|
.append("</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append("<h2 style=\"margin-top: 30px;\">")
|
builder.append("<h2 style=\"margin-top: 30px;\">")
|
||||||
.append(str("revanced_settings_about_links_header"))
|
.append(getString("revanced_settings_about_links_header"))
|
||||||
.append("</h2>");
|
.append("</h2>");
|
||||||
|
|
||||||
builder.append("<div>");
|
builder.append("<div>");
|
||||||
for (WebLink social : socialLinks) {
|
for (WebLink link : aboutLinks) {
|
||||||
builder.append("<div style=\"margin-bottom: 20px;\">");
|
builder.append("<div style=\"margin-bottom: 20px;\">");
|
||||||
builder.append(String.format("<a href=\"%s\">%s</a>", social.url, social.name));
|
builder.append(String.format("<a href=\"%s\">%s</a>", link.url, link.name));
|
||||||
builder.append("</div>");
|
builder.append("</div>");
|
||||||
}
|
}
|
||||||
builder.append("</div>");
|
builder.append("</div>");
|
||||||
@@ -137,25 +147,44 @@ public class ReVancedAboutPreference extends Preference {
|
|||||||
{
|
{
|
||||||
setOnPreferenceClickListener(pref -> {
|
setOnPreferenceClickListener(pref -> {
|
||||||
// Show a progress spinner if the social links are not fetched yet.
|
// Show a progress spinner if the social links are not fetched yet.
|
||||||
if (!SocialLinksRoutes.hasFetchedLinks() && Utils.isNetworkConnected()) {
|
if (!AboutLinksRoutes.hasFetchedLinks() && Utils.isNetworkConnected()) {
|
||||||
|
// Show a progress spinner, but only if the api fetch takes more than a half a second.
|
||||||
|
final long delayToShowProgressSpinner = 500;
|
||||||
ProgressDialog progress = new ProgressDialog(getContext());
|
ProgressDialog progress = new ProgressDialog(getContext());
|
||||||
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||||
progress.show();
|
|
||||||
Utils.runOnBackgroundThread(() -> fetchLinksAndShowDialog(progress));
|
Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
Runnable showDialogRunnable = progress::show;
|
||||||
|
handler.postDelayed(showDialogRunnable, delayToShowProgressSpinner);
|
||||||
|
|
||||||
|
Utils.runOnBackgroundThread(() ->
|
||||||
|
fetchLinksAndShowDialog(handler, showDialogRunnable, progress));
|
||||||
} else {
|
} else {
|
||||||
// No network call required and can run now.
|
// No network call required and can run now.
|
||||||
fetchLinksAndShowDialog(null);
|
fetchLinksAndShowDialog(null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchLinksAndShowDialog(@Nullable ProgressDialog progress) {
|
private void fetchLinksAndShowDialog(@Nullable Handler handler,
|
||||||
WebLink[] socialLinks = SocialLinksRoutes.fetchSocialLinks();
|
Runnable showDialogRunnable,
|
||||||
String htmlDialog = createDialogHtml(socialLinks);
|
@Nullable ProgressDialog progress) {
|
||||||
|
WebLink[] links = AboutLinksRoutes.fetchAboutLinks();
|
||||||
|
String htmlDialog = createDialogHtml(links);
|
||||||
|
|
||||||
|
// Enable to randomly force a delay to debug the spinner logic.
|
||||||
|
final boolean debugSpinnerDelayLogic = false;
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
if (debugSpinnerDelayLogic && handler != null && Math.random() < 0.5f) {
|
||||||
|
Utils.doNothingForDuration((long) (Math.random() * 4000));
|
||||||
|
}
|
||||||
|
|
||||||
Utils.runOnMainThreadNowOrLater(() -> {
|
Utils.runOnMainThreadNowOrLater(() -> {
|
||||||
|
if (handler != null) {
|
||||||
|
handler.removeCallbacks(showDialogRunnable);
|
||||||
|
}
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progress.dismiss();
|
progress.dismiss();
|
||||||
}
|
}
|
||||||
@@ -224,7 +253,7 @@ class WebViewDialog extends Dialog {
|
|||||||
|
|
||||||
class WebLink {
|
class WebLink {
|
||||||
final boolean preferred;
|
final boolean preferred;
|
||||||
final String name;
|
String name;
|
||||||
final String url;
|
final String url;
|
||||||
|
|
||||||
WebLink(JSONObject json) throws JSONException {
|
WebLink(JSONObject json) throws JSONException {
|
||||||
@@ -243,7 +272,7 @@ class WebLink {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ReVancedSocialLink{" +
|
return "WebLink{" +
|
||||||
"preferred=" + preferred +
|
"preferred=" + preferred +
|
||||||
", name='" + name + '\'' +
|
", name='" + name + '\'' +
|
||||||
", url='" + url + '\'' +
|
", url='" + url + '\'' +
|
||||||
@@ -251,25 +280,21 @@ class WebLink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SocialLinksRoutes {
|
class AboutLinksRoutes {
|
||||||
/**
|
/**
|
||||||
* Simple link to the website donate page,
|
* Backup icon url if the API call fails.
|
||||||
* rather than fetching and parsing the donation links using the API.
|
|
||||||
*/
|
*/
|
||||||
public static final WebLink DONATE_LINK = new WebLink(true,
|
public static volatile String aboutLogoUrl = "https://revanced.app/favicon.ico";
|
||||||
sf("revanced_settings_about_links_donate").toString(),
|
|
||||||
"https://revanced.app/donate");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Links to use if fetch links api call fails.
|
* Links to use if fetch links api call fails.
|
||||||
*/
|
*/
|
||||||
private static final WebLink[] NO_CONNECTION_STATIC_LINKS = {
|
private static final WebLink[] NO_CONNECTION_STATIC_LINKS = {
|
||||||
new WebLink(true, "ReVanced.app", "https://revanced.app"),
|
new WebLink(true, "ReVanced.app", "https://revanced.app")
|
||||||
DONATE_LINK,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String SOCIAL_LINKS_PROVIDER = "https://api.revanced.app/v2";
|
private static final String SOCIAL_LINKS_PROVIDER = "https://api.revanced.app/v4";
|
||||||
private static final Route.CompiledRoute GET_SOCIAL = new Route(GET, "/socials").compile();
|
private static final Route.CompiledRoute GET_SOCIAL = new Route(GET, "/about").compile();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static volatile WebLink[] fetchedLinks;
|
private static volatile WebLink[] fetchedLinks;
|
||||||
@@ -278,7 +303,7 @@ class SocialLinksRoutes {
|
|||||||
return fetchedLinks != null;
|
return fetchedLinks != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebLink[] fetchSocialLinks() {
|
static WebLink[] fetchAboutLinks() {
|
||||||
try {
|
try {
|
||||||
if (hasFetchedLinks()) return fetchedLinks;
|
if (hasFetchedLinks()) return fetchedLinks;
|
||||||
|
|
||||||
@@ -298,11 +323,22 @@ class SocialLinksRoutes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JSONObject json = Requester.parseJSONObjectAndDisconnect(connection);
|
JSONObject json = Requester.parseJSONObjectAndDisconnect(connection);
|
||||||
JSONArray socials = json.getJSONArray("socials");
|
aboutLogoUrl = json.getJSONObject("branding").getString("logo");
|
||||||
|
|
||||||
List<WebLink> links = new ArrayList<>();
|
List<WebLink> links = new ArrayList<>();
|
||||||
|
|
||||||
links.add(DONATE_LINK); // Show donate link first.
|
JSONArray donations = json.getJSONObject("donations").getJSONArray("links");
|
||||||
|
for (int i = 0, length = donations.length(); i < length; i++) {
|
||||||
|
WebLink link = new WebLink(donations.getJSONObject(i));
|
||||||
|
if (link.preferred) {
|
||||||
|
// This could be localized, but TikTok does not support localized resources.
|
||||||
|
// All link names returned by the api are also non localized.
|
||||||
|
link.name = "Donate";
|
||||||
|
links.add(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray socials = json.getJSONArray("socials");
|
||||||
for (int i = 0, length = socials.length(); i < length; i++) {
|
for (int i = 0, length = socials.length(); i < length; i++) {
|
||||||
WebLink link = new WebLink(socials.getJSONObject(i));
|
WebLink link = new WebLink(socials.getJSONObject(i));
|
||||||
links.add(link);
|
links.add(link);
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package app.revanced.extension.tiktok.settings.preference;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.settings.preference.ReVancedAboutPreference;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class ReVancedTikTokAboutPreference extends ReVancedAboutPreference {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Because resources cannot be added to TikTok,
|
||||||
|
* these strings are copied from the shared strings.xml file.
|
||||||
|
*
|
||||||
|
* Changes here must also be made in strings.xml
|
||||||
|
*/
|
||||||
|
private final Map<String, String> aboutStrings = Map.of(
|
||||||
|
"revanced_settings_about_links_body", "You are using ReVanced Patches version <i>%s</i>",
|
||||||
|
"revanced_settings_about_links_dev_header", "Note",
|
||||||
|
"revanced_settings_about_links_dev_body", "This version is a pre-release and you may experience unexpected issues",
|
||||||
|
"revanced_settings_about_links_header", "Official links"
|
||||||
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
//noinspection deprecation
|
||||||
|
setTitle("About");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReVancedTikTokAboutPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
public ReVancedTikTokAboutPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
public ReVancedTikTokAboutPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
public ReVancedTikTokAboutPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getString(String key, Object ... args) {
|
||||||
|
String format = aboutStrings.get(key);
|
||||||
|
|
||||||
|
if (format == null) {
|
||||||
|
Logger.printException(() -> "Unknown key: " + key);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format(format, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,13 +4,14 @@ import android.content.Context;
|
|||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
|
|
||||||
import app.revanced.extension.shared.settings.BaseSettings;
|
import app.revanced.extension.shared.settings.BaseSettings;
|
||||||
|
import app.revanced.extension.tiktok.settings.preference.ReVancedTikTokAboutPreference;
|
||||||
import app.revanced.extension.tiktok.settings.preference.TogglePreference;
|
import app.revanced.extension.tiktok.settings.preference.TogglePreference;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class ExtensionPreferenceCategory extends ConditionalPreferenceCategory {
|
public class ExtensionPreferenceCategory extends ConditionalPreferenceCategory {
|
||||||
public ExtensionPreferenceCategory(Context context, PreferenceScreen screen) {
|
public ExtensionPreferenceCategory(Context context, PreferenceScreen screen) {
|
||||||
super(context, screen);
|
super(context, screen);
|
||||||
setTitle("Extension");
|
setTitle("Miscellaneous");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -20,6 +21,8 @@ public class ExtensionPreferenceCategory extends ConditionalPreferenceCategory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPreferences(Context context) {
|
public void addPreferences(Context context) {
|
||||||
|
addPreference(new ReVancedTikTokAboutPreference(context));
|
||||||
|
|
||||||
addPreference(new TogglePreference(context,
|
addPreference(new TogglePreference(context,
|
||||||
"Enable debug log",
|
"Enable debug log",
|
||||||
"Show extension debug log.",
|
"Show extension debug log.",
|
||||||
|
|||||||
@@ -82,4 +82,12 @@ public class ThemeHelper {
|
|||||||
}
|
}
|
||||||
return Utils.getResourceColor(colorString);
|
return Utils.getResourceColor(colorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getBackgroundColor() {
|
||||||
|
return isDarkTheme() ? getDarkThemeColor() : getLightThemeColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getForegroundColor() {
|
||||||
|
return isDarkTheme() ? getLightThemeColor() : getDarkThemeColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,20 @@ public final class MiniplayerPatch {
|
|||||||
* Mini player type. Null fields indicates to use the original un-patched value.
|
* Mini player type. Null fields indicates to use the original un-patched value.
|
||||||
*/
|
*/
|
||||||
public enum MiniplayerType {
|
public enum MiniplayerType {
|
||||||
|
/**
|
||||||
|
* Disabled. When swiped down the miniplayer is immediately closed.
|
||||||
|
* Only available with 19.43+
|
||||||
|
*/
|
||||||
|
DISABLED(false, null),
|
||||||
/** Unmodified type, and same as un-patched. */
|
/** Unmodified type, and same as un-patched. */
|
||||||
ORIGINAL(null, null),
|
ORIGINAL(null, null),
|
||||||
|
/**
|
||||||
|
* Exactly the same as MINIMAL, and only here for migration of user settings.
|
||||||
|
* Eventually this should be deleted.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
PHONE(false, null),
|
PHONE(false, null),
|
||||||
|
MINIMAL(false, null),
|
||||||
TABLET(true, null),
|
TABLET(true, null),
|
||||||
MODERN_1(null, 1),
|
MODERN_1(null, 1),
|
||||||
MODERN_2(null, 2),
|
MODERN_2(null, 2),
|
||||||
@@ -164,6 +175,18 @@ public final class MiniplayerPatch {
|
|||||||
OPACITY_LEVEL = (opacity * 255) / 100;
|
OPACITY_LEVEL = (opacity * 255) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*
|
||||||
|
* Enables a handler that immediately closes the miniplayer when the video is minimized,
|
||||||
|
* effectively disabling the miniplayer.
|
||||||
|
*/
|
||||||
|
public static boolean getMiniplayerOnCloseHandler(boolean original) {
|
||||||
|
return CURRENT_TYPE == ORIGINAL
|
||||||
|
? original
|
||||||
|
: CURRENT_TYPE == DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package app.revanced.extension.youtube.patches;
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import app.revanced.extension.youtube.patches.playback.speed.RememberPlaybackSpeedPatch;
|
|
||||||
import app.revanced.extension.youtube.shared.VideoState;
|
|
||||||
import app.revanced.extension.shared.Logger;
|
|
||||||
import app.revanced.extension.shared.Utils;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.Utils;
|
||||||
|
import app.revanced.extension.youtube.shared.VideoState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hooking class for the current playing video.
|
* Hooking class for the current playing video.
|
||||||
* @noinspection unused
|
* @noinspection unused
|
||||||
@@ -120,6 +120,16 @@ public final class VideoInformation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static void videoSpeedChanged(float currentVideoSpeed) {
|
||||||
|
if (playbackSpeed != currentVideoSpeed) {
|
||||||
|
Logger.printDebug(() -> "Video speed changed: " + currentVideoSpeed);
|
||||||
|
playbackSpeed = currentVideoSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
* Called when user selects a playback speed.
|
* Called when user selects a playback speed.
|
||||||
@@ -131,18 +141,6 @@ public final class VideoInformation {
|
|||||||
playbackSpeed = userSelectedPlaybackSpeed;
|
playbackSpeed = userSelectedPlaybackSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides the current playback speed.
|
|
||||||
* <p>
|
|
||||||
* <b> Used exclusively by {@link RememberPlaybackSpeedPatch} </b>
|
|
||||||
*/
|
|
||||||
public static void overridePlaybackSpeed(float speedOverride) {
|
|
||||||
if (playbackSpeed != speedOverride) {
|
|
||||||
Logger.printDebug(() -> "Overriding playback speed to: " + speedOverride);
|
|
||||||
playbackSpeed = speedOverride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ public final class RememberPlaybackSpeedPatch {
|
|||||||
|
|
||||||
private static final long TOAST_DELAY_MILLISECONDS = 750;
|
private static final long TOAST_DELAY_MILLISECONDS = 750;
|
||||||
|
|
||||||
|
private static volatile boolean newVideoStarted;
|
||||||
|
|
||||||
private static long lastTimeSpeedChanged;
|
private static long lastTimeSpeedChanged;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,7 +21,7 @@ public final class RememberPlaybackSpeedPatch {
|
|||||||
*/
|
*/
|
||||||
public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) {
|
public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) {
|
||||||
Logger.printDebug(() -> "newVideoStarted");
|
Logger.printDebug(() -> "newVideoStarted");
|
||||||
VideoInformation.overridePlaybackSpeed(Settings.PLAYBACK_SPEED_DEFAULT.get());
|
newVideoStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,42 +31,56 @@ public final class RememberPlaybackSpeedPatch {
|
|||||||
* @param playbackSpeed The playback speed the user selected
|
* @param playbackSpeed The playback speed the user selected
|
||||||
*/
|
*/
|
||||||
public static void userSelectedPlaybackSpeed(float playbackSpeed) {
|
public static void userSelectedPlaybackSpeed(float playbackSpeed) {
|
||||||
if (Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) {
|
try {
|
||||||
// With the 0.05x menu, if the speed is set by integrations to higher than 2.0x
|
if (Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) {
|
||||||
// then the menu will allow increasing without bounds but the max speed is
|
// With the 0.05x menu, if the speed is set by integrations to higher than 2.0x
|
||||||
// still capped to under 8.0x.
|
// then the menu will allow increasing without bounds but the max speed is
|
||||||
playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f);
|
// still capped to under 8.0x.
|
||||||
|
playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f);
|
||||||
|
|
||||||
// Prevent toast spamming if using the 0.05x adjustments.
|
// Prevent toast spamming if using the 0.05x adjustments.
|
||||||
// Show exactly one toast after the user stops interacting with the speed menu.
|
// Show exactly one toast after the user stops interacting with the speed menu.
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
lastTimeSpeedChanged = now;
|
lastTimeSpeedChanged = now;
|
||||||
|
|
||||||
final float finalPlaybackSpeed = playbackSpeed;
|
final float finalPlaybackSpeed = playbackSpeed;
|
||||||
Utils.runOnMainThreadDelayed(() -> {
|
Utils.runOnMainThreadDelayed(() -> {
|
||||||
if (lastTimeSpeedChanged != now) {
|
if (lastTimeSpeedChanged != now) {
|
||||||
// The user made additional speed adjustments and this call is outdated.
|
// The user made additional speed adjustments and this call is outdated.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.PLAYBACK_SPEED_DEFAULT.get() == finalPlaybackSpeed) {
|
if (Settings.PLAYBACK_SPEED_DEFAULT.get() == finalPlaybackSpeed) {
|
||||||
// User changed to a different speed and immediately changed back.
|
// User changed to a different speed and immediately changed back.
|
||||||
// Or the user is going past 8.0x in the glitched out 0.05x menu.
|
// Or the user is going past 8.0x in the glitched out 0.05x menu.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Settings.PLAYBACK_SPEED_DEFAULT.save(finalPlaybackSpeed);
|
Settings.PLAYBACK_SPEED_DEFAULT.save(finalPlaybackSpeed);
|
||||||
|
|
||||||
Utils.showToastLong(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x")));
|
Utils.showToastLong(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x")));
|
||||||
}, TOAST_DELAY_MILLISECONDS);
|
}, TOAST_DELAY_MILLISECONDS);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "userSelectedPlaybackSpeed failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
* Overrides the video speed. Called after video loads, and immediately after user selects a different playback speed
|
* Overrides the video speed. Called after video loads,
|
||||||
|
* and immediately after the user selects a different playback speed.
|
||||||
*/
|
*/
|
||||||
public static float getPlaybackSpeedOverride() {
|
public static float getPlaybackSpeedOverride() {
|
||||||
return VideoInformation.getPlaybackSpeed();
|
if (newVideoStarted) {
|
||||||
|
newVideoStarted = false;
|
||||||
|
|
||||||
|
final float defaultSpeed = Settings.PLAYBACK_SPEED_DEFAULT.get();
|
||||||
|
if (defaultSpeed > 0) {
|
||||||
|
return defaultSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,17 @@ import android.os.Build;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
public enum ClientType {
|
public enum ClientType {
|
||||||
|
// Specific purpose for age restricted, or private videos, because the iOS client is not logged in.
|
||||||
|
ANDROID_VR(28,
|
||||||
|
"Quest 3",
|
||||||
|
"12",
|
||||||
|
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip",
|
||||||
|
"32", // Android 12.1
|
||||||
|
"1.56.21",
|
||||||
|
"ANDROID_VR",
|
||||||
|
true
|
||||||
|
),
|
||||||
|
// Specific for kids videos.
|
||||||
// https://dumps.tadiphone.dev/dumps/oculus/eureka
|
// https://dumps.tadiphone.dev/dumps/oculus/eureka
|
||||||
IOS(5,
|
IOS(5,
|
||||||
// iPhone 15 supports AV1 hardware decoding.
|
// iPhone 15 supports AV1 hardware decoding.
|
||||||
@@ -25,14 +36,9 @@ public enum ClientType {
|
|||||||
null,
|
null,
|
||||||
// Version number should be a valid iOS release.
|
// Version number should be a valid iOS release.
|
||||||
// https://www.ipa4fun.com/history/185230
|
// https://www.ipa4fun.com/history/185230
|
||||||
"19.10.7"
|
"19.10.7",
|
||||||
),
|
"IOS",
|
||||||
ANDROID_VR(28,
|
false
|
||||||
"Quest 3",
|
|
||||||
"12",
|
|
||||||
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip",
|
|
||||||
"32", // Android 12.1
|
|
||||||
"1.56.21"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +50,7 @@ public enum ClientType {
|
|||||||
/**
|
/**
|
||||||
* Device model, equivalent to {@link Build#MODEL} (System property: ro.product.model)
|
* Device model, equivalent to {@link Build#MODEL} (System property: ro.product.model)
|
||||||
*/
|
*/
|
||||||
public final String model;
|
public final String deviceModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Device OS version.
|
* Device OS version.
|
||||||
@@ -63,17 +69,37 @@ public enum ClientType {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public final String androidSdkVersion;
|
public final String androidSdkVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client name.
|
||||||
|
*/
|
||||||
|
public final String clientName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App version.
|
* App version.
|
||||||
*/
|
*/
|
||||||
public final String appVersion;
|
public final String clientVersion;
|
||||||
|
|
||||||
ClientType(int id, String model, String osVersion, String userAgent, @Nullable String androidSdkVersion, String appVersion) {
|
/**
|
||||||
|
* If the client can access the API logged in.
|
||||||
|
*/
|
||||||
|
public final boolean canLogin;
|
||||||
|
|
||||||
|
ClientType(int id,
|
||||||
|
String deviceModel,
|
||||||
|
String osVersion,
|
||||||
|
String userAgent,
|
||||||
|
@Nullable String androidSdkVersion,
|
||||||
|
String clientVersion,
|
||||||
|
String clientName,
|
||||||
|
boolean canLogin
|
||||||
|
) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.model = model;
|
this.deviceModel = deviceModel;
|
||||||
this.osVersion = osVersion;
|
this.osVersion = osVersion;
|
||||||
this.userAgent = userAgent;
|
this.userAgent = userAgent;
|
||||||
this.androidSdkVersion = androidSdkVersion;
|
this.androidSdkVersion = androidSdkVersion;
|
||||||
this.appVersion = appVersion;
|
this.clientVersion = clientVersion;
|
||||||
|
this.clientName = clientName;
|
||||||
|
this.canLogin = canLogin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,13 @@ import app.revanced.extension.youtube.requests.Requester;
|
|||||||
import app.revanced.extension.youtube.requests.Route;
|
import app.revanced.extension.youtube.requests.Route;
|
||||||
|
|
||||||
final class PlayerRoutes {
|
final class PlayerRoutes {
|
||||||
private static final String YT_API_URL = "https://youtubei.googleapis.com/youtubei/v1/";
|
|
||||||
|
|
||||||
static final Route.CompiledRoute GET_STREAMING_DATA = new Route(
|
static final Route.CompiledRoute GET_STREAMING_DATA = new Route(
|
||||||
Route.Method.POST,
|
Route.Method.POST,
|
||||||
"player" +
|
"player" +
|
||||||
"?fields=streamingData" +
|
"?fields=streamingData" +
|
||||||
"&alt=proto"
|
"&alt=proto"
|
||||||
).compile();
|
).compile();
|
||||||
|
private static final String YT_API_URL = "https://youtubei.googleapis.com/youtubei/v1/";
|
||||||
/**
|
/**
|
||||||
* TCP connection and HTTP read timeout
|
* TCP connection and HTTP read timeout
|
||||||
*/
|
*/
|
||||||
@@ -30,15 +28,15 @@ final class PlayerRoutes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static String createInnertubeBody(ClientType clientType) {
|
static String createInnertubeBody(ClientType clientType) {
|
||||||
JSONObject innerTubeBody = new JSONObject();
|
JSONObject innerTubeBody = new JSONObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JSONObject context = new JSONObject();
|
JSONObject context = new JSONObject();
|
||||||
|
|
||||||
JSONObject client = new JSONObject();
|
JSONObject client = new JSONObject();
|
||||||
client.put("clientName", clientType.name());
|
client.put("clientName", clientType.name());
|
||||||
client.put("clientVersion", clientType.appVersion);
|
client.put("clientVersion", clientType.clientVersion);
|
||||||
client.put("deviceModel", clientType.model);
|
client.put("deviceModel", clientType.deviceModel);
|
||||||
client.put("osVersion", clientType.osVersion);
|
client.put("osVersion", clientType.osVersion);
|
||||||
if (clientType.androidSdkVersion != null) {
|
if (clientType.androidSdkVersion != null) {
|
||||||
client.put("androidSdkVersion", clientType.androidSdkVersion);
|
client.put("androidSdkVersion", clientType.androidSdkVersion);
|
||||||
@@ -57,7 +55,9 @@ final class PlayerRoutes {
|
|||||||
return innerTubeBody.toString();
|
return innerTubeBody.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @noinspection SameParameterValue*/
|
/**
|
||||||
|
* @noinspection SameParameterValue
|
||||||
|
*/
|
||||||
static HttpURLConnection getPlayerResponseConnectionFromRoute(Route.CompiledRoute route, ClientType clientType) throws IOException {
|
static HttpURLConnection getPlayerResponseConnectionFromRoute(Route.CompiledRoute route, ClientType clientType) throws IOException {
|
||||||
var connection = Requester.getConnectionFromCompiledRoute(YT_API_URL, route);
|
var connection = Requester.getConnectionFromCompiledRoute(YT_API_URL, route);
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import app.revanced.extension.youtube.settings.Settings;
|
|||||||
/**
|
/**
|
||||||
* Video streaming data. Fetching is tied to the behavior YT uses,
|
* Video streaming data. Fetching is tied to the behavior YT uses,
|
||||||
* where this class fetches the streams only when YT fetches.
|
* where this class fetches the streams only when YT fetches.
|
||||||
*
|
* <p>
|
||||||
* Effectively the cache expiration of these fetches is the same as the stock app,
|
* Effectively the cache expiration of these fetches is the same as the stock app,
|
||||||
* since the stock app would not use expired streams and therefor
|
* since the stock app would not use expired streams and therefor
|
||||||
* the extension replace stream hook is called only if YT
|
* the extension replace stream hook is called only if YT
|
||||||
@@ -37,38 +37,20 @@ import app.revanced.extension.youtube.settings.Settings;
|
|||||||
public class StreamingDataRequest {
|
public class StreamingDataRequest {
|
||||||
|
|
||||||
private static final ClientType[] CLIENT_ORDER_TO_USE;
|
private static final ClientType[] CLIENT_ORDER_TO_USE;
|
||||||
|
private static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
static {
|
|
||||||
ClientType[] allClientTypes = ClientType.values();
|
|
||||||
ClientType preferredClient = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
|
|
||||||
|
|
||||||
CLIENT_ORDER_TO_USE = new ClientType[allClientTypes.length];
|
|
||||||
CLIENT_ORDER_TO_USE[0] = preferredClient;
|
|
||||||
|
|
||||||
int i = 1;
|
|
||||||
for (ClientType c : allClientTypes) {
|
|
||||||
if (c != preferredClient) {
|
|
||||||
CLIENT_ORDER_TO_USE[i++] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String[] REQUEST_HEADER_KEYS = {
|
private static final String[] REQUEST_HEADER_KEYS = {
|
||||||
"Authorization", // Available only to logged in users.
|
AUTHORIZATION_HEADER, // Available only to logged-in users.
|
||||||
"X-GOOG-API-FORMAT-VERSION",
|
"X-GOOG-API-FORMAT-VERSION",
|
||||||
"X-Goog-Visitor-Id"
|
"X-Goog-Visitor-Id"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TCP connection and HTTP read timeout.
|
* TCP connection and HTTP read timeout.
|
||||||
*/
|
*/
|
||||||
private static final int HTTP_TIMEOUT_MILLISECONDS = 10 * 1000;
|
private static final int HTTP_TIMEOUT_MILLISECONDS = 10 * 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any arbitrarily large value, but must be at least twice {@link #HTTP_TIMEOUT_MILLISECONDS}
|
* Any arbitrarily large value, but must be at least twice {@link #HTTP_TIMEOUT_MILLISECONDS}
|
||||||
*/
|
*/
|
||||||
private static final int MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000;
|
private static final int MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000;
|
||||||
|
|
||||||
private static final Map<String, StreamingDataRequest> cache = Collections.synchronizedMap(
|
private static final Map<String, StreamingDataRequest> cache = Collections.synchronizedMap(
|
||||||
new LinkedHashMap<>(100) {
|
new LinkedHashMap<>(100) {
|
||||||
/**
|
/**
|
||||||
@@ -86,8 +68,32 @@ public class StreamingDataRequest {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static {
|
||||||
|
ClientType[] allClientTypes = ClientType.values();
|
||||||
|
ClientType preferredClient = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
|
||||||
|
|
||||||
|
CLIENT_ORDER_TO_USE = new ClientType[allClientTypes.length];
|
||||||
|
CLIENT_ORDER_TO_USE[0] = preferredClient;
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
for (ClientType c : allClientTypes) {
|
||||||
|
if (c != preferredClient) {
|
||||||
|
CLIENT_ORDER_TO_USE[i++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String videoId;
|
||||||
|
private final Future<ByteBuffer> future;
|
||||||
|
|
||||||
|
private StreamingDataRequest(String videoId, Map<String, String> playerHeaders) {
|
||||||
|
Objects.requireNonNull(playerHeaders);
|
||||||
|
this.videoId = videoId;
|
||||||
|
this.future = Utils.submitOnBackgroundThread(() -> fetch(videoId, playerHeaders));
|
||||||
|
}
|
||||||
|
|
||||||
public static void fetchRequest(String videoId, Map<String, String> fetchHeaders) {
|
public static void fetchRequest(String videoId, Map<String, String> fetchHeaders) {
|
||||||
// Always fetch, even if there is a existing request for the same video.
|
// Always fetch, even if there is an existing request for the same video.
|
||||||
cache.put(videoId, new StreamingDataRequest(videoId, fetchHeaders));
|
cache.put(videoId, new StreamingDataRequest(videoId, fetchHeaders));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +125,10 @@ public class StreamingDataRequest {
|
|||||||
connection.setReadTimeout(HTTP_TIMEOUT_MILLISECONDS);
|
connection.setReadTimeout(HTTP_TIMEOUT_MILLISECONDS);
|
||||||
|
|
||||||
for (String key : REQUEST_HEADER_KEYS) {
|
for (String key : REQUEST_HEADER_KEYS) {
|
||||||
|
if (!clientType.canLogin && key.equals(AUTHORIZATION_HEADER)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String value = playerHeaders.get(key);
|
String value = playerHeaders.get(key);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
connection.setRequestProperty(key, value);
|
connection.setRequestProperty(key, value);
|
||||||
@@ -186,15 +196,6 @@ public class StreamingDataRequest {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String videoId;
|
|
||||||
private final Future<ByteBuffer> future;
|
|
||||||
|
|
||||||
private StreamingDataRequest(String videoId, Map<String, String> playerHeaders) {
|
|
||||||
Objects.requireNonNull(playerHeaders);
|
|
||||||
this.videoId = videoId;
|
|
||||||
this.future = Utils.submitOnBackgroundThread(() -> fetch(videoId, playerHeaders));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean fetchCompleted() {
|
public boolean fetchCompleted() {
|
||||||
return future.isDone();
|
return future.isDone();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ package app.revanced.extension.youtube.patches.theme;
|
|||||||
|
|
||||||
import static app.revanced.extension.shared.StringRef.str;
|
import static app.revanced.extension.shared.StringRef.str;
|
||||||
|
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
import app.revanced.extension.shared.Utils;
|
import app.revanced.extension.shared.Utils;
|
||||||
@@ -16,7 +19,8 @@ public final class SeekbarColorPatch {
|
|||||||
private static final boolean SEEKBAR_CUSTOM_COLOR_ENABLED = Settings.SEEKBAR_CUSTOM_COLOR.get();
|
private static final boolean SEEKBAR_CUSTOM_COLOR_ENABLED = Settings.SEEKBAR_CUSTOM_COLOR.get();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default color of the seekbar.
|
* Default color of the litho seekbar.
|
||||||
|
* Differs slightly from the default custom seekbar color setting.
|
||||||
*/
|
*/
|
||||||
private static final int ORIGINAL_SEEKBAR_COLOR = 0xFFFF0000;
|
private static final int ORIGINAL_SEEKBAR_COLOR = 0xFFFF0000;
|
||||||
|
|
||||||
@@ -72,12 +76,76 @@ public final class SeekbarColorPatch {
|
|||||||
return seekbarColor;
|
return seekbarColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point
|
||||||
|
*/
|
||||||
public static boolean playerSeekbarGradientEnabled(boolean original) {
|
public static boolean playerSeekbarGradientEnabled(boolean original) {
|
||||||
if (SEEKBAR_CUSTOM_COLOR_ENABLED) return false;
|
if (SEEKBAR_CUSTOM_COLOR_ENABLED) return false;
|
||||||
|
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point
|
||||||
|
*/
|
||||||
|
public static boolean useLotteLaunchSplashScreen(boolean original) {
|
||||||
|
Logger.printDebug(() -> "useLotteLaunchSplashScreen original: " + original);
|
||||||
|
|
||||||
|
if (SEEKBAR_CUSTOM_COLOR_ENABLED) return false;
|
||||||
|
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int colorChannelTo3Bits(int channel8Bits) {
|
||||||
|
final float channel3Bits = channel8Bits * 7 / 255f;
|
||||||
|
|
||||||
|
// If a color channel is near zero, then allow rounding up so values between
|
||||||
|
// 0x12 and 0x23 will show as 0x24. But always round down when the channel is
|
||||||
|
// near full saturation, otherwise rounding to nearest will cause all values
|
||||||
|
// between 0xEC and 0xFE to always show as full saturation (0xFF).
|
||||||
|
return channel3Bits < 6
|
||||||
|
? Math.round(channel3Bits)
|
||||||
|
: (int) channel3Bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String get9BitStyleIdentifier(int color24Bit) {
|
||||||
|
final int r3 = colorChannelTo3Bits(Color.red(color24Bit));
|
||||||
|
final int g3 = colorChannelTo3Bits(Color.green(color24Bit));
|
||||||
|
final int b3 = colorChannelTo3Bits(Color.blue(color24Bit));
|
||||||
|
|
||||||
|
return String.format(Locale.US, "splash_seekbar_color_style_%d_%d_%d", r3, g3, b3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point
|
||||||
|
*/
|
||||||
|
public static void setSplashAnimationDrawableTheme(AnimatedVectorDrawable vectorDrawable) {
|
||||||
|
// Alternatively a ColorMatrixColorFilter can be used to change the color of the drawable
|
||||||
|
// without using any styles, but a color filter cannot selectively change the seekbar
|
||||||
|
// while keeping the red YT logo untouched.
|
||||||
|
// Even if the seekbar color xml value is changed to a completely different color (such as green),
|
||||||
|
// a color filter still cannot be selectively applied when the drawable has more than 1 color.
|
||||||
|
try {
|
||||||
|
String seekbarStyle = get9BitStyleIdentifier(seekbarColor);
|
||||||
|
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);
|
||||||
|
|
||||||
|
final int styleIdentifierDefault = Utils.getResourceIdentifier(
|
||||||
|
seekbarStyle,
|
||||||
|
"style"
|
||||||
|
);
|
||||||
|
if (styleIdentifierDefault == 0) {
|
||||||
|
throw new RuntimeException("Seekbar style not found: " + seekbarStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Resources.Theme theme = Utils.getContext().getResources().newTheme();
|
||||||
|
theme.applyStyle(styleIdentifierDefault, true);
|
||||||
|
|
||||||
|
vectorDrawable.applyTheme(theme);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "setSplashAnimationDrawableTheme failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*
|
*
|
||||||
@@ -189,4 +257,4 @@ public final class SeekbarColorPatch {
|
|||||||
private static float clamp(float value, float lower, float upper) {
|
private static float clamp(float value, float lower, float upper) {
|
||||||
return Math.max(lower, Math.min(value, upper));
|
return Math.max(lower, Math.min(value, upper));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment;
|
||||||
import app.revanced.extension.youtube.ThemeHelper;
|
import app.revanced.extension.youtube.ThemeHelper;
|
||||||
import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment;
|
import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment;
|
||||||
import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment;
|
import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment;
|
||||||
@@ -39,7 +40,7 @@ public class LicenseActivityHook {
|
|||||||
|
|
||||||
PreferenceFragment fragment;
|
PreferenceFragment fragment;
|
||||||
String toolbarTitleResourceName;
|
String toolbarTitleResourceName;
|
||||||
String dataString = licenseActivity.getIntent().getDataString();
|
String dataString = Objects.requireNonNull(licenseActivity.getIntent().getDataString());
|
||||||
switch (dataString) {
|
switch (dataString) {
|
||||||
case "revanced_sb_settings_intent":
|
case "revanced_sb_settings_intent":
|
||||||
toolbarTitleResourceName = "revanced_sb_settings_title";
|
toolbarTitleResourceName = "revanced_sb_settings_title";
|
||||||
@@ -59,12 +60,14 @@ public class LicenseActivityHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setToolbarTitle(licenseActivity, toolbarTitleResourceName);
|
setToolbarTitle(licenseActivity, toolbarTitleResourceName);
|
||||||
|
|
||||||
|
//noinspection deprecation
|
||||||
licenseActivity.getFragmentManager()
|
licenseActivity.getFragmentManager()
|
||||||
.beginTransaction()
|
.beginTransaction()
|
||||||
.replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment)
|
.replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment)
|
||||||
.commit();
|
.commit();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "onCreate failure", ex);
|
Logger.printException(() -> "initialize failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +83,7 @@ public class LicenseActivityHook {
|
|||||||
ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
|
ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
|
||||||
ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false,
|
ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false,
|
||||||
view -> view instanceof ImageButton));
|
view -> view instanceof ImageButton));
|
||||||
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme()
|
imageButton.setImageDrawable(AbstractPreferenceFragment.getBackButtonDrawable());
|
||||||
? "yt_outline_arrow_left_white_24"
|
|
||||||
: "yt_outline_arrow_left_black_24",
|
|
||||||
"drawable");
|
|
||||||
imageButton.setImageDrawable(activity.getResources().getDrawable(backButtonResource));
|
|
||||||
imageButton.setOnClickListener(view -> activity.onBackPressed());
|
imageButton.setOnClickListener(view -> activity.onBackPressed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillIm
|
|||||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption;
|
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption;
|
||||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailStillTime;
|
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailStillTime;
|
||||||
import app.revanced.extension.youtube.patches.spoof.ClientType;
|
import app.revanced.extension.youtube.patches.spoof.ClientType;
|
||||||
import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch;
|
|
||||||
import app.revanced.extension.youtube.patches.spoof.SpoofVideoStreamsPatch;
|
import app.revanced.extension.youtube.patches.spoof.SpoofVideoStreamsPatch;
|
||||||
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
||||||
|
|
||||||
@@ -197,7 +196,7 @@ public class Settings extends BaseSettings {
|
|||||||
// General layout
|
// General layout
|
||||||
public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true);
|
public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true);
|
||||||
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
|
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
|
||||||
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "18.38.44" : "17.33.42", true, parent(SPOOF_APP_VERSION));
|
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "19.16.39" : "17.33.42", true, parent(SPOOF_APP_VERSION));
|
||||||
public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message");
|
public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message");
|
||||||
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
|
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
|
||||||
public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true);
|
public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true);
|
||||||
@@ -277,7 +276,7 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
|
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
|
||||||
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability());
|
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability());
|
||||||
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
|
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
|
||||||
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1);
|
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false);
|
||||||
public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false);
|
public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false);
|
||||||
public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE);
|
public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE);
|
||||||
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);
|
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);
|
||||||
@@ -375,15 +374,20 @@ public class Settings extends BaseSettings {
|
|||||||
|
|
||||||
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
|
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
|
||||||
|
|
||||||
|
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS);
|
||||||
|
|
||||||
|
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER, HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER);
|
||||||
|
|
||||||
// Old spoof versions that no longer work reliably.
|
// Old spoof versions that no longer work reliably.
|
||||||
if (SpoofAppVersionPatch.isSpoofingToLessThan(SPOOF_APP_VERSION_TARGET.defaultValue)) {
|
if (SPOOF_APP_VERSION_TARGET.get().compareTo(SPOOF_APP_VERSION_TARGET.defaultValue) < 0) {
|
||||||
Logger.printInfo(() -> "Resetting spoof app version target");
|
Logger.printInfo(() -> "Resetting spoof app version target");
|
||||||
SPOOF_APP_VERSION_TARGET.resetToDefault();
|
SPOOF_APP_VERSION_TARGET.resetToDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS);
|
// Migrate renamed enum type.
|
||||||
|
if (MINIPLAYER_TYPE.get() == PHONE) {
|
||||||
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER, HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER);
|
MINIPLAYER_TYPE.save(MINIMAL);
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
|
|||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
android.useAndroidX = true
|
android.useAndroidX = true
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 5.1.0-dev.2
|
version = 5.2.1-dev.1
|
||||||
|
|||||||
@@ -503,6 +503,10 @@ public final class app/revanced/patches/reddit/customclients/sync/syncforreddit/
|
|||||||
public static final fun getUseUserEndpointPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getUseUserEndpointPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatchKt {
|
||||||
|
public static final fun getFixVideoDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatchKt {
|
public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatchKt {
|
||||||
public static final fun getFixVideoDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getFixVideoDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@@ -1324,6 +1328,7 @@ public final class app/revanced/patches/youtube/misc/playservice/VersionCheckPat
|
|||||||
public static final fun is_19_36_or_greater ()Z
|
public static final fun is_19_36_or_greater ()Z
|
||||||
public static final fun is_19_41_or_greater ()Z
|
public static final fun is_19_41_or_greater ()Z
|
||||||
public static final fun is_19_43_or_greater ()Z
|
public static final fun is_19_43_or_greater ()Z
|
||||||
|
public static final fun is_19_46_or_greater ()Z
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt {
|
public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt {
|
||||||
@@ -1365,11 +1370,9 @@ public final class app/revanced/patches/youtube/shared/FingerprintsKt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt {
|
public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt {
|
||||||
public static final fun getSetPlaybackSpeedClassFieldReference ()Ljava/lang/String;
|
|
||||||
public static final fun getSetPlaybackSpeedContainerClassFieldReference ()Ljava/lang/String;
|
|
||||||
public static final fun getSetPlaybackSpeedMethodReference ()Ljava/lang/String;
|
|
||||||
public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V
|
public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V
|
||||||
|
public static final fun videoSpeedChangedHook (Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public static final fun videoTimeHook (Ljava/lang/String;Ljava/lang/String;)V
|
public static final fun videoTimeHook (Ljava/lang/String;Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import app.revanced.patcher.patch.bytecodePatch
|
|||||||
val unlockProPatch = bytecodePatch(
|
val unlockProPatch = bytecodePatch(
|
||||||
name = "Unlock pro",
|
name = "Unlock pro",
|
||||||
) {
|
) {
|
||||||
compatibleWith("org.totschnig.myexpenses")
|
compatibleWith("org.totschnig.myexpenses"("3.4.9"))
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
isEnabledFingerprint.method.addInstructions(
|
isEnabledFingerprint.method.addInstructions(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.video
|
package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/syncforreddit/FixRedditVideoDownloadPatch;"
|
||||||
|
private const val GET_LINKS_METHOD = "getLinks([B)[Ljava/lang/String;"
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val fixVideoDownloadsPatch = bytecodePatch(
|
||||||
|
name = "Fix video downloads",
|
||||||
|
description = "Fixes a bug in Sync's MPD parser resulting in only the audio-track being saved.",
|
||||||
|
) {
|
||||||
|
dependsOn(sharedExtensionPatch)
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.laurencedawson.reddit_sync",
|
||||||
|
"com.laurencedawson.reddit_sync.pro",
|
||||||
|
"com.laurencedawson.reddit_sync.dev",
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
val scanResult = parseRedditVideoNetworkResponseFingerprint.patternMatch!!
|
||||||
|
val newInstanceIndex = scanResult.startIndex
|
||||||
|
val invokeDirectIndex = scanResult.endIndex - 1
|
||||||
|
|
||||||
|
val buildResponseInstruction =
|
||||||
|
parseRedditVideoNetworkResponseFingerprint.method.getInstruction<Instruction35c>(invokeDirectIndex)
|
||||||
|
|
||||||
|
parseRedditVideoNetworkResponseFingerprint.method.addInstructions(
|
||||||
|
newInstanceIndex + 1,
|
||||||
|
"""
|
||||||
|
# Get byte array from response.
|
||||||
|
iget-object v2, p1, Lcom/android/volley/NetworkResponse;->data:[B
|
||||||
|
|
||||||
|
# Parse the videoUrl and audioUrl from the byte array.
|
||||||
|
invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->$GET_LINKS_METHOD
|
||||||
|
move-result-object v2
|
||||||
|
|
||||||
|
# Get videoUrl (Index 0).
|
||||||
|
const/4 v5, 0x0
|
||||||
|
aget-object v${buildResponseInstruction.registerE}, v2, v5
|
||||||
|
|
||||||
|
# Get audioUrl (Index 1).
|
||||||
|
const/4 v6, 0x1
|
||||||
|
aget-object v${buildResponseInstruction.registerF}, v2, v6
|
||||||
|
|
||||||
|
# Register E and F are used to build the response.
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,56 +1,18 @@
|
|||||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.video
|
package app.revanced.patches.reddit.customclients.syncforreddit.fix.video
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
|
||||||
"Lapp/revanced/extension/syncforreddit/FixRedditVideoDownloadPatch;"
|
|
||||||
private const val GET_LINKS_METHOD = "getLinks([B)[Ljava/lang/String;"
|
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
message = "Patch was move to a different package",
|
||||||
|
ReplaceWith("app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video.fixVideoDownloadsPatch")
|
||||||
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val fixVideoDownloadsPatch = bytecodePatch(
|
val fixVideoDownloadsPatch = bytecodePatch {
|
||||||
name = "Fix video downloads",
|
dependsOn(app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video.fixVideoDownloadsPatch)
|
||||||
description = "Fixes a bug in Sync's MPD parser resulting in only the audio-track being saved.",
|
|
||||||
) {
|
|
||||||
dependsOn(sharedExtensionPatch)
|
|
||||||
|
|
||||||
compatibleWith(
|
compatibleWith(
|
||||||
"com.laurencedawson.reddit_sync",
|
"com.laurencedawson.reddit_sync",
|
||||||
"com.laurencedawson.reddit_sync.pro",
|
"com.laurencedawson.reddit_sync.pro",
|
||||||
"com.laurencedawson.reddit_sync.dev",
|
"com.laurencedawson.reddit_sync.dev",
|
||||||
)
|
)
|
||||||
|
}
|
||||||
execute {
|
|
||||||
val scanResult = parseRedditVideoNetworkResponseFingerprint.patternMatch!!
|
|
||||||
val newInstanceIndex = scanResult.startIndex
|
|
||||||
val invokeDirectIndex = scanResult.endIndex - 1
|
|
||||||
|
|
||||||
val buildResponseInstruction =
|
|
||||||
parseRedditVideoNetworkResponseFingerprint.method.getInstruction<Instruction35c>(invokeDirectIndex)
|
|
||||||
|
|
||||||
parseRedditVideoNetworkResponseFingerprint.method.addInstructions(
|
|
||||||
newInstanceIndex + 1,
|
|
||||||
"""
|
|
||||||
# Get byte array from response.
|
|
||||||
iget-object v2, p1, Lcom/android/volley/NetworkResponse;->data:[B
|
|
||||||
|
|
||||||
# Parse the videoUrl and audioUrl from the byte array.
|
|
||||||
invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->$GET_LINKS_METHOD
|
|
||||||
move-result-object v2
|
|
||||||
|
|
||||||
# Get videoUrl (Index 0).
|
|
||||||
const/4 v5, 0x0
|
|
||||||
aget-object v${buildResponseInstruction.registerE}, v2, v5
|
|
||||||
|
|
||||||
# Get audioUrl (Index 1).
|
|
||||||
const/4 v6, 0x1
|
|
||||||
aget-object v${buildResponseInstruction.registerF}, v2, v6
|
|
||||||
|
|
||||||
# Register E and F are used to build the response.
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,9 +3,9 @@ package app.revanced.patches.vsco.misc.pro
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
|
||||||
|
@Deprecated("This patch is deprecated because it does not work anymore and will be removed in the future.")
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val unlockProPatch = bytecodePatch(
|
val unlockProPatch = bytecodePatch(
|
||||||
name = "Unlock pro",
|
|
||||||
description = "Unlocks pro features.",
|
description = "Unlocks pro features.",
|
||||||
) {
|
) {
|
||||||
compatibleWith("com.vsco.cam"("345"))
|
compatibleWith("com.vsco.cam"("345"))
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ val hideAdsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ val hideGetPremiumPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ val videoAdsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ val copyVideoUrlPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ val downloadsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ val disablePreciseSeekingGesturePatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ val enableSeekbarTappingPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ val enableSlideToSeekPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ val seekbarThumbnailsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ val swipeControlsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ val autoCaptionsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ val customBrandingPatch = resourcePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ val changeHeaderPatch = resourcePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ val hideButtonsPatch = resourcePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ val navigationButtonsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ val hideEndscreenCardsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ val hideInfoCardsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ val disableRollingNumberAnimationPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ val hideSeekbarPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -189,9 +189,13 @@ val hideShortsComponentsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
hideShortsAppShortcutOption()
|
||||||
|
hideShortsWidgetOption()
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
// region Hide the Shorts shelf.
|
// region Hide the Shorts shelf.
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ val disableSuggestedVideoEndScreenPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ val hideTimestampPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ internal const val MINIPLAYER_DRAG_DROP_FEATURE_KEY = 45628752L
|
|||||||
internal const val MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY = 45658112L
|
internal const val MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY = 45658112L
|
||||||
internal const val MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY = 45652224L
|
internal const val MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY = 45652224L
|
||||||
internal const val MINIPLAYER_INITIAL_SIZE_FEATURE_KEY = 45640023L
|
internal const val MINIPLAYER_INITIAL_SIZE_FEATURE_KEY = 45640023L
|
||||||
|
internal const val MINIPLAYER_DISABLED_FEATURE_KEY = 45657015L
|
||||||
|
|
||||||
internal val miniplayerModernConstructorFingerprint = fingerprint {
|
internal val miniplayerModernConstructorFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
@@ -50,6 +51,12 @@ internal val miniplayerModernConstructorFingerprint = fingerprint {
|
|||||||
literal { 45623000L }
|
literal { 45623000L }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val miniplayerOnCloseHandlerFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("Z")
|
||||||
|
literal { MINIPLAYER_DISABLED_FEATURE_KEY }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches using the class found in [miniplayerModernViewParentFingerprint].
|
* Matches using the class found in [miniplayerModernViewParentFingerprint].
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,8 +135,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val miniplayerPatch = bytecodePatch(
|
val miniplayerPatch = bytecodePatch(
|
||||||
name = "Miniplayer",
|
name = "Miniplayer",
|
||||||
description = "Adds options to change the in app minimized player. " +
|
description = "Adds options to change the in app minimized player."
|
||||||
"Patching target 19.16+ adds modern miniplayers.",
|
|
||||||
) {
|
) {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
sharedExtensionPatch,
|
sharedExtensionPatch,
|
||||||
@@ -147,8 +146,7 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
|
|
||||||
compatibleWith(
|
compatibleWith(
|
||||||
"com.google.android.youtube"(
|
"com.google.android.youtube"(
|
||||||
"18.38.44",
|
// 18.49.37 // Could be supported, but no reason when 19.16 exists and has modern types.
|
||||||
"18.49.37",
|
|
||||||
// 19.14.43 // Incomplete code for modern miniplayers.
|
// 19.14.43 // Incomplete code for modern miniplayers.
|
||||||
// 19.15.36 // Different code for handling subtitle texts and not worth supporting.
|
// 19.15.36 // Different code for handling subtitle texts and not worth supporting.
|
||||||
"19.16.39", // First with modern miniplayers.
|
"19.16.39", // First with modern miniplayers.
|
||||||
@@ -171,6 +169,7 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -179,58 +178,60 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
|
|
||||||
val preferences = mutableSetOf<BasePreference>()
|
val preferences = mutableSetOf<BasePreference>()
|
||||||
|
|
||||||
if (!is_19_16_or_greater) {
|
|
||||||
preferences += ListPreference(
|
|
||||||
"revanced_miniplayer_type",
|
|
||||||
summaryKey = null,
|
|
||||||
entriesKey = "revanced_miniplayer_type_legacy_entries",
|
|
||||||
entryValuesKey = "revanced_miniplayer_type_legacy_entry_values",
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
preferences += ListPreference(
|
|
||||||
"revanced_miniplayer_type",
|
|
||||||
summaryKey = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (is_19_25_or_greater) {
|
|
||||||
if (!is_19_29_or_greater) {
|
|
||||||
preferences += SwitchPreference("revanced_miniplayer_double_tap_action")
|
|
||||||
}
|
|
||||||
preferences += SwitchPreference("revanced_miniplayer_drag_and_drop")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
preferences +=
|
||||||
if (is_19_43_or_greater) {
|
if (is_19_43_or_greater) {
|
||||||
preferences += SwitchPreference("revanced_miniplayer_horizontal_drag")
|
ListPreference(
|
||||||
}
|
"revanced_miniplayer_type",
|
||||||
|
summaryKey = null,
|
||||||
if (is_19_36_or_greater) {
|
)
|
||||||
preferences += SwitchPreference("revanced_miniplayer_rounded_corners")
|
|
||||||
}
|
|
||||||
|
|
||||||
preferences += SwitchPreference("revanced_miniplayer_hide_subtext")
|
|
||||||
|
|
||||||
preferences += if (is_19_26_or_greater) {
|
|
||||||
SwitchPreference("revanced_miniplayer_hide_expand_close")
|
|
||||||
} else {
|
} else {
|
||||||
SwitchPreference(
|
ListPreference(
|
||||||
key = "revanced_miniplayer_hide_expand_close",
|
"revanced_miniplayer_type",
|
||||||
titleKey = "revanced_miniplayer_hide_expand_close_legacy_title",
|
summaryKey = null,
|
||||||
summaryOnKey = "revanced_miniplayer_hide_expand_close_legacy_summary_on",
|
entriesKey = "revanced_miniplayer_type_legacy_entries",
|
||||||
summaryOffKey = "revanced_miniplayer_hide_expand_close_legacy_summary_off",
|
entryValuesKey = "revanced_miniplayer_type_legacy_entry_values",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_19_26_or_greater) {
|
if (is_19_25_or_greater) {
|
||||||
preferences += SwitchPreference("revanced_miniplayer_hide_rewind_forward")
|
if (!is_19_29_or_greater) {
|
||||||
|
preferences += SwitchPreference("revanced_miniplayer_double_tap_action")
|
||||||
}
|
}
|
||||||
|
preferences += SwitchPreference("revanced_miniplayer_drag_and_drop")
|
||||||
if (is_19_26_or_greater) {
|
|
||||||
preferences += TextPreference("revanced_miniplayer_width_dip", inputType = InputType.NUMBER)
|
|
||||||
}
|
|
||||||
|
|
||||||
preferences += TextPreference("revanced_miniplayer_opacity", inputType = InputType.NUMBER)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_19_43_or_greater) {
|
||||||
|
preferences += SwitchPreference("revanced_miniplayer_horizontal_drag")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_19_36_or_greater) {
|
||||||
|
preferences += SwitchPreference("revanced_miniplayer_rounded_corners")
|
||||||
|
}
|
||||||
|
|
||||||
|
preferences += SwitchPreference("revanced_miniplayer_hide_subtext")
|
||||||
|
|
||||||
|
preferences += if (is_19_26_or_greater) {
|
||||||
|
SwitchPreference("revanced_miniplayer_hide_expand_close")
|
||||||
|
} else {
|
||||||
|
SwitchPreference(
|
||||||
|
key = "revanced_miniplayer_hide_expand_close",
|
||||||
|
titleKey = "revanced_miniplayer_hide_expand_close_legacy_title",
|
||||||
|
summaryOnKey = "revanced_miniplayer_hide_expand_close_legacy_summary_on",
|
||||||
|
summaryOffKey = "revanced_miniplayer_hide_expand_close_legacy_summary_off",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_19_26_or_greater) {
|
||||||
|
preferences += SwitchPreference("revanced_miniplayer_hide_rewind_forward")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_19_26_or_greater) {
|
||||||
|
preferences += TextPreference("revanced_miniplayer_width_dip", inputType = InputType.NUMBER)
|
||||||
|
}
|
||||||
|
|
||||||
|
preferences += TextPreference("revanced_miniplayer_opacity", inputType = InputType.NUMBER)
|
||||||
|
|
||||||
PreferenceScreen.PLAYER.addPreferences(
|
PreferenceScreen.PLAYER.addPreferences(
|
||||||
PreferenceScreenPreference(
|
PreferenceScreenPreference(
|
||||||
key = "revanced_miniplayer_screen",
|
key = "revanced_miniplayer_screen",
|
||||||
@@ -350,11 +351,6 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
it.method.insertLegacyTabletMiniplayerOverride(it.patternMatch!!.endIndex)
|
it.method.insertLegacyTabletMiniplayerOverride(it.patternMatch!!.endIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_19_16_or_greater) {
|
|
||||||
// Return here, as patch below is only for the current versions of the app.
|
|
||||||
return@execute
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Enable modern miniplayer.
|
// region Enable modern miniplayer.
|
||||||
@@ -380,13 +376,6 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_19_43_or_greater) {
|
|
||||||
miniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
|
||||||
MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY,
|
|
||||||
"setHorizontalDrag",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_19_25_or_greater) {
|
if (is_19_25_or_greater) {
|
||||||
miniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
miniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
||||||
MINIPLAYER_MODERN_FEATURE_LEGACY_KEY,
|
MINIPLAYER_MODERN_FEATURE_LEGACY_KEY,
|
||||||
@@ -443,6 +432,18 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_19_43_or_greater) {
|
||||||
|
miniplayerOnCloseHandlerFingerprint.insertLiteralValueBooleanOverride(
|
||||||
|
MINIPLAYER_DISABLED_FEATURE_KEY,
|
||||||
|
"getMiniplayerOnCloseHandler"
|
||||||
|
)
|
||||||
|
|
||||||
|
miniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
||||||
|
MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY,
|
||||||
|
"setHorizontalDrag",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Fix 19.16 using mixed up drawables for tablet modern.
|
// region Fix 19.16 using mixed up drawables for tablet modern.
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ val playerPopupPanelsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ val playerControlsBackgroundPatch = resourcePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ val wideSearchbarPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -48,3 +48,17 @@ internal val lithoLinearGradientFingerprint = fingerprint {
|
|||||||
returns("Landroid/graphics/LinearGradient;")
|
returns("Landroid/graphics/LinearGradient;")
|
||||||
parameters("F", "F", "F", "F", "[I", "[F")
|
parameters("F", "F", "F", "F", "[I", "[F")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal const val launchScreenLayoutTypeLotteFeatureFlag = 268507948L
|
||||||
|
|
||||||
|
internal val launchScreenLayoutTypeFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
returns("V")
|
||||||
|
custom { method, _ ->
|
||||||
|
val firstParameter = method.parameterTypes.firstOrNull()
|
||||||
|
// 19.25 - 19.45
|
||||||
|
(firstParameter == "Lcom/google/android/apps/youtube/app/watchwhile/MainActivity;"
|
||||||
|
|| firstParameter == "Landroid/app/Activity;") // 19.46+
|
||||||
|
&& method.containsLiteralInstruction(launchScreenLayoutTypeLotteFeatureFlag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,15 +13,24 @@ import app.revanced.patches.shared.misc.mapping.resourceMappings
|
|||||||
import app.revanced.patches.youtube.layout.theme.lithoColorHookPatch
|
import app.revanced.patches.youtube.layout.theme.lithoColorHookPatch
|
||||||
import app.revanced.patches.youtube.layout.theme.lithoColorOverrideHook
|
import app.revanced.patches.youtube.layout.theme.lithoColorOverrideHook
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_23_or_greater
|
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
||||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
|
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||||
|
import app.revanced.util.copyXmlNode
|
||||||
|
import app.revanced.util.findElementByAttributeValueOrThrow
|
||||||
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||||
|
import app.revanced.util.inputStreamFromBundledResource
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import kotlin.use
|
||||||
|
|
||||||
internal var reelTimeBarPlayedColorId = -1L
|
internal var reelTimeBarPlayedColorId = -1L
|
||||||
private set
|
private set
|
||||||
@@ -30,6 +39,8 @@ internal var inlineTimeBarColorizedBarPlayedColorDarkId = -1L
|
|||||||
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
|
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
internal const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color"
|
||||||
|
|
||||||
private val seekbarColorResourcePatch = resourcePatch {
|
private val seekbarColorResourcePatch = resourcePatch {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
@@ -51,9 +62,8 @@ private val seekbarColorResourcePatch = resourcePatch {
|
|||||||
"inline_time_bar_played_not_highlighted_color",
|
"inline_time_bar_played_not_highlighted_color",
|
||||||
]
|
]
|
||||||
|
|
||||||
// Edit the resume playback drawable and replace the progress bar with a custom drawable
|
// Modify the resume playback drawable and replace the progress bar with a custom drawable.
|
||||||
document("res/drawable/resume_playback_progressbar_drawable.xml").use { document ->
|
document("res/drawable/resume_playback_progressbar_drawable.xml").use { document ->
|
||||||
|
|
||||||
val layerList = document.getElementsByTagName("layer-list").item(0) as Element
|
val layerList = document.getElementsByTagName("layer-list").item(0) as Element
|
||||||
val progressNode = layerList.getElementsByTagName("item").item(1) as Element
|
val progressNode = layerList.getElementsByTagName("item").item(1) as Element
|
||||||
if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) {
|
if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) {
|
||||||
@@ -66,9 +76,102 @@ private val seekbarColorResourcePatch = resourcePatch {
|
|||||||
)
|
)
|
||||||
scaleNode.replaceChild(replacementNode, shapeNode)
|
scaleNode.replaceChild(replacementNode, shapeNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!is_19_25_or_greater) {
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add attribute and styles for splash screen custom color.
|
||||||
|
// Using a style is the only way to selectively change just the seekbar fill color.
|
||||||
|
//
|
||||||
|
// Because the style colors must be hard coded for all color possibilities,
|
||||||
|
// instead of allowing 24 bit color the style is restricted to 9-bit (3 bits per color channel)
|
||||||
|
// and the style color closest to the users custom color is used for the splash screen.
|
||||||
|
arrayOf(
|
||||||
|
inputStreamFromBundledResource("seekbar/values", "attrs.xml")!! to "res/values/attrs.xml",
|
||||||
|
ByteArrayInputStream(create9BitSeekbarColorStyles().toByteArray()) to "res/values/styles.xml"
|
||||||
|
).forEach { (source, destination) ->
|
||||||
|
"resources".copyXmlNode(
|
||||||
|
document(source),
|
||||||
|
document(destination),
|
||||||
|
).close()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSplashDrawablePathFillColor(xmlFileNames: Iterable<String>, vararg resourceNames: String) {
|
||||||
|
xmlFileNames.forEach { xmlFileName ->
|
||||||
|
document(xmlFileName).use { document ->
|
||||||
|
resourceNames.forEach { elementId ->
|
||||||
|
val element = document.childNodes.findElementByAttributeValueOrThrow(
|
||||||
|
"android:name",
|
||||||
|
elementId
|
||||||
|
)
|
||||||
|
|
||||||
|
val attribute = "android:fillColor"
|
||||||
|
if (!element.hasAttribute(attribute)) {
|
||||||
|
throw PatchException("Could not find $attribute for $elementId")
|
||||||
|
}
|
||||||
|
|
||||||
|
element.setAttribute(attribute, "?attr/$splashSeekbarColorAttributeName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setSplashDrawablePathFillColor(
|
||||||
|
listOf(
|
||||||
|
"res/drawable/\$startup_animation_light__0.xml",
|
||||||
|
"res/drawable/\$startup_animation_dark__0.xml"
|
||||||
|
),
|
||||||
|
"_R_G_L_10_G_D_0_P_0"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!is_19_46_or_greater) {
|
||||||
|
// Resources removed in 19.46+
|
||||||
|
setSplashDrawablePathFillColor(
|
||||||
|
listOf(
|
||||||
|
"res/drawable/\$buenos_aires_animation_light__0.xml",
|
||||||
|
"res/drawable/\$buenos_aires_animation_dark__0.xml"
|
||||||
|
),
|
||||||
|
"_R_G_L_8_G_D_0_P_0"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a style xml with all combinations of 9-bit colors.
|
||||||
|
*/
|
||||||
|
private fun create9BitSeekbarColorStyles(): String = StringBuilder().apply {
|
||||||
|
append("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
|
||||||
|
append("<resources>\n")
|
||||||
|
|
||||||
|
for (red in 0..7) {
|
||||||
|
for (green in 0..7) {
|
||||||
|
for (blue in 0..7) {
|
||||||
|
val name = "${red}_${green}_${blue}"
|
||||||
|
|
||||||
|
fun roundTo3BitHex(channel8Bits: Int) =
|
||||||
|
(channel8Bits * 255 / 7).toString(16).padStart(2, '0')
|
||||||
|
val r = roundTo3BitHex(red)
|
||||||
|
val g = roundTo3BitHex(green)
|
||||||
|
val b = roundTo3BitHex(blue)
|
||||||
|
val color = "#ff$r$g$b"
|
||||||
|
|
||||||
|
append(
|
||||||
|
"""
|
||||||
|
<style name="splash_seekbar_color_style_$name">
|
||||||
|
<item name="$splashSeekbarColorAttributeName">$color</item>
|
||||||
|
</style>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
append("</resources>")
|
||||||
|
}.toString()
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/SeekbarColorPatch;"
|
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/SeekbarColorPatch;"
|
||||||
|
|
||||||
val seekbarColorPatch = bytecodePatch(
|
val seekbarColorPatch = bytecodePatch(
|
||||||
@@ -117,27 +220,73 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_19_23_or_greater) {
|
lithoColorOverrideHook(EXTENSION_CLASS_DESCRIPTOR, "getLithoColor")
|
||||||
playerSeekbarGradientConfigFingerprint.method.apply {
|
|
||||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG)
|
if (!is_19_25_or_greater) {
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
|
||||||
|
// 19.25+ changes
|
||||||
|
|
||||||
|
playerSeekbarGradientConfigFingerprint.method.apply {
|
||||||
|
val literalIndex = indexOfFirstLiteralInstructionOrThrow(PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG)
|
||||||
|
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
resultIndex + 1,
|
||||||
|
"""
|
||||||
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->playerSeekbarGradientEnabled(Z)Z
|
||||||
|
move-result v$register
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
lithoLinearGradientFingerprint.method.addInstruction(
|
||||||
|
0,
|
||||||
|
"invoke-static/range { p4 .. p5 }, $EXTENSION_CLASS_DESCRIPTOR->setLinearGradient([I[F)V"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// region apply seekbar custom color to splash screen animation.
|
||||||
|
|
||||||
|
// Don't use the lotte splash screen layout if using custom seekbar.
|
||||||
|
arrayOf(
|
||||||
|
launchScreenLayoutTypeFingerprint,
|
||||||
|
mainActivityOnCreateFingerprint
|
||||||
|
).forEach { fingerprint ->
|
||||||
|
fingerprint.method.apply {
|
||||||
|
val literalIndex = indexOfFirstLiteralInstructionOrThrow(launchScreenLayoutTypeLotteFeatureFlag)
|
||||||
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||||
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA
|
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
resultIndex + 1,
|
resultIndex + 1,
|
||||||
"""
|
"""
|
||||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->playerSeekbarGradientEnabled(Z)Z
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->useLotteLaunchSplashScreen(Z)Z
|
||||||
move-result v$register
|
move-result v$register
|
||||||
""",
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lithoLinearGradientFingerprint.method.addInstruction(
|
// Hook the splash animation drawable to set the a seekbar color theme.
|
||||||
0,
|
mainActivityOnCreateFingerprint.method.apply {
|
||||||
"invoke-static/range { p4 .. p5 }, $EXTENSION_CLASS_DESCRIPTOR->setLinearGradient([I[F)V",
|
val drawableIndex = indexOfFirstInstructionOrThrow {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
reference?.definingClass == "Landroid/widget/ImageView;"
|
||||||
|
&& reference.name == "getDrawable"
|
||||||
|
}
|
||||||
|
val checkCastIndex = indexOfFirstInstructionOrThrow(drawableIndex, Opcode.CHECK_CAST)
|
||||||
|
val drawableRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
checkCastIndex + 1,
|
||||||
|
"invoke-static { v$drawableRegister }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||||
|
"setSplashAnimationDrawableTheme(Landroid/graphics/drawable/AnimatedVectorDrawable;)V"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
lithoColorOverrideHook(EXTENSION_CLASS_DESCRIPTOR, "getLithoColor")
|
// endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ val shortsAutoplayPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,7 +57,7 @@ val shortsAutoplayPatch = bytecodePatch(
|
|||||||
|
|
||||||
// Main activity is used to check if app is in pip mode.
|
// Main activity is used to check if app is in pip mode.
|
||||||
mainActivityOnCreateFingerprint.method.addInstructions(
|
mainActivityOnCreateFingerprint.method.addInstructions(
|
||||||
0,
|
1,
|
||||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||||
"setMainActivity(Landroid/app/Activity;)V",
|
"setMainActivity(Landroid/app/Activity;)V",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ val sponsorBlockPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ val spoofAppVersionPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ val changeStartPagePatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ val enableTabletLayoutPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ val themePatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ val alternativeThumbnailsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ val bypassImageRegionRestrictionsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ val announcementsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ val autoRepeatPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ val backgroundPlaybackPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ val enableDebuggingPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ val spoofDeviceDimensionsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ val spoofVideoStreamsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ val bypassURLRedirectsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ val openLinksExternallyPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ var is_19_41_or_greater = false
|
|||||||
private set
|
private set
|
||||||
var is_19_43_or_greater = false
|
var is_19_43_or_greater = false
|
||||||
private set
|
private set
|
||||||
|
var is_19_46_or_greater = false
|
||||||
|
private set
|
||||||
|
|
||||||
val versionCheckPatch = resourcePatch(
|
val versionCheckPatch = resourcePatch(
|
||||||
description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.",
|
description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.",
|
||||||
@@ -68,5 +70,6 @@ val versionCheckPatch = resourcePatch(
|
|||||||
is_19_36_or_greater = 243705000 <= playStoreServicesVersion
|
is_19_36_or_greater = 243705000 <= playStoreServicesVersion
|
||||||
is_19_41_or_greater = 244305000 <= playStoreServicesVersion
|
is_19_41_or_greater = 244305000 <= playStoreServicesVersion
|
||||||
is_19_43_or_greater = 244405000 <= playStoreServicesVersion
|
is_19_43_or_greater = 244405000 <= playStoreServicesVersion
|
||||||
|
is_19_46_or_greater = 244705000 <= playStoreServicesVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ val removeTrackingQueryParameterPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ val zoomHapticsPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import app.revanced.util.getReference
|
|||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
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.builder.BuilderInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||||
import com.android.tools.smali.dexlib2.iface.Method
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
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.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||||
@@ -57,12 +57,16 @@ private lateinit var speedSelectionInsertMethod: MutableMethod
|
|||||||
private var speedSelectionInsertIndex = -1
|
private var speedSelectionInsertIndex = -1
|
||||||
private var speedSelectionValueRegister = -1
|
private var speedSelectionValueRegister = -1
|
||||||
|
|
||||||
|
// Change playback speed method.
|
||||||
|
private lateinit var setPlaybackSpeedMethod: MutableMethod
|
||||||
|
private var setPlaybackSpeedMethodIndex = -1
|
||||||
|
|
||||||
// Used by other patches.
|
// Used by other patches.
|
||||||
lateinit var setPlaybackSpeedContainerClassFieldReference: String
|
internal lateinit var setPlaybackSpeedContainerClassFieldReference: FieldReference
|
||||||
private set
|
private set
|
||||||
lateinit var setPlaybackSpeedClassFieldReference: String
|
internal lateinit var setPlaybackSpeedClassFieldReference: FieldReference
|
||||||
private set
|
private set
|
||||||
lateinit var setPlaybackSpeedMethodReference: String
|
internal lateinit var setPlaybackSpeedMethodReference: MethodReference
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val videoInformationPatch = bytecodePatch(
|
val videoInformationPatch = bytecodePatch(
|
||||||
@@ -164,24 +168,27 @@ val videoInformationPatch = bytecodePatch(
|
|||||||
videoTimeHook(EXTENSION_CLASS_DESCRIPTOR, "setVideoTime")
|
videoTimeHook(EXTENSION_CLASS_DESCRIPTOR, "setVideoTime")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hook the user playback speed selection
|
* Hook the user playback speed selection.
|
||||||
*/
|
*/
|
||||||
onPlaybackSpeedItemClickFingerprint.method.apply {
|
onPlaybackSpeedItemClickFingerprint.method.apply {
|
||||||
val speedSelectionMethodInstructions = implementation!!.instructions
|
val speedSelectionValueInstructionIndex = indexOfFirstInstructionOrThrow(Opcode.IGET)
|
||||||
val speedSelectionValueInstructionIndex = speedSelectionMethodInstructions.indexOfFirst {
|
|
||||||
it.opcode == Opcode.IGET
|
|
||||||
}
|
|
||||||
legacySpeedSelectionInsertMethod = this
|
legacySpeedSelectionInsertMethod = this
|
||||||
legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1
|
legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1
|
||||||
legacySpeedSelectionValueRegister =
|
legacySpeedSelectionValueRegister =
|
||||||
getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA
|
getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA
|
||||||
|
|
||||||
setPlaybackSpeedClassFieldReference =
|
|
||||||
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference.toString()
|
|
||||||
setPlaybackSpeedMethodReference =
|
setPlaybackSpeedMethodReference =
|
||||||
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference.toString()
|
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference as MethodReference
|
||||||
|
setPlaybackSpeedClassFieldReference =
|
||||||
|
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference as FieldReference
|
||||||
setPlaybackSpeedContainerClassFieldReference =
|
setPlaybackSpeedContainerClassFieldReference =
|
||||||
getReference(speedSelectionMethodInstructions, -1, Opcode.IF_EQZ)
|
getInstruction<ReferenceInstruction>(indexOfFirstInstructionOrThrow(Opcode.IF_EQZ) - 1).reference as FieldReference
|
||||||
|
|
||||||
|
setPlaybackSpeedMethod =
|
||||||
|
proxy(classes.first { it.type == setPlaybackSpeedMethodReference.definingClass })
|
||||||
|
.mutableClass.methods.first { it.name == setPlaybackSpeedMethodReference.name }
|
||||||
|
setPlaybackSpeedMethodIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle new playback speed menu.
|
// Handle new playback speed menu.
|
||||||
@@ -195,6 +202,7 @@ val videoInformationPatch = bytecodePatch(
|
|||||||
speedSelectionValueRegister = getInstruction<TwoRegisterInstruction>(index).registerA
|
speedSelectionValueRegister = getInstruction<TwoRegisterInstruction>(index).registerA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
videoSpeedChangedHook(EXTENSION_CLASS_DESCRIPTOR, "videoSpeedChanged")
|
||||||
userSelectedPlaybackSpeedHook(EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
|
userSelectedPlaybackSpeedHook(EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,9 +303,14 @@ fun videoTimeHook(targetMethodClass: String, targetMethodName: String) =
|
|||||||
"$targetMethodClass->$targetMethodName(J)V",
|
"$targetMethodClass->$targetMethodName(J)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) =
|
/**
|
||||||
(instructions[instructions.indexOfFirst { it.opcode == opcode } + offset] as ReferenceInstruction)
|
* Hook when the video speed is changed for any reason _except when the user manually selects a new speed_.
|
||||||
.reference.toString()
|
*/
|
||||||
|
fun videoSpeedChangedHook(targetMethodClass: String, targetMethodName: String) =
|
||||||
|
setPlaybackSpeedMethod.addInstruction(
|
||||||
|
setPlaybackSpeedMethodIndex++,
|
||||||
|
"invoke-static { p1 }, $targetMethodClass->$targetMethodName(F)V"
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook the video speed selected by the user.
|
* Hook the video speed selected by the user.
|
||||||
@@ -312,4 +325,4 @@ fun userSelectedPlaybackSpeedHook(targetMethodClass: String, targetMethodName: S
|
|||||||
speedSelectionInsertIndex++,
|
speedSelectionInsertIndex++,
|
||||||
"invoke-static { v$speedSelectionValueRegister }, $targetMethodClass->$targetMethodName(F)V",
|
"invoke-static { v$speedSelectionValueRegister }, $targetMethodClass->$targetMethodName(F)V",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -42,6 +42,7 @@ val rememberVideoQualityPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ val playbackSpeedPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ val restoreOldVideoQualityMenuPatch = bytecodePatch(
|
|||||||
"19.34.42",
|
"19.34.42",
|
||||||
"19.43.41",
|
"19.43.41",
|
||||||
"19.45.38",
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,6 @@ fun String.copyXmlNode(
|
|||||||
target: Document,
|
target: Document,
|
||||||
): AutoCloseable {
|
): AutoCloseable {
|
||||||
val hostNodes = source.getElementsByTagName(this).item(0).childNodes
|
val hostNodes = source.getElementsByTagName(this).item(0).childNodes
|
||||||
|
|
||||||
val destinationNode = target.getElementsByTagName(this).item(0)
|
val destinationNode = target.getElementsByTagName(this).item(0)
|
||||||
|
|
||||||
for (index in 0 until hostNodes.length) {
|
for (index in 0 until hostNodes.length) {
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
<!-- Settings about dialog. -->
|
<!-- Settings about dialog. -->
|
||||||
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -208,6 +210,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
<!-- Settings about dialog. -->
|
<!-- Settings about dialog. -->
|
||||||
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -208,6 +210,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">ملاحظة</string>
|
<string name="revanced_settings_about_links_dev_header">ملاحظة</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">هذا الإصدار هو إصدار مسبق، وقد تواجه مشاكل غير متوقعة</string>
|
<string name="revanced_settings_about_links_dev_body">هذا الإصدار هو إصدار مسبق، وقد تواجه مشاكل غير متوقعة</string>
|
||||||
<string name="revanced_settings_about_links_header">الروابط الرسمية</string>
|
<string name="revanced_settings_about_links_header">الروابط الرسمية</string>
|
||||||
<string name="revanced_settings_about_links_donate">تبرع</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -1010,8 +1011,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">المشغل المصغر</string>
|
<string name="revanced_miniplayer_screen_title">المشغل المصغر</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">تغيير نمط المشغل المصغر داخل التطبيق</string>
|
<string name="revanced_miniplayer_screen_summary">تغيير نمط المشغل المصغر داخل التطبيق</string>
|
||||||
<string name="revanced_miniplayer_type_title">نوع المشغل المصغر</string>
|
<string name="revanced_miniplayer_type_title">نوع المشغل المصغر</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">معطّل</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">الأصلي</string>
|
<string name="revanced_miniplayer_type_entry_1">الأصلي</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">الجوّال</string>
|
<string name="revanced_miniplayer_type_entry_2">الحد الأدنى</string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">الجهاز اللوحي</string>
|
<string name="revanced_miniplayer_type_entry_3">الجهاز اللوحي</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">حديث 1</string>
|
<string name="revanced_miniplayer_type_entry_4">حديث 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">حديث 2</string>
|
<string name="revanced_miniplayer_type_entry_5">حديث 2</string>
|
||||||
@@ -1146,7 +1148,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">تم تمكين الاهتزاز</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">تم تمكين الاهتزاز</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">جودة تلقائية</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">تلقائي</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">تذكر تغييرات جودة الفيديو</string>
|
<string name="revanced_remember_video_quality_last_selected_title">تذكر تغييرات جودة الفيديو</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">تنطبق تغييرات الجودة على جميع مقاطع الفيديو</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">تنطبق تغييرات الجودة على جميع مقاطع الفيديو</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">تنطبق تغييرات الجودة على الفيديو الحالي فقط</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">تنطبق تغييرات الجودة على الفيديو الحالي فقط</string>
|
||||||
@@ -1202,9 +1205,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">لا يحتوي جهازك على فك تشفير الأجهزة VP9، وهذا الإعداد يعمل دائما عند تمكين تزييف العميل</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">لا يحتوي جهازك على فك تشفير الأجهزة VP9، وهذا الإعداد يعمل دائما عند تمكين تزييف العميل</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">قد يؤدي تمكين هذا إلى تحسين عمر البطارية وإصلاح مشكلة تقطيع التشغيل.\n\nيتمتع تنسيق AVC بدقة قصوى تبلغ 1080P، وسيستخدم تشغيل الفيديو المزيد من بيانات الإنترنت مقارنةً بتنسيق VP9 أو AV1.</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">قد يؤدي تمكين هذا إلى تحسين عمر البطارية وإصلاح مشكلة تقطيع التشغيل.\n\nيتمتع تنسيق AVC بدقة قصوى تبلغ 1080P، وسيستخدم تشغيل الفيديو المزيد من بيانات الإنترنت مقارنةً بتنسيق VP9 أو AV1.</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">التأثيرات الجانبية لمحاكاة iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_title">التأثيرات الجانبية لمحاكاة iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">• قد لا يتم تشغيل الأفلام أو الفيديوهات المدفوعة\n• تبدأ البثوث المباشرة من البداية\n• قد تنتهي الفيديوهات قبل النهاية بثانية واحدة\n• لا يوجد ترميز الصوت Opus</string>
|
<string name="revanced_spoof_video_streams_about_ios_summary">• قد لا يتم تشغيل فيديوهات الأطفال الخاصة\n• تبدأ البثوث المباشر من البداية\n• قد تنتهي الفيديوهات قبل النهاية بثانية واحدة\n• لا يوجد ترميز الصوت opus</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">التأثيرات الجانبية لمحاكاة Android VR</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_title">التأثيرات الجانبية لمحاكاة Android VR</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• قائمة المقطع الصوتي مفقودة\n• مستوى الصوت الثابت غير متوفر</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_summary">• قد لا يتم تشغيل فيديوهات الأطفال\n• قائمة المقطع الصوتي مفقودة\n• مستوى الصوت الثابت غير متوفر</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
<!-- Settings about dialog. -->
|
<!-- Settings about dialog. -->
|
||||||
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -208,6 +210,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">Qeyd</string>
|
<string name="revanced_settings_about_links_dev_header">Qeyd</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">Bu versiya ilkin buraxılışdır və gözlənilməz problemlərlə üzləşə bilərsiniz</string>
|
<string name="revanced_settings_about_links_dev_body">Bu versiya ilkin buraxılışdır və gözlənilməz problemlərlə üzləşə bilərsiniz</string>
|
||||||
<string name="revanced_settings_about_links_header">Rəsmi bağlantılar</string>
|
<string name="revanced_settings_about_links_header">Rəsmi bağlantılar</string>
|
||||||
<string name="revanced_settings_about_links_donate">İanə ver</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -1010,8 +1011,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">Kiçik oynadıcı</string>
|
<string name="revanced_miniplayer_screen_title">Kiçik oynadıcı</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Tətbiqdə kiçildilən oynadıcı üslubunu dəyişdir</string>
|
<string name="revanced_miniplayer_screen_summary">Tətbiqdə kiçildilən oynadıcı üslubunu dəyişdir</string>
|
||||||
<string name="revanced_miniplayer_type_title">Kiçik oynadıcı növü</string>
|
<string name="revanced_miniplayer_type_title">Kiçik oynadıcı növü</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Qeyri-aktivdir</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Orijinal</string>
|
<string name="revanced_miniplayer_type_entry_1">Orijinal</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">Telefon</string>
|
<string name="revanced_miniplayer_type_entry_2">Ən kiçik</string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">Planşet</string>
|
<string name="revanced_miniplayer_type_entry_3">Planşet</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Müasir 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Müasir 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Müasir 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Müasir 2</string>
|
||||||
@@ -1146,7 +1148,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">Toxunuş əks-əlaqəsi aktivdir</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">Toxunuş əks-əlaqəsi aktivdir</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">Avtomatik keyfiyyət</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">Avtomatik</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Video keyfiyyəti dəyişikliklərini xatırla</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Video keyfiyyəti dəyişikliklərini xatırla</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Keyfiyyət dəyişiklikləri bütün videolara tətbiq edilir</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Keyfiyyət dəyişiklikləri bütün videolara tətbiq edilir</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Keyfiyyət dəyişiklikləri yalnız cari videoya tətbiq edilir</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Keyfiyyət dəyişiklikləri yalnız cari videoya tətbiq edilir</string>
|
||||||
@@ -1202,9 +1205,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Cihazınızın VP9 hardware decoding\'i yoxdur və bu seçim, \"Qəbuledicini saxtalaşdırma\" aktivləşdikdə həmişəlikdir</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Cihazınızın VP9 hardware decoding\'i yoxdur və bu seçim, \"Qəbuledicini saxtalaşdırma\" aktivləşdikdə həmişəlikdir</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Bunu aktivləşdirmə batareya ömrünü yaxşılaşdıra və oynatma donmasını düzəldə bilər.\n\nAVC maksimum 1080p görüntü imkanına malikdir və video oynadılması VP9 və ya AV1-dən daha çox internet məlumatı istifadə edəcək.</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Bunu aktivləşdirmə batareya ömrünü yaxşılaşdıra və oynatma donmasını düzəldə bilər.\n\nAVC maksimum 1080p görüntü imkanına malikdir və video oynadılması VP9 və ya AV1-dən daha çox internet məlumatı istifadə edəcək.</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS saxtakarlığı yan təsirləri</string>
|
<string name="revanced_spoof_video_streams_about_ios_title">iOS saxtakarlığı yan təsirləri</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Filmlər və ya ödənişli videolar oynadılmaya bilər\n• Canlı yayımlar əvvəldən başlayır\n• Videolar 1 saniyə tez bitə bilər\n• Opus səs kodlama yoxdur</string>
|
<string name="revanced_spoof_video_streams_about_ios_summary">• Şəxsi uşaq videoları oynadılmaya bilər\n• Canlı yayımlar başdan başlayır\n• Videolar 1 saniyə tez bitə bilər\n• Opus səs kodlama yoxdur</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR saxtakarlığı yan təsirləri</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR saxtakarlığı yan təsirləri</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Səs axını menyusu əskikdir\n• Stabil səs səviyyəsi əlçatan deyil</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Uşaq videoları oynadılmaya bilər\n• Səs treki menyusu əskikdir\n• Sabit səs həcmi əlçatan deyil</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">Нататка</string>
|
<string name="revanced_settings_about_links_dev_header">Нататка</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">Гэтая версія з\"яўляецца папярэдняй версіяй, і вы можаце сутыкнуцца з непрадбачанымі праблемамі</string>
|
<string name="revanced_settings_about_links_dev_body">Гэтая версія з\"яўляецца папярэдняй версіяй, і вы можаце сутыкнуцца з непрадбачанымі праблемамі</string>
|
||||||
<string name="revanced_settings_about_links_header">Афіцыйныя спасылкі</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. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -914,8 +916,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">Міні-плэер</string>
|
<string name="revanced_miniplayer_screen_title">Міні-плэер</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Змяніце стыль мінімізаванага плэера ў праграме</string>
|
<string name="revanced_miniplayer_screen_summary">Змяніце стыль мінімізаванага плэера ў праграме</string>
|
||||||
<string name="revanced_miniplayer_type_title">Тып мініплэера</string>
|
<string name="revanced_miniplayer_type_title">Тып мініплэера</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Інваліды</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Арыгінал</string>
|
<string name="revanced_miniplayer_type_entry_1">Арыгінал</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">Тэлефон</string>
|
|
||||||
<string name="revanced_miniplayer_type_entry_3">Планшэт</string>
|
<string name="revanced_miniplayer_type_entry_3">Планшэт</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Сучасны 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Сучасны 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Сучасны 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Сучасны 2</string>
|
||||||
@@ -1029,7 +1031,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">Тактыльныя сігналы ўключаны</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">Тактыльныя сігналы ўключаны</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">Аўтаматычнае якасць</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">Аўто</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Запомніце змены якасці відэа</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Запомніце змены якасці відэа</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Змены якасці распаўсюджваюцца на ўсе відэа</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Змены якасці распаўсюджваюцца на ўсе відэа</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Змены якасці прымяняюцца толькі да бягучага відэа</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Змены якасці прымяняюцца толькі да бягучага відэа</string>
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">Забележка</string>
|
<string name="revanced_settings_about_links_dev_header">Забележка</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">Тази версия е предварителна, така че може да срещнете неочаквани проблеми</string>
|
<string name="revanced_settings_about_links_dev_body">Тази версия е предварителна, така че може да срещнете неочаквани проблеми</string>
|
||||||
<string name="revanced_settings_about_links_header">Официални линкове</string>
|
<string name="revanced_settings_about_links_header">Официални линкове</string>
|
||||||
<string name="revanced_settings_about_links_donate">Дарение</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -87,6 +88,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||||
<string name="revanced_shorts_disable_background_playback_title">Възпроизвеждане на Shorts в фонов режим</string>
|
<string name="revanced_shorts_disable_background_playback_title">Възпроизвеждане на Shorts в фонов режим</string>
|
||||||
|
<string name="revanced_shorts_disable_background_playback_summary_on">Фоновото възпроизвеждане на Shorts е деактивирано</string>
|
||||||
|
<string name="revanced_shorts_disable_background_playback_summary_off">Фоновото възпроизвеждане на Shorts е активирано</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.debugging.enableDebuggingPatch">
|
<patch id="misc.debugging.enableDebuggingPatch">
|
||||||
<string name="revanced_debug_screen_title">Отстраняване на грешки</string>
|
<string name="revanced_debug_screen_title">Отстраняване на грешки</string>
|
||||||
@@ -960,6 +963,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'.
|
<!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'.
|
||||||
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
|
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
|
||||||
<string name="revanced_spoof_app_version_target_title">Подлъгване за версията на</string>
|
<string name="revanced_spoof_app_version_target_title">Подлъгване за версията на</string>
|
||||||
|
<string name="revanced_spoof_app_version_target_entry_1">18.38.44 - Възстановете старите икони на Shorts в плейъра</string>
|
||||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||||
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Възстановете RYD в режим „инкогнито“ на Shorts</string>
|
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Възстановете RYD в режим „инкогнито“ на Shorts</string>
|
||||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Възстановяване на видео скорост & в менюто за качество</string>
|
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Възстановяване на видео скорост & в менюто за качество</string>
|
||||||
@@ -1007,8 +1011,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">Минимизиран екран за възпроизвеждане</string>
|
<string name="revanced_miniplayer_screen_title">Минимизиран екран за възпроизвеждане</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Променете стила на минимизирания екран за възпроизвеждане</string>
|
<string name="revanced_miniplayer_screen_summary">Променете стила на минимизирания екран за възпроизвеждане</string>
|
||||||
<string name="revanced_miniplayer_type_title">Минимизиран тип екран за гледане</string>
|
<string name="revanced_miniplayer_type_title">Минимизиран тип екран за гледане</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Деактивирано</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Оригинал</string>
|
<string name="revanced_miniplayer_type_entry_1">Оригинал</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">Телефон</string>
|
<string name="revanced_miniplayer_type_entry_2">Минимално</string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">Таблет</string>
|
<string name="revanced_miniplayer_type_entry_3">Таблет</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Модерен 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Модерен 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Модерен 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Модерен 2</string>
|
||||||
@@ -1143,7 +1148,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">Вибрациите са активирани</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">Вибрациите са активирани</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">Автоматично качество</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">Авто</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Запомни промените в качеството на видеото</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Запомни промените в качеството на видеото</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Промените в качеството се отнасят за всички видеоклипове</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Промените в качеството се отнасят за всички видеоклипове</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Промените в качеството се отнасят само за текущия видеоклип</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Промените в качеството се отнасят само за текущия видеоклип</string>
|
||||||
@@ -1199,9 +1205,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Вашето устройство няма хардуерно VP9 декодиране и тази настройка винаги е активирана, когато е активно подправяне на клиента</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Вашето устройство няма хардуерно VP9 декодиране и тази настройка винаги е активирана, когато е активно подправяне на клиента</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Активирането на това може да подобри живота на батерията и да коригира прекъсванията при възпроизвеждане.\n\nAVC има максимална разделителна способност от 1080p и възпроизвеждането на видео ще използва повече интернет данни от VP9 или AV1.</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Активирането на това може да подобри живота на батерията и да коригира прекъсванията при възпроизвеждане.\n\nAVC има максимална разделителна способност от 1080p и възпроизвеждането на видео ще използва повече интернет данни от VP9 или AV1.</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">Cтранични ефекти от подмяната на iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_title">Cтранични ефекти от подмяната на iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Филми или платени видеоклипове може да не се възпроизвеждат\n• Потоците на живо започват отначало\n• Видеоклиповете може да завършват 1 секунда по-рано\n• Няма аудиокодек Opus</string>
|
<string name="revanced_spoof_video_streams_about_ios_summary">• Платените видеоклипове за деца може да не се възпроизвеждат\n• Потоците на живо започват отначало\n• Видеоклиповете може да завършват 1 секунда по-рано\n• Няма аудиокодек Opus</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Странични ефекти от подправяне на Android VR</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_title">Странични ефекти от подправяне на Android VR</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Липсва менюто за избор аудио\n• Не е налична стабилна сила на звука</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Детските видеоклипове може да не се възпроизвеждат\n• Липсва менюто за аудио запис\n• Не е налична стабилна сила на звука</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">দ্রষ্টব্য</string>
|
<string name="revanced_settings_about_links_dev_header">দ্রষ্টব্য</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">এই সংস্করণ একটি প্রাক-প্রকাশনা এবং এতে আপনি অনাকাঙ্খিত সমস্যার সম্মুখিন হতে পারেন</string>
|
<string name="revanced_settings_about_links_dev_body">এই সংস্করণ একটি প্রাক-প্রকাশনা এবং এতে আপনি অনাকাঙ্খিত সমস্যার সম্মুখিন হতে পারেন</string>
|
||||||
<string name="revanced_settings_about_links_header">অফিশ্যাল লিংকসমূহ</string>
|
<string name="revanced_settings_about_links_header">অফিশ্যাল লিংকসমূহ</string>
|
||||||
<string name="revanced_settings_about_links_donate">দান করুন</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -906,8 +907,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">মিনিপ্লেয়ার</string>
|
<string name="revanced_miniplayer_screen_title">মিনিপ্লেয়ার</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">অ্যাপের মধ্যকার মিনিমাইজড প্লেয়ার এর ধরণ পরিবর্তন করুন</string>
|
<string name="revanced_miniplayer_screen_summary">অ্যাপের মধ্যকার মিনিমাইজড প্লেয়ার এর ধরণ পরিবর্তন করুন</string>
|
||||||
<string name="revanced_miniplayer_type_title">মিনিপ্লেয়ার ধরণ</string>
|
<string name="revanced_miniplayer_type_title">মিনিপ্লেয়ার ধরণ</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">নিষ্ক্রিয় হয়েছে</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">আসল</string>
|
<string name="revanced_miniplayer_type_entry_1">আসল</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">ফোন</string>
|
|
||||||
<string name="revanced_miniplayer_type_entry_3">ট্যাবলেট</string>
|
<string name="revanced_miniplayer_type_entry_3">ট্যাবলেট</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">মর্ডান ১</string>
|
<string name="revanced_miniplayer_type_entry_4">মর্ডান ১</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">মর্ডান ২</string>
|
<string name="revanced_miniplayer_type_entry_5">মর্ডান ২</string>
|
||||||
@@ -1017,7 +1018,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">কম্পন সক্রিয় করা হয়েছে</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">কম্পন সক্রিয় করা হয়েছে</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">স্বয়ংক্রিয় গুণমান</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">স্বতস্ফূর্তভাবে</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">ভিডিও গুণমান পরিবর্তন মনে রাখুন</string>
|
<string name="revanced_remember_video_quality_last_selected_title">ভিডিও গুণমান পরিবর্তন মনে রাখুন</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">গুণমান পরিবর্তন সব ভিডিওতে প্রয়োগ করা হয়েছে</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">গুণমান পরিবর্তন সব ভিডিওতে প্রয়োগ করা হয়েছে</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">গুণমান পরিবর্তন বর্তমান ভিডিওতে প্রয়োগ করা হয়েছে</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">গুণমান পরিবর্তন বর্তমান ভিডিওতে প্রয়োগ করা হয়েছে</string>
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
<!-- Settings about dialog. -->
|
<!-- Settings about dialog. -->
|
||||||
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -208,6 +210,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
<string name="revanced_settings_reset">Restablir</string>
|
<string name="revanced_settings_reset">Restablir</string>
|
||||||
<!-- Settings about dialog. -->
|
<!-- Settings about dialog. -->
|
||||||
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -183,6 +185,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
<patch id="layout.tablet.enableTabletLayoutPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.miniplayer.miniplayerPatch">
|
<patch id="layout.miniplayer.miniplayerPatch">
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Desactivat</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.theme.themePatch">
|
<patch id="layout.theme.themePatch">
|
||||||
</patch>
|
</patch>
|
||||||
@@ -216,6 +219,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
<patch id="misc.zoomhaptics.zoomHapticsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">Poznámka</string>
|
<string name="revanced_settings_about_links_dev_header">Poznámka</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">Tato verze je předběžná verze a můžete zaznamenat neočekávané problémy</string>
|
<string name="revanced_settings_about_links_dev_body">Tato verze je předběžná verze a můžete zaznamenat neočekávané problémy</string>
|
||||||
<string name="revanced_settings_about_links_header">Oficiální odkazy</string>
|
<string name="revanced_settings_about_links_header">Oficiální odkazy</string>
|
||||||
<string name="revanced_settings_about_links_donate">Přispět</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -1011,8 +1012,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">Minipřehrávač</string>
|
<string name="revanced_miniplayer_screen_title">Minipřehrávač</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Změnit styl přehrávače minimalizovaného nastavení</string>
|
<string name="revanced_miniplayer_screen_summary">Změnit styl přehrávače minimalizovaného nastavení</string>
|
||||||
<string name="revanced_miniplayer_type_title">Typ minipřehrávače</string>
|
<string name="revanced_miniplayer_type_title">Typ minipřehrávače</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Vypnuto</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Původní</string>
|
<string name="revanced_miniplayer_type_entry_1">Původní</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">Telefon</string>
|
<string name="revanced_miniplayer_type_entry_2">Minimální</string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">Tablet</string>
|
<string name="revanced_miniplayer_type_entry_3">Tablet</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Moderní 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Moderní 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Moderní 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Moderní 2</string>
|
||||||
@@ -1147,7 +1149,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">Hmatové úlohy jsou povoleny</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">Hmatové úlohy jsou povoleny</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">Automatická kvalita</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">Automaticky</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Zapamatovat změny kvality videa</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Zapamatovat změny kvality videa</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Změny kvality platí pro všechna videa</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Změny kvality platí pro všechna videa</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Změny kvality se vztahují pouze na aktuální video</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Změny kvality se vztahují pouze na aktuální video</string>
|
||||||
@@ -1203,9 +1206,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Vaše zařízení nemá hardwarové dekódování VP9 a toto nastavení je vždy zapnuto, když je aktivní spoofování klienta</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Vaše zařízení nemá hardwarové dekódování VP9 a toto nastavení je vždy zapnuto, když je aktivní spoofování klienta</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Povolení této funkce může zlepšit životnost baterie a opravit stahování přehrávání.\n\nAVC má maximální rozlišení 1080p a video přehrávání bude používat více dat než VP9 nebo AV1.</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Povolení této funkce může zlepšit životnost baterie a opravit stahování přehrávání.\n\nAVC má maximální rozlišení 1080p a video přehrávání bude používat více dat než VP9 nebo AV1.</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">Boční efekty iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_title">Boční efekty iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Filmy nebo placená videa nemusí přehrávat\n• Živočišné rekony začínající od začátku\n• Videa mohou skončit 1 sekundu na začátku\n• Žádný opus audio kodek</string>
|
<string name="revanced_spoof_video_streams_about_ios_summary">• Soukromá dětská videa nemusí přehrávat\n• Živočišná zvířata začínající od začátku\n• Videa mohou skončit 1 sekundu na začátku\n• Žádný opus zvukový kodek</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Boční efekty Android VR</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_title">Boční efekty Android VR</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Menu zvukové stopy chybí\n• Stabilní hlasitost není k dispozici</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Dětská videa nemusí přehrát\n• Menu zvukové stopy chybí\n• Stabilní hlasitost není k dispozici</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">Bemærkning</string>
|
<string name="revanced_settings_about_links_dev_header">Bemærkning</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">Denne version er en pre-release og du kan opleve uventede problemer</string>
|
<string name="revanced_settings_about_links_dev_body">Denne version er en pre-release og du kan opleve uventede problemer</string>
|
||||||
<string name="revanced_settings_about_links_header">Officielle links</string>
|
<string name="revanced_settings_about_links_header">Officielle links</string>
|
||||||
<string name="revanced_settings_about_links_donate">Donér</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -993,8 +994,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">Miniplayer</string>
|
<string name="revanced_miniplayer_screen_title">Miniplayer</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Ændre stilen for den i app minimeret afspiller</string>
|
<string name="revanced_miniplayer_screen_summary">Ændre stilen for den i app minimeret afspiller</string>
|
||||||
<string name="revanced_miniplayer_type_title">Type af miniplayer</string>
|
<string name="revanced_miniplayer_type_title">Type af miniplayer</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Deaktiveret</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Oprindelig</string>
|
<string name="revanced_miniplayer_type_entry_1">Oprindelig</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">Telefon</string>
|
<string name="revanced_miniplayer_type_entry_2">Minimal</string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">Tablet</string>
|
<string name="revanced_miniplayer_type_entry_3">Tablet</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Moderne 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Moderne 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Moderne 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Moderne 2</string>
|
||||||
@@ -1129,7 +1131,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">Haptics er aktiveret</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">Haptics er aktiveret</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">Automatisk kvalitet</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">Automatisk</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Husk ændringer i videokvalitet</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Husk ændringer i videokvalitet</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Kvalitetsændringer gælder for alle videoer</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Kvalitetsændringer gælder for alle videoer</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Kvalitetsændringer gælder kun for den aktuelle video</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Kvalitetsændringer gælder kun for den aktuelle video</string>
|
||||||
@@ -1185,9 +1188,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Din enhed har ikke VP9 hardwareafkodning, og denne indstilling er altid tændt, når Client spoofing er aktiveret</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Din enhed har ikke VP9 hardwareafkodning, og denne indstilling er altid tændt, når Client spoofing er aktiveret</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Aktivering af dette kan forbedre batteriets levetid og rette afspilningsstuttering.\n\nAVC har en maksimal opløsning på 1080p, og videoafspilning vil bruge flere internetdata end VP9 eller AV1.</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Aktivering af dette kan forbedre batteriets levetid og rette afspilningsstuttering.\n\nAVC har en maksimal opløsning på 1080p, og videoafspilning vil bruge flere internetdata end VP9 eller AV1.</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS forfalskning bivirkninger</string>
|
<string name="revanced_spoof_video_streams_about_ios_title">iOS forfalskning bivirkninger</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Film eller betalte videoer kan ikke afspille\n• Livestreams starter fra begyndelsen\n• Videoer kan ende 1 sekund tidlig\n• Ingen opus lydkode</string>
|
<string name="revanced_spoof_video_streams_about_ios_summary">• Private børn videoer kan ikke afspille\n• Livestreams starter fra begyndelsen\n• Videoer kan ende 1 sekund tidlig\n• Ingen opus audio codec</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing bivirkninger</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing bivirkninger</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Menuen Lydspor mangler\n• Stabil lydstyrke er ikke tilgængelig</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Kids videoer afspiller muligvis ikke\n• Menuen for lydspor mangler\n• Stabil lydstyrke er ikke tilgængelig</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<resources>
|
<resources>
|
||||||
<app id="shared">
|
<app id="shared">
|
||||||
<patch id="misc.checks.checkEnvironmentPatch">
|
<patch id="misc.checks.checkEnvironmentPatch">
|
||||||
<string name="revanced_check_environment_failed_title">Überprüfungen fehlgeschlagen</string>
|
<string name="revanced_check_environment_failed_title">Überprüfung fehlgeschlagen</string>
|
||||||
<string name="revanced_check_environment_dialog_open_official_source_button">Offizielle Webseite öffnen</string>
|
<string name="revanced_check_environment_dialog_open_official_source_button">Offizielle Webseite öffnen</string>
|
||||||
<string name="revanced_check_environment_dialog_ignore_button">Ignorieren</string>
|
<string name="revanced_check_environment_dialog_ignore_button">Ignorieren</string>
|
||||||
<string name="revanced_check_environment_failed_message"><h5>Diese App wurde offenbar nicht von Ihnen gepatcht.</h5><br>Diese App funktioniert möglicherweise nicht richtig, <b>könnte schädlich oder sogar gefährlich in der Verwendung sein</b>.< br><br>Diese Prüfungen deuten darauf hin, dass diese App vorab gepatcht wurde oder von jemandem bezogen wurde sonst:<br><br><small>%1$s</small><br>Es wird dringend empfohlen, <b>diese App zu deinstallieren und selbst zu patchen</b> um sicherzustellen, dass Sie eine validierte und sichere App verwenden.<p><br>Wenn Sie diese Warnung ignorieren, wird sie nur zweimal angezeigt.</string>
|
<string name="revanced_check_environment_failed_message"><h5>Diese App wurde offenbar nicht von Ihnen gepatcht.</h5><br>Diese App funktioniert möglicherweise nicht richtig, <b>könnte schädlich oder sogar gefährlich in der Verwendung sein</b>.< br><br>Diese Prüfungen deuten darauf hin, dass diese App vorab gepatcht wurde oder von jemandem bezogen wurde sonst:<br><br><small>%1$s</small><br>Es wird dringend empfohlen, <b>diese App zu deinstallieren und selbst zu patchen</b> um sicherzustellen, dass Sie eine validierte und sichere App verwenden.<p><br>Wenn Sie diese Warnung ignorieren, wird sie nur zweimal angezeigt.</string>
|
||||||
@@ -61,7 +61,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">Notiz</string>
|
<string name="revanced_settings_about_links_dev_header">Notiz</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">Diese Version ist eine Vorabversion und du könntest unerwartete Probleme haben</string>
|
<string name="revanced_settings_about_links_dev_body">Diese Version ist eine Vorabversion und du könntest unerwartete Probleme haben</string>
|
||||||
<string name="revanced_settings_about_links_header">Offizielle Links</string>
|
<string name="revanced_settings_about_links_header">Offizielle Links</string>
|
||||||
<string name="revanced_settings_about_links_donate">Spenden</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -1011,8 +1012,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">Miniplayer</string>
|
<string name="revanced_miniplayer_screen_title">Miniplayer</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Ändere den Stil des in App minimierten Players</string>
|
<string name="revanced_miniplayer_screen_summary">Ändere den Stil des in App minimierten Players</string>
|
||||||
<string name="revanced_miniplayer_type_title">Minispielertyp</string>
|
<string name="revanced_miniplayer_type_title">Minispielertyp</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Deaktiviert</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Original</string>
|
<string name="revanced_miniplayer_type_entry_1">Original</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">Telefon</string>
|
<string name="revanced_miniplayer_type_entry_2">Minimal</string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">Tablets</string>
|
<string name="revanced_miniplayer_type_entry_3">Tablets</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Modern 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Modern 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Modern 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Modern 2</string>
|
||||||
@@ -1147,7 +1149,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">Haptik ist aktiviert</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">Haptik ist aktiviert</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">Automatische Qualität</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">Auto</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Änderungen der Videoqualität merken</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Änderungen der Videoqualität merken</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Qualitätsänderungen gelten für alle Videos</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Qualitätsänderungen gelten für alle Videos</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Qualitätsänderungen gelten nur für das aktuelle Video</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Qualitätsänderungen gelten nur für das aktuelle Video</string>
|
||||||
@@ -1203,9 +1206,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Ihr Gerät hat keine VP9-Hardware-Dekodierung, und diese Einstellung ist immer aktiviert, wenn Client-Spoofing aktiviert ist</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Ihr Gerät hat keine VP9-Hardware-Dekodierung, und diese Einstellung ist immer aktiviert, wenn Client-Spoofing aktiviert ist</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Das Aktivieren kann die Akkulaufzeit verbessern und die Wiedergabe-Stutting beheben.\n\nAVC hat eine maximale Auflösung von 1080p, und die Videowiedergabe wird mehr Internet-Daten als VP9 oder AV1 verwenden.</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Das Aktivieren kann die Akkulaufzeit verbessern und die Wiedergabe-Stutting beheben.\n\nAVC hat eine maximale Auflösung von 1080p, und die Videowiedergabe wird mehr Internet-Daten als VP9 oder AV1 verwenden.</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS Spoofing Nebeneffekte</string>
|
<string name="revanced_spoof_video_streams_about_ios_title">iOS Spoofing Nebeneffekte</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Filme oder bezahlte Videos werden möglicherweise nicht abgespielt\n• Livestreams starten von Anfang an\n• Videos enden möglicherweise 1 Sekunde früher\n• kein Opus-Audiocodec</string>
|
<string name="revanced_spoof_video_streams_about_ios_summary">• Videos für Privatkinder dürfen nicht\nabspielen • Livestreams beginnen von Anfang an\n• Videos können 1 Sekunde früher\n• Kein opus Audio Codec</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR Spoofing Nebeneffekte</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR Spoofing Nebeneffekte</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Audio Track Menü fehlt\n• Stabile Lautstärke ist nicht verfügbar</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Kindervideos dürfen nicht\nabspielen • Audiospurmenü fehlt\n• Stabile Lautstärke ist nicht verfügbar</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">Σημείωση</string>
|
<string name="revanced_settings_about_links_dev_header">Σημείωση</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">Αυτή η έκδοση είναι σε πρώιμο στάδιο, επομένως πιθανότατα να αντιμετωπίσετε απρόοπτα προβλήματα</string>
|
<string name="revanced_settings_about_links_dev_body">Αυτή η έκδοση είναι σε πρώιμο στάδιο, επομένως πιθανότατα να αντιμετωπίσετε απρόοπτα προβλήματα</string>
|
||||||
<string name="revanced_settings_about_links_header">Επίσημοι σύνδεσμοι</string>
|
<string name="revanced_settings_about_links_header">Επίσημοι σύνδεσμοι</string>
|
||||||
<string name="revanced_settings_about_links_donate">Δωρεά</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -1010,12 +1011,13 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">Ελαχιστοποιημένη οθόνη αναπαραγωγής</string>
|
<string name="revanced_miniplayer_screen_title">Ελαχιστοποιημένη οθόνη αναπαραγωγής</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Αλλάξτε το στυλ της ελαχιστοποιημένης οθόνης αναπαραγωγής</string>
|
<string name="revanced_miniplayer_screen_summary">Αλλάξτε το στυλ της ελαχιστοποιημένης οθόνης αναπαραγωγής</string>
|
||||||
<string name="revanced_miniplayer_type_title">Τύπος ελαχιστοποιημένης οθόνης αναπαραγωγής</string>
|
<string name="revanced_miniplayer_type_title">Τύπος ελαχιστοποιημένης οθόνης αναπαραγωγής</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Ανενεργή</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Αρχικός</string>
|
<string name="revanced_miniplayer_type_entry_1">Αρχικός</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">Τηλεφώνου</string>
|
<string name="revanced_miniplayer_type_entry_2">Ελάχιστη</string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">Ταμπλετ</string>
|
<string name="revanced_miniplayer_type_entry_3">Ταμπλετ</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Μοντέρνος 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Μοντέρνα 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Μοντέρνος 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Μοντέρνα 2</string>
|
||||||
<string name="revanced_miniplayer_type_entry_6">Μοντέρνος 3</string>
|
<string name="revanced_miniplayer_type_entry_6">Μοντέρνα 3</string>
|
||||||
<string name="revanced_miniplayer_rounded_corners_title">Στρογγυλεμένες γωνίες</string>
|
<string name="revanced_miniplayer_rounded_corners_title">Στρογγυλεμένες γωνίες</string>
|
||||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Οι γωνίες είναι στρογγυλεμένες</string>
|
<string name="revanced_miniplayer_rounded_corners_summary_on">Οι γωνίες είναι στρογγυλεμένες</string>
|
||||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Οι γωνίες είναι τετράγωνες</string>
|
<string name="revanced_miniplayer_rounded_corners_summary_off">Οι γωνίες είναι τετράγωνες</string>
|
||||||
@@ -1146,7 +1148,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">Η απόκριση δόνησης είναι ενεργοποιημένη</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">Η απόκριση δόνησης είναι ενεργοποιημένη</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">Αυτόματη ποιότητα</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">Αυτόματη</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Απομνημόνευση αλλαγών ποιότητας βίντεο</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Απομνημόνευση αλλαγών ποιότητας βίντεο</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Οι αλλαγές ποιότητας θα ισχύουν για όλα τα βίντεο</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Οι αλλαγές ποιότητας θα ισχύουν για όλα τα βίντεο</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Οι αλλαγές ποιότητας θα ισχύουν μόνο για το τρέχον βίντεο</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Οι αλλαγές ποιότητας θα ισχύουν μόνο για το τρέχον βίντεο</string>
|
||||||
@@ -1202,9 +1205,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Η συσκευή σας δεν διαθέτει αποκωδικοποίηση υλικού VP9, και αυτή η ρύθμιση είναι πάντα ενεργή όταν είναι ενεργοποιημένη η παραποίηση προγράμματος πελάτη</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Η συσκευή σας δεν διαθέτει αποκωδικοποίηση υλικού VP9, και αυτή η ρύθμιση είναι πάντα ενεργή όταν είναι ενεργοποιημένη η παραποίηση προγράμματος πελάτη</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Ενεργοποιώντας αυτόν τον κωδικοποιητή ίσως να βελτιώσει κατανάλωση ενέργειας και ίσως διορθώσει κολλήματα αναπαραγωγής.\n\nΟ AVC έχει μέγιστη ανάλυση 1080p, και καταναλώνει περισσότερα δεδομένα internet από τον VP9 ή τον AV1.</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Ενεργοποιώντας αυτόν τον κωδικοποιητή ίσως να βελτιώσει κατανάλωση ενέργειας και ίσως διορθώσει κολλήματα αναπαραγωγής.\n\nΟ AVC έχει μέγιστη ανάλυση 1080p, και καταναλώνει περισσότερα δεδομένα internet από τον VP9 ή τον AV1.</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">Παρενέργειες παραποίησης σε iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_title">Παρενέργειες παραποίησης σε iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Οι ταινίες ή τα επί πληρωμή βίντεο ενδέχεται να μην αναπαράγονται\n• Οι ζωντανές μεταδόσεις ξεκινούν από την αρχή κατά την αναπαραγωγή\n• Τα βίντεο μπορεί να τελειώνουν 1 δευτερόλεπτο νωρίτερα\n• Ο κωδικοποιητής ήχου opus δεν είναι διαθέσιμος</string>
|
<string name="revanced_spoof_video_streams_about_ios_summary">• Ιδιωτικά βίντεο για παιδιά ενδεχομένως να μην αναπαράγονται\n• Οι ζωντανές μεταδόσεις ξεκινούν από την αρχή\n• Τα βίντεο ενδέχεται να λήξουν 1 δευτερόλεπτο νωρίτερα\n• Δεν υπάρχει κωδικοποιητής ήχου opus</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Παρενέργειες παραποίησης σε Android VR</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_title">Παρενέργειες παραποίησης σε Android VR</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Το μενού «Κομμάτι ήχου» λείπει\n• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται\n• Το μενού «Κομμάτι ήχου» λείπει\n• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_settings_about_links_dev_header">Nota</string>
|
<string name="revanced_settings_about_links_dev_header">Nota</string>
|
||||||
<string name="revanced_settings_about_links_dev_body">Esta versión es un pre-lanzamiento y puede que experimentes problemas inesperados</string>
|
<string name="revanced_settings_about_links_dev_body">Esta versión es un pre-lanzamiento y puede que experimentes problemas inesperados</string>
|
||||||
<string name="revanced_settings_about_links_header">Enlaces oficiales</string>
|
<string name="revanced_settings_about_links_header">Enlaces oficiales</string>
|
||||||
<string name="revanced_settings_about_links_donate">Donar</string>
|
<!-- NOTE: the about strings above are duplicated in the TikTok about screen code,
|
||||||
|
and changes made here must also be made there. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
<patch id="misc.gms.gmsCoreSupportResourcePatch">
|
||||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||||
@@ -1010,8 +1011,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_screen_title">Minireproductor</string>
|
<string name="revanced_miniplayer_screen_title">Minireproductor</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Cambiar el estilo del reproductor minimizado de la aplicación</string>
|
<string name="revanced_miniplayer_screen_summary">Cambiar el estilo del reproductor minimizado de la aplicación</string>
|
||||||
<string name="revanced_miniplayer_type_title">Tipo de minreproductor</string>
|
<string name="revanced_miniplayer_type_title">Tipo de minreproductor</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_0">Desactivado</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Original</string>
|
<string name="revanced_miniplayer_type_entry_1">Original</string>
|
||||||
<string name="revanced_miniplayer_type_entry_2">Teléfono</string>
|
<string name="revanced_miniplayer_type_entry_2">Mínimo</string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">Tablet</string>
|
<string name="revanced_miniplayer_type_entry_3">Tablet</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Moderna 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Moderna 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Moderna 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Moderna 2</string>
|
||||||
@@ -1084,7 +1086,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">Toast no se muestra si DeFlecha no está disponible</string>
|
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">Toast no se muestra si DeFlecha no está disponible</string>
|
||||||
<string name="revanced_alt_thumbnail_dearrow_api_url_title">DeArrow API endpoint</string>
|
<string name="revanced_alt_thumbnail_dearrow_api_url_title">DeArrow API endpoint</string>
|
||||||
<string name="revanced_alt_thumbnail_dearrow_api_url_summary">La URL del final de la caché en miniatura de DeArrow</string>
|
<string name="revanced_alt_thumbnail_dearrow_api_url_summary">La URL del final de la caché en miniatura de DeArrow</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_about_title">Todavía captura de vídeo</string>
|
<string name="revanced_alt_thumbnail_stills_about_title">Capturas estáticas de vídeo</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_about_summary">Las capturas se toman desde el principio/medio/final de cada vídeo. Estas imágenes están incorporadas en YouTube y no se utiliza ninguna API externa</string>
|
<string name="revanced_alt_thumbnail_stills_about_summary">Las capturas se toman desde el principio/medio/final de cada vídeo. Estas imágenes están incorporadas en YouTube y no se utiliza ninguna API externa</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_fast_title">Usar capturas aún rápidas</string>
|
<string name="revanced_alt_thumbnail_stills_fast_title">Usar capturas aún rápidas</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_fast_summary_on">Usar captura de calidad media todavía. Las miniaturas se cargarán más rápido, pero streams en vivo, no liberados o vídeos muy antiguos pueden mostrar miniaturas en blanco</string>
|
<string name="revanced_alt_thumbnail_stills_fast_summary_on">Usar captura de calidad media todavía. Las miniaturas se cargarán más rápido, pero streams en vivo, no liberados o vídeos muy antiguos pueden mostrar miniaturas en blanco</string>
|
||||||
@@ -1146,7 +1148,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_disable_zoom_haptics_summary_off">Haptics están habilitados</string>
|
<string name="revanced_disable_zoom_haptics_summary_off">Haptics están habilitados</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<string name="revanced_video_quality_default_entry_1">Calidad automática</string>
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
|
<string name="revanced_video_quality_default_entry_1">Auto</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">Recordar cambios de calidad de vídeo</string>
|
<string name="revanced_remember_video_quality_last_selected_title">Recordar cambios de calidad de vídeo</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">Los cambios de calidad se aplican a todos los vídeos</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">Los cambios de calidad se aplican a todos los vídeos</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_off">Los cambios de calidad sólo se aplican al vídeo actual</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_off">Los cambios de calidad sólo se aplican al vídeo actual</string>
|
||||||
@@ -1202,9 +1205,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Su dispositivo no tiene decodificación de hardware VP9, y esta configuración siempre está encendida cuando el cliente spoofing está habilitado</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Su dispositivo no tiene decodificación de hardware VP9, y esta configuración siempre está encendida cuando el cliente spoofing está habilitado</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Activar esto puede mejorar la vida de la batería y corregir el retraso en la reproducción.\n\nAVC tiene una resolución máxima de 1080p, y la reproducción de vídeo utilizará más datos de Internet que VP9 o AV1.</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Activar esto puede mejorar la vida de la batería y corregir el retraso en la reproducción.\n\nAVC tiene una resolución máxima de 1080p, y la reproducción de vídeo utilizará más datos de Internet que VP9 o AV1.</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">Efectos secundarios para la falsificación de iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_title">Efectos secundarios para la falsificación de iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Las películas o vídeos de pago pueden no reproducirse\n• Los directos empiezan desde el principio\n• Los vídeos pueden terminar 1 segundo antes\n• No hay códec de audio de Opus</string>
|
<string name="revanced_spoof_video_streams_about_ios_summary">• Los vídeos de niños privados no pueden reproducir\n• Livestreams comienzan desde el principio\n• Los vídeos pueden terminar 1 segundo antes de\n• No hay código de audio de opus</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Efectos secundarios para la falsificación de Android RV</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_title">Efectos secundarios para la falsificación de Android RV</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Falta el menú de pista de audio\n• El volumen estable no está disponible</string>
|
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Los vídeos infantiles no pueden reproducir\n• Falta el menú de pista de audio\n• El volumen estable no está disponible</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user