From 1fc212ee88a2ee0e99e889a8d93763562a690aed Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 24 May 2024 14:21:21 +0200 Subject: [PATCH] Move auto-delete settings (#7096) Users had a hard time understanding that automatic deletion and episode cleanup are two different things. Maybe that is because in German, both got translated to the exact same string. Now both are next to each other and the titles are updated, so that it hopefully causes less confusion. --- .../test/antennapod/ui/FeedSettingsTest.java | 2 +- .../test/antennapod/ui/PreferencesTest.java | 21 ++-- .../AutomaticDeletionPreferencesFragment.java | 96 +++++++++++++++++++ .../DownloadsPreferencesFragment.java | 34 ++----- .../preferences/PreferenceActivity.java | 4 + .../FeedMultiSelectActionHandler.java | 2 +- .../res/menu/nav_feed_action_speeddial.xml | 2 +- app/src/main/res/xml/feed_settings.xml | 2 +- .../storage/preferences/UserPreferences.java | 4 +- ui/i18n/src/main/res/values/strings.xml | 13 +-- .../AutoDownloadPreferencesFragment.java | 31 ------ .../res/xml/preferences_auto_deletion.xml | 31 ++++++ .../main/res/xml/preferences_autodownload.xml | 7 -- .../main/res/xml/preferences_downloads.xml | 18 +--- 14 files changed, 164 insertions(+), 103 deletions(-) create mode 100644 app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/AutomaticDeletionPreferencesFragment.java create mode 100644 ui/preferences/src/main/res/xml/preferences_auto_deletion.xml diff --git a/app/src/androidTest/java/de/test/antennapod/ui/FeedSettingsTest.java b/app/src/androidTest/java/de/test/antennapod/ui/FeedSettingsTest.java index 187c9e16d..c34ab19c0 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/FeedSettingsTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/FeedSettingsTest.java @@ -70,7 +70,7 @@ public class FeedSettingsTest { clickPreference(R.string.pref_feed_skip); onView(withText(R.string.cancel_label)).perform(click()); - clickPreference(R.string.auto_delete_label); + clickPreference(R.string.pref_auto_delete_playback_title); onView(withText(R.string.cancel_label)).perform(click()); clickPreference(R.string.feed_volume_adapdation); diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java index 93d9fe129..3e6267ac4 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java @@ -173,11 +173,12 @@ public class PreferencesTest { @Test public void testAutoDelete() { clickPreference(R.string.downloads_pref); - final boolean autoDelete = UserPreferences.isAutoDelete(); onView(withText(R.string.pref_auto_delete_title)).perform(click()); + final boolean autoDelete = UserPreferences.isAutoDelete(); + onView(withText(R.string.pref_auto_delete_playback_title)).perform(click()); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> autoDelete != UserPreferences.isAutoDelete()); - onView(withText(R.string.pref_auto_delete_title)).perform(click()); + onView(withText(R.string.pref_auto_delete_playback_title)).perform(click()); Awaitility.await().atMost(1000, MILLISECONDS) .until(() -> autoDelete == UserPreferences.isAutoDelete()); } @@ -185,8 +186,10 @@ public class PreferencesTest { @Test public void testAutoDeleteLocal() { clickPreference(R.string.downloads_pref); - final boolean initialAutoDelete = UserPreferences.isAutoDeleteLocal(); - assertFalse(initialAutoDelete); + onView(withText(R.string.pref_auto_delete_title)).perform(click()); + onView(withText(R.string.pref_auto_delete_playback_title)).perform(click()); + assertTrue(UserPreferences.isAutoDelete()); + assertFalse(UserPreferences.isAutoDeleteLocal()); onView(withText(R.string.pref_auto_local_delete_title)).perform(click()); onView(withText(R.string.yes)).perform(click()); @@ -289,7 +292,7 @@ public class PreferencesTest { @Test public void testEpisodeCleanupFavoriteOnly() { clickPreference(R.string.downloads_pref); - onView(withText(R.string.pref_automatic_download_title)).perform(click()); + onView(withText(R.string.pref_auto_delete_title)).perform(click()); onView(withText(R.string.pref_episode_cleanup_title)).perform(click()); onView(withId(R.id.select_dialog_listview)).perform(swipeDown()); onView(withText(R.string.episode_cleanup_except_favorite_removal)).perform(click()); @@ -300,7 +303,7 @@ public class PreferencesTest { @Test public void testEpisodeCleanupQueueOnly() { clickPreference(R.string.downloads_pref); - onView(withText(R.string.pref_automatic_download_title)).perform(click()); + onView(withText(R.string.pref_auto_delete_title)).perform(click()); onView(withText(R.string.pref_episode_cleanup_title)).perform(click()); onView(withId(R.id.select_dialog_listview)).perform(swipeDown()); onView(withText(R.string.episode_cleanup_queue_removal)).perform(click()); @@ -311,7 +314,7 @@ public class PreferencesTest { @Test public void testEpisodeCleanupNeverAlg() { clickPreference(R.string.downloads_pref); - onView(withText(R.string.pref_automatic_download_title)).perform(click()); + onView(withText(R.string.pref_auto_delete_title)).perform(click()); onView(withText(R.string.pref_episode_cleanup_title)).perform(click()); onView(withId(R.id.select_dialog_listview)).perform(swipeUp()); onView(withText(R.string.episode_cleanup_never)).perform(click()); @@ -322,7 +325,7 @@ public class PreferencesTest { @Test public void testEpisodeCleanupClassic() { clickPreference(R.string.downloads_pref); - onView(withText(R.string.pref_automatic_download_title)).perform(click()); + onView(withText(R.string.pref_auto_delete_title)).perform(click()); onView(withText(R.string.pref_episode_cleanup_title)).perform(click()); onView(withText(R.string.episode_cleanup_after_listening)).perform(click()); Awaitility.await().atMost(1000, MILLISECONDS) @@ -339,7 +342,7 @@ public class PreferencesTest { @Test public void testEpisodeCleanupNumDays() { clickPreference(R.string.downloads_pref); - clickPreference(R.string.pref_automatic_download_title); + onView(withText(R.string.pref_auto_delete_title)).perform(click()); clickPreference(R.string.pref_episode_cleanup_title); String search = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, 3, 3); onView(withText(search)).perform(scrollTo()); diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/AutomaticDeletionPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/AutomaticDeletionPreferencesFragment.java new file mode 100644 index 000000000..8c7608b6b --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/AutomaticDeletionPreferencesFragment.java @@ -0,0 +1,96 @@ +package de.danoeh.antennapod.ui.screen.preferences; + +import android.content.res.Resources; +import android.os.Bundle; +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.TwoStatePreference; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.storage.preferences.UserPreferences; + + +public class AutomaticDeletionPreferencesFragment extends PreferenceFragmentCompat { + private static final String PREF_AUTO_DELETE_LOCAL = "prefAutoDeleteLocal"; + private boolean blockAutoDeleteLocal = true; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.preferences_auto_deletion); + setupScreen(); + buildEpisodeCleanupPreference(); + checkItemVisibility(UserPreferences.isAutoDelete()); + } + + @Override + public void onStart() { + super.onStart(); + ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.pref_auto_delete_title); + } + + private void checkItemVisibility(boolean autoDeleteEnabled) { + findPreference(UserPreferences.PREF_FAVORITE_KEEPS_EPISODE).setEnabled(autoDeleteEnabled); + findPreference(PREF_AUTO_DELETE_LOCAL).setEnabled(autoDeleteEnabled); + } + + private void setupScreen() { + if (!UserPreferences.isEnableAutodownload()) { + findPreference(UserPreferences.PREF_EPISODE_CLEANUP).setEnabled(false); + findPreference(UserPreferences.PREF_EPISODE_CLEANUP).setSummary(R.string.auto_download_disabled_globally); + } + findPreference(PREF_AUTO_DELETE_LOCAL).setOnPreferenceChangeListener((preference, newValue) -> { + if (blockAutoDeleteLocal && newValue == Boolean.TRUE) { + showAutoDeleteEnableDialog(); + return false; + } else { + return true; + } + }); + findPreference(UserPreferences.PREF_AUTO_DELETE).setOnPreferenceChangeListener((preference, newValue) -> { + if (newValue instanceof Boolean) { + checkItemVisibility((Boolean) newValue); + } + return true; + }); + } + + private void showAutoDeleteEnableDialog() { + new MaterialAlertDialogBuilder(requireContext()) + .setMessage(R.string.pref_auto_local_delete_dialog_body) + .setPositiveButton(R.string.yes, (dialog, which) -> { + blockAutoDeleteLocal = false; + ((TwoStatePreference) findPreference(PREF_AUTO_DELETE_LOCAL)).setChecked(true); + blockAutoDeleteLocal = true; + }) + .setNegativeButton(R.string.cancel_label, null) + .show(); + } + + + private void buildEpisodeCleanupPreference() { + final Resources res = getActivity().getResources(); + + ListPreference pref = findPreference(UserPreferences.PREF_EPISODE_CLEANUP); + String[] values = res.getStringArray( + de.danoeh.antennapod.ui.preferences.R.array.episode_cleanup_values); + String[] entries = new String[values.length]; + for (int x = 0; x < values.length; x++) { + int v = Integer.parseInt(values[x]); + if (v == UserPreferences.EPISODE_CLEANUP_EXCEPT_FAVORITE) { + entries[x] = res.getString(R.string.episode_cleanup_except_favorite_removal); + } else if (v == UserPreferences.EPISODE_CLEANUP_QUEUE) { + entries[x] = res.getString(R.string.episode_cleanup_queue_removal); + } else if (v == UserPreferences.EPISODE_CLEANUP_NULL) { + entries[x] = res.getString(R.string.episode_cleanup_never); + } else if (v == 0) { + entries[x] = res.getString(R.string.episode_cleanup_after_listening); + } else if (v > 0 && v < 24) { + entries[x] = res.getQuantityString(R.plurals.episode_cleanup_hours_after_listening, v, v); + } else { + int numDays = v / 24; // assume underlying value will be NOT fraction of days, e.g., 36 (hours) + entries[x] = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, numDays, numDays); + } + } + pref.setEntries(entries); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/DownloadsPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/DownloadsPreferencesFragment.java index fad8c6986..3af3a0248 100644 --- a/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/DownloadsPreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/DownloadsPreferencesFragment.java @@ -2,16 +2,12 @@ package de.danoeh.antennapod.ui.screen.preferences; import android.content.SharedPreferences; import android.os.Bundle; - import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; -import androidx.preference.TwoStatePreference; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; import de.danoeh.antennapod.R; import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager; -import de.danoeh.antennapod.ui.preferences.screen.downloads.ChooseDataFolderDialog; import de.danoeh.antennapod.storage.preferences.UserPreferences; +import de.danoeh.antennapod.ui.preferences.screen.downloads.ChooseDataFolderDialog; import java.io.File; @@ -19,12 +15,10 @@ import java.io.File; public class DownloadsPreferencesFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String PREF_SCREEN_AUTODL = "prefAutoDownloadSettings"; - private static final String PREF_AUTO_DELETE_LOCAL = "prefAutoDeleteLocal"; + private static final String PREF_SCREEN_AUTO_DELETE = "prefAutoDeleteScreen"; private static final String PREF_PROXY = "prefProxy"; private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; - private boolean blockAutoDeleteLocal = true; - @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { addPreferencesFromResource(R.xml.preferences_downloads); @@ -55,6 +49,10 @@ public class DownloadsPreferencesFragment extends PreferenceFragmentCompat ((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_autodownload); return true; }); + findPreference(PREF_SCREEN_AUTO_DELETE).setOnPreferenceClickListener(preference -> { + ((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_auto_deletion); + return true; + }); // validate and set correct value: number of downloads between 1 and 50 (inclusive) findPreference(PREF_PROXY).setOnPreferenceClickListener(preference -> { ProxyDialog dialog = new ProxyDialog(getActivity()); @@ -68,14 +66,6 @@ public class DownloadsPreferencesFragment extends PreferenceFragmentCompat }); return true; }); - findPreference(PREF_AUTO_DELETE_LOCAL).setOnPreferenceChangeListener((preference, newValue) -> { - if (blockAutoDeleteLocal && newValue == Boolean.TRUE) { - showAutoDeleteEnableDialog(); - return false; - } else { - return true; - } - }); } private void setDataFolderText() { @@ -91,16 +81,4 @@ public class DownloadsPreferencesFragment extends PreferenceFragmentCompat FeedUpdateManager.getInstance().restartUpdateAlarm(getContext(), true); } } - - private void showAutoDeleteEnableDialog() { - new MaterialAlertDialogBuilder(requireContext()) - .setMessage(R.string.pref_auto_local_delete_dialog_body) - .setPositiveButton(R.string.yes, (dialog, which) -> { - blockAutoDeleteLocal = false; - ((TwoStatePreference) findPreference(PREF_AUTO_DELETE_LOCAL)).setChecked(true); - blockAutoDeleteLocal = true; - }) - .setNegativeButton(R.string.cancel_label, null) - .show(); - } } diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceActivity.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceActivity.java index e82c2c084..b083bda5d 100644 --- a/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceActivity.java @@ -83,6 +83,8 @@ public class PreferenceActivity extends AppCompatActivity implements SearchPrefe prefFragment = new NotificationPreferencesFragment(); } else if (screen == R.xml.preferences_swipe) { prefFragment = new SwipePreferencesFragment(); + } else if (screen == R.xml.preferences_auto_deletion) { + prefFragment = new AutomaticDeletionPreferencesFragment(); } return prefFragment; } @@ -106,6 +108,8 @@ public class PreferenceActivity extends AppCompatActivity implements SearchPrefe return R.string.feed_settings_label; } else if (preferences == R.xml.preferences_swipe) { return R.string.swipeactions_label; + } else if (preferences == R.xml.preferences_auto_deletion) { + return R.string.pref_auto_delete_title; } return R.string.settings_label; } diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMultiSelectActionHandler.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMultiSelectActionHandler.java index f2c89f12f..7f2d96ed4 100644 --- a/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMultiSelectActionHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMultiSelectActionHandler.java @@ -96,7 +96,7 @@ public class FeedMultiSelectActionHandler { private void autoDeleteEpisodesPrefHandler() { PreferenceListDialog preferenceListDialog = new PreferenceListDialog(activity, - activity.getString(R.string.auto_delete_label)); + activity.getString(R.string.pref_auto_delete_playback_title)); String[] items = activity.getResources().getStringArray(R.array.spnAutoDeleteItems); preferenceListDialog.openDialog(items); preferenceListDialog.setOnPreferenceChangedListener(which -> { diff --git a/app/src/main/res/menu/nav_feed_action_speeddial.xml b/app/src/main/res/menu/nav_feed_action_speeddial.xml index 250d12bc2..ce2453ab6 100644 --- a/app/src/main/res/menu/nav_feed_action_speeddial.xml +++ b/app/src/main/res/menu/nav_feed_action_speeddial.xml @@ -23,7 +23,7 @@ + android:title="@string/pref_auto_delete_playback_title" /> Close Retry Include in auto downloads - Auto delete episode Volume adaptation Turn volume for episodes of this podcast up or down: %1$s No adaption @@ -390,7 +389,7 @@ Search… No results Clear history - Episode cleanup + Delete before auto download Episodes that should be eligible for removal if Auto Download needs space for new episodes Pause playback when headphones or bluetooth are disconnected Resume playback when the headphones are reconnected @@ -404,8 +403,10 @@ Skip episode Restart episode Jump to next queue item when playback completes - Delete episode when playback completes - Auto delete + Delete episode when playback completes + Delete after playing + Automatic deletion + Delete episodes after playing or when automatic download needs space Auto delete from local folders Include local folders in Auto delete functionality Note that for local folders this will remove episodes from AntennaPod and delete their media files from your device storage. They cannot be downloaded again through AntennaPod. Enable auto delete? @@ -460,8 +461,8 @@ Allow automatic download only for selected Wi-Fi networks. Download when not charging Allow automatic download when the battery is not charging - Episode cache - Total number of downloaded episodes cached on the device. Automatic download will be suspended if this number is reached. + Episode limit + Automatic download is stopped if this number is reached Use episode cover Use the episode specific cover in lists whenever available. If unchecked, the app will always use the podcast cover image. Show remaining time diff --git a/ui/preferences/src/main/java/de/danoeh/antennapod/ui/preferences/screen/AutoDownloadPreferencesFragment.java b/ui/preferences/src/main/java/de/danoeh/antennapod/ui/preferences/screen/AutoDownloadPreferencesFragment.java index 7c0c3ed4c..1f0fbfbeb 100644 --- a/ui/preferences/src/main/java/de/danoeh/antennapod/ui/preferences/screen/AutoDownloadPreferencesFragment.java +++ b/ui/preferences/src/main/java/de/danoeh/antennapod/ui/preferences/screen/AutoDownloadPreferencesFragment.java @@ -3,7 +3,6 @@ package de.danoeh.antennapod.ui.preferences.screen; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; -import android.content.res.Resources; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Build; @@ -11,7 +10,6 @@ import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import androidx.preference.CheckBoxPreference; -import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceScreen; @@ -35,7 +33,6 @@ public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat { setupAutoDownloadScreen(); buildAutodownloadSelectedNetworksPreference(); setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); - buildEpisodeCleanupPreference(); } @Override @@ -78,7 +75,6 @@ public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat { findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setEnabled(autoDownload); findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY).setEnabled(autoDownload); findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(autoDownload); - findPreference(UserPreferences.PREF_EPISODE_CLEANUP).setEnabled(autoDownload); setSelectedNetworksEnabled(autoDownload && UserPreferences.isEnableAutodownloadWifiFilter()); } @@ -165,33 +161,6 @@ public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat { } } - private void buildEpisodeCleanupPreference() { - final Resources res = getActivity().getResources(); - - ListPreference pref = findPreference(UserPreferences.PREF_EPISODE_CLEANUP); - String[] values = res.getStringArray( - R.array.episode_cleanup_values); - String[] entries = new String[values.length]; - for (int x = 0; x < values.length; x++) { - int v = Integer.parseInt(values[x]); - if (v == UserPreferences.EPISODE_CLEANUP_EXCEPT_FAVORITE) { - entries[x] = res.getString(R.string.episode_cleanup_except_favorite_removal); - } else if (v == UserPreferences.EPISODE_CLEANUP_QUEUE) { - entries[x] = res.getString(R.string.episode_cleanup_queue_removal); - } else if (v == UserPreferences.EPISODE_CLEANUP_NULL){ - entries[x] = res.getString(R.string.episode_cleanup_never); - } else if (v == 0) { - entries[x] = res.getString(R.string.episode_cleanup_after_listening); - } else if (v > 0 && v < 24) { - entries[x] = res.getQuantityString(R.plurals.episode_cleanup_hours_after_listening, v, v); - } else { - int numDays = v / 24; // assume underlying value will be NOT fraction of days, e.g., 36 (hours) - entries[x] = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, numDays, numDays); - } - } - pref.setEntries(entries); - } - private void setSelectedNetworksEnabled(boolean b) { if (selectedNetworks != null) { for (Preference p : selectedNetworks) { diff --git a/ui/preferences/src/main/res/xml/preferences_auto_deletion.xml b/ui/preferences/src/main/res/xml/preferences_auto_deletion.xml new file mode 100644 index 000000000..057ce5517 --- /dev/null +++ b/ui/preferences/src/main/res/xml/preferences_auto_deletion.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/ui/preferences/src/main/res/xml/preferences_autodownload.xml b/ui/preferences/src/main/res/xml/preferences_autodownload.xml index 339ddc9af..3ababbf1d 100644 --- a/ui/preferences/src/main/res/xml/preferences_autodownload.xml +++ b/ui/preferences/src/main/res/xml/preferences_autodownload.xml @@ -15,13 +15,6 @@ android:title="@string/pref_episode_cache_title" android:summary="@string/pref_episode_cache_summary" android:entryValues="@array/episode_cache_size_values"/> - - - -