1
mirror of https://github.com/revanced/revanced-integrations synced 2025-11-19 03:23:27 +01:00

Compare commits

...

19 Commits

Author SHA1 Message Date
semantic-release-bot
dba707800e chore(release): 1.8.0-dev.4 [skip ci]
# [1.8.0-dev.4](https://github.com/ReVanced/revanced-integrations/compare/v1.8.0-dev.3...v1.8.0-dev.4) (2024-04-10)

### Bug Fixes

* **YouTube - Hide Shorts components:** Correctly hide Shorts if navigation tab is changed using device back button ([#611](https://github.com/ReVanced/revanced-integrations/issues/611)) ([ffc3437](ffc3437843))
2024-04-10 08:32:23 +00:00
LisoUseInAIKyrios
ffc3437843 fix(YouTube - Hide Shorts components): Correctly hide Shorts if navigation tab is changed using device back button (#611) 2024-04-10 12:29:23 +04:00
semantic-release-bot
4939a22da1 chore(release): 1.8.0-dev.3 [skip ci]
# [1.8.0-dev.3](https://github.com/ReVanced/revanced-integrations/compare/v1.8.0-dev.2...v1.8.0-dev.3) (2024-04-09)

### Bug Fixes

* **YouTube - Settings:** Do not show a toast if migrating old unknown settings ([f2e15a2](f2e15a2e1f))
2024-04-09 21:02:25 +00:00
LisoUseInAIKyrios
f2e15a2e1f fix(YouTube - Settings): Do not show a toast if migrating old unknown settings 2024-04-10 00:59:23 +04:00
LisoUseInAIKyrios
eba73c5947 chore(YouTube): Fix typos, simplify some strings for translating 2024-04-07 23:55:33 +04:00
semantic-release-bot
c0764e9046 chore(release): 1.8.0-dev.2 [skip ci]
# [1.8.0-dev.2](https://github.com/ReVanced/revanced-integrations/compare/v1.8.0-dev.1...v1.8.0-dev.2) (2024-04-07)

### Bug Fixes

* **YouTube - Hide layout components:** Do not hide playlist shelf in library ([c5d38a7](c5d38a7e07))
2024-04-07 16:17:56 +00:00
LisoUseInAIKyrios
c5d38a7e07 fix(YouTube - Hide layout components): Do not hide playlist shelf in library 2024-04-07 20:14:29 +04:00
LisoUseInAIKyrios
f6de32884e chore: Add check in missing from merge 2024-04-06 22:49:49 +04:00
semantic-release-bot
628c25e808 chore(release): 1.8.0-dev.1 [skip ci]
# [1.8.0-dev.1](https://github.com/ReVanced/revanced-integrations/compare/v1.7.1-dev.4...v1.8.0-dev.1) (2024-04-06)

### Bug Fixes

* **YouTube - GmsCore support:** Prompt to disable battery optimizations, if not done already ([#601](https://github.com/ReVanced/revanced-integrations/issues/601)) ([c5c9de5](c5c9de500d))

### Features

* **YouTube - Hide layout components:** Add option to hide horizontal shelves ([#598](https://github.com/ReVanced/revanced-integrations/issues/598)) ([fedace0](fedace02fd))
2024-04-06 18:48:59 +00:00
LisoUseInAIKyrios
c5c9de500d fix(YouTube - GmsCore support): Prompt to disable battery optimizations, if not done already (#601)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-06 20:46:07 +02:00
nullptr
fedace02fd feat(YouTube - Hide layout components): Add option to hide horizontal shelves (#598)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2024-04-06 22:41:50 +04:00
semantic-release-bot
bddcc97392 chore(release): 1.7.1-dev.4 [skip ci]
## [1.7.1-dev.4](https://github.com/ReVanced/revanced-integrations/compare/v1.7.1-dev.3...v1.7.1-dev.4) (2024-04-04)

### Bug Fixes

* **YouTube - Hide load more button:** Include patch with `Hide layout components`, and hide button only in search feed  ([#600](https://github.com/ReVanced/revanced-integrations/issues/600)) ([c420891](c420891e3e))
2024-04-04 21:12:44 +00:00
nullptr
c420891e3e fix(YouTube - Hide load more button): Include patch with Hide layout components, and hide button only in search feed (#600) 2024-04-05 01:09:42 +04:00
semantic-release-bot
33da670984 chore(release): 1.7.1-dev.3 [skip ci]
## [1.7.1-dev.3](https://github.com/ReVanced/revanced-integrations/compare/v1.7.1-dev.2...v1.7.1-dev.3) (2024-04-04)

### Bug Fixes

* **YouTube - Player flyout menu:** Add hide Lock screen menu ([#609](https://github.com/ReVanced/revanced-integrations/issues/609)) ([b2fe105](b2fe105199))
2024-04-04 06:49:49 +00:00
LisoUseInAIKyrios
b2fe105199 fix(YouTube - Player flyout menu): Add hide Lock screen menu (#609) 2024-04-04 10:46:54 +04:00
semantic-release-bot
20162f977b chore(release): 1.7.1-dev.2 [skip ci]
## [1.7.1-dev.2](https://github.com/ReVanced/revanced-integrations/compare/v1.7.1-dev.1...v1.7.1-dev.2) (2024-04-03)

### Bug Fixes

* **YouTube - Navigation bar hook:** Handle if search is active but hidden behind a maximized player ([cbccb46](cbccb46e63))
2024-04-03 20:25:32 +00:00
LisoUseInAIKyrios
cbccb46e63 fix(YouTube - Navigation bar hook): Handle if search is active but hidden behind a maximized player 2024-04-04 00:21:51 +04:00
semantic-release-bot
eaa2e1139c chore(release): 1.7.1-dev.1 [skip ci]
## [1.7.1-dev.1](https://github.com/ReVanced/revanced-integrations/compare/v1.7.0...v1.7.1-dev.1) (2024-04-01)

### Bug Fixes

* **YouTube - Disable suggested video end screen:** Require app restart ([38ae5aa](38ae5aac84))
2024-04-01 13:14:01 +00:00
LisoUseInAIKyrios
38ae5aac84 fix(YouTube - Disable suggested video end screen): Require app restart 2024-04-01 17:11:07 +04:00
15 changed files with 469 additions and 203 deletions

View File

@@ -1,3 +1,64 @@
# [1.8.0-dev.4](https://github.com/ReVanced/revanced-integrations/compare/v1.8.0-dev.3...v1.8.0-dev.4) (2024-04-10)
### Bug Fixes
* **YouTube - Hide Shorts components:** Correctly hide Shorts if navigation tab is changed using device back button ([#611](https://github.com/ReVanced/revanced-integrations/issues/611)) ([ffc3437](https://github.com/ReVanced/revanced-integrations/commit/ffc3437843c24af255d2a0dda9930d2843cac4b6))
# [1.8.0-dev.3](https://github.com/ReVanced/revanced-integrations/compare/v1.8.0-dev.2...v1.8.0-dev.3) (2024-04-09)
### Bug Fixes
* **YouTube - Settings:** Do not show a toast if migrating old unknown settings ([f2e15a2](https://github.com/ReVanced/revanced-integrations/commit/f2e15a2e1ff59ae7780cfbd366e5165f4e2b191d))
# [1.8.0-dev.2](https://github.com/ReVanced/revanced-integrations/compare/v1.8.0-dev.1...v1.8.0-dev.2) (2024-04-07)
### Bug Fixes
* **YouTube - Hide layout components:** Do not hide playlist shelf in library ([c5d38a7](https://github.com/ReVanced/revanced-integrations/commit/c5d38a7e0791ebb8fe59397fff959cc94e0a7aed))
# [1.8.0-dev.1](https://github.com/ReVanced/revanced-integrations/compare/v1.7.1-dev.4...v1.8.0-dev.1) (2024-04-06)
### Bug Fixes
* **YouTube - GmsCore support:** Prompt to disable battery optimizations, if not done already ([#601](https://github.com/ReVanced/revanced-integrations/issues/601)) ([c5c9de5](https://github.com/ReVanced/revanced-integrations/commit/c5c9de500d8f1268799e55c31c446bfe8336f79a))
### Features
* **YouTube - Hide layout components:** Add option to hide horizontal shelves ([#598](https://github.com/ReVanced/revanced-integrations/issues/598)) ([fedace0](https://github.com/ReVanced/revanced-integrations/commit/fedace02fd5c443ef37dcf77253438b041f4c3f9))
## [1.7.1-dev.4](https://github.com/ReVanced/revanced-integrations/compare/v1.7.1-dev.3...v1.7.1-dev.4) (2024-04-04)
### Bug Fixes
* **YouTube - Hide load more button:** Include patch with `Hide layout components`, and hide button only in search feed ([#600](https://github.com/ReVanced/revanced-integrations/issues/600)) ([c420891](https://github.com/ReVanced/revanced-integrations/commit/c420891e3ef134f30af79cf2f30da3fa2fe5a455))
## [1.7.1-dev.3](https://github.com/ReVanced/revanced-integrations/compare/v1.7.1-dev.2...v1.7.1-dev.3) (2024-04-04)
### Bug Fixes
* **YouTube - Player flyout menu:** Add hide Lock screen menu ([#609](https://github.com/ReVanced/revanced-integrations/issues/609)) ([b2fe105](https://github.com/ReVanced/revanced-integrations/commit/b2fe105199d4a5958676cbc8f9c701541e8ff24a))
## [1.7.1-dev.2](https://github.com/ReVanced/revanced-integrations/compare/v1.7.1-dev.1...v1.7.1-dev.2) (2024-04-03)
### Bug Fixes
* **YouTube - Navigation bar hook:** Handle if search is active but hidden behind a maximized player ([cbccb46](https://github.com/ReVanced/revanced-integrations/commit/cbccb46e639003adbed941f9b88c41b4c9998729))
## [1.7.1-dev.1](https://github.com/ReVanced/revanced-integrations/compare/v1.7.0...v1.7.1-dev.1) (2024-04-01)
### Bug Fixes
* **YouTube - Disable suggested video end screen:** Require app restart ([38ae5aa](https://github.com/ReVanced/revanced-integrations/commit/38ae5aac845745824218a08053db519a3325d7a9))
# [1.7.0](https://github.com/ReVanced/revanced-integrations/compare/v1.6.0...v1.7.0) (2024-03-30)

View File

@@ -1,21 +1,25 @@
package app.revanced.integrations.shared;
import static app.revanced.integrations.shared.StringRef.str;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import androidx.annotation.RequiresApi;
import java.net.MalformedURLException;
import java.net.URL;
import static app.revanced.integrations.shared.StringRef.str;
/**
* @noinspection unused
*/
@@ -45,26 +49,19 @@ public class GmsCoreSupport {
System.exit(0);
}
private static void showToastOrDialog(Context context, String toastMessageKey, String dialogMessageKey, String link) {
if (!(context instanceof Activity)) {
// Context is for the application and cannot show a dialog using it.
Utils.showToastLong(str(toastMessageKey));
open(link);
return;
}
private static void showBatteryOptimizationDialog(Activity context,
String dialogMessageRef,
String positiveButtonStringRef,
DialogInterface.OnClickListener onPositiveClickListener) {
// Use a delay to allow the activity to finish initializing.
// Otherwise, if device is in dark mode the dialog is shown with wrong color scheme.
Utils.runOnMainThreadDelayed(() -> {
new AlertDialog.Builder(context)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setTitle(str("gms_core_dialog_title"))
.setMessage(str(dialogMessageKey))
.setPositiveButton(str("gms_core_dialog_ok_button_text"), (dialog, id) -> {
open(link);
})
// Manually allow using the back button to dismiss the dialog with the back button,
// if troubleshooting and somehow the GmsCore verification checks always fail.
.setMessage(str(dialogMessageRef))
.setPositiveButton(str(positiveButtonStringRef), onPositiveClickListener)
// Allow using back button to skip the action, just in case the check can never be satisfied.
.setCancelable(true)
.show();
}, 100);
@@ -74,47 +71,62 @@ public class GmsCoreSupport {
* Injection point.
*/
@RequiresApi(api = Build.VERSION_CODES.N)
public static void checkGmsCore(Context context) {
public static void checkGmsCore(Activity context) {
try {
// Verify GmsCore is installed.
try {
PackageManager manager = context.getPackageManager();
manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
} catch (PackageManager.NameNotFoundException exception) {
Logger.printDebug(() -> "GmsCore was not found");
Logger.printInfo(() -> "GmsCore was not found");
// Cannot show a dialog and must show a toast,
// because on some installations the app crashes before the dialog can display.
// because on some installations the app crashes before a dialog can be displayed.
Utils.showToastLong(str("gms_core_toast_not_installed_message"));
open(getGmsCoreDownload());
return;
}
// Check if GmsCore is whitelisted from battery optimizations.
var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) {
Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations");
showToastOrDialog(context,
"gms_core_toast_not_whitelisted_message",
"gms_core_dialog_not_whitelisted_using_battery_optimizations_message",
DONT_KILL_MY_APP_LINK);
return;
}
// Check if GmsCore is running in the background.
try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) {
if (client == null) {
Logger.printDebug(() -> "GmsCore is not running in the background");
showToastOrDialog(context,
"gms_core_toast_not_whitelisted_message",
Logger.printInfo(() -> "GmsCore is not running in the background");
showBatteryOptimizationDialog(context,
"gms_core_dialog_not_whitelisted_not_allowed_in_background_message",
DONT_KILL_MY_APP_LINK);
"gms_core_dialog_open_website_text",
(dialog, id) -> open(DONT_KILL_MY_APP_LINK));
return;
}
}
// Check if GmsCore is whitelisted from battery optimizations.
if (batteryOptimizationsEnabled(context)) {
Logger.printInfo(() -> "GmsCore is not whitelisted from battery optimizations");
showBatteryOptimizationDialog(context,
"gms_core_dialog_not_whitelisted_using_battery_optimizations_message",
"gms_core_dialog_continue_text",
(dialog, id) -> openGmsCoreDisableBatteryOptimizationsIntent(context));
}
} catch (Exception ex) {
Logger.printException(() -> "checkGmsCore failure", ex);
}
}
@SuppressLint("BatteryLife") // Permission is part of GmsCore
private static void openGmsCoreDisableBatteryOptimizationsIntent(Activity activity) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.fromParts("package", GMS_CORE_PACKAGE_NAME, null));
activity.startActivityForResult(intent, 0);
}
/**
* @return If GmsCore is not whitelisted from battery optimizations.
*/
private static boolean batteryOptimizationsEnabled(Context context) {
var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return !powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME);
}
private static String getGmsCoreDownload() {
final var vendorGroupId = getGmsCoreVendorGroupId();
//noinspection SwitchStatementWithTooFewBranches

View File

@@ -224,6 +224,7 @@ public abstract class Setting<T> {
if (!oldPrefs.preferences.contains(settingKey)) {
return; // Nothing to do.
}
Object newValue = setting.get();
final Object migratedValue;
if (setting instanceof BooleanSetting) {
@@ -238,13 +239,17 @@ public abstract class Setting<T> {
migratedValue = oldPrefs.getString(settingKey, (String) newValue);
} else {
Logger.printException(() -> "Unknown setting: " + setting);
// Remove otherwise it'll show a toast on every launch
oldPrefs.preferences.edit().remove(settingKey).apply();
return;
}
oldPrefs.preferences.edit().remove(settingKey).apply(); // Remove the old setting.
if (migratedValue.equals(newValue)) {
Logger.printDebug(() -> "Value does not need migrating: " + settingKey);
return; // Old value is already equal to the new setting value.
}
Logger.printDebug(() -> "Migrating old preference value into current preference: " + settingKey);
//noinspection unchecked
setting.save(migratedValue);

View File

@@ -1,19 +1,15 @@
package app.revanced.integrations.youtube.patches;
import static app.revanced.integrations.shared.StringRef.str;
import static app.revanced.integrations.youtube.settings.Settings.*;
import static app.revanced.integrations.youtube.shared.NavigationBar.NavigationButton;
import android.net.Uri;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.revanced.integrations.shared.settings.BaseSettings;
import app.revanced.integrations.shared.settings.EnumSetting;
import app.revanced.integrations.shared.settings.Setting;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.shared.Utils;
import app.revanced.integrations.youtube.shared.NavigationBar;
import app.revanced.integrations.youtube.shared.PlayerType;
import org.chromium.net.UrlRequest;
import org.chromium.net.UrlResponseInfo;
import org.chromium.net.impl.CronetUrlRequest;
@@ -26,13 +22,12 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import static app.revanced.integrations.shared.StringRef.str;
import static app.revanced.integrations.youtube.settings.Settings.ALT_THUMBNAIL_HOME;
import static app.revanced.integrations.youtube.settings.Settings.ALT_THUMBNAIL_LIBRARY;
import static app.revanced.integrations.youtube.settings.Settings.ALT_THUMBNAIL_PLAYER;
import static app.revanced.integrations.youtube.settings.Settings.ALT_THUMBNAIL_SEARCH;
import static app.revanced.integrations.youtube.settings.Settings.ALT_THUMBNAIL_SUBSCRIPTIONS;
import static app.revanced.integrations.youtube.shared.NavigationBar.NavigationButton;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.shared.Utils;
import app.revanced.integrations.shared.settings.Setting;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.youtube.shared.NavigationBar;
import app.revanced.integrations.youtube.shared.PlayerType;
/**
* Alternative YouTube thumbnails.
@@ -134,11 +129,6 @@ public final class AlternativeThumbnailsPatch {
*/
private static volatile long timeToResumeDeArrowAPICalls;
/**
* Used only for debug logging.
*/
private static volatile EnumSetting<ThumbnailOption> currentOptionSetting;
static {
dearrowApiUri = validateSettings();
final int port = dearrowApiUri.getPort();
@@ -162,21 +152,38 @@ public final class AlternativeThumbnailsPatch {
return apiUri;
}
private static EnumSetting<ThumbnailOption> optionSettingForCurrentNavigation() {
if (NavigationBar.isSearchBarActive()) { // Must check search first.
return ALT_THUMBNAIL_SEARCH;
}
private static ThumbnailOption optionSettingForCurrentNavigation() {
// Must check player type first, as search bar can be active behind the player.
if (PlayerType.getCurrent().isMaximizedOrFullscreen()) {
return ALT_THUMBNAIL_PLAYER;
return ALT_THUMBNAIL_PLAYER.get();
}
if (NavigationButton.HOME.isSelected()) {
return ALT_THUMBNAIL_HOME;
// Must check second, as search can be from any tab.
if (NavigationBar.isSearchBarActive()) {
return ALT_THUMBNAIL_SEARCH.get();
}
if (NavigationButton.SUBSCRIPTIONS.isSelected() || NavigationButton.NOTIFICATIONS.isSelected()) {
return ALT_THUMBNAIL_SUBSCRIPTIONS;
// Avoid checking which navigation button is selected, if all other settings are the same.
ThumbnailOption homeOption = ALT_THUMBNAIL_HOME.get();
ThumbnailOption subscriptionsOption = ALT_THUMBNAIL_SUBSCRIPTIONS.get();
ThumbnailOption libraryOption = ALT_THUMBNAIL_LIBRARY.get();
if ((homeOption == subscriptionsOption) && (homeOption == libraryOption)) {
return homeOption; // All are the same option.
}
NavigationButton selectedNavButton = NavigationButton.getSelectedNavigationButton();
if (selectedNavButton == null) {
// Unknown tab, treat as the home tab;
return homeOption;
}
if (selectedNavButton == NavigationButton.HOME) {
return homeOption;
}
if (selectedNavButton == NavigationButton.SUBSCRIPTIONS || selectedNavButton == NavigationButton.NOTIFICATIONS) {
return subscriptionsOption;
}
// A library tab variant is active.
return ALT_THUMBNAIL_LIBRARY;
return libraryOption;
}
/**
@@ -254,14 +261,7 @@ public final class AlternativeThumbnailsPatch {
*/
public static String overrideImageURL(String originalUrl) {
try {
EnumSetting<ThumbnailOption> optionSetting = optionSettingForCurrentNavigation();
ThumbnailOption option = optionSetting.get();
if (BaseSettings.DEBUG.get()) {
if (currentOptionSetting != optionSetting) {
currentOptionSetting = optionSetting;
Logger.printDebug(() -> "Changed to setting: " + optionSetting.key);
}
}
ThumbnailOption option = optionSettingForCurrentNavigation();
if (option == ThumbnailOption.ORIGINAL) {
return originalUrl;

View File

@@ -1,29 +0,0 @@
package app.revanced.integrations.youtube.patches;
import android.view.View;
import app.revanced.integrations.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.shared.Utils;
@SuppressWarnings("unused")
public class HideBreakingNewsPatch {
/**
* When spoofing to app versions 17.31.00 and older, the watch history preview bar uses
* the same layout components as the breaking news shelf.
*
* Breaking news does not appear to be present in these older versions anyways.
*/
private static final boolean isSpoofingOldVersionWithHorizontalCardListWatchHistory =
SpoofAppVersionPatch.isSpoofingToLessThan("18.01.00");
/**
* Injection point.
*/
public static void hideBreakingNews(View view) {
if (!Settings.HIDE_BREAKING_NEWS.get()
|| isSpoofingOldVersionWithHorizontalCardListWatchHistory) return;
Utils.hideViewByLayoutParams(view);
}
}

View File

@@ -1,14 +0,0 @@
package app.revanced.integrations.youtube.patches;
import android.view.View;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.shared.Utils;
@SuppressWarnings("unused")
public class HideLoadMoreButtonPatch {
public static void hideLoadMoreButton(View view){
if(!Settings.HIDE_LOAD_MORE_BUTTON.get()) return;
Utils.hideViewByLayoutParams(view);
}
}

View File

@@ -112,34 +112,35 @@ final class KeywordContentFilter extends Filter {
private volatile ByteTrieSearch bufferSearch;
private static void logNavigationState(String state) {
// Enable locally to debug filtering. Default off to reduce log spam.
final boolean LOG_NAVIGATION_STATE = false;
// noinspection ConstantValue
if (LOG_NAVIGATION_STATE) {
Logger.printDebug(() -> "Navigation state: " + state);
}
}
private static boolean hideKeywordSettingIsActive() {
if (NavigationBar.isSearchBarActive()) {
// Must check first. Search bar can be active with almost any tab.
logNavigationState("Search");
return Settings.HIDE_KEYWORD_CONTENT_SEARCH.get();
} else if (PlayerType.getCurrent().isMaximizedOrFullscreen()) {
// Must check player type first, as search bar can be active behind the player.
if (PlayerType.getCurrent().isMaximizedOrFullscreen()) {
// For now, consider the under video results the same as the home feed.
logNavigationState("Player active");
return Settings.HIDE_KEYWORD_CONTENT_HOME.get();
} else if (NavigationButton.HOME.isSelected()) {
logNavigationState("Home tab");
return Settings.HIDE_KEYWORD_CONTENT_HOME.get();
} else if (NavigationButton.SUBSCRIPTIONS.isSelected()) {
logNavigationState("Subscription tab");
return Settings.HIDE_SUBSCRIPTIONS_BUTTON.get();
} else {
// User is in the Library or Notifications tab.
logNavigationState("Ignored tab");
}
// Must check second, as search can be from any tab.
if (NavigationBar.isSearchBarActive()) {
return Settings.HIDE_KEYWORD_CONTENT_SEARCH.get();
}
// Avoid checking navigation button status if all other settings are off.
final boolean hideHome = Settings.HIDE_KEYWORD_CONTENT_HOME.get();
final boolean hideSubscriptions = Settings.HIDE_SUBSCRIPTIONS_BUTTON.get();
if (!hideHome && !hideSubscriptions) {
return false;
}
NavigationButton selectedNavButton = NavigationButton.getSelectedNavigationButton();
if (selectedNavButton == null) {
return hideHome; // Unknown tab, treat the same as home.
}
if (selectedNavButton == NavigationButton.HOME) {
return hideHome;
}
if (selectedNavButton == NavigationButton.SUBSCRIPTIONS) {
return hideSubscriptions;
}
// User is in the Library or Notifications tab.
return false;
}
@@ -195,6 +196,7 @@ final class KeywordContentFilter extends Filter {
private synchronized void parseKeywords() { // Must be synchronized since Litho is multi-threaded.
String rawKeywords = Settings.HIDE_KEYWORD_CONTENT_PHRASES.get();
//noinspection StringEquality
if (rawKeywords == lastKeywordPhrasesParsed) {
Logger.printDebug(() -> "Using previously initialized search");
return; // Another thread won the race, and search is already initialized.
@@ -265,6 +267,7 @@ final class KeywordContentFilter extends Filter {
if (!hideKeywordSettingIsActive()) return false;
// Field is intentionally compared using reference equality.
//noinspection StringEquality
if (Settings.HIDE_KEYWORD_CONTENT_PHRASES.get() != lastKeywordPhrasesParsed) {
// User changed the keywords.
parseKeywords();

View File

@@ -1,13 +1,19 @@
package app.revanced.integrations.youtube.patches.components;
import static app.revanced.integrations.youtube.shared.NavigationBar.NavigationButton;
import android.os.Build;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.shared.Utils;
import app.revanced.integrations.youtube.StringTrieSearch;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.youtube.shared.NavigationBar;
import app.revanced.integrations.youtube.shared.PlayerType;
@SuppressWarnings("unused")
public final class LayoutComponentsFilter extends Filter {
@@ -31,6 +37,7 @@ public final class LayoutComponentsFilter extends Filter {
private final StringFilterGroup compactChannelBarInner;
private final StringFilterGroup compactChannelBarInnerButton;
private final ByteArrayFilterGroup joinMembershipButton;
private final StringFilterGroup horizontalShelves;
static {
mixPlaylistsExceptions.addPatterns(
@@ -39,7 +46,6 @@ public final class LayoutComponentsFilter extends Filter {
);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public LayoutComponentsFilter() {
exceptions.addPatterns(
@@ -233,6 +239,12 @@ public final class LayoutComponentsFilter extends Filter {
"endorsement_header_footer"
);
horizontalShelves = new StringFilterGroup(
Settings.HIDE_HORIZONTAL_SHELVES,
"horizontal_video_shelf.eml",
"horizontal_shelf.eml"
);
addPathCallbacks(
expandableMetadata,
inFeedSurvey,
@@ -259,7 +271,8 @@ public final class LayoutComponentsFilter extends Filter {
timedReactions,
imageShelf,
channelMemberShelf,
forYouShelf
forYouShelf,
horizontalShelves
);
}
@@ -270,12 +283,15 @@ public final class LayoutComponentsFilter extends Filter {
if (searchResultRecommendations.check(protobufBufferArray).isFiltered()) {
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
return false;
}
// The groups are excluded from the filter due to the exceptions list below.
// Filter them separately here.
if (matchedGroup == notifyMe || matchedGroup == inFeedSurvey || matchedGroup == expandableMetadata)
{
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
if (exceptions.matches(path)) return false; // Exceptions are not filtered.
@@ -294,6 +310,14 @@ public final class LayoutComponentsFilter extends Filter {
// TODO: This also hides the feed Shorts shelf header
if (matchedGroup == searchResultShelfHeader && contentIndex != 0) return false;
if (matchedGroup == horizontalShelves) {
if (contentIndex == 0 && hideShelves()) {
return super.isFiltered(path, identifier, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
return false;
}
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
@@ -322,7 +346,40 @@ public final class LayoutComponentsFilter extends Filter {
return true;
}
/**
* Injection point.
*/
public static boolean showWatermark() {
return !Settings.HIDE_VIDEO_CHANNEL_WATERMARK.get();
}
private static final boolean HIDE_SHOW_MORE_BUTTON_ENABLED = Settings.HIDE_SHOW_MORE_BUTTON.get();
/**
* Injection point.
*/
public static void hideShowMoreButton(View view) {
if (HIDE_SHOW_MORE_BUTTON_ENABLED
&& NavigationBar.isSearchBarActive()
// Search bar can be active but behind the player.
&& !PlayerType.getCurrent().isMaximizedOrFullscreen()) {
Utils.hideViewByLayoutParams(view);
}
}
private static boolean hideShelves() {
// If the player is opened while library is selected,
// then filter any recommendations below the player.
if (PlayerType.getCurrent().isMaximizedOrFullscreen()
// Or if the search is active while library is selected, then also filter.
|| NavigationBar.isSearchBarActive()) {
return true;
}
// Check navigation button last.
// Only filter if the library tab is not selected.
// This check is important as the shelf layout is used for the library tab playlists.
NavigationButton selectedNavButton = NavigationButton.getSelectedNavigationButton();
return selectedNavButton != null && !selectedNavButton.isLibraryOrYouTab();
}
}

View File

@@ -57,6 +57,10 @@ public class PlayerFlyoutMenuItemsFilter extends Filter {
Settings.HIDE_MORE_INFO_MENU,
"yt_outline_info_circle"
),
new ByteArrayFilterGroup(
Settings.HIDE_LOCK_SCREEN_MENU,
"yt_outline_lock"
),
new ByteArrayFilterGroup(
Settings.HIDE_SPEED_MENU,
"yt_outline_play_arrow_half_circle"
@@ -75,15 +79,21 @@ public class PlayerFlyoutMenuItemsFilter extends Filter {
@Override
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
// Shorts also use this player flyout panel
if (PlayerType.getCurrent().isNoneOrHidden() || exception.check(protobufBufferArray).isFiltered())
return false;
// Only 1 path callback was added, so the matched group must be the overflow menu.
if (contentIndex == 0 && flyoutFilterGroupList.check(protobufBufferArray).isFiltered()) {
if (contentIndex != 0) {
return false; // Overflow menu is always the start of the path.
}
// Shorts also use this player flyout panel
if (PlayerType.getCurrent().isNoneOrHidden() || exception.check(protobufBufferArray).isFiltered()) {
return false;
}
if (flyoutFilterGroupList.check(protobufBufferArray).isFiltered()) {
// Super class handles logging.
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
return false;
}
}

View File

@@ -1,6 +1,7 @@
package app.revanced.integrations.youtube.patches.components;
import static app.revanced.integrations.shared.Utils.hideViewUnderCondition;
import static app.revanced.integrations.youtube.shared.NavigationBar.NavigationButton;
import android.view.View;
@@ -219,14 +220,35 @@ public final class ShortsFilter extends Filter {
}
private static boolean shouldHideShortsFeedItems() {
if (NavigationBar.isSearchBarActive()) { // Must check search first.
return Settings.HIDE_SHORTS_SEARCH.get();
} else if (PlayerType.getCurrent().isMaximizedOrFullscreen()
|| NavigationBar.NavigationButton.HOME.isSelected()) {
// Must check player type first, as search bar can be active behind the player.
if (PlayerType.getCurrent().isMaximizedOrFullscreen()) {
// For now, consider the under video results the same as the home feed.
return Settings.HIDE_SHORTS_HOME.get();
} else if (NavigationBar.NavigationButton.SUBSCRIPTIONS.isSelected()) {
return Settings.HIDE_SHORTS_SUBSCRIPTIONS.get();
}
// Must check second, as search can be from any tab.
if (NavigationBar.isSearchBarActive()) {
return Settings.HIDE_SHORTS_SEARCH.get();
}
// Avoid checking navigation button status if all other settings are off.
final boolean hideHome = Settings.HIDE_SHORTS_HOME.get();
final boolean hideSubscriptions = Settings.HIDE_SHORTS_SUBSCRIPTIONS.get();
if (!hideHome && !hideSubscriptions) {
return false;
}
NavigationButton selectedNavButton = NavigationButton.getSelectedNavigationButton();
if (selectedNavButton == null) {
return hideHome; // Unknown tab, treat the same as home.
}
if (selectedNavButton == NavigationButton.HOME) {
return hideHome;
}
if (selectedNavButton == NavigationButton.SUBSCRIPTIONS) {
return hideSubscriptions;
}
// User must be in the library tab. Don't hide the history or any playlists here.
return false;
}

View File

@@ -55,6 +55,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_SELF_SPONSOR = new BooleanSetting("revanced_hide_self_sponsor_ads", TRUE);
public static final BooleanSetting HIDE_VIDEO_ADS = new BooleanSetting("revanced_hide_video_ads", TRUE, true);
public static final BooleanSetting HIDE_WEB_SEARCH_RESULTS = new BooleanSetting("revanced_hide_web_search_results", TRUE);
// Layout
public static final EnumSetting<ThumbnailOption> ALT_THUMBNAIL_HOME = new EnumSetting<>("revanced_alt_thumbnail_home", ThumbnailOption.ORIGINAL);
public static final EnumSetting<ThumbnailOption> ALT_THUMBNAIL_SUBSCRIPTIONS = new EnumSetting<>("revanced_alt_thumbnail_subscription", ThumbnailOption.ORIGINAL);
@@ -71,12 +72,12 @@ public class Settings extends BaseSettings {
public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true);
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", FALSE);
public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE);
public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE, true);
public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE);
public static final BooleanSetting HIDE_ALBUM_CARDS = new BooleanSetting("revanced_hide_album_cards", FALSE, true);
public static final BooleanSetting HIDE_ARTIST_CARDS = new BooleanSetting("revanced_hide_artist_cards", FALSE);
public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
public static final BooleanSetting HIDE_BREAKING_NEWS = new BooleanSetting("revanced_hide_breaking_news", TRUE, true);
public static final BooleanSetting HIDE_HORIZONTAL_SHELVES = new BooleanSetting("revanced_hide_horizontal_shelves", TRUE);
public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("revanced_hide_captions_button", FALSE);
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
public static final BooleanSetting HIDE_CHANNEL_BAR = new BooleanSetting("revanced_hide_channel_bar", FALSE);
@@ -108,7 +109,8 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_KEYWORD_CONTENT_SEARCH = new BooleanSetting("revanced_hide_keyword_content_search", FALSE);
public static final StringSetting HIDE_KEYWORD_CONTENT_PHRASES = new StringSetting("revanced_hide_keyword_content_phrases", "",
parentsAny(HIDE_KEYWORD_CONTENT_HOME, HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS, HIDE_KEYWORD_CONTENT_SEARCH));
public static final BooleanSetting HIDE_LOAD_MORE_BUTTON = new BooleanSetting("revanced_hide_load_more_button", TRUE, true);
@Deprecated public static final BooleanSetting HIDE_LOAD_MORE_BUTTON = new BooleanSetting("revanced_hide_load_more_button", TRUE);
public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true);
public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE);
public static final BooleanSetting HIDE_MIX_PLAYLISTS = new BooleanSetting("revanced_hide_mix_playlists", TRUE);
public static final BooleanSetting HIDE_MOVIES_SECTION = new BooleanSetting("revanced_hide_movies_section", TRUE);
@@ -198,6 +200,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_HELP_MENU = new BooleanSetting("revanced_hide_player_flyout_help", TRUE);
public static final BooleanSetting HIDE_SPEED_MENU = new BooleanSetting("revanced_hide_player_flyout_speed", FALSE);
public static final BooleanSetting HIDE_MORE_INFO_MENU = new BooleanSetting("revanced_hide_player_flyout_more_info", TRUE);
public static final BooleanSetting HIDE_LOCK_SCREEN_MENU = new BooleanSetting("revanced_hide_player_flyout_lock_screen", FALSE);
public static final BooleanSetting HIDE_AUDIO_TRACK_MENU = new BooleanSetting("revanced_hide_player_flyout_audio_track", FALSE);
public static final BooleanSetting HIDE_WATCH_IN_VR_MENU = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE);
@@ -218,7 +221,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true);
public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE);
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
@Deprecated
@Deprecated
public static final StringSetting DEPRECATED_ANNOUNCEMENT_LAST_HASH = new StringSetting("revanced_announcement_last_hash", "");
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1);
public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE);
@@ -383,6 +386,8 @@ public class Settings extends BaseSettings {
HIDE_SHORTS_SEARCH.save(true);
}
migrateOldSettingToNew(HIDE_LOAD_MORE_BUTTON, HIDE_SHOW_MORE_BUTTON);
// endregion
}
}

View File

@@ -79,10 +79,9 @@ public class ReturnYouTubeDislikePreferenceFragment extends PreferenceFragment {
shortsPreference = new SwitchPreference(context);
shortsPreference.setChecked(Settings.RYD_SHORTS.get());
shortsPreference.setTitle(str("revanced_ryd_shorts_title"));
String shortsSummary = str("revanced_ryd_shorts_summary_on",
ReturnYouTubeDislikePatch.IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER
? ""
: "\n\n" + str("revanced_ryd_shorts_summary_disclaimer"));
String shortsSummary = ReturnYouTubeDislikePatch.IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER
? str("revanced_ryd_shorts_summary_on")
: str("revanced_ryd_shorts_summary_on_disclaimer");
shortsPreference.setSummaryOn(shortsSummary);
shortsPreference.setSummaryOff(str("revanced_ryd_shorts_summary_off"));
shortsPreference.setOnPreferenceChangeListener((pref, newValue) -> {

View File

@@ -100,10 +100,10 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
privateUserId.setEnabled(enabled);
// If the user has a private user id, then include a subtext that mentions not to share it.
String exportSummarySubText = SponsorBlockSettings.userHasSBPrivateId()
String importExportSummary = SponsorBlockSettings.userHasSBPrivateId()
? str("revanced_sb_settings_ie_sum_warning")
: "";
importExport.setSummary(str("revanced_sb_settings_ie_sum", exportSummarySubText));
: str("revanced_sb_settings_ie_sum");
importExport.setSummary(importExportSummary);
apiUrl.setEnabled(enabled);
importExport.setEnabled(enabled);

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
android.useAndroidX = true
version = 1.7.0
version = 1.8.0-dev.4