From 4b07740b9e4b6f84cc09dbe8c1110f3ae70ecd73 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 14 Apr 2024 11:38:21 +0200 Subject: [PATCH] Move auto-delete settings 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/PreferencesTest.java | 17 ++-- .../AutomaticDeletionPreferencesFragment.java | 96 +++++++++++++++++++ .../DownloadsPreferencesFragment.java | 34 ++----- .../preferences/PreferenceActivity.java | 4 + .../storage/preferences/UserPreferences.java | 4 +- ui/i18n/src/main/res/values/strings.xml | 6 +- .../AutoDownloadPreferencesFragment.java | 31 ------ .../res/xml/preferences_auto_deletion.xml | 31 ++++++ .../main/res/xml/preferences_autodownload.xml | 7 -- .../main/res/xml/preferences_downloads.xml | 18 +--- 10 files changed, 154 insertions(+), 94 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/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java index 93d9fe1290..13c41fc4db 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java @@ -173,6 +173,7 @@ public void testContinuousPlayback() { @Test public void testAutoDelete() { clickPreference(R.string.downloads_pref); + onView(withText(R.string.pref_auto_delete_title)).perform(click()); final boolean autoDelete = UserPreferences.isAutoDelete(); onView(withText(R.string.pref_auto_delete_title)).perform(click()); Awaitility.await().atMost(1000, MILLISECONDS) @@ -185,8 +186,10 @@ public void testAutoDelete() { @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_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 void testAutomaticDownload() { @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 void testEpisodeCleanupFavoriteOnly() { @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 void testEpisodeCleanupQueueOnly() { @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 void testEpisodeCleanupNeverAlg() { @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 void testEpisodeCleanupClassic() { @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 0000000000..a06e21445c --- /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.auto_delete_label); + } + + 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 fad8c69868..3af3a0248e 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 @@ 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 @@ 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 @@ private void setupNetworkScreen() { ((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 @@ private void setupNetworkScreen() { }); 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 void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin 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 e82c2c0843..c9e9cda404 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 @@ private PreferenceFragmentCompat getPreferenceScreen(int screen) { 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 static int getTitleOfPage(int preferences) { 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.auto_delete_label; } return R.string.settings_label; } diff --git a/storage/preferences/src/main/java/de/danoeh/antennapod/storage/preferences/UserPreferences.java b/storage/preferences/src/main/java/de/danoeh/antennapod/storage/preferences/UserPreferences.java index 9e7333a2ec..f68fa77a71 100644 --- a/storage/preferences/src/main/java/de/danoeh/antennapod/storage/preferences/UserPreferences.java +++ b/storage/preferences/src/main/java/de/danoeh/antennapod/storage/preferences/UserPreferences.java @@ -80,8 +80,8 @@ public abstract class UserPreferences { public static final String PREF_HARDWARE_PREVIOUS_BUTTON = "prefHardwarePreviousButton"; public static final String PREF_FOLLOW_QUEUE = "prefFollowQueue"; public static final String PREF_SKIP_KEEPS_EPISODE = "prefSkipKeepsEpisode"; - private static final String PREF_FAVORITE_KEEPS_EPISODE = "prefFavoriteKeepsEpisode"; - private static final String PREF_AUTO_DELETE = "prefAutoDelete"; + public static final String PREF_FAVORITE_KEEPS_EPISODE = "prefFavoriteKeepsEpisode"; + public static final String PREF_AUTO_DELETE = "prefAutoDelete"; private static final String PREF_AUTO_DELETE_LOCAL = "prefAutoDeleteLocal"; public static final String PREF_SMART_MARK_AS_PLAYED_SECS = "prefSmartMarkAsPlayedSecs"; private static final String PREF_PLAYBACK_SPEED_ARRAY = "prefPlaybackSpeedArray"; diff --git a/ui/i18n/src/main/res/values/strings.xml b/ui/i18n/src/main/res/values/strings.xml index 6a42387799..de0961de37 100644 --- a/ui/i18n/src/main/res/values/strings.xml +++ b/ui/i18n/src/main/res/values/strings.xml @@ -385,7 +385,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 @@ -455,8 +455,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 7c0c3ed4c7..1f0fbfbebe 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 @@ 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.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 void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setupAutoDownloadScreen(); buildAutodownloadSelectedNetworksPreference(); setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); - buildEpisodeCleanupPreference(); } @Override @@ -78,7 +75,6 @@ private void checkAutodownloadItemVisibility(boolean autoDownload) { 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 @@ private void clearAutodownloadSelectedNetworsPreference() { } } - 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 0000000000..215d5dffcd --- /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 339ddc9af2..3ababbf1dd 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"/> - - - -