diff --git a/app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java new file mode 100644 index 000000000..bc24fbe81 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java @@ -0,0 +1,271 @@ +package org.schabi.newpipe.settings; + +import static org.schabi.newpipe.extractor.utils.Utils.isBlank; +import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Bundle; +import android.widget.Toast; + +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.preference.Preference; +import androidx.preference.PreferenceManager; + +import org.schabi.newpipe.NewPipeDatabase; +import org.schabi.newpipe.R; +import org.schabi.newpipe.error.ErrorUtil; +import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; +import org.schabi.newpipe.streams.io.StoredFileHelper; +import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.ZipHelper; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.Objects; + +public class BackupRestoreSettingsFragment extends BasePreferenceFragment { + + private static final String ZIP_MIME_TYPE = "application/zip"; + + private final SimpleDateFormat exportDateFormat = + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US); + private ContentSettingsManager manager; + private String importExportDataPathKey; + private final ActivityResultLauncher requestImportPathLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + this::requestImportPathResult); + private final ActivityResultLauncher requestExportPathLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + this::requestExportPathResult); + + + @Override + public void onCreatePreferences(@Nullable final Bundle savedInstanceState, + @Nullable final String rootKey) { + final File homeDir = ContextCompat.getDataDir(requireContext()); + Objects.requireNonNull(homeDir); + manager = new ContentSettingsManager(new NewPipeFileLocator(homeDir)); + manager.deleteSettingsFile(); + + importExportDataPathKey = getString(R.string.import_export_data_path); + + + addPreferencesFromResourceRegistry(); + + final Preference importDataPreference = requirePreference(R.string.import_data); + importDataPreference.setOnPreferenceClickListener((Preference p) -> { + NoFileManagerSafeGuard.launchSafe( + requestImportPathLauncher, + StoredFileHelper.getPicker(requireContext(), + ZIP_MIME_TYPE, getImportExportDataUri()), + TAG, + getContext() + ); + + return true; + }); + + final Preference exportDataPreference = requirePreference(R.string.export_data); + exportDataPreference.setOnPreferenceClickListener((final Preference p) -> { + NoFileManagerSafeGuard.launchSafe( + requestExportPathLauncher, + StoredFileHelper.getNewPicker(requireContext(), + "NewPipeData-" + exportDateFormat.format(new Date()) + ".zip", + ZIP_MIME_TYPE, getImportExportDataUri()), + TAG, + getContext() + ); + + return true; + }); + + final Preference resetSettings = findPreference(getString(R.string.reset_settings)); + // Resets all settings by deleting shared preference and restarting the app + // A dialogue will pop up to confirm if user intends to reset all settings + assert resetSettings != null; + resetSettings.setOnPreferenceClickListener(preference -> { + // Show Alert Dialogue + final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setMessage(R.string.reset_all_settings); + builder.setCancelable(true); + builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> { + // Deletes all shared preferences xml files. + final SharedPreferences sharedPreferences = + PreferenceManager.getDefaultSharedPreferences(requireContext()); + sharedPreferences.edit().clear().apply(); + // Restarts the app + if (getActivity() == null) { + return; + } + NavigationHelper.restartApp(getActivity()); + }); + builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + }); + final AlertDialog alertDialog = builder.create(); + alertDialog.show(); + return true; + }); + } + + private void requestExportPathResult(final ActivityResult result) { + assureCorrectAppLanguage(requireContext()); + if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { + // will be saved only on success + final Uri lastExportDataUri = result.getData().getData(); + + final StoredFileHelper file = new StoredFileHelper( + requireContext(), result.getData().getData(), ZIP_MIME_TYPE); + + exportDatabase(file, lastExportDataUri); + } + } + + private void requestImportPathResult(final ActivityResult result) { + assureCorrectAppLanguage(requireContext()); + if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { + // will be saved only on success + final Uri lastImportDataUri = result.getData().getData(); + + final StoredFileHelper file = new StoredFileHelper( + requireContext(), result.getData().getData(), ZIP_MIME_TYPE); + + new androidx.appcompat.app.AlertDialog.Builder(requireActivity()) + .setMessage(R.string.override_current_data) + .setPositiveButton(R.string.ok, (d, id) -> + importDatabase(file, lastImportDataUri)) + .setNegativeButton(R.string.cancel, (d, id) -> + d.cancel()) + .show(); + } + } + + private void exportDatabase(final StoredFileHelper file, final Uri exportDataUri) { + try { + //checkpoint before export + NewPipeDatabase.checkpoint(); + + final SharedPreferences preferences = PreferenceManager + .getDefaultSharedPreferences(requireContext()); + manager.exportDatabase(preferences, file); + + saveLastImportExportDataUri(exportDataUri); // save export path only on success + Toast.makeText(requireContext(), R.string.export_complete_toast, Toast.LENGTH_SHORT) + .show(); + } catch (final Exception e) { + ErrorUtil.showUiErrorSnackbar(this, "Exporting database", e); + } + } + + private void importDatabase(final StoredFileHelper file, final Uri importDataUri) { + // check if file is supported + if (!ZipHelper.isValidZipFile(file)) { + Toast.makeText(requireContext(), R.string.no_valid_zip_file, Toast.LENGTH_SHORT) + .show(); + return; + } + + try { + if (!manager.ensureDbDirectoryExists()) { + throw new IOException("Could not create databases dir"); + } + + if (!manager.extractDb(file)) { + Toast.makeText(requireContext(), R.string.could_not_import_all_files, + Toast.LENGTH_LONG) + .show(); + } + + // if settings file exist, ask if it should be imported. + if (manager.extractSettings(file)) { + new androidx.appcompat.app.AlertDialog.Builder(requireContext()) + .setTitle(R.string.import_settings) + .setNegativeButton(R.string.cancel, (dialog, which) -> { + dialog.dismiss(); + finishImport(importDataUri); + }) + .setPositiveButton(R.string.ok, (dialog, which) -> { + dialog.dismiss(); + final Context context = requireContext(); + final SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(context); + manager.loadSharedPreferences(prefs); + cleanImport(context, prefs); + finishImport(importDataUri); + }) + .show(); + } else { + finishImport(importDataUri); + } + } catch (final Exception e) { + ErrorUtil.showUiErrorSnackbar(this, "Importing database", e); + } + } + + /** + * Remove settings that are not supposed to be imported on different devices + * and reset them to default values. + * @param context the context used for the import + * @param prefs the preferences used while running the import + */ + private void cleanImport(@NonNull final Context context, + @NonNull final SharedPreferences prefs) { + // Check if media tunnelling needs to be disabled automatically, + // if it was disabled automatically in the imported preferences. + final String tunnelingKey = context.getString(R.string.disable_media_tunneling_key); + final String automaticTunnelingKey = + context.getString(R.string.disabled_media_tunneling_automatically_key); + // R.string.disable_media_tunneling_key should always be true + // if R.string.disabled_media_tunneling_automatically_key equals 1, + // but we double check here just to be sure and to avoid regressions + // caused by possible later modification of the media tunneling functionality. + // R.string.disabled_media_tunneling_automatically_key == 0: + // automatic value overridden by user in settings + // R.string.disabled_media_tunneling_automatically_key == -1: not set + final boolean wasMediaTunnelingDisabledAutomatically = + prefs.getInt(automaticTunnelingKey, -1) == 1 + && prefs.getBoolean(tunnelingKey, false); + if (wasMediaTunnelingDisabledAutomatically) { + prefs.edit() + .putInt(automaticTunnelingKey, -1) + .putBoolean(tunnelingKey, false) + .apply(); + NewPipeSettings.setMediaTunneling(context); + } + } + + /** + * Save import path and restart system. + * + * @param importDataUri The import path to save + */ + private void finishImport(final Uri importDataUri) { + // save import path only on success + saveLastImportExportDataUri(importDataUri); + // restart app to properly load db + NavigationHelper.restartApp(requireActivity()); + } + + private Uri getImportExportDataUri() { + final String path = defaultPreferences.getString(importExportDataPathKey, null); + return isBlank(path) ? null : Uri.parse(path); + } + + private void saveLastImportExportDataUri(final Uri importExportDataUri) { + final SharedPreferences.Editor editor = defaultPreferences.edit() + .putString(importExportDataPathKey, importExportDataUri.toString()); + editor.apply(); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index ee34f01dd..ec3b1b2d7 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -1,104 +1,34 @@ package org.schabi.newpipe.settings; -import static org.schabi.newpipe.extractor.utils.Utils.isBlank; -import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; - -import android.app.Activity; import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.widget.Toast; -import androidx.activity.result.ActivityResult; -import androidx.activity.result.ActivityResultLauncher; -import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.core.content.ContextCompat; import androidx.preference.Preference; -import androidx.preference.PreferenceManager; import org.schabi.newpipe.DownloaderImpl; -import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; -import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.localization.ContentCountry; import org.schabi.newpipe.extractor.localization.Localization; -import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; -import org.schabi.newpipe.streams.io.StoredFileHelper; -import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PicassoHelper; -import org.schabi.newpipe.util.ZipHelper; -import java.io.File; import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.Objects; public class ContentSettingsFragment extends BasePreferenceFragment { - private static final String ZIP_MIME_TYPE = "application/zip"; - - private final SimpleDateFormat exportDateFormat = - new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US); - - private ContentSettingsManager manager; - - private String importExportDataPathKey; private String youtubeRestrictedModeEnabledKey; private Localization initialSelectedLocalization; private ContentCountry initialSelectedContentCountry; private String initialLanguage; - private final ActivityResultLauncher requestImportPathLauncher = - registerForActivityResult(new StartActivityForResult(), this::requestImportPathResult); - private final ActivityResultLauncher requestExportPathLauncher = - registerForActivityResult(new StartActivityForResult(), this::requestExportPathResult); @Override public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { - final File homeDir = ContextCompat.getDataDir(requireContext()); - Objects.requireNonNull(homeDir); - manager = new ContentSettingsManager(new NewPipeFileLocator(homeDir)); - manager.deleteSettingsFile(); - - importExportDataPathKey = getString(R.string.import_export_data_path); youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled); addPreferencesFromResourceRegistry(); - final Preference importDataPreference = requirePreference(R.string.import_data); - importDataPreference.setOnPreferenceClickListener((Preference p) -> { - NoFileManagerSafeGuard.launchSafe( - requestImportPathLauncher, - StoredFileHelper.getPicker(requireContext(), - ZIP_MIME_TYPE, getImportExportDataUri()), - TAG, - getContext() - ); - - return true; - }); - - final Preference exportDataPreference = requirePreference(R.string.export_data); - exportDataPreference.setOnPreferenceClickListener((final Preference p) -> { - NoFileManagerSafeGuard.launchSafe( - requestExportPathLauncher, - StoredFileHelper.getNewPicker(requireContext(), - "NewPipeData-" + exportDateFormat.format(new Date()) + ".zip", - ZIP_MIME_TYPE, getImportExportDataUri()), - TAG, - getContext() - ); - - return true; - }); - initialSelectedLocalization = org.schabi.newpipe.util.Localization .getPreferredLocalization(requireContext()); initialSelectedContentCountry = org.schabi.newpipe.util.Localization @@ -154,151 +84,4 @@ public class ContentSettingsFragment extends BasePreferenceFragment { NewPipe.setupLocalization(selectedLocalization, selectedContentCountry); } } - - private void requestExportPathResult(final ActivityResult result) { - assureCorrectAppLanguage(getContext()); - if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { - // will be saved only on success - final Uri lastExportDataUri = result.getData().getData(); - - final StoredFileHelper file = - new StoredFileHelper(getContext(), result.getData().getData(), ZIP_MIME_TYPE); - - exportDatabase(file, lastExportDataUri); - } - } - - private void requestImportPathResult(final ActivityResult result) { - assureCorrectAppLanguage(getContext()); - if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { - // will be saved only on success - final Uri lastImportDataUri = result.getData().getData(); - - final StoredFileHelper file = - new StoredFileHelper(getContext(), result.getData().getData(), ZIP_MIME_TYPE); - - new AlertDialog.Builder(requireActivity()) - .setMessage(R.string.override_current_data) - .setPositiveButton(R.string.ok, (d, id) -> - importDatabase(file, lastImportDataUri)) - .setNegativeButton(R.string.cancel, (d, id) -> - d.cancel()) - .show(); - } - } - - private void exportDatabase(final StoredFileHelper file, final Uri exportDataUri) { - try { - //checkpoint before export - NewPipeDatabase.checkpoint(); - - final SharedPreferences preferences = PreferenceManager - .getDefaultSharedPreferences(requireContext()); - manager.exportDatabase(preferences, file); - - saveLastImportExportDataUri(exportDataUri); // save export path only on success - Toast.makeText(getContext(), R.string.export_complete_toast, Toast.LENGTH_SHORT).show(); - } catch (final Exception e) { - ErrorUtil.showUiErrorSnackbar(this, "Exporting database", e); - } - } - - private void importDatabase(final StoredFileHelper file, final Uri importDataUri) { - // check if file is supported - if (!ZipHelper.isValidZipFile(file)) { - Toast.makeText(getContext(), R.string.no_valid_zip_file, Toast.LENGTH_SHORT) - .show(); - return; - } - - try { - if (!manager.ensureDbDirectoryExists()) { - throw new IOException("Could not create databases dir"); - } - - if (!manager.extractDb(file)) { - Toast.makeText(getContext(), R.string.could_not_import_all_files, Toast.LENGTH_LONG) - .show(); - } - - // if settings file exist, ask if it should be imported. - if (manager.extractSettings(file)) { - new AlertDialog.Builder(requireContext()) - .setTitle(R.string.import_settings) - .setNegativeButton(R.string.cancel, (dialog, which) -> { - dialog.dismiss(); - finishImport(importDataUri); - }) - .setPositiveButton(R.string.ok, (dialog, which) -> { - dialog.dismiss(); - final Context context = requireContext(); - final SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(context); - manager.loadSharedPreferences(prefs); - cleanImport(context, prefs); - finishImport(importDataUri); - }) - .show(); - } else { - finishImport(importDataUri); - } - } catch (final Exception e) { - ErrorUtil.showUiErrorSnackbar(this, "Importing database", e); - } - } - - /** - * Remove settings that are not supposed to be imported on different devices - * and reset them to default values. - * @param context the context used for the import - * @param prefs the preferences used while running the import - */ - private void cleanImport(@NonNull final Context context, - @NonNull final SharedPreferences prefs) { - // Check if media tunnelling needs to be disabled automatically, - // if it was disabled automatically in the imported preferences. - final String tunnelingKey = context.getString(R.string.disable_media_tunneling_key); - final String automaticTunnelingKey = - context.getString(R.string.disabled_media_tunneling_automatically_key); - // R.string.disable_media_tunneling_key should always be true - // if R.string.disabled_media_tunneling_automatically_key equals 1, - // but we double check here just to be sure and to avoid regressions - // caused by possible later modification of the media tunneling functionality. - // R.string.disabled_media_tunneling_automatically_key == 0: - // automatic value overridden by user in settings - // R.string.disabled_media_tunneling_automatically_key == -1: not set - final boolean wasMediaTunnelingDisabledAutomatically = - prefs.getInt(automaticTunnelingKey, -1) == 1 - && prefs.getBoolean(tunnelingKey, false); - if (wasMediaTunnelingDisabledAutomatically) { - prefs.edit() - .putInt(automaticTunnelingKey, -1) - .putBoolean(tunnelingKey, false) - .apply(); - NewPipeSettings.setMediaTunneling(context); - } - } - - /** - * Save import path and restart system. - * - * @param importDataUri The import path to save - */ - private void finishImport(final Uri importDataUri) { - // save import path only on success - saveLastImportExportDataUri(importDataUri); - // restart app to properly load db - NavigationHelper.restartApp(requireActivity()); - } - - private Uri getImportExportDataUri() { - final String path = defaultPreferences.getString(importExportDataPathKey, null); - return isBlank(path) ? null : Uri.parse(path); - } - - private void saveLastImportExportDataUri(final Uri importExportDataUri) { - final SharedPreferences.Editor editor = defaultPreferences.edit() - .putString(importExportDataPathKey, importExportDataUri.toString()); - editor.apply(); - } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java index f2a4e1190..0f4c9765e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java @@ -1,19 +1,15 @@ package org.schabi.newpipe.settings; -import android.app.AlertDialog; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import androidx.preference.Preference; -import androidx.preference.PreferenceManager; import org.schabi.newpipe.R; import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.feed.notifications.NotificationWorker; -import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PicassoHelper; import java.util.Optional; @@ -39,8 +35,6 @@ public class DebugSettingsFragment extends BasePreferenceFragment { findPreference(getString(R.string.show_error_snackbar_key)); final Preference createErrorNotificationPreference = findPreference(getString(R.string.create_error_notification_key)); - final Preference resetSettings = - findPreference(getString(R.string.reset_settings)); assert allowHeapDumpingPreference != null; assert showMemoryLeaksPreference != null; @@ -92,32 +86,6 @@ public class DebugSettingsFragment extends BasePreferenceFragment { new ErrorInfo(new RuntimeException(DUMMY), UserAction.UI_ERROR, DUMMY)); return true; }); - - // Resets all settings by deleting shared preference and restarting the app - // A dialogue will pop up to confirm if user intends to reset all settings - assert resetSettings != null; - resetSettings.setOnPreferenceClickListener(preference -> { - // Show Alert Dialogue - final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - builder.setMessage(R.string.reset_all_settings); - builder.setCancelable(true); - builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> { - // Deletes all shared preferences xml files. - final SharedPreferences sharedPreferences = - PreferenceManager.getDefaultSharedPreferences(requireContext()); - sharedPreferences.edit().clear().apply(); - // Restarts the app - if (getActivity() == null) { - return; - } - NavigationHelper.restartApp(getActivity()); - }); - builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - }); - final AlertDialog alertDialog = builder.create(); - alertDialog.show(); - return true; - }); } /** diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java index b85b95eb0..f280324cf 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java @@ -63,6 +63,7 @@ public final class NewPipeSettings { PreferenceManager.setDefaultValues(context, R.xml.player_notification_settings, true); PreferenceManager.setDefaultValues(context, R.xml.update_settings, true); PreferenceManager.setDefaultValues(context, R.xml.debug_settings, true); + PreferenceManager.setDefaultValues(context, R.xml.backup_restore_settings, true); saveDefaultVideoDownloadDirectory(context); saveDefaultAudioDownloadDirectory(context); diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsResourceRegistry.java b/app/src/main/java/org/schabi/newpipe/settings/SettingsResourceRegistry.java index b3d0741bb..06e0a7c1e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingsResourceRegistry.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsResourceRegistry.java @@ -41,6 +41,7 @@ public final class SettingsResourceRegistry { add(UpdateSettingsFragment.class, R.xml.update_settings); add(VideoAudioSettingsFragment.class, R.xml.video_audio_settings); add(ExoPlayerSettingsFragment.class, R.xml.exoplayer_settings); + add(BackupRestoreSettingsFragment.class, R.xml.backup_restore_settings); } private SettingRegistryEntry add( diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index ea283e62c..30efca080 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -223,7 +223,6 @@ prefer_descriptive_audio last_resize_mode - reset_settings diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9c843784e..314eaa9bd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,6 +155,7 @@ Updates Player notification Configure current playing stream notification + Backup and restore Playing in background Playing in popup mode Content diff --git a/app/src/main/res/xml/backup_restore_settings.xml b/app/src/main/res/xml/backup_restore_settings.xml new file mode 100644 index 000000000..b8fee0aa6 --- /dev/null +++ b/app/src/main/res/xml/backup_restore_settings.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index 73a849af7..dac5dccc1 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -124,20 +124,6 @@ app:singleLineTitle="false" app:iconSpaceReserved="false" /> - - - - - diff --git a/app/src/main/res/xml/main_settings.xml b/app/src/main/res/xml/main_settings.xml index 1b1c17e85..5f96989f9 100644 --- a/app/src/main/res/xml/main_settings.xml +++ b/app/src/main/res/xml/main_settings.xml @@ -47,6 +47,12 @@ android:title="@string/settings_category_updates_title" app:iconSpaceReserved="false" /> + +