diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/Setting.java b/app/src/main/java/app/revanced/integrations/shared/settings/Setting.java index 9f6b3ae5..26bcd254 100644 --- a/app/src/main/java/app/revanced/integrations/shared/settings/Setting.java +++ b/app/src/main/java/app/revanced/integrations/shared/settings/Setting.java @@ -7,7 +7,7 @@ import app.revanced.integrations.shared.Logger; import app.revanced.integrations.shared.StringRef; import app.revanced.integrations.shared.Utils; import app.revanced.integrations.shared.settings.preference.SharedPrefCategory; -import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings; + import org.jetbrains.annotations.NotNull; import org.json.JSONException; import org.json.JSONObject; @@ -62,6 +62,21 @@ public abstract class Setting { }; } + /** + * Callback for importing/exporting settings. + */ + public interface ImportExportCallback { + /** + * Called after all settings have been imported. + */ + void settingsImported(@Nullable Context context); + + /** + * Called after all settings have been exported. + */ + void settingsExported(@Nullable Context context); + } + /** * All settings that were instantiated. * When a new setting is created, it is automatically added to this list. @@ -78,6 +93,15 @@ public abstract class Setting { */ public static final SharedPrefCategory preferences = new SharedPrefCategory("revanced_prefs"); + private static final List importExportCallbacks = new ArrayList<>(); + + /** + * Adds a callback for {@link #importFromJSON(Context, String)} and {@link #exportToJson(Context)}. + */ + public static void addImportExportCallback(@NonNull ImportExportCallback callback) { + importExportCallbacks.add(Objects.requireNonNull(callback)); + } + @Nullable public static Setting getSettingFromPath(@NonNull String str) { return PATH_TO_SETTINGS.get(str); @@ -357,7 +381,10 @@ public abstract class Setting { setting.writeToJSON(json, importExportKey); } } - SponsorBlockSettings.showExportWarningIfNeeded(alertDialogContext); + + for (ImportExportCallback callback : importExportCallbacks) { + callback.settingsExported(alertDialogContext); + } if (json.length() == 0) { return ""; @@ -377,7 +404,7 @@ public abstract class Setting { /** * @return if any settings that require a reboot were changed. */ - public static boolean importFromJSON(@NonNull String settingsJsonString) { + public static boolean importFromJSON(@Nullable Context context, @NonNull String settingsJsonString) { try { if (!settingsJsonString.matches("[\\s\\S]*\\{")) { settingsJsonString = '{' + settingsJsonString + '}'; // Restore outer JSON braces @@ -403,12 +430,9 @@ public abstract class Setting { } } - // SB Enum categories are saved using StringSettings. - // Which means they need to reload again if changed by other code (such as here). - // This call could be removed by creating a custom Setting class that manages the - // "String <-> Enum" logic or by adding an event hook of when settings are imported. - // But for now this is simple and works. - SponsorBlockSettings.updateFromImportedSettings(); + for (ImportExportCallback callback : importExportCallbacks) { + callback.settingsImported(context); + } Utils.showToastLong(numberOfSettingsImported == 0 ? str("revanced_settings_import_reset") diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/preference/ImportExportPreference.java b/app/src/main/java/app/revanced/integrations/shared/settings/preference/ImportExportPreference.java index 0a9b54c1..b07bab6a 100644 --- a/app/src/main/java/app/revanced/integrations/shared/settings/preference/ImportExportPreference.java +++ b/app/src/main/java/app/revanced/integrations/shared/settings/preference/ImportExportPreference.java @@ -83,7 +83,7 @@ public class ImportExportPreference extends EditTextPreference implements Prefer return; } AbstractPreferenceFragment.settingImportInProgress = true; - final boolean rebootNeeded = Setting.importFromJSON(replacementSettings); + final boolean rebootNeeded = Setting.importFromJSON(getContext(), replacementSettings); if (rebootNeeded) { AbstractPreferenceFragment.showRestartDialog(getContext()); } diff --git a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java index bbf11fba..0340e418 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java @@ -15,15 +15,14 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; -import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.settings.BaseSettings; import app.revanced.integrations.shared.settings.BooleanSetting; import app.revanced.integrations.shared.settings.FloatSetting; import app.revanced.integrations.shared.settings.IntegerSetting; import app.revanced.integrations.shared.settings.LongSetting; import app.revanced.integrations.shared.settings.Setting; -import app.revanced.integrations.shared.settings.preference.SharedPrefCategory; -import app.revanced.integrations.shared.settings.BaseSettings; import app.revanced.integrations.shared.settings.StringSetting; +import app.revanced.integrations.shared.settings.preference.SharedPrefCategory; import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings; public class Settings extends BaseSettings { @@ -339,12 +338,18 @@ public class Settings extends BaseSettings { } } - // Do _not_ delete this SB private user id migration property until sometime in 2024. // This is the only setting that cannot be reconfigured if lost, // and more time should be given for users who rarely upgrade. migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID); // endregion + + + // region SB import/export callbacks + + Setting.addImportExportCallback(SponsorBlockSettings.SB_IMPORT_EXPORT_CALLBACK); + + // endregion } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockSettings.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockSettings.java index 084bbf52..6e3c742b 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockSettings.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockSettings.java @@ -1,6 +1,7 @@ package app.revanced.integrations.youtube.sponsorblock; import static app.revanced.integrations.shared.StringRef.str; +import static app.revanced.integrations.shared.settings.Setting.ImportExportCallback; import android.app.AlertDialog; import android.content.Context; @@ -159,9 +160,18 @@ public class SponsorBlockSettings { } /** - * Export the categories using flatten json (no embedded dictionaries or arrays). + * Updates internal data based on {@link Setting} values. */ - public static void showExportWarningIfNeeded(@Nullable Context dialogContext) { + private static void updateFromImportedSettings() { + // SB Enum categories are saved using StringSettings. + // Which means they need to reload again if changed by other code. + SegmentCategory.loadAllCategoriesFromSettings(); + } + + /** + * Shows a warning, if a private SB user id exists. + */ + private static void showExportWarningIfNeeded(@Nullable Context dialogContext) { Utils.verifyOnMainThread(); initialize(); @@ -178,6 +188,17 @@ public class SponsorBlockSettings { } } + public static final ImportExportCallback SB_IMPORT_EXPORT_CALLBACK = new ImportExportCallback() { + @Override + public void settingsImported(@Nullable Context context) { + updateFromImportedSettings(); + } + @Override + public void settingsExported(@Nullable Context context) { + showExportWarningIfNeeded(context); + } + }; + public static boolean isValidSBUserId(@NonNull String userId) { return !userId.isEmpty() && userId.length() >= SB_PRIVATE_USER_ID_MINIMUM_LENGTH; } @@ -234,11 +255,4 @@ public class SponsorBlockSettings { SegmentCategory.updateEnabledCategories(); } - - /** - * Updates internal data based on {@link Setting} values. - */ - public static void updateFromImportedSettings() { - SegmentCategory.loadAllCategoriesFromSettings(); - } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategory.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategory.java index 03d74b3b..92cf9b2d 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategory.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategory.java @@ -106,7 +106,7 @@ public enum SegmentCategory { } /** - * Must be called if behavior of any category is changed + * Must be called if behavior of any category is changed. */ public static void updateEnabledCategories() { Utils.verifyOnMainThread();