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 <semantic-release-bot@martynus.net>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
LisoUseInAIKyrios 2023-04-05 12:24:55 +04:00 committed by oSumAtrIX
parent d4de3f6819
commit a0ad968aaa
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
21 changed files with 800 additions and 730 deletions

View File

@ -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);
}
}
}

View File

@ -8,13 +8,12 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import app.revanced.integrations.settings.SettingsEnum; import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.settings.SharedPrefCategory;
import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils; import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.utils.ReVancedUtils.NetworkType; import app.revanced.integrations.utils.ReVancedUtils.NetworkType;
import app.revanced.integrations.utils.SharedPrefHelper;
public class RememberVideoQualityPatch { public class RememberVideoQualityPatch {
public static int selectedQuality1 = -2; public static int selectedQuality1 = -2;
private static Boolean newVideo = false; private static Boolean newVideo = false;
private static Boolean userChangedQuality = false; private static Boolean userChangedQuality = false;
@ -35,7 +34,7 @@ public class RememberVideoQualityPatch {
preferenceKey = "mobile_quality"; 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); ReVancedUtils.showToastShort("Changing default " + networkTypeMessage + " quality to: " + defaultQuality);
} }
@ -94,7 +93,7 @@ public class RememberVideoQualityPatch {
var preferenceKey = "wifi_quality"; var preferenceKey = "wifi_quality";
if (networkType == NetworkType.MOBILE) preferenceKey = "mobile_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; if (preferredQuality == -2) return quality;
for (int streamQuality2 : iStreamQualities) { for (int streamQuality2 : iStreamQualities) {

View File

@ -36,7 +36,7 @@ public final class RememberPlaybackSpeedPatch {
// TODO: extract these strings into localized file // TODO: extract these strings into localized file
ReVancedUtils.showToastLong("Remembering playback speed: " + playbackSpeed + "x"); 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"); ReVancedUtils.showToastLong("Applying playback speed: " + playbackSpeed + "x");
} }
} }

View File

@ -1,10 +0,0 @@
package app.revanced.integrations.settings;
public enum ReturnType {
BOOLEAN,
INTEGER,
STRING,
LONG,
FLOAT;
}

View File

@ -1,190 +1,289 @@
package app.revanced.integrations.settings; package app.revanced.integrations.settings;
import app.revanced.integrations.utils.LogHelper; import static java.lang.Boolean.FALSE;
import app.revanced.integrations.utils.ReVancedUtils; import static java.lang.Boolean.TRUE;
import app.revanced.integrations.utils.SharedPrefHelper; 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 { public enum SettingsEnum {
//Download Settings //Download Settings
// TODO: DOWNLOAD_PATH("revanced_download_path", Environment.getExternalStorageDirectory().getPath() + "/Download", ReturnType.STRING), // TODO: DOWNLOAD_PATH("revanced_download_path", STRING, Environment.getExternalStorageDirectory().getPath() + "/Download"),
DOWNLOADS_BUTTON_SHOWN("revanced_downloads_enabled", true, ReturnType.BOOLEAN, true), DOWNLOADS_BUTTON_SHOWN("revanced_downloads_enabled", BOOLEAN, TRUE, true),
DOWNLOADS_PACKAGE_NAME("revanced_downloads_package_name", "org.schabi.newpipe" /* NewPipe */, ReturnType.STRING), DOWNLOADS_PACKAGE_NAME("revanced_downloads_package_name", STRING, "org.schabi.newpipe" /* NewPipe */, parents(DOWNLOADS_BUTTON_SHOWN)),
// Copy video URL settings // Copy video URL settings
COPY_VIDEO_URL_BUTTON_SHOWN("revanced_copy_video_url_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", true, ReturnType.BOOLEAN, true), COPY_VIDEO_URL_TIMESTAMP_BUTTON_SHOWN("revanced_copy_video_url_timestamp_enabled", BOOLEAN, TRUE, true),
// Video settings // Video settings
OLD_STYLE_VIDEO_QUALITY_PLAYER_SETTINGS("revanced_use_old_style_quality_settings", true, ReturnType.BOOLEAN), 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", true, ReturnType.BOOLEAN), REMEMBER_VIDEO_QUALITY_LAST_SELECTED("revanced_remember_video_quality_last_selected", BOOLEAN, TRUE),
REMEMBER_PLAYBACK_SPEED_LAST_SELECTED("revanced_remember_playback_speed_last_selected", true, ReturnType.BOOLEAN), 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", 1.0f, ReturnType.FLOAT), REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_VALUE("revanced_remember_playback_speed_last_selected_value", FLOAT, 1.0f),
// TODO: Unused currently // TODO: Unused currently
// Whitelist settings // Whitelist settings
ENABLE_WHITELIST("revanced_whitelist_ads_enabled", false, ReturnType.BOOLEAN), //ENABLE_WHITELIST("revanced_whitelist_ads_enabled", BOOLEAN, FALSE),
// Ad settings // Ad settings
ADREMOVER_CUSTOM_ENABLED("revanced_adremover_custom_enabled", false, ReturnType.BOOLEAN), ADREMOVER_BUTTONED_REMOVAL("revanced_adremover_buttoned", BOOLEAN, TRUE),
ADREMOVER_CUSTOM_REMOVAL("revanced_adremover_custom_strings", "", ReturnType.STRING, true), ADREMOVER_CHANNEL_BAR("revanced_hide_channel_bar", BOOLEAN, FALSE),
VIDEO_ADS_REMOVAL("revanced_video_ads_removal", true, ReturnType.BOOLEAN, true), ADREMOVER_CHANNEL_MEMBER_SHELF_REMOVAL("revanced_adremover_channel_member_shelf_removal", BOOLEAN, TRUE),
ADREMOVER_GENERAL_ADS_REMOVAL("revanced_adremover_ad_removal", true, ReturnType.BOOLEAN), ADREMOVER_CHAPTER_TEASER_REMOVAL("revanced_adremover_chapter_teaser", BOOLEAN, TRUE),
ADREMOVER_MERCHANDISE_REMOVAL("revanced_adremover_merchandise", true, ReturnType.BOOLEAN), ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_community_guidelines", BOOLEAN, TRUE),
ADREMOVER_COMMUNITY_POSTS_REMOVAL("revanced_adremover_community_posts_removal", false, ReturnType.BOOLEAN), ADREMOVER_COMMUNITY_POSTS_REMOVAL("revanced_adremover_community_posts_removal", BOOLEAN, FALSE),
ADREMOVER_COMPACT_BANNER_REMOVAL("revanced_adremover_compact_banner_removal", true, ReturnType.BOOLEAN), ADREMOVER_COMPACT_BANNER_REMOVAL("revanced_adremover_compact_banner_removal", BOOLEAN, TRUE),
ADREMOVER_MOVIE_REMOVAL("revanced_adremover_movie", true, ReturnType.BOOLEAN), ADREMOVER_CUSTOM_ENABLED("revanced_adremover_custom_enabled", BOOLEAN, FALSE),
ADREMOVER_FEED_SURVEY_REMOVAL("revanced_adremover_feed_survey", true, ReturnType.BOOLEAN), ADREMOVER_CUSTOM_REMOVAL("revanced_adremover_custom_strings", STRING, "", true, parents(ADREMOVER_CUSTOM_ENABLED)),
ADREMOVER_SHORTS_REMOVAL("revanced_adremover_shorts", true, ReturnType.BOOLEAN, true), ADREMOVER_EMERGENCY_BOX_REMOVAL("revanced_adremover_emergency_box_removal", BOOLEAN, TRUE),
ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_community_guidelines", true, ReturnType.BOOLEAN), ADREMOVER_FEED_SURVEY_REMOVAL("revanced_adremover_feed_survey", BOOLEAN, TRUE),
ADREMOVER_SUBSCRIBERS_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_subscribers_community_guidelines_removal", true, ReturnType.BOOLEAN), ADREMOVER_GENERAL_ADS_REMOVAL("revanced_adremover_ad_removal", BOOLEAN, TRUE),
ADREMOVER_CHANNEL_MEMBER_SHELF_REMOVAL("revanced_adremover_channel_member_shelf_removal", true, ReturnType.BOOLEAN), ADREMOVER_GRAY_SEPARATOR("revanced_adremover_separator", BOOLEAN, TRUE),
ADREMOVER_EMERGENCY_BOX_REMOVAL("revanced_adremover_emergency_box_removal", true, ReturnType.BOOLEAN), ADREMOVER_HIDE_CHANNEL_GUIDELINES("revanced_adremover_hide_channel_guidelines", BOOLEAN, TRUE),
ADREMOVER_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", true, ReturnType.BOOLEAN), ADREMOVER_HIDE_LATEST_POSTS("revanced_adremover_hide_latest_posts", BOOLEAN, TRUE),
ADREMOVER_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", true, ReturnType.BOOLEAN), ADREMOVER_IMAGE_SHELF("revanced_hide_image_shelf", BOOLEAN, TRUE),
ADREMOVER_PAID_CONTENT_REMOVAL("revanced_adremover_paid_content", true, ReturnType.BOOLEAN), ADREMOVER_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", BOOLEAN, TRUE),
ADREMOVER_HIDE_LATEST_POSTS("revanced_adremover_hide_latest_posts", true, ReturnType.BOOLEAN), ADREMOVER_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", BOOLEAN, TRUE),
ADREMOVER_HIDE_CHANNEL_GUIDELINES("revanced_adremover_hide_channel_guidelines", true, ReturnType.BOOLEAN), ADREMOVER_MERCHANDISE_REMOVAL("revanced_adremover_merchandise", BOOLEAN, TRUE),
ADREMOVER_SELF_SPONSOR_REMOVAL("revanced_adremover_self_sponsor", true, ReturnType.BOOLEAN), ADREMOVER_MOVIE_REMOVAL("revanced_adremover_movie", BOOLEAN, TRUE),
ADREMOVER_CHAPTER_TEASER_REMOVAL("revanced_adremover_chapter_teaser", true, ReturnType.BOOLEAN), ADREMOVER_PAID_CONTENT_REMOVAL("revanced_adremover_paid_content", BOOLEAN, TRUE),
ADREMOVER_BUTTONED_REMOVAL("revanced_adremover_buttoned", true, ReturnType.BOOLEAN), ADREMOVER_QUICK_ACTIONS("revanced_hide_quick_actions", BOOLEAN, FALSE),
ADREMOVER_GRAY_SEPARATOR("revanced_adremover_separator", true, ReturnType.BOOLEAN), ADREMOVER_RELATED_VIDEOS("revanced_hide_related_videos", BOOLEAN, FALSE),
ADREMOVER_VIEW_PRODUCTS("revanced_adremover_view_products", true, ReturnType.BOOLEAN), ADREMOVER_SELF_SPONSOR_REMOVAL("revanced_adremover_self_sponsor", BOOLEAN, TRUE),
ADREMOVER_WEB_SEARCH_RESULTS("revanced_adremover_web_search_result", true, ReturnType.BOOLEAN), ADREMOVER_SHORTS_REMOVAL("revanced_adremover_shorts", BOOLEAN, TRUE, true),
ADREMOVER_CHANNEL_BAR("revanced_hide_channel_bar", false, ReturnType.BOOLEAN), ADREMOVER_SUBSCRIBERS_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_subscribers_community_guidelines_removal", BOOLEAN, TRUE),
ADREMOVER_QUICK_ACTIONS("revanced_hide_quick_actions", false, ReturnType.BOOLEAN), ADREMOVER_VIEW_PRODUCTS("revanced_adremover_view_products", BOOLEAN, TRUE),
ADREMOVER_RELATED_VIDEOS("revanced_hide_related_videos", false, ReturnType.BOOLEAN), ADREMOVER_WEB_SEARCH_RESULTS("revanced_adremover_web_search_result", BOOLEAN, TRUE),
ADREMOVER_IMAGE_SHELF("revanced_hide_image_shelf", true, ReturnType.BOOLEAN), VIDEO_ADS_REMOVAL("revanced_video_ads_removal", BOOLEAN, TRUE, true),
// Action buttons // Action buttons
HIDE_LIKE_BUTTON("revanced_hide_like_button", false, ReturnType.BOOLEAN), HIDE_ACTION_BUTTON("revanced_hide_action_button", BOOLEAN, FALSE),
HIDE_DISLIKE_BUTTON("revanced_hide_dislike_button", false, ReturnType.BOOLEAN), HIDE_DISLIKE_BUTTON("revanced_hide_dislike_button", BOOLEAN, FALSE),
HIDE_DOWNLOAD_BUTTON("revanced_hide_download_button", false, ReturnType.BOOLEAN), HIDE_DOWNLOAD_BUTTON("revanced_hide_download_button", BOOLEAN, FALSE),
HIDE_PLAYLIST_BUTTON("revanced_hide_playlist_button", false, ReturnType.BOOLEAN), HIDE_LIKE_BUTTON("revanced_hide_like_button", BOOLEAN, FALSE),
HIDE_ACTION_BUTTON("revanced_hide_action_button", false, ReturnType.BOOLEAN), HIDE_PLAYLIST_BUTTON("revanced_hide_playlist_button", BOOLEAN, FALSE),
HIDE_SHARE_BUTTON("revanced_hide_share_button", false, ReturnType.BOOLEAN), HIDE_SHARE_BUTTON("revanced_hide_share_button", BOOLEAN, FALSE),
// Layout settings // Layout settings
DISABLE_STARTUP_SHORTS_PLAYER("revanced_startup_shorts_player_enabled", false, ReturnType.BOOLEAN), DISABLE_STARTUP_SHORTS_PLAYER("revanced_startup_shorts_player_enabled", BOOLEAN, FALSE),
PLAYER_POPUP_PANELS("revanced_player_popup_panels_enabled", false, ReturnType.BOOLEAN), HIDE_ALBUM_CARDS("revanced_hide_album_cards", BOOLEAN, FALSE, true),
USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", false, ReturnType.BOOLEAN, true), HIDE_ARTIST_CARDS("revanced_hide_artist_cards", BOOLEAN, FALSE),
SPOOF_APP_VERSION("revanced_spoof_app_version", false, ReturnType.BOOLEAN, true), HIDE_AUTOPLAY_BUTTON("revanced_hide_autoplay_button", BOOLEAN, TRUE, true),
WIDE_SEARCHBAR("revanced_wide_searchbar", false, ReturnType.BOOLEAN, true), HIDE_BREAKING_NEWS("revanced_hide_breaking_news", BOOLEAN, TRUE, true),
HIDE_ALBUM_CARDS("revanced_hide_album_cards", false, ReturnType.BOOLEAN, true), HIDE_CAPTIONS_BUTTON("revanced_hide_captions_button", BOOLEAN, FALSE),
HIDE_ARTIST_CARDS("revanced_hide_artist_cards", false, ReturnType.BOOLEAN), HIDE_CAST_BUTTON("revanced_hide_cast_button", BOOLEAN, TRUE, true),
HIDE_AUTOPLAY_BUTTON("revanced_hide_autoplay_button", true, ReturnType.BOOLEAN, true), HIDE_COMMENTS_SECTION("revanced_hide_comments_section", BOOLEAN, FALSE, true),
HIDE_VIDEO_WATERMARK("revanced_hide_video_watermark", true, ReturnType.BOOLEAN), HIDE_CREATE_BUTTON("revanced_hide_create_button", BOOLEAN, TRUE, true),
HIDE_CAPTIONS_BUTTON("revanced_hide_captions_button", false, ReturnType.BOOLEAN), HIDE_CROWDFUNDING_BOX("revanced_hide_crowdfunding_box", BOOLEAN, FALSE, true),
HIDE_CAST_BUTTON("revanced_hide_cast_button", true, ReturnType.BOOLEAN, true), HIDE_EMAIL_ADDRESS("revanced_hide_email_address", BOOLEAN, FALSE),
HIDE_COMMENTS_SECTION("revanced_hide_comments_section", false, ReturnType.BOOLEAN, true), HIDE_ENDSCREEN_CARDS("revanced_hide_endscreen_cards", BOOLEAN, TRUE),
HIDE_CREATE_BUTTON("revanced_hide_create_button", true, ReturnType.BOOLEAN, true), HIDE_FLOATING_MICROPHONE_BUTTON("revanced_hide_floating_microphone_button", BOOLEAN, TRUE, true),
HIDE_CROWDFUNDING_BOX("revanced_hide_crowdfunding_box", false, ReturnType.BOOLEAN, true), HIDE_FULLSCREEN_PANELS("revanced_hide_fullscreen_panels", BOOLEAN, TRUE),
HIDE_EMAIL_ADDRESS("revanced_hide_email_address", false, ReturnType.BOOLEAN), HIDE_INFO_CARDS("revanced_hide_infocards", BOOLEAN, TRUE),
HIDE_ENDSCREEN_CARDS("revanced_hide_endscreen_cards", true, ReturnType.BOOLEAN), HIDE_MIX_PLAYLISTS("revanced_hide_mix_playlists", BOOLEAN, FALSE, true),
HIDE_FULLSCREEN_PANELS("revanced_hide_fullscreen_panels", true, ReturnType.BOOLEAN), //ToDo: Add to prefs HIDE_PLAYER_BUTTONS("revanced_hide_player_buttons", BOOLEAN, FALSE),
HIDE_INFO_CARDS("revanced_hide_infocards", true, ReturnType.BOOLEAN), HIDE_PREVIEW_COMMENT("revanced_hide_preview_comment", BOOLEAN, FALSE, true),
HIDE_MIX_PLAYLISTS("revanced_hide_mix_playlists", false, ReturnType.BOOLEAN, true), HIDE_SEEKBAR("revanced_hide_seekbar", BOOLEAN, FALSE),
HIDE_PREVIEW_COMMENT("revanced_hide_preview_comment", false, ReturnType.BOOLEAN, true), HIDE_SHORTS_BUTTON("revanced_hide_shorts_button", BOOLEAN, TRUE, true),
HIDE_REEL_BUTTON("revanced_hide_reel_button", true, ReturnType.BOOLEAN, true), HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", BOOLEAN, FALSE),
HIDE_SHORTS_BUTTON("revanced_hide_shorts_button", true, ReturnType.BOOLEAN, true), HIDE_TIMESTAMP("revanced_hide_timestamp", BOOLEAN, FALSE),
HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", false, ReturnType.BOOLEAN), HIDE_VIDEO_WATERMARK("revanced_hide_video_watermark", BOOLEAN, TRUE),
HIDE_TIMESTAMP("revanced_hide_timestamp", false, ReturnType.BOOLEAN), HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", BOOLEAN, FALSE, true),
HIDE_SEEKBAR("revanced_hide_seekbar", false, ReturnType.BOOLEAN), PLAYER_POPUP_PANELS("revanced_player_popup_panels_enabled", BOOLEAN, FALSE),
HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", false, ReturnType.BOOLEAN, true), SPOOF_APP_VERSION("revanced_spoof_app_version", BOOLEAN, FALSE, true, "revanced_spoof_app_version_user_dialog_message"),
HIDE_BREAKING_NEWS("revanced_hide_breaking_news", true, ReturnType.BOOLEAN, true), USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", BOOLEAN, FALSE, true),
HIDE_PLAYER_BUTTONS("revanced_hide_player_buttons", false, ReturnType.BOOLEAN), WIDE_SEARCHBAR("revanced_wide_searchbar", BOOLEAN, FALSE, true),
HIDE_FLOATING_MICROPHONE_BUTTON("revanced_hide_floating_microphone_button", true, ReturnType.BOOLEAN, true),
// Misc. Settings // Misc. Settings
SIGNATURE_SPOOFING("revanced_spoof_signature_verification", true, ReturnType.BOOLEAN), SIGNATURE_SPOOFING("revanced_spoof_signature_verification", BOOLEAN, TRUE, "revanced_spoof_signature_verification_user_dialog_message"),
CAPTIONS_ENABLED("revanced_autocaptions_enabled", false, ReturnType.BOOLEAN), CAPTIONS_ENABLED("revanced_autocaptions_enabled", BOOLEAN, FALSE),
PREFERRED_AUTO_REPEAT("revanced_pref_auto_repeat", false, ReturnType.BOOLEAN), DISABLE_ZOOM_HAPTICS("revanced_disable_zoom_haptics", BOOLEAN, TRUE),
USE_HDR_AUTO_BRIGHTNESS("revanced_pref_hdr_autobrightness", true, ReturnType.BOOLEAN), ENABLE_EXTERNAL_BROWSER("revanced_enable_external_browser", BOOLEAN, TRUE, true),
TAP_SEEKING_ENABLED("revanced_enable_tap_seeking", true, ReturnType.BOOLEAN), ENABLE_MINIMIZED_PLAYBACK("revanced_enable_minimized_playback", BOOLEAN, TRUE),
ENABLE_MINIMIZED_PLAYBACK("revanced_enable_minimized_playback", true, ReturnType.BOOLEAN), PREFERRED_AUTO_REPEAT("revanced_pref_auto_repeat", BOOLEAN, FALSE),
OPEN_LINKS_DIRECTLY("revanced_uri_redirect", true, ReturnType.BOOLEAN, true), TAP_SEEKING_ENABLED("revanced_enable_tap_seeking", BOOLEAN, TRUE),
DISABLE_ZOOM_HAPTICS("revanced_disable_zoom_haptics", true, ReturnType.BOOLEAN), USE_HDR_AUTO_BRIGHTNESS("revanced_pref_hdr_autobrightness", BOOLEAN, TRUE),
ENABLE_EXTERNAL_BROWSER("revanced_enable_external_browser", true, ReturnType.BOOLEAN, true),
// Swipe controls // Swipe controls
ENABLE_SWIPE_BRIGHTNESS("revanced_enable_swipe_brightness", true, ReturnType.BOOLEAN), ENABLE_SWIPE_BRIGHTNESS("revanced_enable_swipe_brightness", BOOLEAN, TRUE),
ENABLE_SWIPE_VOLUME("revanced_enable_swipe_volume", true, ReturnType.BOOLEAN), ENABLE_SWIPE_VOLUME("revanced_enable_swipe_volume", BOOLEAN, TRUE),
ENABLE_PRESS_TO_SWIPE("revanced_enable_press_to_swipe", false, ReturnType.BOOLEAN), ENABLE_PRESS_TO_SWIPE("revanced_enable_press_to_swipe", BOOLEAN, FALSE,
ENABLE_SWIPE_HAPTIC_FEEDBACK("revanced_enable_swipe_haptic_feedback", true, ReturnType.BOOLEAN), parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)),
SWIPE_OVERLAY_TIMEOUT("revanced_swipe_overlay_timeout", 500L, ReturnType.LONG), ENABLE_SWIPE_HAPTIC_FEEDBACK("revanced_enable_swipe_haptic_feedback", BOOLEAN, TRUE,
SWIPE_OVERLAY_TEXT_SIZE("revanced_swipe_overlay_text_size", 22f, ReturnType.FLOAT), parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)),
SWIPE_OVERLAY_BACKGROUND_ALPHA("revanced_swipe_overlay_background_alpha", 127, ReturnType.INTEGER), SWIPE_MAGNITUDE_THRESHOLD("revanced_swipe_magnitude_threshold", FLOAT, 30f,
SWIPE_MAGNITUDE_THRESHOLD("revanced_swipe_magnitude_threshold", 30f, ReturnType.FLOAT), 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 settings
DEBUG("revanced_debug_enabled", false, ReturnType.BOOLEAN), DEBUG("revanced_debug_enabled", BOOLEAN, FALSE),
DEBUG_STACKTRACE("revanced_debug_stacktrace_enabled", false, ReturnType.BOOLEAN), DEBUG_STACKTRACE("revanced_debug_stacktrace_enabled", BOOLEAN, FALSE, parents(DEBUG)),
DEBUG_SHOW_TOAST_ON_ERROR("revanced_debug_toast_on_error_enabled", true, ReturnType.BOOLEAN), 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), // ReturnYoutubeDislike settings
RYD_ENABLED("ryd_enabled", BOOLEAN, TRUE, RETURN_YOUTUBE_DISLIKE),
// RYD settings RYD_USER_ID("ryd_userId", STRING, "", RETURN_YOUTUBE_DISLIKE),
RYD_USER_ID("ryd_userId", null, SharedPrefHelper.SharedPrefNames.RYD, ReturnType.STRING), RYD_SHOW_DISLIKE_PERCENTAGE("ryd_show_dislike_percentage", BOOLEAN, FALSE, RETURN_YOUTUBE_DISLIKE, parents(RYD_ENABLED)),
RYD_ENABLED("ryd_enabled", true, SharedPrefHelper.SharedPrefNames.RYD, ReturnType.BOOLEAN), RYD_USE_COMPACT_LAYOUT("ryd_use_compact_layout", BOOLEAN, FALSE, RETURN_YOUTUBE_DISLIKE, parents(RYD_ENABLED)),
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),
// SponsorBlock settings // SponsorBlock settings
SB_ENABLED("sb-enabled", true, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), SB_ENABLED("sb-enabled", BOOLEAN, TRUE, SPONSOR_BLOCK),
SB_VOTING_ENABLED("sb-voting-enabled", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), SB_VOTING_ENABLED("sb-voting-enabled", BOOLEAN, FALSE, SPONSOR_BLOCK, parents(SB_ENABLED)),
SB_CREATE_NEW_SEGMENT_ENABLED("sb-new-segment-enabled", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), 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", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), SB_USE_COMPACT_SKIPBUTTON("sb-use-compact-skip-button", BOOLEAN, FALSE, SPONSOR_BLOCK, parents(SB_ENABLED)),
SB_SHOW_TOAST_ON_SKIP("show-toast", true, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), SB_SHOW_TOAST_ON_SKIP("show-toast", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)),
SB_TRACK_SKIP_COUNT("count-skips", true, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), SB_TRACK_SKIP_COUNT("count-skips", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)),
SB_UUID("uuid", "", SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.STRING), SB_UUID("uuid", STRING, "", SPONSOR_BLOCK),
SB_ADJUST_NEW_SEGMENT_STEP("new-segment-step-accuracy", 150, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.INTEGER), SB_ADJUST_NEW_SEGMENT_STEP("new-segment-step-accuracy", INTEGER, 150, SPONSOR_BLOCK, parents(SB_ENABLED)),
SB_MIN_DURATION("sb-min-duration", 0F, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.FLOAT), SB_MIN_DURATION("sb-min-duration", FLOAT, 0F, SPONSOR_BLOCK, parents(SB_ENABLED)),
SB_SEEN_GUIDELINES("sb-seen-gl", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), SB_SEEN_GUIDELINES("sb-seen-gl", BOOLEAN, FALSE, SPONSOR_BLOCK),
SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED("sb-skipped-segments", 0, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.INTEGER), SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED("sb-skipped-segments", INTEGER, 0, SPONSOR_BLOCK),
SB_SKIPPED_SEGMENTS_TIME_SAVED("sb-skipped-segments-time", 0L, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.LONG), SB_SKIPPED_SEGMENTS_TIME_SAVED("sb-skipped-segments-time", LONG, 0L, SPONSOR_BLOCK),
SB_SHOW_TIME_WITHOUT_SEGMENTS("sb-length-without-segments", true, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), SB_SHOW_TIME_WITHOUT_SEGMENTS("sb-length-without-segments", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)),
SB_IS_VIP("sb-is-vip", false, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.BOOLEAN), SB_IS_VIP("sb-is-vip", BOOLEAN, FALSE, SPONSOR_BLOCK),
SB_LAST_VIP_CHECK("sb-last-vip-check", 0L, SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.LONG), SB_LAST_VIP_CHECK("sb-last-vip-check", LONG, 0L, SPONSOR_BLOCK),
SB_API_URL("sb-api-host-url", "https://sponsor.ajay.app", SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK, ReturnType.STRING); SB_API_URL("sb-api-host-url", STRING, "https://sponsor.ajay.app", SPONSOR_BLOCK);
private final String path; private static SettingsEnum[] parents(SettingsEnum ... parents) {
private final Object defaultValue; return parents;
private final SharedPrefHelper.SharedPrefNames sharedPref; }
private final ReturnType returnType;
private final boolean rebootApp;
// must be volatile, as some settings are read/write from different threads @NonNull
// of note, the object value is persistently stored using SharedPreferences (which is thread safe) 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; private volatile Object value;
SettingsEnum(String path, Object defaultValue, ReturnType returnType) { SettingsEnum(String path, ReturnType returnType, Object defaultValue) {
this(path, defaultValue, SharedPrefHelper.SharedPrefNames.YOUTUBE, returnType, false); 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) { SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName) {
this(path, defaultValue, SharedPrefHelper.SharedPrefNames.YOUTUBE, returnType, rebootApp); this(path, returnType, defaultValue, prefName, false, null, null);
} }
SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName,
SettingsEnum(String path, Object defaultValue, SharedPrefHelper.SharedPrefNames prefName, ReturnType returnType) { boolean rebootApp) {
this(path, defaultValue, prefName, returnType, false); this(path, returnType, defaultValue, prefName, rebootApp, null, null);
} }
SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName,
SettingsEnum(String path, Object defaultValue, SharedPrefHelper.SharedPrefNames prefName, ReturnType returnType, boolean rebootApp) { String userDialogMessage) {
this.path = path; this(path, returnType, defaultValue, prefName, false, userDialogMessage, null);
this.defaultValue = defaultValue; }
this.sharedPref = prefName; SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName,
this.returnType = returnType; 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; 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 { static {
loadAllSettings(); loadAllSettings();
} }
private static void loadAllSettings() { @Nullable
if (ReVancedUtils.getContext() == null) { public static SettingsEnum settingFromPath(@NonNull String str) {
LogHelper.printException(() -> "SettingsEnum loaded before ReVancedUtils context was set"); for (SettingsEnum setting : values()) {
return; if (setting.path.equals(str)) return setting;
} }
return null;
}
private static void loadAllSettings() {
for (SettingsEnum setting : values()) { for (SettingsEnum setting : values()) {
setting.load(); setting.load();
} }
@ -192,64 +291,78 @@ public enum SettingsEnum {
private void load() { private void load() {
switch (returnType) { switch (returnType) {
case FLOAT:
value = SharedPrefHelper.getFloat(sharedPref, path, (float) defaultValue);
break;
case LONG:
value = SharedPrefHelper.getLong(sharedPref, path, (long) defaultValue);
break;
case BOOLEAN: case BOOLEAN:
value = SharedPrefHelper.getBoolean(sharedPref, path, (boolean) defaultValue); value = sharedPref.getBoolean(path, (boolean) defaultValue);
break; break;
case INTEGER: 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; break;
case STRING: case STRING:
value = SharedPrefHelper.getString(sharedPref, path, (String) defaultValue); value = sharedPref.getString(path, (String) defaultValue);
break; break;
default: default:
LogHelper.printException(() -> "Setting does not have a valid Type: " + name()); throw new IllegalStateException(name());
break;
} }
} }
/** /**
* Sets, but does _not_ persistently save the value. * 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) { public static void setValue(@NonNull SettingsEnum setting, @NonNull Object newValue) {
this.value = 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) { switch (returnType) {
case FLOAT:
SharedPrefHelper.saveFloat(sharedPref, path, (float) newValue);
break;
case LONG:
SharedPrefHelper.saveLong(sharedPref, path, (long) newValue);
break;
case BOOLEAN: case BOOLEAN:
SharedPrefHelper.saveBoolean(sharedPref, path, (boolean) newValue); sharedPref.saveBoolean(path, (boolean) newValue);
break; break;
case INTEGER: 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; break;
case STRING: case STRING:
SharedPrefHelper.saveString(sharedPref, path, (String) newValue); sharedPref.saveString(path, (String) newValue);
break; break;
default: default:
LogHelper.printException(() -> "Setting does not have a valid Type: " + name()); throw new IllegalStateException(name());
break;
} }
value = newValue; 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() { public boolean getBoolean() {
return (Boolean) value; return (Boolean) value;
} }
@ -266,23 +379,16 @@ public enum SettingsEnum {
return (Float) value; return (Float) value;
} }
@NonNull
public String getString() { public String getString() {
return (String) value; return (String) value;
} }
public Object getDefaultValue() { public enum ReturnType {
return defaultValue; BOOLEAN,
INTEGER,
STRING,
LONG,
FLOAT,
} }
}
public String getPath() {
return path;
}
public ReturnType getReturnType() {
return returnType;
}
public boolean shouldRebootOnChange() {
return rebootApp;
}
}

View File

@ -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;
}
}

View File

@ -16,6 +16,9 @@ import app.revanced.integrations.utils.ThemeHelper;
public class ReVancedSettingActivity { public class ReVancedSettingActivity {
/**
* Injection point.
*/
public static void setTheme(LicenseActivity base) { public static void setTheme(LicenseActivity base) {
final var whiteTheme = "Theme.YouTube.Settings"; final var whiteTheme = "Theme.YouTube.Settings";
final var darkTheme = "Theme.YouTube.Settings.Dark"; final var darkTheme = "Theme.YouTube.Settings.Dark";
@ -26,6 +29,9 @@ public class ReVancedSettingActivity {
base.setTheme(ReVancedUtils.getResourceIdentifier(theme, "style")); base.setTheme(ReVancedUtils.getResourceIdentifier(theme, "style"));
} }
/**
* Injection point.
*/
public static void initializeSettings(LicenseActivity base) { public static void initializeSettings(LicenseActivity base) {
base.setContentView(ReVancedUtils.getResourceIdentifier("revanced_settings_with_toolbar", "layout")); base.setContentView(ReVancedUtils.getResourceIdentifier("revanced_settings_with_toolbar", "layout"));

View File

@ -15,152 +15,148 @@ import android.os.Process;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen; import android.preference.PreferenceManager;
import android.preference.SwitchPreference; import android.preference.SwitchPreference;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.apps.youtube.app.application.Shell_HomeActivity; 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.SettingsEnum;
import app.revanced.integrations.settings.SharedPrefCategory;
import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils; import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.utils.SharedPrefHelper;
public class ReVancedSettingsFragment extends PreferenceFragment { public class ReVancedSettingsFragment extends PreferenceFragment {
/**
private List<PreferenceScreen> screens; * If a dialog is currently being shown. Used to prevent showing additional dialogs if user cancels a dialog.
*/
private boolean Registered = false; private static boolean currentlyShowingDialog;
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"};
SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
for (SettingsEnum setting : SettingsEnum.values()) { try {
if (!setting.getPath().equals(str)) continue; SettingsEnum setting = SettingsEnum.settingFromPath(str);
Preference pref = this.findPreferenceOnScreen(str); if (setting == null) {
return;
LogHelper.printDebug(() -> "Setting " + setting.name() + " was changed. Preference " + str + ": " + pref.toString()); }
Preference pref = this.findPreference(str);
LogHelper.printDebug(() -> "Setting " + setting.name() + " was changed. Preference " + str + ": " + pref);
if (pref instanceof SwitchPreference) { if (pref instanceof SwitchPreference) {
SwitchPreference switchPref = (SwitchPreference) pref; SwitchPreference switchPref = (SwitchPreference) pref;
setting.setValue(switchPref.isChecked()); SettingsEnum.setValue(setting, switchPref.isChecked());
} else if (pref instanceof EditTextPreference) { } else if (pref instanceof EditTextPreference) {
EditTextPreference editPref = (EditTextPreference) pref; String editText = ((EditTextPreference) pref).getText();
Object value = null; Object value;
switch (setting.getReturnType()) { switch (setting.returnType) {
case FLOAT: case INTEGER:
value = Float.parseFloat(editPref.getText()); value = Integer.parseInt(editText);
break; break;
case LONG: case LONG:
value = Long.parseLong(editPref.getText()); value = Long.parseLong(editText);
break;
case FLOAT:
value = Float.parseFloat(editText);
break; break;
case STRING: case STRING:
value = editPref.getText(); value = editText;
break;
case INTEGER:
value = Integer.parseInt(editPref.getText());
break; break;
default: default:
LogHelper.printException(() -> "Setting has no valid return type! " + setting.getReturnType()); throw new IllegalStateException(setting.toString());
break;
} }
setting.setValue(value); SettingsEnum.setValue(setting, value);
} else { } 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()) { if (!currentlyShowingDialog) {
rebootDialog(getActivity()); 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") @SuppressLint("ResourceType")
@Override // android.preference.PreferenceFragment, android.app.Fragment @Override
public void onCreate(Bundle bundle) { public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onCreate(bundle); super.onActivityCreated(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.YOUTUBE.getName());
try { try {
PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setSharedPreferencesName(SharedPrefCategory.YOUTUBE.prefName);
addPreferencesFromResource(ReVancedUtils.getResourceIdentifier("revanced_prefs", "xml")); addPreferencesFromResource(ReVancedUtils.getResourceIdentifier("revanced_prefs", "xml"));
SharedPreferences sharedPreferences = getPreferenceManager().getSharedPreferences(); enableDisablePreferences();
this.settingsInitialized = sharedPreferences.getBoolean("revanced_initialized", false);
sharedPreferences.registerOnSharedPreferenceChangeListener(this.listener);
this.Registered = true;
this.settingsInitialized = true; preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
} catch (Throwable th) { } catch (Exception ex) {
LogHelper.printException(() -> "Error during onCreate()", th); LogHelper.printException(() -> "onActivityCreated() error", ex);
} }
} }
@Override // android.preference.PreferenceFragment, android.app.Fragment @Override // android.preference.PreferenceFragment, android.app.Fragment
public void onDestroy() { public void onDestroy() {
if (this.Registered) { getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener);
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this.listener);
this.Registered = false;
}
super.onDestroy(); super.onDestroy();
} }
private Preference findPreferenceOnScreen(CharSequence key) { private void enableDisablePreferences() {
if (key == null) { for (SettingsEnum setting : SettingsEnum.values()) {
LogHelper.printException(() -> "Key cannot be null!"); Preference preference = this.findPreference(setting.path);
return null; if (preference != null) {
} preference.setEnabled(setting.isAvailable());
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());
} }
} }
return pref;
} }
/* private void reboot(@NonNull Activity activity) {
private void setCopyLinkListPreferenceData(ListPreference listPreference, String str) { final int intentFlags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE;
listPreference.setEntries(this.buttonLocationEntries); PendingIntent intent = PendingIntent.getActivity(activity, 0,
listPreference.setEntryValues(this.buttonLocationentryValues); new Intent(activity, Shell_HomeActivity.class), intentFlags);
String string = this.sharedPreferences.getString(str, "NONE"); AlarmManager systemService = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
if (listPreference.getValue() == null) { systemService.setExact(AlarmManager.ELAPSED_REALTIME, 1500L, intent);
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));
Process.killProcess(Process.myPid()); Process.killProcess(Process.myPid());
} }
private void rebootDialog(final Activity activity) { private void rebootDialog(@NonNull 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(); 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();
} }
} }

View File

@ -15,7 +15,7 @@ import android.preference.SwitchPreference;
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike; import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
import app.revanced.integrations.settings.SettingsEnum; import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.SharedPrefHelper; import app.revanced.integrations.settings.SharedPrefCategory;
public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment { public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
@ -35,27 +35,25 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
private SwitchPreference compactLayoutPreference; private SwitchPreference compactLayoutPreference;
private void updateUIState() { private void updateUIState() {
final boolean rydIsEnabled = SettingsEnum.RYD_ENABLED.getBoolean(); enabledPreference.setSummary(SettingsEnum.RYD_ENABLED.getBoolean()
enabledPreference.setSummary(rydIsEnabled
? str("revanced_ryd_enable_summary_on") ? str("revanced_ryd_enable_summary_on")
: str("revanced_ryd_enable_summary_off")); : str("revanced_ryd_enable_summary_off"));
percentagePreference.setSummary(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean() percentagePreference.setSummary(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean()
? str("revanced_ryd_dislike_percentage_summary_on") ? str("revanced_ryd_dislike_percentage_summary_on")
: str("revanced_ryd_dislike_percentage_summary_off")); : 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() compactLayoutPreference.setSummary(SettingsEnum.RYD_USE_COMPACT_LAYOUT.getBoolean()
? str("revanced_ryd_compact_layout_summary_on") ? str("revanced_ryd_compact_layout_summary_on")
: str("revanced_ryd_compact_layout_summary_off")); : str("revanced_ryd_compact_layout_summary_off"));
compactLayoutPreference.setEnabled(rydIsEnabled); compactLayoutPreference.setEnabled(SettingsEnum.RYD_USE_COMPACT_LAYOUT.isAvailable());
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.RYD.getName()); getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.RETURN_YOUTUBE_DISLIKE.prefName);
Activity context = this.getActivity(); Activity context = this.getActivity();
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context); PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context);
@ -78,7 +76,7 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
percentagePreference.setChecked(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean()); percentagePreference.setChecked(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean());
percentagePreference.setTitle(str("revanced_ryd_dislike_percentage_title")); percentagePreference.setTitle(str("revanced_ryd_dislike_percentage_title"));
percentagePreference.setOnPreferenceChangeListener((pref, newValue) -> { percentagePreference.setOnPreferenceChangeListener((pref, newValue) -> {
SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.saveValue((Boolean)newValue); SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.saveValue(newValue);
updateUIState(); updateUIState();
return true; return true;
@ -89,7 +87,7 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
compactLayoutPreference.setChecked(SettingsEnum.RYD_USE_COMPACT_LAYOUT.getBoolean()); compactLayoutPreference.setChecked(SettingsEnum.RYD_USE_COMPACT_LAYOUT.getBoolean());
compactLayoutPreference.setTitle(str("revanced_ryd_compact_layout_title")); compactLayoutPreference.setTitle(str("revanced_ryd_compact_layout_title"));
compactLayoutPreference.setOnPreferenceChangeListener((pref, newValue) -> { compactLayoutPreference.setOnPreferenceChangeListener((pref, newValue) -> {
SettingsEnum.RYD_USE_COMPACT_LAYOUT.saveValue((Boolean)newValue); SettingsEnum.RYD_USE_COMPACT_LAYOUT.saveValue(newValue);
updateUIState(); updateUIState();
return true; return true;

View File

@ -28,6 +28,7 @@ import androidx.annotation.Nullable;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import app.revanced.integrations.settings.SettingsEnum; import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.settings.SharedPrefCategory;
import app.revanced.integrations.sponsorblock.SegmentPlaybackController; import app.revanced.integrations.sponsorblock.SegmentPlaybackController;
import app.revanced.integrations.sponsorblock.SponsorBlockSettings; import app.revanced.integrations.sponsorblock.SponsorBlockSettings;
import app.revanced.integrations.sponsorblock.SponsorBlockUtils; 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.sponsorblock.ui.SponsorBlockViewController;
import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils; import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.utils.SharedPrefHelper;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class SponsorBlockSettingsFragment extends PreferenceFragment { public class SponsorBlockSettingsFragment extends PreferenceFragment {
@ -115,7 +115,7 @@ public class SponsorBlockSettingsFragment extends PreferenceFragment {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
try { try {
PreferenceManager preferenceManager = getPreferenceManager(); PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK.getName()); preferenceManager.setSharedPreferencesName(SharedPrefCategory.SPONSOR_BLOCK.prefName);
Activity context = this.getActivity(); Activity context = this.getActivity();
PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(context); PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(context);
@ -304,7 +304,7 @@ public class SponsorBlockSettingsFragment extends PreferenceFragment {
DialogInterface.OnClickListener urlChangeListener = (dialog, buttonPressed) -> { DialogInterface.OnClickListener urlChangeListener = (dialog, buttonPressed) -> {
if (buttonPressed == DialogInterface.BUTTON_NEUTRAL) { 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")); ReVancedUtils.showToastLong(str("sb_api_url_reset"));
} else if (buttonPressed == DialogInterface.BUTTON_POSITIVE) { } else if (buttonPressed == DialogInterface.BUTTON_POSITIVE) {
String serverAddress = editText.getText().toString(); String serverAddress = editText.getText().toString();
@ -522,8 +522,8 @@ public class SponsorBlockSettingsFragment extends PreferenceFragment {
new AlertDialog.Builder(preference1.getContext()) new AlertDialog.Builder(preference1.getContext())
.setTitle(str("sb_stats_self_saved_reset_title")) .setTitle(str("sb_stats_self_saved_reset_title"))
.setPositiveButton(android.R.string.yes, (dialog, whichButton) -> { .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_NUMBER_SKIPPED.saveValue(SettingsEnum.SB_SKIPPED_SEGMENTS_NUMBER_SKIPPED.defaultValue);
SettingsEnum.SB_SKIPPED_SEGMENTS_TIME_SAVED.saveValue(SettingsEnum.SB_SKIPPED_SEGMENTS_TIME_SAVED.getDefaultValue()); SettingsEnum.SB_SKIPPED_SEGMENTS_TIME_SAVED.saveValue(SettingsEnum.SB_SKIPPED_SEGMENTS_TIME_SAVED.defaultValue);
updateStatsSelfSaved.run(); updateStatsSelfSaved.run();
}) })
.setNegativeButton(android.R.string.no, null).show(); .setNegativeButton(android.R.string.no, null).show();

View File

@ -14,11 +14,11 @@ import org.json.JSONObject;
import java.util.UUID; import java.util.UUID;
import app.revanced.integrations.settings.SettingsEnum; 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.CategoryBehaviour;
import app.revanced.integrations.sponsorblock.objects.SegmentCategory; import app.revanced.integrations.sponsorblock.objects.SegmentCategory;
import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils; import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.utils.SharedPrefHelper;
public class SponsorBlockSettings { public class SponsorBlockSettings {
@ -55,7 +55,7 @@ public class SponsorBlockSettings {
} }
SegmentCategory.updateEnabledCategories(); 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()) { for (SegmentCategory category : SegmentCategory.valuesWithoutUnsubmitted()) {
category.save(editor); category.save(editor);
} }

View File

@ -21,8 +21,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import app.revanced.integrations.settings.SharedPrefCategory;
import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.SharedPrefHelper;
import app.revanced.integrations.utils.StringRef; import app.revanced.integrations.utils.StringRef;
public enum SegmentCategory { public enum SegmentCategory {
@ -84,7 +84,7 @@ public enum SegmentCategory {
} }
public static void loadFromPreferences() { public static void loadFromPreferences() {
SharedPreferences preferences = SharedPrefHelper.getPreferences(SharedPrefHelper.SharedPrefNames.SPONSOR_BLOCK); SharedPreferences preferences = SharedPrefCategory.SPONSOR_BLOCK.preferences;
LogHelper.printDebug(() -> "loadFromPreferences"); LogHelper.printDebug(() -> "loadFromPreferences");
for (SegmentCategory category : valuesWithoutUnsubmitted()) { for (SegmentCategory category : valuesWithoutUnsubmitted()) {
category.load(preferences); category.load(preferences);

View File

@ -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;
}
}
}

View File

@ -1,5 +0,0 @@
package app.revanced.tiktok.settings;
public enum ReturnType {
BOOLEAN, INTEGER, STRING, LONG, FLOAT
}

View File

@ -1,104 +1,112 @@
package app.revanced.tiktok.settings; 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.content.Context;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import app.revanced.tiktok.utils.LogHelper; import app.revanced.tiktok.utils.LogHelper;
import app.revanced.tiktok.utils.ReVancedUtils; import app.revanced.tiktok.utils.ReVancedUtils;
import app.revanced.tiktok.utils.SharedPrefHelper;
public enum SettingsEnum { public enum SettingsEnum {
//TikTok Settings //TikTok Settings
TIK_REMOVE_ADS("tik_remove_ads", true, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN, true), TIK_DEBUG("tik_debug", BOOLEAN, FALSE), // must be first value, otherwise logging during loading will not work
TIK_HIDE_LIVE("tik_hide_live", false, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN, true), TIK_REMOVE_ADS("tik_remove_ads", BOOLEAN, TRUE, true),
TIK_DOWN_PATH("tik_down_path", "DCIM/TikTok", SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.STRING), TIK_HIDE_LIVE("tik_hide_live", BOOLEAN, FALSE, true),
TIK_DOWN_WATERMARK("tik_down_watermark", true, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN), TIK_DOWN_PATH("tik_down_path", STRING, "DCIM/TikTok"),
TIK_SIMSPOOF("tik_simspoof", true, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN, true), TIK_DOWN_WATERMARK("tik_down_watermark", BOOLEAN, TRUE),
TIK_SIMSPOOF_ISO("tik_simspoof_iso", "us", SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.STRING), TIK_SIMSPOOF("tik_simspoof", BOOLEAN, TRUE, true),
TIK_SIMSPOOF_MCCMNC("tik_simspoof_mccmnc", "310160", SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.STRING), TIK_SIMSPOOF_ISO("tik_simspoof_iso", STRING, "us"),
TIK_SIMSPOOF_OP_NAME("tik_simspoof_op_name", "T-Mobile", SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.STRING), TIK_SIMSPOOF_MCCMNC("tik_simspoof_mccmnc", STRING, "310160"),
TIK_DEBUG("tik_debug", false, SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS, ReturnType.BOOLEAN); TIK_SIMSPOOF_OP_NAME("tik_simspoof_op_name", STRING, "T-Mobile");
static { static {
load(); loadAllSettings();
} }
private final String path; @NonNull
private final Object defaultValue; public final String path;
private final SharedPrefHelper.SharedPrefNames sharedPref; @NonNull
private final ReturnType returnType; public final Object defaultValue;
private final boolean rebootApp; @NonNull
private Object value = null; 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.path = path;
this.defaultValue = defaultValue;
this.sharedPref = SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS;
this.returnType = returnType; this.returnType = returnType;
this.rebootApp = false;
}
SettingsEnum(String path, Object defaultValue, SharedPrefHelper.SharedPrefNames prefName, ReturnType returnType) {
this.path = path;
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
this.sharedPref = prefName; 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; this.rebootApp = rebootApp;
} }
private static void load() { private static void loadAllSettings() {
Context context = ReVancedUtils.getAppContext(); try {
if (context == null) { Context context = ReVancedUtils.getAppContext();
Log.e("revanced: SettingsEnum", "Context returned null! Setings NOT initialized"); if (context == null) {
} else { Log.e("revanced: SettingsEnum", "Context returned null! Settings NOT initialized");
try { return;
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);
} }
for (SettingsEnum setting : values()) {
setting.load(context);
}
} catch (Exception ex) {
LogHelper.printException(SettingsEnum.class, "Error during load()!", ex);
} }
} }
public void setValue(Object newValue) { private void load(Context context) {
this.value = newValue; 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) { public void saveValue(Object newValue) {
@ -108,48 +116,39 @@ public enum SettingsEnum {
return; return;
} }
if (returnType == ReturnType.BOOLEAN) { if (returnType == BOOLEAN) {
SharedPrefHelper.saveBoolean(context, sharedPref, path, (Boolean) newValue); sharedPref.saveBoolean(context, path, (Boolean) newValue);
} else { } else {
SharedPrefHelper.saveString(context, sharedPref, path, newValue + ""); sharedPref.saveString(context, path, newValue.toString());
} }
value = newValue; value = newValue;
} }
public int getInt() {
return (int) value;
}
public String getString() {
return (String) value;
}
public boolean getBoolean() { public boolean getBoolean() {
return (Boolean) value; return (Boolean) value;
} }
public Long getLong() { public int getInt() {
return (Integer) value;
}
public long getLong() {
return (Long) value; return (Long) value;
} }
public Float getFloat() { public float getFloat() {
return (Float) value; return (Float) value;
} }
public Object getDefaultValue() { public String getString() {
return defaultValue; return (String) value;
} }
public String getPath() { public enum ReturnType {
return path; BOOLEAN,
INTEGER,
LONG,
FLOAT,
STRING,
} }
public ReturnType getReturnType() {
return returnType;
}
public boolean shouldRebootOnChange() {
return rebootApp;
}
} }

View File

@ -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);
}
}

View File

@ -21,9 +21,9 @@ import androidx.annotation.Nullable;
import com.ss.android.ugc.aweme.splash.SplashActivity; import com.ss.android.ugc.aweme.splash.SplashActivity;
import app.revanced.tiktok.settings.SettingsEnum; import app.revanced.tiktok.settings.SettingsEnum;
import app.revanced.tiktok.settings.SharedPrefCategory;
import app.revanced.tiktok.settingsmenu.preference.DownloadPathPreference; import app.revanced.tiktok.settingsmenu.preference.DownloadPathPreference;
import app.revanced.tiktok.utils.ReVancedUtils; import app.revanced.tiktok.utils.ReVancedUtils;
import app.revanced.tiktok.utils.SharedPrefHelper;
public class ReVancedSettingsFragment extends PreferenceFragment { public class ReVancedSettingsFragment extends PreferenceFragment {
@ -32,9 +32,9 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
for (SettingsEnum setting : SettingsEnum.values()) { 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()); rebootDialog(getActivity());
} }
} }
@ -43,7 +43,7 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.TIKTOK_PREFS.getName()); getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.TIKTOK_PREFS.prefName);
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this.listener); getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this.listener);
this.Registered = true; this.Registered = true;
@ -61,12 +61,14 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
SwitchPreference preference = new SwitchPreference(context); SwitchPreference preference = new SwitchPreference(context);
feedFilter.addPreference(preference); feedFilter.addPreference(preference);
preference.setKey(SettingsEnum.TIK_REMOVE_ADS.getPath()); preference.setKey(SettingsEnum.TIK_REMOVE_ADS.path);
preference.setDefaultValue(SettingsEnum.TIK_REMOVE_ADS.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_REMOVE_ADS.defaultValue);
preference.setChecked(SettingsEnum.TIK_REMOVE_ADS.getBoolean()); preference.setChecked(SettingsEnum.TIK_REMOVE_ADS.getBoolean());
preference.setTitle("Remove feed ads"); preference.setTitle("Remove feed ads");
preference.setSummary("Remove ads from feed."); preference.setSummary("Remove ads from feed.");
preference.setOnPreferenceChangeListener((pref, newValue) -> { 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; final boolean value = (Boolean) newValue;
SettingsEnum.TIK_REMOVE_ADS.saveValue(value); SettingsEnum.TIK_REMOVE_ADS.saveValue(value);
return true; return true;
@ -76,8 +78,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
SwitchPreference preference = new SwitchPreference(context); SwitchPreference preference = new SwitchPreference(context);
feedFilter.addPreference(preference); feedFilter.addPreference(preference);
preference.setKey(SettingsEnum.TIK_HIDE_LIVE.getPath()); preference.setKey(SettingsEnum.TIK_HIDE_LIVE.path);
preference.setDefaultValue(SettingsEnum.TIK_HIDE_LIVE.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_HIDE_LIVE.defaultValue);
preference.setChecked(SettingsEnum.TIK_HIDE_LIVE.getBoolean()); preference.setChecked(SettingsEnum.TIK_HIDE_LIVE.getBoolean());
preference.setTitle("Hide livestreams"); preference.setTitle("Hide livestreams");
preference.setSummary("Hide livestreams from feed."); preference.setSummary("Hide livestreams from feed.");
@ -98,8 +100,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
DownloadPathPreference preference = new DownloadPathPreference(context); DownloadPathPreference preference = new DownloadPathPreference(context);
download.addPreference(preference); download.addPreference(preference);
preference.setKey(SettingsEnum.TIK_DOWN_PATH.getPath()); preference.setKey(SettingsEnum.TIK_DOWN_PATH.path);
preference.setDefaultValue(SettingsEnum.TIK_DOWN_PATH.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_DOWN_PATH.defaultValue);
preference.setValue(SettingsEnum.TIK_DOWN_PATH.getString()); preference.setValue(SettingsEnum.TIK_DOWN_PATH.getString());
preference.setTitle("Download path"); preference.setTitle("Download path");
preference.setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + preference.getValue()); preference.setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + preference.getValue());
@ -113,8 +115,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
SwitchPreference preference = new SwitchPreference(context); SwitchPreference preference = new SwitchPreference(context);
download.addPreference(preference); download.addPreference(preference);
preference.setKey(SettingsEnum.TIK_DOWN_WATERMARK.getPath()); preference.setKey(SettingsEnum.TIK_DOWN_WATERMARK.path);
preference.setDefaultValue(SettingsEnum.TIK_DOWN_WATERMARK.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_DOWN_WATERMARK.defaultValue);
preference.setChecked(SettingsEnum.TIK_DOWN_WATERMARK.getBoolean()); preference.setChecked(SettingsEnum.TIK_DOWN_WATERMARK.getBoolean());
preference.setTitle("Remove watermark"); preference.setTitle("Remove watermark");
preference.setOnPreferenceChangeListener((pref, newValue) -> { preference.setOnPreferenceChangeListener((pref, newValue) -> {
@ -134,8 +136,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
SwitchPreference preference = new SwitchPreference(context); SwitchPreference preference = new SwitchPreference(context);
simSpoof.addPreference(preference); simSpoof.addPreference(preference);
preference.setKey(SettingsEnum.TIK_SIMSPOOF.getPath()); preference.setKey(SettingsEnum.TIK_SIMSPOOF.path);
preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF.defaultValue);
preference.setChecked(SettingsEnum.TIK_SIMSPOOF.getBoolean()); preference.setChecked(SettingsEnum.TIK_SIMSPOOF.getBoolean());
preference.setTitle("Fake sim card info"); preference.setTitle("Fake sim card info");
preference.setSummary("Bypass regional restriction by fake sim card information."); preference.setSummary("Bypass regional restriction by fake sim card information.");
@ -149,8 +151,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
EditTextPreference preference = new EditTextPreference(context); EditTextPreference preference = new EditTextPreference(context);
simSpoof.addPreference(preference); simSpoof.addPreference(preference);
preference.setKey(SettingsEnum.TIK_SIMSPOOF_ISO.getPath()); preference.setKey(SettingsEnum.TIK_SIMSPOOF_ISO.path);
preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_ISO.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_ISO.defaultValue);
preference.setText(SettingsEnum.TIK_SIMSPOOF_ISO.getString()); preference.setText(SettingsEnum.TIK_SIMSPOOF_ISO.getString());
preference.setTitle("Country ISO"); preference.setTitle("Country ISO");
preference.setSummary("us, uk, jp, ..."); preference.setSummary("us, uk, jp, ...");
@ -164,8 +166,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
EditTextPreference preference = new EditTextPreference(context); EditTextPreference preference = new EditTextPreference(context);
simSpoof.addPreference(preference); simSpoof.addPreference(preference);
preference.setKey(SettingsEnum.TIK_SIMSPOOF_MCCMNC.getPath()); preference.setKey(SettingsEnum.TIK_SIMSPOOF_MCCMNC.path);
preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_MCCMNC.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_MCCMNC.defaultValue);
preference.setText(SettingsEnum.TIK_SIMSPOOF_MCCMNC.getString()); preference.setText(SettingsEnum.TIK_SIMSPOOF_MCCMNC.getString());
preference.setTitle("Operator mcc+mnc"); preference.setTitle("Operator mcc+mnc");
preference.setSummary("mcc+mnc"); preference.setSummary("mcc+mnc");
@ -179,8 +181,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
EditTextPreference preference = new EditTextPreference(context); EditTextPreference preference = new EditTextPreference(context);
simSpoof.addPreference(preference); simSpoof.addPreference(preference);
preference.setKey(SettingsEnum.TIK_SIMSPOOF_OP_NAME.getPath()); preference.setKey(SettingsEnum.TIK_SIMSPOOF_OP_NAME.path);
preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_OP_NAME.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_SIMSPOOF_OP_NAME.defaultValue);
preference.setText(SettingsEnum.TIK_SIMSPOOF_OP_NAME.getString()); preference.setText(SettingsEnum.TIK_SIMSPOOF_OP_NAME.getString());
preference.setTitle("Operator name"); preference.setTitle("Operator name");
preference.setSummary("Name of the operator"); preference.setSummary("Name of the operator");
@ -200,8 +202,8 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
{ {
SwitchPreference preference = new SwitchPreference(context); SwitchPreference preference = new SwitchPreference(context);
integration.addPreference(preference); integration.addPreference(preference);
preference.setKey(SettingsEnum.TIK_DEBUG.getPath()); preference.setKey(SettingsEnum.TIK_DEBUG.path);
preference.setDefaultValue(SettingsEnum.TIK_DEBUG.getDefaultValue()); preference.setDefaultValue(SettingsEnum.TIK_DEBUG.defaultValue);
preference.setChecked(SettingsEnum.TIK_DEBUG.getBoolean()); preference.setChecked(SettingsEnum.TIK_DEBUG.getBoolean());
preference.setTitle("Enable debug log"); preference.setTitle("Enable debug log");
preference.setSummary("Show integration debug log."); preference.setSummary("Show integration debug log.");

View File

@ -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;
}
}
}

View File

@ -1,5 +0,0 @@
package app.revanced.twitch.settings;
public enum ReturnType {
BOOLEAN, INTEGER, STRING, LONG, FLOAT
}

View File

@ -1,150 +1,163 @@
package app.revanced.twitch.settings; 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.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import app.revanced.twitch.utils.LogHelper; import app.revanced.twitch.utils.LogHelper;
import app.revanced.twitch.utils.ReVancedUtils; import app.revanced.twitch.utils.ReVancedUtils;
public enum SettingsEnum { public enum SettingsEnum {
/* Ads */ /* Ads */
BLOCK_VIDEO_ADS("revanced_block_video_ads", true, ReturnType.BOOLEAN), BLOCK_VIDEO_ADS("revanced_block_video_ads", BOOLEAN, TRUE),
BLOCK_AUDIO_ADS("revanced_block_audio_ads", true, ReturnType.BOOLEAN), BLOCK_AUDIO_ADS("revanced_block_audio_ads", BOOLEAN, TRUE),
BLOCK_EMBEDDED_ADS("revanced_block_embedded_ads", "ttv-lol", ReturnType.STRING), BLOCK_EMBEDDED_ADS("revanced_block_embedded_ads", STRING, "ttv-lol"),
/* Chat */ /* Chat */
SHOW_DELETED_MESSAGES("revanced_show_deleted_messages", "cross-out", ReturnType.STRING), SHOW_DELETED_MESSAGES("revanced_show_deleted_messages", STRING, "cross-out"),
/* Misc */ /* 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"; public static final String REVANCED_PREFS = "revanced_prefs";
private final String path; @NonNull
private final Object defaultValue; public final String path;
private final ReturnType returnType; @NonNull
private final boolean rebootApp; 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) { SettingsEnum(String path, ReturnType returnType, Object defaultValue) {
this.path = path; this(path, returnType, defaultValue, false);
this.defaultValue = defaultValue;
this.returnType = returnType;
this.rebootApp = 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.path = path;
this.defaultValue = defaultValue;
this.returnType = returnType; this.returnType = returnType;
this.defaultValue = defaultValue;
this.rebootApp = rebootApp; this.rebootApp = rebootApp;
} }
static { static {
load(); loadAllSettings();
} }
private static void load() { private static void loadAllSettings() {
ReVancedUtils.ifContextAttached((context -> { ReVancedUtils.ifContextAttached((context -> {
try { try {
SharedPreferences prefs = context.getSharedPreferences(REVANCED_PREFS, Context.MODE_PRIVATE); SharedPreferences prefs = context.getSharedPreferences(REVANCED_PREFS, Context.MODE_PRIVATE);
for (SettingsEnum setting : values()) { for (SettingsEnum setting : values()) {
Object value = setting.getDefaultValue(); setting.load(prefs);
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);
} }
} catch (Throwable th) { } catch (Exception ex) {
LogHelper.printException("Failed to load settings", th); 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 // Implicitly convert strings to numbers depending on the ResultType
switch (returnType) { switch (returnType) {
case FLOAT: case FLOAT:
value = Float.valueOf(newValue + ""); value = Float.valueOf(newValue.toString());
break; break;
case LONG: case LONG:
value = Long.valueOf(newValue + ""); value = Long.valueOf(newValue.toString());
break; break;
case INTEGER: case INTEGER:
value = Integer.valueOf(newValue + ""); value = Integer.valueOf(newValue.toString());
break; break;
default: case BOOLEAN:
case STRING:
value = newValue; value = newValue;
break; break;
default:
throw new IllegalArgumentException(name());
} }
} }
public void saveValue(Object newValue) { public void saveValue(Object newValue) {
ReVancedUtils.ifContextAttached((context) -> { ReVancedUtils.ifContextAttached((context) -> {
SharedPreferences prefs = context.getSharedPreferences(REVANCED_PREFS, Context.MODE_PRIVATE); SharedPreferences prefs = context.getSharedPreferences(REVANCED_PREFS, Context.MODE_PRIVATE);
if (returnType == ReturnType.BOOLEAN) { if (returnType == BOOLEAN) {
prefs.edit().putBoolean(path, (Boolean)newValue).apply(); prefs.edit().putBoolean(path, (Boolean)newValue).apply();
} else { } 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() { public boolean getBoolean() {
return (Boolean) value; return (Boolean) value;
} }
public Long getLong() { public int getInt() {
return (Integer) value;
}
public long getLong() {
return (Long) value; return (Long) value;
} }
public Float getFloat() { public float getFloat() {
return (Float) value; return (Float) value;
} }
public Object getDefaultValue() { public String getString() {
return defaultValue; return (String) value;
} }
public String getPath() { public enum ReturnType {
return path; BOOLEAN,
} INTEGER,
LONG,
public ReturnType getReturnType() { FLOAT,
return returnType; STRING,
}
public boolean shouldRebootOnChange() {
return rebootApp;
} }
} }

View File

@ -22,7 +22,6 @@ import androidx.annotation.Nullable;
import app.revanced.twitch.settings.SettingsEnum; import app.revanced.twitch.settings.SettingsEnum;
import app.revanced.twitch.utils.LogHelper; import app.revanced.twitch.utils.LogHelper;
import app.revanced.twitch.utils.ReVancedUtils; import app.revanced.twitch.utils.ReVancedUtils;
import tv.twitch.android.app.core.LandingActivity; import tv.twitch.android.app.core.LandingActivity;
public class ReVancedSettingsFragment extends PreferenceFragment { public class ReVancedSettingsFragment extends PreferenceFragment {
@ -41,28 +40,28 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
*/ */
private void syncPreference(@Nullable String key) { private void syncPreference(@Nullable String key) {
for (SettingsEnum setting : SettingsEnum.values()) { for (SettingsEnum setting : SettingsEnum.values()) {
if (!setting.getPath().equals(key) && key != null) if (!setting.path.equals(key) && key != null)
continue; continue;
Preference pref = this.findPreference(setting.getPath()); Preference pref = this.findPreference(setting.path);
LogHelper.debug("Syncing setting '%s' with UI", setting.getPath()); LogHelper.debug("Syncing setting '%s' with UI", setting.path);
if (pref instanceof SwitchPreference) { if (pref instanceof SwitchPreference) {
setting.setValue(((SwitchPreference) pref).isChecked()); SettingsEnum.setValue(setting, ((SwitchPreference) pref).isChecked());
} }
else if (pref instanceof EditTextPreference) { else if (pref instanceof EditTextPreference) {
setting.setValue(((EditTextPreference) pref).getText()); SettingsEnum.setValue(setting, ((EditTextPreference) pref).getText());
} }
else if (pref instanceof ListPreference) { else if (pref instanceof ListPreference) {
ListPreference listPref = (ListPreference) pref; ListPreference listPref = (ListPreference) pref;
listPref.setSummary(listPref.getEntry()); listPref.setSummary(listPref.getEntry());
setting.setValue(listPref.getValue()); SettingsEnum.setValue(setting, listPref.getValue());
} }
else { else {
LogHelper.error("Setting '%s' cannot be handled!", pref); 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()); rebootDialog(getActivity());
} }