From a0ad968aaa66422e67de2a61d76bc7aa88f08bf6 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 5 Apr 2023 12:24:55 +0400 Subject: [PATCH] feat(youtube/settings): disable preference control if the feature is turned off. show a dialog explaining side effects of some patches (#328) Co-authored-by: semantic-release-bot Co-authored-by: oSumAtrIX --- .../integrations/patches/HideReelsPatch.java | 20 - .../quality/RememberVideoQualityPatch.java | 7 +- .../speed/RememberPlaybackSpeedPatch.java | 2 +- .../integrations/settings/ReturnType.java | 10 - .../integrations/settings/SettingsEnum.java | 480 +++++++++++------- .../settings/SharedPrefCategory.java | 97 ++++ .../settingsmenu/ReVancedSettingActivity.java | 6 + .../ReVancedSettingsFragment.java | 190 ++++--- .../ReturnYouTubeDislikeSettingsFragment.java | 16 +- .../SponsorBlockSettingsFragment.java | 10 +- .../sponsorblock/SponsorBlockSettings.java | 4 +- .../sponsorblock/objects/SegmentCategory.java | 4 +- .../integrations/utils/SharedPrefHelper.java | 94 ---- .../revanced/tiktok/settings/ReturnType.java | 5 - .../tiktok/settings/SettingsEnum.java | 201 ++++---- .../tiktok/settings/SharedPrefCategory.java | 71 +++ .../ReVancedSettingsFragment.java | 46 +- .../tiktok/utils/SharedPrefHelper.java | 82 --- .../revanced/twitch/settings/ReturnType.java | 5 - .../twitch/settings/SettingsEnum.java | 165 +++--- .../ReVancedSettingsFragment.java | 15 +- 21 files changed, 800 insertions(+), 730 deletions(-) delete mode 100644 app/src/main/java/app/revanced/integrations/patches/HideReelsPatch.java delete mode 100644 app/src/main/java/app/revanced/integrations/settings/ReturnType.java create mode 100644 app/src/main/java/app/revanced/integrations/settings/SharedPrefCategory.java delete mode 100644 app/src/main/java/app/revanced/integrations/utils/SharedPrefHelper.java delete mode 100644 app/src/main/java/app/revanced/tiktok/settings/ReturnType.java create mode 100644 app/src/main/java/app/revanced/tiktok/settings/SharedPrefCategory.java delete mode 100644 app/src/main/java/app/revanced/tiktok/utils/SharedPrefHelper.java delete mode 100644 app/src/main/java/app/revanced/twitch/settings/ReturnType.java diff --git a/app/src/main/java/app/revanced/integrations/patches/HideReelsPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideReelsPatch.java deleted file mode 100644 index 680d05e0..00000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideReelsPatch.java +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.integrations.patches; - -import android.view.View; - -import app.revanced.integrations.adremover.AdRemoverAPI; -import app.revanced.integrations.settings.SettingsEnum; - -public class HideReelsPatch { - - /** - * Used by app.revanced.patches.youtube.layout.reels.patch.HideReelsPatch - * - * @param view - */ - public static void HideReel(View view) { - if (SettingsEnum.HIDE_REEL_BUTTON.getBoolean()) { - AdRemoverAPI.HideViewWithLayout1dp(view); - } - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch.java b/app/src/main/java/app/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch.java index a9fd837e..695b52ac 100644 --- a/app/src/main/java/app/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch.java @@ -8,13 +8,12 @@ import java.util.ArrayList; import java.util.Collections; import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.settings.SharedPrefCategory; import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.ReVancedUtils; import app.revanced.integrations.utils.ReVancedUtils.NetworkType; -import app.revanced.integrations.utils.SharedPrefHelper; public class RememberVideoQualityPatch { - public static int selectedQuality1 = -2; private static Boolean newVideo = false; private static Boolean userChangedQuality = false; @@ -35,7 +34,7 @@ public class RememberVideoQualityPatch { preferenceKey = "mobile_quality"; } - SharedPrefHelper.saveString(SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, preferenceKey, defaultQuality + ""); + SharedPrefCategory.REVANCED_PREFS.saveString(preferenceKey, String.valueOf(defaultQuality)); ReVancedUtils.showToastShort("Changing default " + networkTypeMessage + " quality to: " + defaultQuality); } @@ -94,7 +93,7 @@ public class RememberVideoQualityPatch { var preferenceKey = "wifi_quality"; if (networkType == NetworkType.MOBILE) preferenceKey = "mobile_quality"; - int preferredQuality = SharedPrefHelper.getInt(SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, preferenceKey, -2); + int preferredQuality = SharedPrefCategory.REVANCED_PREFS.getInt(preferenceKey, -2); if (preferredQuality == -2) return quality; for (int streamQuality2 : iStreamQualities) { diff --git a/app/src/main/java/app/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch.java b/app/src/main/java/app/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch.java index babbc291..5b4a9460 100644 --- a/app/src/main/java/app/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch.java @@ -36,7 +36,7 @@ public final class RememberPlaybackSpeedPatch { // TODO: extract these strings into localized file ReVancedUtils.showToastLong("Remembering playback speed: " + playbackSpeed + "x"); - } else if (playbackSpeed != (float) SettingsEnum.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_VALUE.getDefaultValue()) { + } else if (playbackSpeed != (float) SettingsEnum.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_VALUE.defaultValue) { ReVancedUtils.showToastLong("Applying playback speed: " + playbackSpeed + "x"); } } diff --git a/app/src/main/java/app/revanced/integrations/settings/ReturnType.java b/app/src/main/java/app/revanced/integrations/settings/ReturnType.java deleted file mode 100644 index df1d710a..00000000 --- a/app/src/main/java/app/revanced/integrations/settings/ReturnType.java +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.integrations.settings; - -public enum ReturnType { - - BOOLEAN, - INTEGER, - STRING, - LONG, - FLOAT; -} diff --git a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java index 1f34db68..8819bd6e 100644 --- a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java +++ b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java @@ -1,190 +1,289 @@ package app.revanced.integrations.settings; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.SharedPrefHelper; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static app.revanced.integrations.settings.SettingsEnum.ReturnType.BOOLEAN; +import static app.revanced.integrations.settings.SettingsEnum.ReturnType.FLOAT; +import static app.revanced.integrations.settings.SettingsEnum.ReturnType.INTEGER; +import static app.revanced.integrations.settings.SettingsEnum.ReturnType.LONG; +import static app.revanced.integrations.settings.SettingsEnum.ReturnType.STRING; +import static app.revanced.integrations.settings.SharedPrefCategory.RETURN_YOUTUBE_DISLIKE; +import static app.revanced.integrations.settings.SharedPrefCategory.SPONSOR_BLOCK; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Objects; + +import app.revanced.integrations.utils.StringRef; public enum SettingsEnum { //Download Settings - // TODO: DOWNLOAD_PATH("revanced_download_path", Environment.getExternalStorageDirectory().getPath() + "/Download", ReturnType.STRING), - DOWNLOADS_BUTTON_SHOWN("revanced_downloads_enabled", true, ReturnType.BOOLEAN, true), - DOWNLOADS_PACKAGE_NAME("revanced_downloads_package_name", "org.schabi.newpipe" /* NewPipe */, ReturnType.STRING), + // TODO: DOWNLOAD_PATH("revanced_download_path", STRING, Environment.getExternalStorageDirectory().getPath() + "/Download"), + DOWNLOADS_BUTTON_SHOWN("revanced_downloads_enabled", BOOLEAN, TRUE, true), + DOWNLOADS_PACKAGE_NAME("revanced_downloads_package_name", STRING, "org.schabi.newpipe" /* NewPipe */, parents(DOWNLOADS_BUTTON_SHOWN)), // Copy video URL settings - COPY_VIDEO_URL_BUTTON_SHOWN("revanced_copy_video_url_enabled", true, ReturnType.BOOLEAN, true), - COPY_VIDEO_URL_TIMESTAMP_BUTTON_SHOWN("revanced_copy_video_url_timestamp_enabled", true, ReturnType.BOOLEAN, true), + COPY_VIDEO_URL_BUTTON_SHOWN("revanced_copy_video_url_enabled", BOOLEAN, TRUE, true), + COPY_VIDEO_URL_TIMESTAMP_BUTTON_SHOWN("revanced_copy_video_url_timestamp_enabled", BOOLEAN, TRUE, true), // Video settings - OLD_STYLE_VIDEO_QUALITY_PLAYER_SETTINGS("revanced_use_old_style_quality_settings", true, ReturnType.BOOLEAN), - REMEMBER_VIDEO_QUALITY_LAST_SELECTED("revanced_remember_video_quality_last_selected", true, ReturnType.BOOLEAN), - REMEMBER_PLAYBACK_SPEED_LAST_SELECTED("revanced_remember_playback_speed_last_selected", true, ReturnType.BOOLEAN), - REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_VALUE("revanced_remember_playback_speed_last_selected_value", 1.0f, ReturnType.FLOAT), + OLD_STYLE_VIDEO_QUALITY_PLAYER_SETTINGS("revanced_use_old_style_quality_settings", BOOLEAN, TRUE), + REMEMBER_VIDEO_QUALITY_LAST_SELECTED("revanced_remember_video_quality_last_selected", BOOLEAN, TRUE), + REMEMBER_PLAYBACK_SPEED_LAST_SELECTED("revanced_remember_playback_speed_last_selected", BOOLEAN, TRUE), + REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_VALUE("revanced_remember_playback_speed_last_selected_value", FLOAT, 1.0f), // TODO: Unused currently // Whitelist settings - ENABLE_WHITELIST("revanced_whitelist_ads_enabled", false, ReturnType.BOOLEAN), + //ENABLE_WHITELIST("revanced_whitelist_ads_enabled", BOOLEAN, FALSE), // Ad settings - ADREMOVER_CUSTOM_ENABLED("revanced_adremover_custom_enabled", false, ReturnType.BOOLEAN), - ADREMOVER_CUSTOM_REMOVAL("revanced_adremover_custom_strings", "", ReturnType.STRING, true), - VIDEO_ADS_REMOVAL("revanced_video_ads_removal", true, ReturnType.BOOLEAN, true), - ADREMOVER_GENERAL_ADS_REMOVAL("revanced_adremover_ad_removal", true, ReturnType.BOOLEAN), - ADREMOVER_MERCHANDISE_REMOVAL("revanced_adremover_merchandise", true, ReturnType.BOOLEAN), - ADREMOVER_COMMUNITY_POSTS_REMOVAL("revanced_adremover_community_posts_removal", false, ReturnType.BOOLEAN), - ADREMOVER_COMPACT_BANNER_REMOVAL("revanced_adremover_compact_banner_removal", true, ReturnType.BOOLEAN), - ADREMOVER_MOVIE_REMOVAL("revanced_adremover_movie", true, ReturnType.BOOLEAN), - ADREMOVER_FEED_SURVEY_REMOVAL("revanced_adremover_feed_survey", true, ReturnType.BOOLEAN), - ADREMOVER_SHORTS_REMOVAL("revanced_adremover_shorts", true, ReturnType.BOOLEAN, true), - ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_community_guidelines", true, ReturnType.BOOLEAN), - ADREMOVER_SUBSCRIBERS_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_subscribers_community_guidelines_removal", true, ReturnType.BOOLEAN), - ADREMOVER_CHANNEL_MEMBER_SHELF_REMOVAL("revanced_adremover_channel_member_shelf_removal", true, ReturnType.BOOLEAN), - ADREMOVER_EMERGENCY_BOX_REMOVAL("revanced_adremover_emergency_box_removal", true, ReturnType.BOOLEAN), - ADREMOVER_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", true, ReturnType.BOOLEAN), - ADREMOVER_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", true, ReturnType.BOOLEAN), - ADREMOVER_PAID_CONTENT_REMOVAL("revanced_adremover_paid_content", true, ReturnType.BOOLEAN), - ADREMOVER_HIDE_LATEST_POSTS("revanced_adremover_hide_latest_posts", true, ReturnType.BOOLEAN), - ADREMOVER_HIDE_CHANNEL_GUIDELINES("revanced_adremover_hide_channel_guidelines", true, ReturnType.BOOLEAN), - ADREMOVER_SELF_SPONSOR_REMOVAL("revanced_adremover_self_sponsor", true, ReturnType.BOOLEAN), - ADREMOVER_CHAPTER_TEASER_REMOVAL("revanced_adremover_chapter_teaser", true, ReturnType.BOOLEAN), - ADREMOVER_BUTTONED_REMOVAL("revanced_adremover_buttoned", true, ReturnType.BOOLEAN), - ADREMOVER_GRAY_SEPARATOR("revanced_adremover_separator", true, ReturnType.BOOLEAN), - ADREMOVER_VIEW_PRODUCTS("revanced_adremover_view_products", true, ReturnType.BOOLEAN), - ADREMOVER_WEB_SEARCH_RESULTS("revanced_adremover_web_search_result", true, ReturnType.BOOLEAN), - ADREMOVER_CHANNEL_BAR("revanced_hide_channel_bar", false, ReturnType.BOOLEAN), - ADREMOVER_QUICK_ACTIONS("revanced_hide_quick_actions", false, ReturnType.BOOLEAN), - ADREMOVER_RELATED_VIDEOS("revanced_hide_related_videos", false, ReturnType.BOOLEAN), - ADREMOVER_IMAGE_SHELF("revanced_hide_image_shelf", true, ReturnType.BOOLEAN), + ADREMOVER_BUTTONED_REMOVAL("revanced_adremover_buttoned", BOOLEAN, TRUE), + ADREMOVER_CHANNEL_BAR("revanced_hide_channel_bar", BOOLEAN, FALSE), + ADREMOVER_CHANNEL_MEMBER_SHELF_REMOVAL("revanced_adremover_channel_member_shelf_removal", BOOLEAN, TRUE), + ADREMOVER_CHAPTER_TEASER_REMOVAL("revanced_adremover_chapter_teaser", BOOLEAN, TRUE), + ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_community_guidelines", BOOLEAN, TRUE), + ADREMOVER_COMMUNITY_POSTS_REMOVAL("revanced_adremover_community_posts_removal", BOOLEAN, FALSE), + ADREMOVER_COMPACT_BANNER_REMOVAL("revanced_adremover_compact_banner_removal", BOOLEAN, TRUE), + ADREMOVER_CUSTOM_ENABLED("revanced_adremover_custom_enabled", BOOLEAN, FALSE), + ADREMOVER_CUSTOM_REMOVAL("revanced_adremover_custom_strings", STRING, "", true, parents(ADREMOVER_CUSTOM_ENABLED)), + ADREMOVER_EMERGENCY_BOX_REMOVAL("revanced_adremover_emergency_box_removal", BOOLEAN, TRUE), + ADREMOVER_FEED_SURVEY_REMOVAL("revanced_adremover_feed_survey", BOOLEAN, TRUE), + ADREMOVER_GENERAL_ADS_REMOVAL("revanced_adremover_ad_removal", BOOLEAN, TRUE), + ADREMOVER_GRAY_SEPARATOR("revanced_adremover_separator", BOOLEAN, TRUE), + ADREMOVER_HIDE_CHANNEL_GUIDELINES("revanced_adremover_hide_channel_guidelines", BOOLEAN, TRUE), + ADREMOVER_HIDE_LATEST_POSTS("revanced_adremover_hide_latest_posts", BOOLEAN, TRUE), + ADREMOVER_IMAGE_SHELF("revanced_hide_image_shelf", BOOLEAN, TRUE), + ADREMOVER_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", BOOLEAN, TRUE), + ADREMOVER_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", BOOLEAN, TRUE), + ADREMOVER_MERCHANDISE_REMOVAL("revanced_adremover_merchandise", BOOLEAN, TRUE), + ADREMOVER_MOVIE_REMOVAL("revanced_adremover_movie", BOOLEAN, TRUE), + ADREMOVER_PAID_CONTENT_REMOVAL("revanced_adremover_paid_content", BOOLEAN, TRUE), + ADREMOVER_QUICK_ACTIONS("revanced_hide_quick_actions", BOOLEAN, FALSE), + ADREMOVER_RELATED_VIDEOS("revanced_hide_related_videos", BOOLEAN, FALSE), + ADREMOVER_SELF_SPONSOR_REMOVAL("revanced_adremover_self_sponsor", BOOLEAN, TRUE), + ADREMOVER_SHORTS_REMOVAL("revanced_adremover_shorts", BOOLEAN, TRUE, true), + ADREMOVER_SUBSCRIBERS_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_subscribers_community_guidelines_removal", BOOLEAN, TRUE), + ADREMOVER_VIEW_PRODUCTS("revanced_adremover_view_products", BOOLEAN, TRUE), + ADREMOVER_WEB_SEARCH_RESULTS("revanced_adremover_web_search_result", BOOLEAN, TRUE), + VIDEO_ADS_REMOVAL("revanced_video_ads_removal", BOOLEAN, TRUE, true), // Action buttons - HIDE_LIKE_BUTTON("revanced_hide_like_button", false, ReturnType.BOOLEAN), - HIDE_DISLIKE_BUTTON("revanced_hide_dislike_button", false, ReturnType.BOOLEAN), - HIDE_DOWNLOAD_BUTTON("revanced_hide_download_button", false, ReturnType.BOOLEAN), - HIDE_PLAYLIST_BUTTON("revanced_hide_playlist_button", false, ReturnType.BOOLEAN), - HIDE_ACTION_BUTTON("revanced_hide_action_button", false, ReturnType.BOOLEAN), - HIDE_SHARE_BUTTON("revanced_hide_share_button", false, ReturnType.BOOLEAN), + HIDE_ACTION_BUTTON("revanced_hide_action_button", BOOLEAN, FALSE), + HIDE_DISLIKE_BUTTON("revanced_hide_dislike_button", BOOLEAN, FALSE), + HIDE_DOWNLOAD_BUTTON("revanced_hide_download_button", BOOLEAN, FALSE), + HIDE_LIKE_BUTTON("revanced_hide_like_button", BOOLEAN, FALSE), + HIDE_PLAYLIST_BUTTON("revanced_hide_playlist_button", BOOLEAN, FALSE), + HIDE_SHARE_BUTTON("revanced_hide_share_button", BOOLEAN, FALSE), // Layout settings - DISABLE_STARTUP_SHORTS_PLAYER("revanced_startup_shorts_player_enabled", false, ReturnType.BOOLEAN), - PLAYER_POPUP_PANELS("revanced_player_popup_panels_enabled", false, ReturnType.BOOLEAN), - USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", false, ReturnType.BOOLEAN, true), - SPOOF_APP_VERSION("revanced_spoof_app_version", false, ReturnType.BOOLEAN, true), - WIDE_SEARCHBAR("revanced_wide_searchbar", false, ReturnType.BOOLEAN, true), - HIDE_ALBUM_CARDS("revanced_hide_album_cards", false, ReturnType.BOOLEAN, true), - HIDE_ARTIST_CARDS("revanced_hide_artist_cards", false, ReturnType.BOOLEAN), - HIDE_AUTOPLAY_BUTTON("revanced_hide_autoplay_button", true, ReturnType.BOOLEAN, true), - HIDE_VIDEO_WATERMARK("revanced_hide_video_watermark", true, ReturnType.BOOLEAN), - HIDE_CAPTIONS_BUTTON("revanced_hide_captions_button", false, ReturnType.BOOLEAN), - HIDE_CAST_BUTTON("revanced_hide_cast_button", true, ReturnType.BOOLEAN, true), - HIDE_COMMENTS_SECTION("revanced_hide_comments_section", false, ReturnType.BOOLEAN, true), - HIDE_CREATE_BUTTON("revanced_hide_create_button", true, ReturnType.BOOLEAN, true), - HIDE_CROWDFUNDING_BOX("revanced_hide_crowdfunding_box", false, ReturnType.BOOLEAN, true), - HIDE_EMAIL_ADDRESS("revanced_hide_email_address", false, ReturnType.BOOLEAN), - HIDE_ENDSCREEN_CARDS("revanced_hide_endscreen_cards", true, ReturnType.BOOLEAN), - HIDE_FULLSCREEN_PANELS("revanced_hide_fullscreen_panels", true, ReturnType.BOOLEAN), //ToDo: Add to prefs - HIDE_INFO_CARDS("revanced_hide_infocards", true, ReturnType.BOOLEAN), - HIDE_MIX_PLAYLISTS("revanced_hide_mix_playlists", false, ReturnType.BOOLEAN, true), - HIDE_PREVIEW_COMMENT("revanced_hide_preview_comment", false, ReturnType.BOOLEAN, true), - HIDE_REEL_BUTTON("revanced_hide_reel_button", true, ReturnType.BOOLEAN, true), - HIDE_SHORTS_BUTTON("revanced_hide_shorts_button", true, ReturnType.BOOLEAN, true), - HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", false, ReturnType.BOOLEAN), - HIDE_TIMESTAMP("revanced_hide_timestamp", false, ReturnType.BOOLEAN), - HIDE_SEEKBAR("revanced_hide_seekbar", false, ReturnType.BOOLEAN), - HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", false, ReturnType.BOOLEAN, true), - HIDE_BREAKING_NEWS("revanced_hide_breaking_news", true, ReturnType.BOOLEAN, true), - HIDE_PLAYER_BUTTONS("revanced_hide_player_buttons", false, ReturnType.BOOLEAN), - HIDE_FLOATING_MICROPHONE_BUTTON("revanced_hide_floating_microphone_button", true, ReturnType.BOOLEAN, true), + DISABLE_STARTUP_SHORTS_PLAYER("revanced_startup_shorts_player_enabled", BOOLEAN, FALSE), + HIDE_ALBUM_CARDS("revanced_hide_album_cards", BOOLEAN, FALSE, true), + HIDE_ARTIST_CARDS("revanced_hide_artist_cards", BOOLEAN, FALSE), + HIDE_AUTOPLAY_BUTTON("revanced_hide_autoplay_button", BOOLEAN, TRUE, true), + HIDE_BREAKING_NEWS("revanced_hide_breaking_news", BOOLEAN, TRUE, true), + HIDE_CAPTIONS_BUTTON("revanced_hide_captions_button", BOOLEAN, FALSE), + HIDE_CAST_BUTTON("revanced_hide_cast_button", BOOLEAN, TRUE, true), + HIDE_COMMENTS_SECTION("revanced_hide_comments_section", BOOLEAN, FALSE, true), + HIDE_CREATE_BUTTON("revanced_hide_create_button", BOOLEAN, TRUE, true), + HIDE_CROWDFUNDING_BOX("revanced_hide_crowdfunding_box", BOOLEAN, FALSE, true), + HIDE_EMAIL_ADDRESS("revanced_hide_email_address", BOOLEAN, FALSE), + HIDE_ENDSCREEN_CARDS("revanced_hide_endscreen_cards", BOOLEAN, TRUE), + HIDE_FLOATING_MICROPHONE_BUTTON("revanced_hide_floating_microphone_button", BOOLEAN, TRUE, true), + HIDE_FULLSCREEN_PANELS("revanced_hide_fullscreen_panels", BOOLEAN, TRUE), + HIDE_INFO_CARDS("revanced_hide_infocards", BOOLEAN, TRUE), + HIDE_MIX_PLAYLISTS("revanced_hide_mix_playlists", BOOLEAN, FALSE, true), + HIDE_PLAYER_BUTTONS("revanced_hide_player_buttons", BOOLEAN, FALSE), + HIDE_PREVIEW_COMMENT("revanced_hide_preview_comment", BOOLEAN, FALSE, true), + HIDE_SEEKBAR("revanced_hide_seekbar", BOOLEAN, FALSE), + HIDE_SHORTS_BUTTON("revanced_hide_shorts_button", BOOLEAN, TRUE, true), + HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", BOOLEAN, FALSE), + HIDE_TIMESTAMP("revanced_hide_timestamp", BOOLEAN, FALSE), + HIDE_VIDEO_WATERMARK("revanced_hide_video_watermark", BOOLEAN, TRUE), + HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", BOOLEAN, FALSE, true), + PLAYER_POPUP_PANELS("revanced_player_popup_panels_enabled", BOOLEAN, FALSE), + SPOOF_APP_VERSION("revanced_spoof_app_version", BOOLEAN, FALSE, true, "revanced_spoof_app_version_user_dialog_message"), + USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", BOOLEAN, FALSE, true), + WIDE_SEARCHBAR("revanced_wide_searchbar", BOOLEAN, FALSE, true), // Misc. Settings - SIGNATURE_SPOOFING("revanced_spoof_signature_verification", true, ReturnType.BOOLEAN), - CAPTIONS_ENABLED("revanced_autocaptions_enabled", false, ReturnType.BOOLEAN), - PREFERRED_AUTO_REPEAT("revanced_pref_auto_repeat", false, ReturnType.BOOLEAN), - USE_HDR_AUTO_BRIGHTNESS("revanced_pref_hdr_autobrightness", true, ReturnType.BOOLEAN), - TAP_SEEKING_ENABLED("revanced_enable_tap_seeking", true, ReturnType.BOOLEAN), - ENABLE_MINIMIZED_PLAYBACK("revanced_enable_minimized_playback", true, ReturnType.BOOLEAN), - OPEN_LINKS_DIRECTLY("revanced_uri_redirect", true, ReturnType.BOOLEAN, true), - DISABLE_ZOOM_HAPTICS("revanced_disable_zoom_haptics", true, ReturnType.BOOLEAN), - ENABLE_EXTERNAL_BROWSER("revanced_enable_external_browser", true, ReturnType.BOOLEAN, true), + SIGNATURE_SPOOFING("revanced_spoof_signature_verification", BOOLEAN, TRUE, "revanced_spoof_signature_verification_user_dialog_message"), + CAPTIONS_ENABLED("revanced_autocaptions_enabled", BOOLEAN, FALSE), + DISABLE_ZOOM_HAPTICS("revanced_disable_zoom_haptics", BOOLEAN, TRUE), + ENABLE_EXTERNAL_BROWSER("revanced_enable_external_browser", BOOLEAN, TRUE, true), + ENABLE_MINIMIZED_PLAYBACK("revanced_enable_minimized_playback", BOOLEAN, TRUE), + PREFERRED_AUTO_REPEAT("revanced_pref_auto_repeat", BOOLEAN, FALSE), + TAP_SEEKING_ENABLED("revanced_enable_tap_seeking", BOOLEAN, TRUE), + USE_HDR_AUTO_BRIGHTNESS("revanced_pref_hdr_autobrightness", BOOLEAN, TRUE), // Swipe controls - ENABLE_SWIPE_BRIGHTNESS("revanced_enable_swipe_brightness", true, ReturnType.BOOLEAN), - ENABLE_SWIPE_VOLUME("revanced_enable_swipe_volume", true, ReturnType.BOOLEAN), - ENABLE_PRESS_TO_SWIPE("revanced_enable_press_to_swipe", false, ReturnType.BOOLEAN), - ENABLE_SWIPE_HAPTIC_FEEDBACK("revanced_enable_swipe_haptic_feedback", true, ReturnType.BOOLEAN), - SWIPE_OVERLAY_TIMEOUT("revanced_swipe_overlay_timeout", 500L, ReturnType.LONG), - SWIPE_OVERLAY_TEXT_SIZE("revanced_swipe_overlay_text_size", 22f, ReturnType.FLOAT), - SWIPE_OVERLAY_BACKGROUND_ALPHA("revanced_swipe_overlay_background_alpha", 127, ReturnType.INTEGER), - SWIPE_MAGNITUDE_THRESHOLD("revanced_swipe_magnitude_threshold", 30f, ReturnType.FLOAT), + ENABLE_SWIPE_BRIGHTNESS("revanced_enable_swipe_brightness", BOOLEAN, TRUE), + ENABLE_SWIPE_VOLUME("revanced_enable_swipe_volume", BOOLEAN, TRUE), + ENABLE_PRESS_TO_SWIPE("revanced_enable_press_to_swipe", BOOLEAN, FALSE, + parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)), + ENABLE_SWIPE_HAPTIC_FEEDBACK("revanced_enable_swipe_haptic_feedback", BOOLEAN, TRUE, + parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)), + SWIPE_MAGNITUDE_THRESHOLD("revanced_swipe_magnitude_threshold", FLOAT, 30f, + parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)), + SWIPE_OVERLAY_BACKGROUND_ALPHA("revanced_swipe_overlay_background_alpha", INTEGER, 127, + parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)), + SWIPE_OVERLAY_TEXT_SIZE("revanced_swipe_overlay_text_size", FLOAT, 22f, + parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)), + SWIPE_OVERLAY_TIMEOUT("revanced_swipe_overlay_timeout", LONG, 500L, + parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)), // Debug settings - DEBUG("revanced_debug_enabled", false, ReturnType.BOOLEAN), - DEBUG_STACKTRACE("revanced_debug_stacktrace_enabled", false, ReturnType.BOOLEAN), - DEBUG_SHOW_TOAST_ON_ERROR("revanced_debug_toast_on_error_enabled", true, ReturnType.BOOLEAN), + DEBUG("revanced_debug_enabled", BOOLEAN, FALSE), + DEBUG_STACKTRACE("revanced_debug_stacktrace_enabled", BOOLEAN, FALSE, parents(DEBUG)), + DEBUG_SHOW_TOAST_ON_ERROR("revanced_debug_toast_on_error_enabled", BOOLEAN, TRUE, "revanced_debug_toast_on_error_user_dialog_message"), - USE_DARK_THEME("app_theme_dark", false, ReturnType.BOOLEAN), - - // RYD settings - RYD_USER_ID("ryd_userId", null, SharedPrefHelper.SharedPrefNames.RYD, ReturnType.STRING), - RYD_ENABLED("ryd_enabled", true, SharedPrefHelper.SharedPrefNames.RYD, ReturnType.BOOLEAN), - RYD_SHOW_DISLIKE_PERCENTAGE("ryd_show_dislike_percentage", false, SharedPrefHelper.SharedPrefNames.RYD, ReturnType.BOOLEAN), - RYD_USE_COMPACT_LAYOUT("ryd_use_compact_layout", false, SharedPrefHelper.SharedPrefNames.RYD, ReturnType.BOOLEAN), + // ReturnYoutubeDislike settings + RYD_ENABLED("ryd_enabled", BOOLEAN, TRUE, RETURN_YOUTUBE_DISLIKE), + RYD_USER_ID("ryd_userId", STRING, "", RETURN_YOUTUBE_DISLIKE), + RYD_SHOW_DISLIKE_PERCENTAGE("ryd_show_dislike_percentage", BOOLEAN, FALSE, RETURN_YOUTUBE_DISLIKE, parents(RYD_ENABLED)), + RYD_USE_COMPACT_LAYOUT("ryd_use_compact_layout", BOOLEAN, FALSE, RETURN_YOUTUBE_DISLIKE, parents(RYD_ENABLED)), // SponsorBlock settings - SB_ENABLED("sb-enabled", true, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_VOTING_ENABLED("sb-voting-enabled", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_CREATE_NEW_SEGMENT_ENABLED("sb-new-segment-enabled", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_USE_COMPACT_SKIPBUTTON("sb-use-compact-skip-button", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_SHOW_TOAST_ON_SKIP("show-toast", true, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_TRACK_SKIP_COUNT("count-skips", true, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_UUID("uuid", "", SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.STRING), - SB_ADJUST_NEW_SEGMENT_STEP("new-segment-step-accuracy", 150, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.INTEGER), - SB_MIN_DURATION("sb-min-duration", 0F, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.FLOAT), - SB_SEEN_GUIDELINES("sb-seen-gl", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED("sb-skipped-segments", 0, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.INTEGER), - SB_SKIPPED_SEGMENTS_TIME_SAVED("sb-skipped-segments-time", 0L, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.LONG), - SB_SHOW_TIME_WITHOUT_SEGMENTS("sb-length-without-segments", true, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_IS_VIP("sb-is-vip", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), - SB_LAST_VIP_CHECK("sb-last-vip-check", 0L, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.LONG), - SB_API_URL("sb-api-host-url", "https://sponsor.ajay.app", SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.STRING); + SB_ENABLED("sb-enabled", BOOLEAN, TRUE, SPONSOR_BLOCK), + SB_VOTING_ENABLED("sb-voting-enabled", BOOLEAN, FALSE, SPONSOR_BLOCK, parents(SB_ENABLED)), + SB_CREATE_NEW_SEGMENT_ENABLED("sb-new-segment-enabled", BOOLEAN, FALSE, SPONSOR_BLOCK, parents(SB_ENABLED)), + SB_USE_COMPACT_SKIPBUTTON("sb-use-compact-skip-button", BOOLEAN, FALSE, SPONSOR_BLOCK, parents(SB_ENABLED)), + SB_SHOW_TOAST_ON_SKIP("show-toast", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)), + SB_TRACK_SKIP_COUNT("count-skips", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)), + SB_UUID("uuid", STRING, "", SPONSOR_BLOCK), + SB_ADJUST_NEW_SEGMENT_STEP("new-segment-step-accuracy", INTEGER, 150, SPONSOR_BLOCK, parents(SB_ENABLED)), + SB_MIN_DURATION("sb-min-duration", FLOAT, 0F, SPONSOR_BLOCK, parents(SB_ENABLED)), + SB_SEEN_GUIDELINES("sb-seen-gl", BOOLEAN, FALSE, SPONSOR_BLOCK), + SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED("sb-skipped-segments", INTEGER, 0, SPONSOR_BLOCK), + SB_SKIPPED_SEGMENTS_TIME_SAVED("sb-skipped-segments-time", LONG, 0L, SPONSOR_BLOCK), + SB_SHOW_TIME_WITHOUT_SEGMENTS("sb-length-without-segments", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)), + SB_IS_VIP("sb-is-vip", BOOLEAN, FALSE, SPONSOR_BLOCK), + SB_LAST_VIP_CHECK("sb-last-vip-check", LONG, 0L, SPONSOR_BLOCK), + SB_API_URL("sb-api-host-url", STRING, "https://sponsor.ajay.app", SPONSOR_BLOCK); - private final String path; - private final Object defaultValue; - private final SharedPrefHelper.SharedPrefNames sharedPref; - private final ReturnType returnType; - private final boolean rebootApp; + private static SettingsEnum[] parents(SettingsEnum ... parents) { + return parents; + } - // must be volatile, as some settings are read/write from different threads - // of note, the object value is persistently stored using SharedPreferences (which is thread safe) + @NonNull + public final String path; + @NonNull + public final Object defaultValue; + @NonNull + public final SharedPrefCategory sharedPref; + @NonNull + public final ReturnType returnType; + /** + * If the app should be rebooted, if this setting is changed + */ + public final boolean rebootApp; + /** + * Set of boolean parent settings. + * If any of the parents are enabled, then this setting is available to configure. + * + * For example: {@link #DEBUG_STACKTRACE} is non-functional and cannot be configured, + * unless it's parent {@link #DEBUG} is enabled. + * + * Declaration is not needed for items that do not appear in the ReVanced Settings UI. + */ + @Nullable + private final SettingsEnum[] parents; + + /** + * Confirmation message to display, if the user tries to change the setting from the default value. + * Can only be used for {@link ReturnType#BOOLEAN} setting types. + */ + @Nullable + public final StringRef userDialogMessage; + + // Must be volatile, as some settings are read/write from different threads. + // Of note, the object value is persistently stored using SharedPreferences (which is thread safe). + @NonNull private volatile Object value; - SettingsEnum(String path, Object defaultValue, ReturnType returnType) { - this(path, defaultValue, SharedPrefHelper.SharedPrefNames.YOUTUBE, returnType, false); + SettingsEnum(String path, ReturnType returnType, Object defaultValue) { + this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, null, null); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, + boolean rebootApp) { + this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, null,null); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, + String userDialogMessage) { + this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, userDialogMessage, null); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, + SettingsEnum[] parents) { + this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, null, parents); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, + boolean rebootApp, String userDialogMessage) { + this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, userDialogMessage, null); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, + boolean rebootApp, SettingsEnum[] parents) { + this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, null, parents); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, + boolean rebootApp, String userDialogMessage, SettingsEnum[] parents) { + this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, userDialogMessage, parents); } - SettingsEnum(String path, Object defaultValue, ReturnType returnType, boolean rebootApp) { - this(path, defaultValue, SharedPrefHelper.SharedPrefNames.YOUTUBE, returnType, rebootApp); + SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName) { + this(path, returnType, defaultValue, prefName, false, null, null); } - - SettingsEnum(String path, Object defaultValue, SharedPrefHelper.SharedPrefNames prefName, ReturnType returnType) { - this(path, defaultValue, prefName, returnType, false); + SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName, + boolean rebootApp) { + this(path, returnType, defaultValue, prefName, rebootApp, null, null); } - - SettingsEnum(String path, Object defaultValue, SharedPrefHelper.SharedPrefNames prefName, ReturnType returnType, boolean rebootApp) { - this.path = path; - this.defaultValue = defaultValue; - this.sharedPref = prefName; - this.returnType = returnType; + SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName, + String userDialogMessage) { + this(path, returnType, defaultValue, prefName, false, userDialogMessage, null); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName, + SettingsEnum[] parents) { + this(path, returnType, defaultValue, prefName, false, null, parents); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName, + boolean rebootApp, @Nullable String userDialogMessage, @Nullable SettingsEnum[] parents) { + this.path = Objects.requireNonNull(path); + this.returnType = Objects.requireNonNull(returnType); + this.value = this.defaultValue = Objects.requireNonNull(defaultValue); + this.sharedPref = Objects.requireNonNull(prefName); this.rebootApp = rebootApp; + + if (userDialogMessage == null) { + this.userDialogMessage = null; + } else { + if (returnType != ReturnType.BOOLEAN) { + throw new IllegalArgumentException("must be Boolean type: " + path); + } + this.userDialogMessage = new StringRef(userDialogMessage); + } + + this.parents = parents; + if (parents != null) { + for (SettingsEnum parent : parents) { + if (parent.returnType != ReturnType.BOOLEAN) { + throw new IllegalArgumentException("parent must be Boolean type: " + parent); + } + } + } } static { loadAllSettings(); } - private static void loadAllSettings() { - if (ReVancedUtils.getContext() == null) { - LogHelper.printException(() -> "SettingsEnum loaded before ReVancedUtils context was set"); - return; + @Nullable + public static SettingsEnum settingFromPath(@NonNull String str) { + for (SettingsEnum setting : values()) { + if (setting.path.equals(str)) return setting; } + return null; + } + + private static void loadAllSettings() { for (SettingsEnum setting : values()) { setting.load(); } @@ -192,64 +291,78 @@ public enum SettingsEnum { private void load() { switch (returnType) { - case FLOAT: - value = SharedPrefHelper.getFloat(sharedPref, path, (float) defaultValue); - break; - case LONG: - value = SharedPrefHelper.getLong(sharedPref, path, (long) defaultValue); - break; case BOOLEAN: - value = SharedPrefHelper.getBoolean(sharedPref, path, (boolean) defaultValue); + value = sharedPref.getBoolean(path, (boolean) defaultValue); break; case INTEGER: - value = SharedPrefHelper.getInt(sharedPref, path, (int) defaultValue); + value = sharedPref.getInt(path, (Integer) defaultValue); + break; + case LONG: + value = sharedPref.getLong(path, (Long) defaultValue); + break; + case FLOAT: + value = sharedPref.getFloat(path, (Float) defaultValue); break; case STRING: - value = SharedPrefHelper.getString(sharedPref, path, (String) defaultValue); + value = sharedPref.getString(path, (String) defaultValue); break; default: - LogHelper.printException(() -> "Setting does not have a valid Type: " + name()); - break; + throw new IllegalStateException(name()); } } /** * Sets, but does _not_ persistently save the value. * - * @see #saveValue(Object) + * This intentionally is a static method, to deter accidental usage + * when {@link #saveValue(Object)} was intended. */ - public void setValue(Object newValue) { - this.value = newValue; + public static void setValue(@NonNull SettingsEnum setting, @NonNull Object newValue) { + setting.value = Objects.requireNonNull(newValue); } /** - * Sets the value, and persistently saves it + * Sets the value, and persistently saves it. */ - public void saveValue(Object newValue) { + public void saveValue(@NonNull Object newValue) { + Objects.requireNonNull(newValue); switch (returnType) { - case FLOAT: - SharedPrefHelper.saveFloat(sharedPref, path, (float) newValue); - break; - case LONG: - SharedPrefHelper.saveLong(sharedPref, path, (long) newValue); - break; case BOOLEAN: - SharedPrefHelper.saveBoolean(sharedPref, path, (boolean) newValue); + sharedPref.saveBoolean(path, (boolean) newValue); break; case INTEGER: - SharedPrefHelper.saveInt(sharedPref, path, (int) newValue); + sharedPref.saveInt(path, (int) newValue); + break; + case LONG: + sharedPref.saveLong(path, (long) newValue); + break; + case FLOAT: + sharedPref.saveFloat(path, (float) newValue); break; case STRING: - SharedPrefHelper.saveString(sharedPref, path, (String) newValue); + sharedPref.saveString(path, (String) newValue); break; default: - LogHelper.printException(() -> "Setting does not have a valid Type: " + name()); - break; + throw new IllegalStateException(name()); } - value = newValue; } + /** + * @return if this setting can be configured and used. + * + * Not to be confused with {@link #getBoolean()} + */ + public boolean isAvailable() { + if (parents == null) { + return true; + } + for (SettingsEnum parent : parents) { + if (parent.getBoolean()) return true; + } + return false; + } + public boolean getBoolean() { return (Boolean) value; } @@ -266,23 +379,16 @@ public enum SettingsEnum { return (Float) value; } + @NonNull public String getString() { return (String) value; } - public Object getDefaultValue() { - return defaultValue; + public enum ReturnType { + BOOLEAN, + INTEGER, + STRING, + LONG, + FLOAT, } - - public String getPath() { - return path; - } - - public ReturnType getReturnType() { - return returnType; - } - - public boolean shouldRebootOnChange() { - return rebootApp; - } -} +} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/settings/SharedPrefCategory.java b/app/src/main/java/app/revanced/integrations/settings/SharedPrefCategory.java new file mode 100644 index 00000000..59413da3 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/settings/SharedPrefCategory.java @@ -0,0 +1,97 @@ +package app.revanced.integrations.settings; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; + +import java.util.Objects; + +import app.revanced.integrations.utils.ReVancedUtils; + +public enum SharedPrefCategory { + YOUTUBE("youtube"), + RETURN_YOUTUBE_DISLIKE("ryd"), + SPONSOR_BLOCK("sponsor-block"), + REVANCED_PREFS("revanced_prefs"); + + @NonNull + public final String prefName; + @NonNull + public final SharedPreferences preferences; + + SharedPrefCategory(@NonNull String prefName) { + this.prefName = Objects.requireNonNull(prefName); + preferences = Objects.requireNonNull(ReVancedUtils.getContext()).getSharedPreferences(prefName, Context.MODE_PRIVATE); + } + + public void saveString(@NonNull String key, @NonNull String value) { + Objects.requireNonNull(value); + preferences.edit().putString(key, value).apply(); + } + + public void saveBoolean(@NonNull String key, boolean value) { + preferences.edit().putBoolean(key, value).apply(); + } + + public void saveInt(@NonNull String key, int value) { + preferences.edit().putInt(key, value).apply(); + } + + public void saveLong(@NonNull String key, long value) { + preferences.edit().putLong(key, value).apply(); + } + + public void saveFloat(@NonNull String key, float value) { + preferences.edit().putFloat(key, value).apply(); + } + + + @NonNull + public String getString(@NonNull String key, @NonNull String _default) { + Objects.requireNonNull(_default); + return preferences.getString(key, _default); + } + + public boolean getBoolean(@NonNull String key, boolean _default) { + return preferences.getBoolean(key, _default); + } + + // region Hack, required for PreferencesFragments to function correctly. unknown why required + + @NonNull + public Integer getInt(@NonNull String key, @NonNull Integer _default) { + try { + return Integer.valueOf(preferences.getString(key, _default.toString())); + } catch (ClassCastException ex) { + return preferences.getInt(key, _default); + } + } + + @NonNull + public Long getLong(@NonNull String key, @NonNull Long _default) { + try { + return Long.valueOf(preferences.getString(key, _default.toString())); + } catch (ClassCastException ex) { + return preferences.getLong(key, _default); + } + } + + @NonNull + public Float getFloat(@NonNull String key, @NonNull Float _default) { + try { + return Float.valueOf(preferences.getString(key, _default.toString())); + } catch (ClassCastException ex) { + return preferences.getFloat(key, _default); + } + } + + // endregion + + + @NonNull + @Override + public String toString() { + return prefName; + } +} diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingActivity.java b/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingActivity.java index 898d21c9..cda92cb9 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingActivity.java +++ b/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingActivity.java @@ -16,6 +16,9 @@ import app.revanced.integrations.utils.ThemeHelper; public class ReVancedSettingActivity { + /** + * Injection point. + */ public static void setTheme(LicenseActivity base) { final var whiteTheme = "Theme.YouTube.Settings"; final var darkTheme = "Theme.YouTube.Settings.Dark"; @@ -26,6 +29,9 @@ public class ReVancedSettingActivity { base.setTheme(ReVancedUtils.getResourceIdentifier(theme, "style")); } + /** + * Injection point. + */ public static void initializeSettings(LicenseActivity base) { base.setContentView(ReVancedUtils.getResourceIdentifier("revanced_settings_with_toolbar", "layout")); diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java b/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java index 308f348d..43a240dd 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java +++ b/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java @@ -15,152 +15,148 @@ import android.os.Process; import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.PreferenceFragment; -import android.preference.PreferenceScreen; +import android.preference.PreferenceManager; import android.preference.SwitchPreference; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.google.android.apps.youtube.app.application.Shell_HomeActivity; -import java.util.List; - import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.settings.SharedPrefCategory; import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.SharedPrefHelper; public class ReVancedSettingsFragment extends PreferenceFragment { - - private List screens; - - private boolean Registered = false; - private boolean settingsInitialized = false; - - private final CharSequence[] videoSpeedEntries = {"Auto", "0.25x", "0.5x", "0.75x", "Normal", "1.25x", "1.5x", "1.75x", "2x", "3x", "4x", "5x"}; - private final CharSequence[] videoSpeedentryValues = {"-2", "0.25", "0.5", "0.75", "1.0", "1.25", "1.5", "1.75", "2.0", "3.0", "4.0", "5.0"}; - //private final CharSequence[] buttonLocationEntries = {"None", "In player", "Under player", "Both"}; - //private final CharSequence[] buttonLocationentryValues = {"NONE", "PLAYER", "BUTTON_BAR", "BOTH"}; + /** + * If a dialog is currently being shown. Used to prevent showing additional dialogs if user cancels a dialog. + */ + private static boolean currentlyShowingDialog; SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { - for (SettingsEnum setting : SettingsEnum.values()) { - if (!setting.getPath().equals(str)) continue; - Preference pref = this.findPreferenceOnScreen(str); - - LogHelper.printDebug(() -> "Setting " + setting.name() + " was changed. Preference " + str + ": " + pref.toString()); + try { + SettingsEnum setting = SettingsEnum.settingFromPath(str); + if (setting == null) { + return; + } + Preference pref = this.findPreference(str); + LogHelper.printDebug(() -> "Setting " + setting.name() + " was changed. Preference " + str + ": " + pref); if (pref instanceof SwitchPreference) { SwitchPreference switchPref = (SwitchPreference) pref; - setting.setValue(switchPref.isChecked()); + SettingsEnum.setValue(setting, switchPref.isChecked()); } else if (pref instanceof EditTextPreference) { - EditTextPreference editPref = (EditTextPreference) pref; - Object value = null; - switch (setting.getReturnType()) { - case FLOAT: - value = Float.parseFloat(editPref.getText()); + String editText = ((EditTextPreference) pref).getText(); + Object value; + switch (setting.returnType) { + case INTEGER: + value = Integer.parseInt(editText); break; case LONG: - value = Long.parseLong(editPref.getText()); + value = Long.parseLong(editText); + break; + case FLOAT: + value = Float.parseFloat(editText); break; case STRING: - value = editPref.getText(); - break; - case INTEGER: - value = Integer.parseInt(editPref.getText()); + value = editText; break; default: - LogHelper.printException(() -> "Setting has no valid return type! " + setting.getReturnType()); - break; + throw new IllegalStateException(setting.toString()); } - setting.setValue(value); + SettingsEnum.setValue(setting, value); } else { - LogHelper.printException(() -> "Setting cannot be handled: " + pref.getClass() + " " + pref.toString()); + LogHelper.printException(() -> "Setting cannot be handled: " + pref.getClass() + " " + pref); } - if (ReVancedUtils.getContext() != null && settingsInitialized && setting.shouldRebootOnChange()) { - rebootDialog(getActivity()); + if (!currentlyShowingDialog) { + if (setting.userDialogMessage != null && ((SwitchPreference) pref).isChecked() != (Boolean) setting.defaultValue) { + showSettingUserDialogConfirmation(getActivity(), (SwitchPreference) pref, setting); + } else if (setting.rebootApp) { + rebootDialog(getActivity()); + } } + + enableDisablePreferences(); + } catch (Exception ex) { + LogHelper.printException(() -> "OnSharedPreferenceChangeListener failure", ex); } }; @SuppressLint("ResourceType") - @Override // android.preference.PreferenceFragment, android.app.Fragment - public void onCreate(Bundle bundle) { - super.onCreate(bundle); - getPreferenceManager().setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.YOUTUBE.getName()); + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); try { + PreferenceManager preferenceManager = getPreferenceManager(); + preferenceManager.setSharedPreferencesName(SharedPrefCategory.YOUTUBE.prefName); addPreferencesFromResource(ReVancedUtils.getResourceIdentifier("revanced_prefs", "xml")); - SharedPreferences sharedPreferences = getPreferenceManager().getSharedPreferences(); - this.settingsInitialized = sharedPreferences.getBoolean("revanced_initialized", false); - sharedPreferences.registerOnSharedPreferenceChangeListener(this.listener); - this.Registered = true; + enableDisablePreferences(); - this.settingsInitialized = true; - } catch (Throwable th) { - LogHelper.printException(() -> "Error during onCreate()", th); + preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener); + } catch (Exception ex) { + LogHelper.printException(() -> "onActivityCreated() error", ex); } } @Override // android.preference.PreferenceFragment, android.app.Fragment public void onDestroy() { - if (this.Registered) { - getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this.listener); - this.Registered = false; - } + getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener); super.onDestroy(); } - private Preference findPreferenceOnScreen(CharSequence key) { - if (key == null) { - LogHelper.printException(() -> "Key cannot be null!"); - return null; - } - Preference pref = null; - if (this.findPreference(key) != null) { - pref = this.findPreference(key); - } else { - for (PreferenceScreen screen : this.screens) { - Preference toCheck = screen.findPreference(key); - if (toCheck == null) continue; - pref = toCheck; - LogHelper.printDebug(() -> "Found preference " + key + " on screen: " + screen.getTitle()); + private void enableDisablePreferences() { + for (SettingsEnum setting : SettingsEnum.values()) { + Preference preference = this.findPreference(setting.path); + if (preference != null) { + preference.setEnabled(setting.isAvailable()); } } - - return pref; } - /* - private void setCopyLinkListPreferenceData(ListPreference listPreference, String str) { - listPreference.setEntries(this.buttonLocationEntries); - listPreference.setEntryValues(this.buttonLocationentryValues); - String string = this.sharedPreferences.getString(str, "NONE"); - if (listPreference.getValue() == null) { - listPreference.setValue(string); - } - listPreference.setSummary(this.buttonLocationEntries[listPreference.findIndexOfValue(string)]); - } - */ - - private String getPackageName() { - Context context = ReVancedUtils.getContext(); - if (context == null) { - LogHelper.printException(() -> "Context is null, returning com.google.android.youtube!"); - return "com.google.android.youtube"; - } - String PACKAGE_NAME = context.getPackageName(); - LogHelper.printDebug(() -> "getPackageName: " + PACKAGE_NAME); - - return PACKAGE_NAME; - } - - private void reboot(Activity activity, Class homeActivityClass) { - int intent; - intent = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE; - ((AlarmManager) activity.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME, 1500L, PendingIntent.getActivity(activity, 0, new Intent(activity, Shell_HomeActivity.class), intent)); + private void reboot(@NonNull Activity activity) { + final int intentFlags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE; + PendingIntent intent = PendingIntent.getActivity(activity, 0, + new Intent(activity, Shell_HomeActivity.class), intentFlags); + AlarmManager systemService = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE); + systemService.setExact(AlarmManager.ELAPSED_REALTIME, 1500L, intent); Process.killProcess(Process.myPid()); } - private void rebootDialog(final Activity activity) { - new AlertDialog.Builder(activity).setMessage(str("pref_refresh_config")).setPositiveButton(str("in_app_update_restart_button"), (dialog, id) -> reboot(activity, Shell_HomeActivity.class)).setNegativeButton(str("sign_in_cancel"), null).show(); + private void rebootDialog(@NonNull Activity activity) { + currentlyShowingDialog = true; + String positiveButton = str("in_app_update_restart_button"); + String negativeButton = str("sign_in_cancel"); + new AlertDialog.Builder(activity).setMessage(str("pref_refresh_config")) + .setPositiveButton(positiveButton, (dialog, id) -> { + reboot(activity); + currentlyShowingDialog = false; + }) + .setNegativeButton(negativeButton, (dialog, id) -> { + currentlyShowingDialog = false; + }).show(); + } + + private void showSettingUserDialogConfirmation(@NonNull Activity activity, SwitchPreference switchPref, SettingsEnum setting) { + currentlyShowingDialog = true; + new AlertDialog.Builder(activity) + .setTitle(str("revanced_settings_confirm_user_dialog_title")) + .setMessage(setting.userDialogMessage.toString()) + .setPositiveButton(android.R.string.ok, (dialog, id) -> { + if (setting.rebootApp) { + rebootDialog(activity); + } else { + currentlyShowingDialog = false; + } + }) + .setNegativeButton(android.R.string.cancel, (dialog, id) -> { + Boolean defaultBooleanValue = (Boolean) setting.defaultValue; + SettingsEnum.setValue(setting, defaultBooleanValue); + switchPref.setChecked(defaultBooleanValue); + currentlyShowingDialog = false; + }).show(); } } diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ReturnYouTubeDislikeSettingsFragment.java b/app/src/main/java/app/revanced/integrations/settingsmenu/ReturnYouTubeDislikeSettingsFragment.java index 41d5eb21..6664861f 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ReturnYouTubeDislikeSettingsFragment.java +++ b/app/src/main/java/app/revanced/integrations/settingsmenu/ReturnYouTubeDislikeSettingsFragment.java @@ -15,7 +15,7 @@ import android.preference.SwitchPreference; import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike; import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.SharedPrefHelper; +import app.revanced.integrations.settings.SharedPrefCategory; public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment { @@ -35,27 +35,25 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment { private SwitchPreference compactLayoutPreference; private void updateUIState() { - final boolean rydIsEnabled = SettingsEnum.RYD_ENABLED.getBoolean(); - - enabledPreference.setSummary(rydIsEnabled + enabledPreference.setSummary(SettingsEnum.RYD_ENABLED.getBoolean() ? str("revanced_ryd_enable_summary_on") : str("revanced_ryd_enable_summary_off")); percentagePreference.setSummary(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean() ? str("revanced_ryd_dislike_percentage_summary_on") : str("revanced_ryd_dislike_percentage_summary_off")); - percentagePreference.setEnabled(rydIsEnabled); + percentagePreference.setEnabled(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.isAvailable()); compactLayoutPreference.setSummary(SettingsEnum.RYD_USE_COMPACT_LAYOUT.getBoolean() ? str("revanced_ryd_compact_layout_summary_on") : str("revanced_ryd_compact_layout_summary_off")); - compactLayoutPreference.setEnabled(rydIsEnabled); + compactLayoutPreference.setEnabled(SettingsEnum.RYD_USE_COMPACT_LAYOUT.isAvailable()); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getPreferenceManager().setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.RYD.getName()); + getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.RETURN_YOUTUBE_DISLIKE.prefName); Activity context = this.getActivity(); PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context); @@ -78,7 +76,7 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment { percentagePreference.setChecked(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean()); percentagePreference.setTitle(str("revanced_ryd_dislike_percentage_title")); percentagePreference.setOnPreferenceChangeListener((pref, newValue) -> { - SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.saveValue((Boolean)newValue); + SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.saveValue(newValue); updateUIState(); return true; @@ -89,7 +87,7 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment { compactLayoutPreference.setChecked(SettingsEnum.RYD_USE_COMPACT_LAYOUT.getBoolean()); compactLayoutPreference.setTitle(str("revanced_ryd_compact_layout_title")); compactLayoutPreference.setOnPreferenceChangeListener((pref, newValue) -> { - SettingsEnum.RYD_USE_COMPACT_LAYOUT.saveValue((Boolean)newValue); + SettingsEnum.RYD_USE_COMPACT_LAYOUT.saveValue(newValue); updateUIState(); return true; diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/SponsorBlockSettingsFragment.java b/app/src/main/java/app/revanced/integrations/settingsmenu/SponsorBlockSettingsFragment.java index f1c1bbff..05da518b 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/SponsorBlockSettingsFragment.java +++ b/app/src/main/java/app/revanced/integrations/settingsmenu/SponsorBlockSettingsFragment.java @@ -28,6 +28,7 @@ import androidx.annotation.Nullable; import java.text.DecimalFormat; import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.settings.SharedPrefCategory; import app.revanced.integrations.sponsorblock.SegmentPlaybackController; import app.revanced.integrations.sponsorblock.SponsorBlockSettings; import app.revanced.integrations.sponsorblock.SponsorBlockUtils; @@ -38,7 +39,6 @@ import app.revanced.integrations.sponsorblock.requests.SBRequester; import app.revanced.integrations.sponsorblock.ui.SponsorBlockViewController; import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.SharedPrefHelper; @SuppressWarnings("deprecation") public class SponsorBlockSettingsFragment extends PreferenceFragment { @@ -115,7 +115,7 @@ public class SponsorBlockSettingsFragment extends PreferenceFragment { super.onCreate(savedInstanceState); try { PreferenceManager preferenceManager = getPreferenceManager(); - preferenceManager.setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK.getName()); + preferenceManager.setSharedPreferencesName(SharedPrefCategory.SPONSOR_BLOCK.prefName); Activity context = this.getActivity(); PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(context); @@ -304,7 +304,7 @@ public class SponsorBlockSettingsFragment extends PreferenceFragment { DialogInterface.OnClickListener urlChangeListener = (dialog, buttonPressed) -> { if (buttonPressed == DialogInterface.BUTTON_NEUTRAL) { - SettingsEnum.SB_API_URL.saveValue(SettingsEnum.SB_API_URL.getDefaultValue()); + SettingsEnum.SB_API_URL.saveValue(SettingsEnum.SB_API_URL.defaultValue); ReVancedUtils.showToastLong(str("sb_api_url_reset")); } else if (buttonPressed == DialogInterface.BUTTON_POSITIVE) { String serverAddress = editText.getText().toString(); @@ -522,8 +522,8 @@ public class SponsorBlockSettingsFragment extends PreferenceFragment { new AlertDialog.Builder(preference1.getContext()) .setTitle(str("sb_stats_self_saved_reset_title")) .setPositiveButton(android.R.string.yes, (dialog, whichButton) -> { - SettingsEnum.SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED.saveValue(SettingsEnum.SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED.getDefaultValue()); - SettingsEnum.SB_SKIPPED_SEGMENTS_TIME_SAVED.saveValue(SettingsEnum.SB_SKIPPED_SEGMENTS_TIME_SAVED.getDefaultValue()); + SettingsEnum.SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED.saveValue(SettingsEnum.SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED.defaultValue); + SettingsEnum.SB_SKIPPED_SEGMENTS_TIME_SAVED.saveValue(SettingsEnum.SB_SKIPPED_SEGMENTS_TIME_SAVED.defaultValue); updateStatsSelfSaved.run(); }) .setNegativeButton(android.R.string.no, null).show(); diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockSettings.java b/app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockSettings.java index 22923d55..f8f4fffa 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockSettings.java +++ b/app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockSettings.java @@ -14,11 +14,11 @@ import org.json.JSONObject; import java.util.UUID; import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.settings.SharedPrefCategory; import app.revanced.integrations.sponsorblock.objects.CategoryBehaviour; import app.revanced.integrations.sponsorblock.objects.SegmentCategory; import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.SharedPrefHelper; public class SponsorBlockSettings { @@ -55,7 +55,7 @@ public class SponsorBlockSettings { } SegmentCategory.updateEnabledCategories(); - SharedPreferences.Editor editor = SharedPrefHelper.getPreferences(SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK).edit(); + SharedPreferences.Editor editor = SharedPrefCategory.SPONSOR_BLOCK.preferences.edit(); for (SegmentCategory category : SegmentCategory.valuesWithoutUnsubmitted()) { category.save(editor); } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategory.java b/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategory.java index f23160a0..a11703da 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategory.java +++ b/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategory.java @@ -21,8 +21,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import app.revanced.integrations.settings.SharedPrefCategory; import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.SharedPrefHelper; import app.revanced.integrations.utils.StringRef; public enum SegmentCategory { @@ -84,7 +84,7 @@ public enum SegmentCategory { } public static void loadFromPreferences() { - SharedPreferences preferences = SharedPrefHelper.getPreferences(SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK); + SharedPreferences preferences = SharedPrefCategory.SPONSOR_BLOCK.preferences; LogHelper.printDebug(() -> "loadFromPreferences"); for (SegmentCategory category : valuesWithoutUnsubmitted()) { category.load(preferences); diff --git a/app/src/main/java/app/revanced/integrations/utils/SharedPrefHelper.java b/app/src/main/java/app/revanced/integrations/utils/SharedPrefHelper.java deleted file mode 100644 index d792bc07..00000000 --- a/app/src/main/java/app/revanced/integrations/utils/SharedPrefHelper.java +++ /dev/null @@ -1,94 +0,0 @@ -package app.revanced.integrations.utils; - -import android.content.Context; -import android.content.SharedPreferences; - -import java.util.Objects; - -public class SharedPrefHelper { - public static void saveString(SharedPrefNames prefName, String key, String value) { - getPreferences(prefName).edit().putString(key, value).apply(); - } - - public static void saveBoolean(SharedPrefNames prefName, String key, boolean value) { - getPreferences(prefName).edit().putBoolean(key, value).apply(); - } - - public static void saveFloat(SharedPrefNames prefName, String key, float value) { - getPreferences(prefName).edit().putFloat(key, value).apply(); - } - - public static void saveInt(SharedPrefNames prefName, String key, int value) { - getPreferences(prefName).edit().putInt(key, value).apply(); - } - - public static void saveLong(SharedPrefNames prefName, String key, long value) { - getPreferences(prefName).edit().putLong(key, value).apply(); - } - - public static String getString(SharedPrefNames prefName, String key, String _default) { - return getPreferences(prefName).getString(key, _default); - } - - public static boolean getBoolean(SharedPrefNames prefName, String key, boolean _default) { - return getPreferences(prefName).getBoolean(key, _default); - } - - // region Hack, unknown why required - - public static Long getLong(SharedPrefNames prefName, String key, long _default) { - SharedPreferences sharedPreferences = getPreferences(prefName); - try { - return Long.valueOf(sharedPreferences.getString(key, _default + "")); - } catch (ClassCastException ex) { - return sharedPreferences.getLong(key, _default); - } - } - - public static Float getFloat(SharedPrefNames prefName, String key, float _default) { - SharedPreferences sharedPreferences = getPreferences(prefName); - try { - return Float.valueOf(sharedPreferences.getString(key, _default + "")); - } catch (ClassCastException ex) { - return sharedPreferences.getFloat(key, _default); - } - } - - public static Integer getInt(SharedPrefNames prefName, String key, int _default) { - SharedPreferences sharedPreferences = getPreferences(prefName); - try { - return Integer.valueOf(sharedPreferences.getString(key, _default + "")); - } catch (ClassCastException ex) { - return sharedPreferences.getInt(key, _default); - } - } - - // endregion - - public static SharedPreferences getPreferences(SharedPrefNames name) { - return Objects.requireNonNull(ReVancedUtils.getContext()).getSharedPreferences(name.getName(), Context.MODE_PRIVATE); - } - - public enum SharedPrefNames { - - YOUTUBE("youtube"), - RYD("ryd"), - SPONSOR_BLOCK("sponsor-block"), - REVANCED_PREFS("revanced_prefs"); - - private final String name; - - SharedPrefNames(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - } -} diff --git a/app/src/main/java/app/revanced/tiktok/settings/ReturnType.java b/app/src/main/java/app/revanced/tiktok/settings/ReturnType.java deleted file mode 100644 index bd64c8ea..00000000 --- a/app/src/main/java/app/revanced/tiktok/settings/ReturnType.java +++ /dev/null @@ -1,5 +0,0 @@ -package app.revanced.tiktok.settings; - -public enum ReturnType { - BOOLEAN, INTEGER, STRING, LONG, FLOAT -} diff --git a/app/src/main/java/app/revanced/tiktok/settings/SettingsEnum.java b/app/src/main/java/app/revanced/tiktok/settings/SettingsEnum.java index a114b429..2318c869 100644 --- a/app/src/main/java/app/revanced/tiktok/settings/SettingsEnum.java +++ b/app/src/main/java/app/revanced/tiktok/settings/SettingsEnum.java @@ -1,104 +1,112 @@ package app.revanced.tiktok.settings; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static app.revanced.tiktok.settings.SettingsEnum.ReturnType.BOOLEAN; +import static app.revanced.tiktok.settings.SettingsEnum.ReturnType.STRING; + import android.content.Context; import android.util.Log; +import androidx.annotation.NonNull; + import app.revanced.tiktok.utils.LogHelper; import app.revanced.tiktok.utils.ReVancedUtils; -import app.revanced.tiktok.utils.SharedPrefHelper; public enum SettingsEnum { //TikTok Settings - TIK_REMOVE_ADS("tik_remove_ads", true, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN, true), - TIK_HIDE_LIVE("tik_hide_live", false, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN, true), - TIK_DOWN_PATH("tik_down_path", "DCIM/TikTok", SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.STRING), - TIK_DOWN_WATERMARK("tik_down_watermark", true, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN), - TIK_SIMSPOOF("tik_simspoof", true, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN, true), - TIK_SIMSPOOF_ISO("tik_simspoof_iso", "us", SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.STRING), - TIK_SIMSPOOF_MCCMNC("tik_simspoof_mccmnc", "310160", SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.STRING), - TIK_SIMSPOOF_OP_NAME("tik_simspoof_op_name", "T-Mobile", SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.STRING), - TIK_DEBUG("tik_debug", false, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN); + TIK_DEBUG("tik_debug", BOOLEAN, FALSE), // must be first value, otherwise logging during loading will not work + TIK_REMOVE_ADS("tik_remove_ads", BOOLEAN, TRUE, true), + TIK_HIDE_LIVE("tik_hide_live", BOOLEAN, FALSE, true), + TIK_DOWN_PATH("tik_down_path", STRING, "DCIM/TikTok"), + TIK_DOWN_WATERMARK("tik_down_watermark", BOOLEAN, TRUE), + TIK_SIMSPOOF("tik_simspoof", BOOLEAN, TRUE, true), + TIK_SIMSPOOF_ISO("tik_simspoof_iso", STRING, "us"), + TIK_SIMSPOOF_MCCMNC("tik_simspoof_mccmnc", STRING, "310160"), + TIK_SIMSPOOF_OP_NAME("tik_simspoof_op_name", STRING, "T-Mobile"); static { - load(); + loadAllSettings(); } - private final String path; - private final Object defaultValue; - private final SharedPrefHelper.SharedPrefNames sharedPref; - private final ReturnType returnType; - private final boolean rebootApp; - private Object value = null; + @NonNull + public final String path; + @NonNull + public final Object defaultValue; + @NonNull + public final SharedPrefCategory sharedPref; + @NonNull + public final ReturnType returnType; + /** + * If the app should be rebooted, if this setting is changed + */ + public final boolean rebootApp; - SettingsEnum(String path, Object defaultValue, ReturnType returnType) { + private Object value; + + SettingsEnum(String path, ReturnType returnType, Object defaultValue) { + this(path, returnType, defaultValue, SharedPrefCategory.TIKTOK_PREFS, false); + } + SettingsEnum(String path, ReturnType returnType, Object defaultValue, boolean rebootApp) { + this(path, returnType, defaultValue, SharedPrefCategory.TIKTOK_PREFS, rebootApp); + } + SettingsEnum(@NonNull String path, @NonNull ReturnType returnType, @NonNull Object defaultValue, + @NonNull SharedPrefCategory prefName, boolean rebootApp) { this.path = path; - this.defaultValue = defaultValue; - this.sharedPref = SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS; this.returnType = returnType; - this.rebootApp = false; - } - - SettingsEnum(String path, Object defaultValue, SharedPrefHelper.SharedPrefNames prefName, ReturnType returnType) { - this.path = path; this.defaultValue = defaultValue; this.sharedPref = prefName; - this.returnType = returnType; - this.rebootApp = false; - } - - SettingsEnum(String path, Object defaultValue, SharedPrefHelper.SharedPrefNames prefName, ReturnType returnType, Boolean rebootApp) { - this.path = path; - this.defaultValue = defaultValue; - this.sharedPref = prefName; - this.returnType = returnType; this.rebootApp = rebootApp; } - private static void load() { - Context context = ReVancedUtils.getAppContext(); - if (context == null) { - Log.e("revanced: SettingsEnum", "Context returned null! Setings NOT initialized"); - } else { - try { - for (SettingsEnum setting : values()) { - Object value = setting.getDefaultValue(); - - //LogHelper is not initialized here - Log.d("revanced: SettingsEnum", "Loading Setting: " + setting.name()); - - switch (setting.getReturnType()) { - case FLOAT: - value = SharedPrefHelper.getFloat(context, setting.sharedPref, setting.getPath(), (float) setting.getDefaultValue()); - break; - case LONG: - value = SharedPrefHelper.getLong(context, setting.sharedPref, setting.getPath(), (long) setting.getDefaultValue()); - break; - case BOOLEAN: - value = SharedPrefHelper.getBoolean(context, setting.sharedPref, setting.getPath(), (boolean) setting.getDefaultValue()); - break; - case INTEGER: - value = SharedPrefHelper.getInt(context, setting.sharedPref, setting.getPath(), (int) setting.getDefaultValue()); - break; - case STRING: - value = SharedPrefHelper.getString(context, setting.sharedPref, setting.getPath(), (String) setting.getDefaultValue()); - break; - default: - LogHelper.printException(SettingsEnum.class, "Setting does not have a valid Type. Name is: " + setting.name()); - break; - } - setting.setValue(value); - - //LogHelper is not initialized here - Log.d("revanced: SettingsEnum", "Loaded Setting: " + setting.name() + " Value: " + value); - } - } catch (Throwable th) { - LogHelper.printException(SettingsEnum.class, "Error during load()!", th); + private static void loadAllSettings() { + try { + Context context = ReVancedUtils.getAppContext(); + if (context == null) { + Log.e("revanced: SettingsEnum", "Context returned null! Settings NOT initialized"); + return; } + for (SettingsEnum setting : values()) { + setting.load(context); + } + } catch (Exception ex) { + LogHelper.printException(SettingsEnum.class, "Error during load()!", ex); } } - public void setValue(Object newValue) { - this.value = newValue; + private void load(Context context) { + switch (returnType) { + case BOOLEAN: + value = sharedPref.getBoolean(context, path, (boolean) defaultValue); + break; + case INTEGER: + value = sharedPref.getInt(context, path, (Integer) defaultValue); + break; + case LONG: + value = sharedPref.getLong(context, path, (Long) defaultValue); + break; + case FLOAT: + value = sharedPref.getFloat(context, path, (Float) defaultValue); + break; + case STRING: + value = sharedPref.getString(context, path, (String) defaultValue); + break; + default: + throw new IllegalStateException(name()); + } + + LogHelper.debug(SettingsEnum.class, "Loaded Setting: " + name() + " Value: " + value); + } + + /** + * Sets, but does _not_ persistently save the value. + * + * This intentionally is a static method, to deter accidental usage + * when {@link #saveValue(Object)} was intended. + */ + public static void setValue(SettingsEnum setting, Object newValue) { + // FIXME: this should validate the parameter matches the return type + setting.value = newValue; } public void saveValue(Object newValue) { @@ -108,48 +116,39 @@ public enum SettingsEnum { return; } - if (returnType == ReturnType.BOOLEAN) { - SharedPrefHelper.saveBoolean(context, sharedPref, path, (Boolean) newValue); + if (returnType == BOOLEAN) { + sharedPref.saveBoolean(context, path, (Boolean) newValue); } else { - SharedPrefHelper.saveString(context, sharedPref, path, newValue + ""); + sharedPref.saveString(context, path, newValue.toString()); } value = newValue; } - public int getInt() { - return (int) value; - } - - public String getString() { - return (String) value; - } - public boolean getBoolean() { return (Boolean) value; } - public Long getLong() { + public int getInt() { + return (Integer) value; + } + + public long getLong() { return (Long) value; } - public Float getFloat() { + public float getFloat() { return (Float) value; } - public Object getDefaultValue() { - return defaultValue; + public String getString() { + return (String) value; } - public String getPath() { - return path; + public enum ReturnType { + BOOLEAN, + INTEGER, + LONG, + FLOAT, + STRING, } - - public ReturnType getReturnType() { - return returnType; - } - - public boolean shouldRebootOnChange() { - return rebootApp; - } - } diff --git a/app/src/main/java/app/revanced/tiktok/settings/SharedPrefCategory.java b/app/src/main/java/app/revanced/tiktok/settings/SharedPrefCategory.java new file mode 100644 index 00000000..79160ba1 --- /dev/null +++ b/app/src/main/java/app/revanced/tiktok/settings/SharedPrefCategory.java @@ -0,0 +1,71 @@ +package app.revanced.tiktok.settings; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; + +public enum SharedPrefCategory { + TIKTOK_PREFS("tiktok_revanced"); + + @NonNull + public final String prefName; + + SharedPrefCategory(@NonNull String prefName) { + this.prefName = prefName; + } + + @NonNull + @Override + public String toString() { + return prefName; + } + + private SharedPreferences getPreferences(Context context) { + return context.getSharedPreferences(prefName, Context.MODE_PRIVATE); + } + + public void saveBoolean(Context context, String key, boolean value) { + getPreferences(context).edit().putBoolean(key, value).apply(); + } + + public void saveString(Context context, String key, String value) { + getPreferences(context).edit().putString(key, value).apply(); + } + + public boolean getBoolean(Context context, String key, boolean _default) { + return getPreferences(context).getBoolean(key, _default); + } + + public Integer getInt(Context context, String key, Integer _default) { + SharedPreferences sharedPreferences = getPreferences(context); + try { + return Integer.valueOf(sharedPreferences.getString(key, _default.toString())); + } catch (ClassCastException ex) { + return sharedPreferences.getInt(key, _default); + } + } + + public Long getLong(Context context, String key, Long _default) { + SharedPreferences sharedPreferences = getPreferences(context); + try { + return Long.valueOf(sharedPreferences.getString(key, _default.toString())); + } catch (ClassCastException ex) { + return sharedPreferences.getLong(key, _default); + } + } + + public Float getFloat(Context context, String key, Float _default) { + SharedPreferences sharedPreferences = getPreferences(context); + try { + return Float.valueOf(sharedPreferences.getString(key, _default.toString())); + } catch (ClassCastException ex) { + return sharedPreferences.getFloat(key, _default); + } + } + + public String getString(Context context, String key, String _default) { + return getPreferences(context).getString(key, _default); + } + +} diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/ReVancedSettingsFragment.java b/app/src/main/java/app/revanced/tiktok/settingsmenu/ReVancedSettingsFragment.java index bb66c254..0febb987 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/ReVancedSettingsFragment.java +++ b/app/src/main/java/app/revanced/tiktok/settingsmenu/ReVancedSettingsFragment.java @@ -21,9 +21,9 @@ import androidx.annotation.Nullable; import com.ss.android.ugc.aweme.splash.SplashActivity; import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.tiktok.settings.SharedPrefCategory; import app.revanced.tiktok.settingsmenu.preference.DownloadPathPreference; import app.revanced.tiktok.utils.ReVancedUtils; -import app.revanced.tiktok.utils.SharedPrefHelper; public class ReVancedSettingsFragment extends PreferenceFragment { @@ -32,9 +32,9 @@ public class ReVancedSettingsFragment extends PreferenceFragment { SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { for (SettingsEnum setting : SettingsEnum.values()) { - if (!setting.getPath().equals(str)) continue; + if (!setting.path.equals(str)) continue; - if (ReVancedUtils.getAppContext() != null && this.settingsInitialized && setting.shouldRebootOnChange()) { + if (ReVancedUtils.getAppContext() != null && this.settingsInitialized && setting.rebootApp) { rebootDialog(getActivity()); } } @@ -43,7 +43,7 @@ public class ReVancedSettingsFragment extends PreferenceFragment { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getPreferenceManager().setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS.getName()); + getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.TIKTOK_PREFS.prefName); getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this.listener); this.Registered = true; @@ -61,12 +61,14 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { SwitchPreference preference = new SwitchPreference(context); feedFilter.addPreference(preference); - preference.setKey(SettingsEnum.TIK_REMOVE_ADS.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_REMOVE_ADS.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_REMOVE_ADS.path); + preference.setDefaultValue(SettingsEnum.TIK_REMOVE_ADS.defaultValue); preference.setChecked(SettingsEnum.TIK_REMOVE_ADS.getBoolean()); preference.setTitle("Remove feed ads"); preference.setSummary("Remove ads from feed."); preference.setOnPreferenceChangeListener((pref, newValue) -> { + // FIXME: the value is already saved in the preferences. + // instead of saving again, simple call SettingsEnum#setValue() final boolean value = (Boolean) newValue; SettingsEnum.TIK_REMOVE_ADS.saveValue(value); return true; @@ -76,8 +78,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { SwitchPreference preference = new SwitchPreference(context); feedFilter.addPreference(preference); - preference.setKey(SettingsEnum.TIK_HIDE_LIVE.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_HIDE_LIVE.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_HIDE_LIVE.path); + preference.setDefaultValue(SettingsEnum.TIK_HIDE_LIVE.defaultValue); preference.setChecked(SettingsEnum.TIK_HIDE_LIVE.getBoolean()); preference.setTitle("Hide livestreams"); preference.setSummary("Hide livestreams from feed."); @@ -98,8 +100,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { DownloadPathPreference preference = new DownloadPathPreference(context); download.addPreference(preference); - preference.setKey(SettingsEnum.TIK_DOWN_PATH.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_DOWN_PATH.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_DOWN_PATH.path); + preference.setDefaultValue(SettingsEnum.TIK_DOWN_PATH.defaultValue); preference.setValue(SettingsEnum.TIK_DOWN_PATH.getString()); preference.setTitle("Download path"); preference.setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + preference.getValue()); @@ -113,8 +115,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { SwitchPreference preference = new SwitchPreference(context); download.addPreference(preference); - preference.setKey(SettingsEnum.TIK_DOWN_WATERMARK.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_DOWN_WATERMARK.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_DOWN_WATERMARK.path); + preference.setDefaultValue(SettingsEnum.TIK_DOWN_WATERMARK.defaultValue); preference.setChecked(SettingsEnum.TIK_DOWN_WATERMARK.getBoolean()); preference.setTitle("Remove watermark"); preference.setOnPreferenceChangeListener((pref, newValue) -> { @@ -134,8 +136,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { SwitchPreference preference = new SwitchPreference(context); simSpoof.addPreference(preference); - preference.setKey(SettingsEnum.TIK_SIMSPOOF.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_SIMSPOOF.path); + preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF.defaultValue); preference.setChecked(SettingsEnum.TIK_SIMSPOOF.getBoolean()); preference.setTitle("Fake sim card info"); preference.setSummary("Bypass regional restriction by fake sim card information."); @@ -149,8 +151,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { EditTextPreference preference = new EditTextPreference(context); simSpoof.addPreference(preference); - preference.setKey(SettingsEnum.TIK_SIMSPOOF_ISO.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_ISO.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_SIMSPOOF_ISO.path); + preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_ISO.defaultValue); preference.setText(SettingsEnum.TIK_SIMSPOOF_ISO.getString()); preference.setTitle("Country ISO"); preference.setSummary("us, uk, jp, ..."); @@ -164,8 +166,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { EditTextPreference preference = new EditTextPreference(context); simSpoof.addPreference(preference); - preference.setKey(SettingsEnum.TIK_SIMSPOOF_MCCMNC.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_MCCMNC.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_SIMSPOOF_MCCMNC.path); + preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_MCCMNC.defaultValue); preference.setText(SettingsEnum.TIK_SIMSPOOF_MCCMNC.getString()); preference.setTitle("Operator mcc+mnc"); preference.setSummary("mcc+mnc"); @@ -179,8 +181,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { EditTextPreference preference = new EditTextPreference(context); simSpoof.addPreference(preference); - preference.setKey(SettingsEnum.TIK_SIMSPOOF_OP_NAME.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_OP_NAME.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_SIMSPOOF_OP_NAME.path); + preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_OP_NAME.defaultValue); preference.setText(SettingsEnum.TIK_SIMSPOOF_OP_NAME.getString()); preference.setTitle("Operator name"); preference.setSummary("Name of the operator"); @@ -200,8 +202,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment { { SwitchPreference preference = new SwitchPreference(context); integration.addPreference(preference); - preference.setKey(SettingsEnum.TIK_DEBUG.getPath()); - preference.setDefaultValue(SettingsEnum.TIK_DEBUG.getDefaultValue()); + preference.setKey(SettingsEnum.TIK_DEBUG.path); + preference.setDefaultValue(SettingsEnum.TIK_DEBUG.defaultValue); preference.setChecked(SettingsEnum.TIK_DEBUG.getBoolean()); preference.setTitle("Enable debug log"); preference.setSummary("Show integration debug log."); diff --git a/app/src/main/java/app/revanced/tiktok/utils/SharedPrefHelper.java b/app/src/main/java/app/revanced/tiktok/utils/SharedPrefHelper.java deleted file mode 100644 index ff9dd0ec..00000000 --- a/app/src/main/java/app/revanced/tiktok/utils/SharedPrefHelper.java +++ /dev/null @@ -1,82 +0,0 @@ -package app.revanced.tiktok.utils; - -import android.content.Context; -import android.content.SharedPreferences; - -public class SharedPrefHelper { - public static void saveString(Context context, SharedPrefNames prefName, String key, String value) { - SharedPreferences sharedPreferences = getPreferences(context, prefName); - sharedPreferences.edit().putString(key, value).apply(); - } - - public static void saveBoolean(Context context, SharedPrefNames prefName, String key, Boolean value) { - SharedPreferences sharedPreferences = getPreferences(context, prefName); - sharedPreferences.edit().putBoolean(key, value).apply(); - } - - public static String getString(Context context, SharedPrefNames prefName, String key, String _default) { - SharedPreferences sharedPreferences = getPreferences(context, prefName); - return (sharedPreferences.getString(key, _default)); - } - - public static Boolean getBoolean(Context context, SharedPrefNames prefName, String key, Boolean _default) { - SharedPreferences sharedPreferences = getPreferences(context, prefName); - return (sharedPreferences.getBoolean(key, _default)); - } - - public static Long getLong(Context context, SharedPrefNames prefName, String key, Long _default) { - SharedPreferences sharedPreferences = getPreferences(context, prefName); - try { - return Long.valueOf(sharedPreferences.getString(key, _default + "")); - } catch (ClassCastException ex) { - return sharedPreferences.getLong(key, _default); - } - } - - public static Float getFloat(Context context, SharedPrefNames prefName, String key, Float _default) { - SharedPreferences sharedPreferences = getPreferences(context, prefName); - try { - return Float.valueOf(sharedPreferences.getString(key, _default + "")); - } catch (ClassCastException ex) { - return sharedPreferences.getFloat(key, _default); - } - } - - public static Integer getInt(Context context, SharedPrefNames prefName, String key, Integer _default) { - SharedPreferences sharedPreferences = getPreferences(context, prefName); - try { - return Integer.valueOf(sharedPreferences.getString(key, _default + "")); - } catch (ClassCastException ex) { - return sharedPreferences.getInt(key, _default); - } - } - - public static SharedPreferences getPreferences(Context context, SharedPrefNames name) { - if (context == null) return null; - return context.getSharedPreferences(name.getName(), Context.MODE_PRIVATE); - } - - public static SharedPreferences getPreferences(Context context, String name) { - if (context == null) return null; - return context.getSharedPreferences(name, Context.MODE_PRIVATE); - } - - public enum SharedPrefNames { - TIKTOK_PREFS("tiktok_revanced"); - - private final String name; - - SharedPrefNames(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - } -} diff --git a/app/src/main/java/app/revanced/twitch/settings/ReturnType.java b/app/src/main/java/app/revanced/twitch/settings/ReturnType.java deleted file mode 100644 index 142c4a1f..00000000 --- a/app/src/main/java/app/revanced/twitch/settings/ReturnType.java +++ /dev/null @@ -1,5 +0,0 @@ -package app.revanced.twitch.settings; - -public enum ReturnType { - BOOLEAN, INTEGER, STRING, LONG, FLOAT -} diff --git a/app/src/main/java/app/revanced/twitch/settings/SettingsEnum.java b/app/src/main/java/app/revanced/twitch/settings/SettingsEnum.java index fdb48ba9..9103f654 100644 --- a/app/src/main/java/app/revanced/twitch/settings/SettingsEnum.java +++ b/app/src/main/java/app/revanced/twitch/settings/SettingsEnum.java @@ -1,150 +1,163 @@ package app.revanced.twitch.settings; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static app.revanced.twitch.settings.SettingsEnum.ReturnType.BOOLEAN; +import static app.revanced.twitch.settings.SettingsEnum.ReturnType.STRING; + import android.content.Context; import android.content.SharedPreferences; +import androidx.annotation.NonNull; + import app.revanced.twitch.utils.LogHelper; import app.revanced.twitch.utils.ReVancedUtils; public enum SettingsEnum { /* Ads */ - BLOCK_VIDEO_ADS("revanced_block_video_ads", true, ReturnType.BOOLEAN), - BLOCK_AUDIO_ADS("revanced_block_audio_ads", true, ReturnType.BOOLEAN), - BLOCK_EMBEDDED_ADS("revanced_block_embedded_ads", "ttv-lol", ReturnType.STRING), + BLOCK_VIDEO_ADS("revanced_block_video_ads", BOOLEAN, TRUE), + BLOCK_AUDIO_ADS("revanced_block_audio_ads", BOOLEAN, TRUE), + BLOCK_EMBEDDED_ADS("revanced_block_embedded_ads", STRING, "ttv-lol"), /* Chat */ - SHOW_DELETED_MESSAGES("revanced_show_deleted_messages", "cross-out", ReturnType.STRING), + SHOW_DELETED_MESSAGES("revanced_show_deleted_messages", STRING, "cross-out"), /* Misc */ - DEBUG_MODE("revanced_debug_mode", false, ReturnType.BOOLEAN, true); + DEBUG_MODE("revanced_debug_mode", BOOLEAN, FALSE, true); public static final String REVANCED_PREFS = "revanced_prefs"; - private final String path; - private final Object defaultValue; - private final ReturnType returnType; - private final boolean rebootApp; + @NonNull + public final String path; + @NonNull + public final ReturnType returnType; + @NonNull + public final Object defaultValue; + /** + * If the app should be rebooted, if this setting is changed + */ + public final boolean rebootApp; - private Object value = null; + private Object value; - SettingsEnum(String path, Object defaultValue, ReturnType returnType) { - this.path = path; - this.defaultValue = defaultValue; - this.returnType = returnType; - this.rebootApp = false; + SettingsEnum(String path, ReturnType returnType, Object defaultValue) { + this(path, returnType, defaultValue, false); } - SettingsEnum(String path, Object defaultValue, ReturnType returnType, Boolean rebootApp) { + SettingsEnum(@NonNull String path, @NonNull ReturnType returnType, @NonNull Object defaultValue, boolean rebootApp) { this.path = path; - this.defaultValue = defaultValue; this.returnType = returnType; + this.defaultValue = defaultValue; this.rebootApp = rebootApp; } static { - load(); + loadAllSettings(); } - private static void load() { + private static void loadAllSettings() { ReVancedUtils.ifContextAttached((context -> { try { SharedPreferences prefs = context.getSharedPreferences(REVANCED_PREFS, Context.MODE_PRIVATE); for (SettingsEnum setting : values()) { - Object value = setting.getDefaultValue(); - - try { - switch (setting.getReturnType()) { - case BOOLEAN: - value = prefs.getBoolean(setting.getPath(), (boolean)setting.getDefaultValue()); - break; - // Numbers are implicitly converted from strings - case FLOAT: - case LONG: - case INTEGER: - case STRING: - value = prefs.getString(setting.getPath(), setting.getDefaultValue() + ""); - break; - default: - LogHelper.error("Setting '%s' does not have a valid type", setting.name()); - break; - } - } - catch (ClassCastException ex) { - LogHelper.printException("Failed to read value", ex); - } - - setting.setValue(value); - LogHelper.debug("Loaded setting '%s' with value %s", setting.name(), value); + setting.load(prefs); } - } catch (Throwable th) { - LogHelper.printException("Failed to load settings", th); + } catch (Exception ex) { + LogHelper.printException("Failed to load settings", ex); } })); } - public void setValue(Object newValue) { + private void load(SharedPreferences prefs) { + try { + switch (returnType) { + case BOOLEAN: + setValue(prefs.getBoolean(path, (Boolean) defaultValue)); + break; + // Numbers are implicitly converted from strings + case INTEGER: + case LONG: + case FLOAT: + case STRING: + setValue(prefs.getString(path, defaultValue.toString())); + break; + default: + throw new IllegalStateException(name()); + } + LogHelper.debug("Loaded setting '%s' with value %s", name(), value); + } catch (ClassCastException ex) { + LogHelper.printException("Failed to read value", ex); + } + } + + /** + * Sets, but does _not_ persistently save the value. + * + * This intentionally is a static method, to deter accidental usage + * when {@link #saveValue(Object)} was intended. + */ + public static void setValue(SettingsEnum setting, Object newValue) { + setting.setValue(newValue); + } + + private void setValue(Object newValue) { // Implicitly convert strings to numbers depending on the ResultType switch (returnType) { case FLOAT: - value = Float.valueOf(newValue + ""); + value = Float.valueOf(newValue.toString()); break; case LONG: - value = Long.valueOf(newValue + ""); + value = Long.valueOf(newValue.toString()); break; case INTEGER: - value = Integer.valueOf(newValue + ""); + value = Integer.valueOf(newValue.toString()); break; - default: + case BOOLEAN: + case STRING: value = newValue; break; + default: + throw new IllegalArgumentException(name()); } } public void saveValue(Object newValue) { ReVancedUtils.ifContextAttached((context) -> { SharedPreferences prefs = context.getSharedPreferences(REVANCED_PREFS, Context.MODE_PRIVATE); - if (returnType == ReturnType.BOOLEAN) { + if (returnType == BOOLEAN) { prefs.edit().putBoolean(path, (Boolean)newValue).apply(); } else { - prefs.edit().putString(path, newValue + "").apply(); + prefs.edit().putString(path, newValue.toString()).apply(); } - value = newValue; + setValue(newValue); }); } - public int getInt() { - return (int) value; - } - - public String getString() { - return (String) value; - } - public boolean getBoolean() { return (Boolean) value; } - public Long getLong() { + public int getInt() { + return (Integer) value; + } + + public long getLong() { return (Long) value; } - public Float getFloat() { + public float getFloat() { return (Float) value; } - public Object getDefaultValue() { - return defaultValue; + public String getString() { + return (String) value; } - public String getPath() { - return path; - } - - public ReturnType getReturnType() { - return returnType; - } - - public boolean shouldRebootOnChange() { - return rebootApp; + public enum ReturnType { + BOOLEAN, + INTEGER, + LONG, + FLOAT, + STRING, } } diff --git a/app/src/main/java/app/revanced/twitch/settingsmenu/ReVancedSettingsFragment.java b/app/src/main/java/app/revanced/twitch/settingsmenu/ReVancedSettingsFragment.java index e18246d3..1da3eacd 100644 --- a/app/src/main/java/app/revanced/twitch/settingsmenu/ReVancedSettingsFragment.java +++ b/app/src/main/java/app/revanced/twitch/settingsmenu/ReVancedSettingsFragment.java @@ -22,7 +22,6 @@ import androidx.annotation.Nullable; import app.revanced.twitch.settings.SettingsEnum; import app.revanced.twitch.utils.LogHelper; import app.revanced.twitch.utils.ReVancedUtils; - import tv.twitch.android.app.core.LandingActivity; public class ReVancedSettingsFragment extends PreferenceFragment { @@ -41,28 +40,28 @@ public class ReVancedSettingsFragment extends PreferenceFragment { */ private void syncPreference(@Nullable String key) { for (SettingsEnum setting : SettingsEnum.values()) { - if (!setting.getPath().equals(key) && key != null) + if (!setting.path.equals(key) && key != null) continue; - Preference pref = this.findPreference(setting.getPath()); - LogHelper.debug("Syncing setting '%s' with UI", setting.getPath()); + Preference pref = this.findPreference(setting.path); + LogHelper.debug("Syncing setting '%s' with UI", setting.path); if (pref instanceof SwitchPreference) { - setting.setValue(((SwitchPreference) pref).isChecked()); + SettingsEnum.setValue(setting, ((SwitchPreference) pref).isChecked()); } else if (pref instanceof EditTextPreference) { - setting.setValue(((EditTextPreference) pref).getText()); + SettingsEnum.setValue(setting, ((EditTextPreference) pref).getText()); } else if (pref instanceof ListPreference) { ListPreference listPref = (ListPreference) pref; listPref.setSummary(listPref.getEntry()); - setting.setValue(listPref.getValue()); + SettingsEnum.setValue(setting, listPref.getValue()); } else { LogHelper.error("Setting '%s' cannot be handled!", pref); } - if (ReVancedUtils.getContext() != null && key != null && settingsInitialized && setting.shouldRebootOnChange()) { + if (ReVancedUtils.getContext() != null && key != null && settingsInitialized && setting.rebootApp) { rebootDialog(getActivity()); }