Convert autodownloads from master switch to per-podcast setting (#7458)

This commit is contained in:
Felix Nüsse 2025-01-18 12:31:44 +01:00 committed by GitHub
parent cc8f5b6159
commit e4ac872b74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 250 additions and 276 deletions

View File

@ -132,7 +132,7 @@ public class PlaybackServiceMediaPlayerTest {
private Playable writeTestPlayable(String downloadUrl, String fileUrl) {
Feed f = new Feed(0, null, "f", "l", "d", null, null, null, null,
"i", null, null, "l", System.currentTimeMillis());
FeedPreferences prefs = new FeedPreferences(f.getId(), false, FeedPreferences.AutoDeleteAction.NEVER,
FeedPreferences prefs = new FeedPreferences(f.getId(), FeedPreferences.AutoDownloadSetting.GLOBAL, FeedPreferences.AutoDeleteAction.NEVER,
VolumeAdaptionSetting.OFF, FeedPreferences.NewEpisodesAction.NOTHING, null, null);
f.setPreferences(prefs);
f.setItems(new ArrayList<>());

View File

@ -59,7 +59,7 @@ public class PreferencesTest {
EspressoTestUtils.clearPreferences();
activityTestRule.launchActivity(new Intent());
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activityTestRule.getActivity());
prefs.edit().putBoolean(UserPreferences.PREF_ENABLE_AUTODL, true).commit();
prefs.edit().putBoolean(UserPreferences.PREF_AUTODL_GLOBAL, true).commit();
res = activityTestRule.getActivity().getResources();
UserPreferences.init(activityTestRule.getActivity());
@ -269,17 +269,17 @@ public class PreferencesTest {
@Test
public void testAutomaticDownload() {
final boolean automaticDownload = UserPreferences.isEnableAutodownload();
final boolean automaticDownload = UserPreferences.isEnableAutodownloadGlobal();
clickPreference(R.string.downloads_pref);
clickPreference(R.string.pref_automatic_download_title);
clickPreference(R.string.pref_automatic_download_title);
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> automaticDownload != UserPreferences.isEnableAutodownload());
if (!UserPreferences.isEnableAutodownload()) {
.until(() -> automaticDownload != UserPreferences.isEnableAutodownloadGlobal());
if (!UserPreferences.isEnableAutodownloadGlobal()) {
clickPreference(R.string.pref_automatic_download_title);
}
Awaitility.await().atMost(1000, MILLISECONDS)
.until(UserPreferences::isEnableAutodownload);
.until(UserPreferences::isEnableAutodownloadGlobal);
final boolean enableAutodownloadOnBattery = UserPreferences.isEnableAutodownloadOnBattery();
clickPreference(R.string.pref_automatic_download_on_battery_title);
Awaitility.await().atMost(1000, MILLISECONDS)
@ -327,6 +327,7 @@ public class PreferencesTest {
clickPreference(R.string.downloads_pref);
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_after_listening)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> {

View File

@ -10,10 +10,7 @@ import org.apache.commons.lang3.StringUtils;
import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.storage.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.CrashReportWriter;
import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.storage.preferences.UserPreferences.EnqueueLocation;
@ -167,5 +164,13 @@ public class PreferenceUpgrader {
prefs.edit().putString(UserPreferences.PREF_FILTER_ALL_EPISODES, oldEpisodeFilter).apply();
}
}
if (oldVersion < 3070000) {
// If autodownloads are enabled, we will start deleting episodes.
// To prevent accidents, force off the deletions.
if (!UserPreferences.isEnableAutodownloadGlobal()) {
prefs.edit().putString(UserPreferences.PREF_EPISODE_CLEANUP,
"" + UserPreferences.EPISODE_CLEANUP_NULL).apply();
}
}
}
}

View File

@ -8,7 +8,6 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.storage.database.DBWriter;
public class CancelDownloadActionButton extends ItemActionButton {
@ -33,9 +32,7 @@ public class CancelDownloadActionButton extends ItemActionButton {
public void onClick(Context context) {
FeedMedia media = item.getMedia();
DownloadServiceInterface.get().cancel(context, media);
if (UserPreferences.isEnableAutodownload()) {
item.disableAutoDownload();
DBWriter.setFeedItem(item);
}
item.disableAutoDownload();
DBWriter.setFeedItem(item);
}
}

View File

@ -1,7 +1,6 @@
package de.danoeh.antennapod.ui.screen.drawer;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.view.ContextMenu;
@ -22,15 +21,12 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.FitCenter;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.storage.database.NavDrawerData;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.common.ImagePlaceholder;
import de.danoeh.antennapod.ui.screen.InboxFragment;
import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
import de.danoeh.antennapod.ui.screen.preferences.PreferenceActivity;
import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
@ -216,27 +212,6 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
holder.count.setText(NumberFormat.getInstance().format(sum));
holder.count.setVisibility(View.VISIBLE);
}
} else if (tag.equals(CompletedDownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) {
int epCacheSize = UserPreferences.getEpisodeCacheSize();
// don't count episodes that can be reclaimed
int spaceUsed = itemAccess.getNumberOfDownloadedItems()
- itemAccess.getReclaimableItems();
if (epCacheSize > 0 && spaceUsed >= epCacheSize) {
holder.count.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_disc_alert, 0);
holder.count.setVisibility(View.VISIBLE);
holder.count.setOnClickListener(v ->
new MaterialAlertDialogBuilder(context)
.setTitle(R.string.episode_cache_full_title)
.setMessage(R.string.episode_cache_full_message)
.setPositiveButton(android.R.string.ok, null)
.setNeutralButton(R.string.open_autodownload_settings, (dialog, which) -> {
Intent intent = new Intent(context, PreferenceActivity.class);
intent.putExtra(PreferenceActivity.OPEN_AUTO_DOWNLOAD_SETTINGS, true);
context.startActivity(intent);
})
.show()
);
}
}
holder.image.setImageResource(NavigationNames.getDrawable(fragmentTags.get(position)));

View File

@ -108,6 +108,7 @@ public class FeedSettingsFragment extends Fragment {
public static class FeedSettingsPreferenceFragment extends PreferenceFragmentCompat {
private static final String PREF_EPISODE_FILTER = "episodeFilter";
private static final String PREF_AUTODOWNLOAD = "autoDownload";
private static final String PREF_SCREEN = "feedSettingsScreen";
private static final String PREF_AUTHENTICATION = "authentication";
private static final String PREF_AUTO_DELETE = "autoDelete";
@ -180,7 +181,6 @@ public class FeedSettingsFragment extends Fragment {
feed = result;
feedPreferences = feed.getPreferences();
setupAutoDownloadGlobalPreference();
setupAutoDownloadPreference();
setupKeepUpdatedPreference();
setupAutoDeletePreference();
@ -462,42 +462,51 @@ public class FeedSettingsFragment extends Fragment {
});
}
private void setupAutoDownloadGlobalPreference() {
if (!UserPreferences.isEnableAutodownload()) {
SwitchPreferenceCompat autodl = findPreference("autoDownload");
autodl.setChecked(false);
autodl.setEnabled(false);
autodl.setSummary(R.string.auto_download_disabled_globally);
findPreference(PREF_EPISODE_FILTER).setEnabled(false);
}
}
private void setupAutoDownloadPreference() {
SwitchPreferenceCompat pref = findPreference("autoDownload");
pref.setEnabled(UserPreferences.isEnableAutodownload());
if (UserPreferences.isEnableAutodownload()) {
pref.setChecked(feedPreferences.getAutoDownload());
} else {
pref.setChecked(false);
pref.setSummary(R.string.auto_download_disabled_globally);
}
pref.setOnPreferenceChangeListener((preference, newValue) -> {
boolean checked = Boolean.TRUE.equals(newValue);
feedPreferences.setAutoDownload(checked);
findPreference(PREF_AUTODOWNLOAD).setOnPreferenceChangeListener((preference, newValue) -> {
switch ((String) newValue) {
case "global":
feedPreferences.setAutoDownload(FeedPreferences.AutoDownloadSetting.GLOBAL);
break;
case "enabled":
feedPreferences.setAutoDownload(FeedPreferences.AutoDownloadSetting.ENABLED);
break;
case "disabled":
feedPreferences.setAutoDownload(FeedPreferences.AutoDownloadSetting.DISABLED);
break;
default:
}
DBWriter.setFeedPreferences(feedPreferences);
updateAutoDownloadEnabled();
pref.setChecked(checked);
return false;
});
}
private void updateAutoDownloadEnabled() {
if (feed != null && feed.getPreferences() != null) {
boolean enabled = feed.getPreferences().getAutoDownload() && UserPreferences.isEnableAutodownload();
findPreference(PREF_EPISODE_FILTER).setEnabled(enabled);
if (feed == null || feed.getPreferences() == null) {
return;
}
boolean enabled = feed.getPreferences().isAutoDownload(UserPreferences.isEnableAutodownloadGlobal());
findPreference(PREF_EPISODE_FILTER).setEnabled(enabled);
ListPreference autoDownloadPreference = findPreference(PREF_AUTODOWNLOAD);
switch (feedPreferences.getAutoDownload()) {
case GLOBAL:
if (feedPreferences.getAutoDownload() == FeedPreferences.AutoDownloadSetting.GLOBAL) {
autoDownloadPreference.setSummary(getString(R.string.global_default_with_value,
enabled ? getString(R.string.enabled) : getString(R.string.disabled)));
}
autoDownloadPreference.setValue("global");
break;
case ENABLED:
autoDownloadPreference.setSummary(R.string.enabled);
autoDownloadPreference.setValue("enabled");
break;
case DISABLED:
autoDownloadPreference.setSummary(R.string.disabled);
autoDownloadPreference.setValue("disabled");
break;
}
}

View File

@ -34,10 +34,6 @@ public class AutomaticDeletionPreferencesFragment extends AnimatedPreferenceFrag
}
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.equals(Boolean.TRUE)) {
showAutoDeleteEnableDialog();

View File

@ -67,7 +67,9 @@ public class FeedMultiSelectActionHandler {
activity.getString(R.string.auto_download_settings_label),
activity.getString(R.string.auto_download_label));
preferenceSwitchDialog.setOnPreferenceChangedListener(enabled ->
saveFeedPreferences(feedPreferences -> feedPreferences.setAutoDownload(enabled)));
saveFeedPreferences(feedPreferences ->
feedPreferences.setAutoDownload(FeedPreferences.AutoDownloadSetting.fromBoolean(enabled))
));
preferenceSwitchDialog.openDialog();
}

View File

@ -1,16 +1,19 @@
package de.danoeh.antennapod.ui.screen.subscriptions;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.model.feed.SubscriptionsFilter;
public enum SubscriptionsFilterGroup {
COUNTER_GREATER_ZERO(new ItemProperties(R.string.subscriptions_counter_greater_zero, "counter_greater_zero")),
AUTO_DOWNLOAD(new ItemProperties(R.string.auto_downloaded, "enabled_auto_download"),
new ItemProperties(R.string.not_auto_downloaded, "disabled_auto_download")),
UPDATED(new ItemProperties(R.string.kept_updated, "enabled_updates"),
new ItemProperties(R.string.not_kept_updated, "disabled_updates")),
COUNTER_GREATER_ZERO(new ItemProperties(R.string.subscriptions_counter_greater_zero,
SubscriptionsFilter.COUNTER_GREATER_ZERO)),
AUTO_DOWNLOAD(new ItemProperties(R.string.auto_downloaded, SubscriptionsFilter.ENABLED_AUTO_DOWNLOAD),
new ItemProperties(R.string.not_auto_downloaded, SubscriptionsFilter.DISABLED_AUTO_DOWNLOAD)),
UPDATED(new ItemProperties(R.string.kept_updated, SubscriptionsFilter.ENABLED_UPDATES),
new ItemProperties(R.string.not_kept_updated, SubscriptionsFilter.DISABLED_UPDATES)),
NEW_EPISODE_NOTIFICATION(new ItemProperties(R.string.new_episode_notification_enabled,
"episode_notification_enabled"),
new ItemProperties(R.string.new_episode_notification_disabled, "episode_notification_disabled"));
SubscriptionsFilter.EPISODE_NOTIFICATION_ENABLED),
new ItemProperties(R.string.new_episode_notification_disabled,
SubscriptionsFilter.EPISODE_NOTIFICATION_DISABLED));
public final ItemProperties[] values;

View File

@ -68,9 +68,14 @@
<PreferenceCategory
android:key="autoDownloadCategory"
android:title="@string/auto_download_settings_label">
<SwitchPreferenceCompat
<de.danoeh.antennapod.ui.preferences.preference.MaterialListPreference
android:entries="@array/spnEnableAutoDownloadItems"
android:entryValues="@array/spnEnableAutoDownloadValues"
android:icon="@drawable/ic_download"
android:key="autoDownload"
android:title="@string/auto_download_label" />
<Preference
android:key="episodeFilter"
android:summary="@string/episode_filters_description"

View File

@ -179,7 +179,7 @@ public class Feed {
*/
public Feed(String url, String lastModified, String title, String username, String password) {
this(url, lastModified, title);
preferences = new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF,
preferences = new FeedPreferences(0, FeedPreferences.AutoDownloadSetting.GLOBAL, FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF,
FeedPreferences.NewEpisodesAction.GLOBAL, username, password);
}

View File

@ -78,10 +78,38 @@ public class FeedPreferences implements Serializable {
}
}
public enum AutoDownloadSetting {
DISABLED(0),
ENABLED(2),
GLOBAL(1);
public final int code;
AutoDownloadSetting(int code) {
this.code = code;
}
public static AutoDownloadSetting fromInteger(int code) {
for (AutoDownloadSetting setting : values()) {
if (code == setting.code) {
return setting;
}
}
return GLOBAL;
}
public static AutoDownloadSetting fromBoolean(boolean enabled) {
if (enabled) {
return ENABLED;
}
return DISABLED;
}
}
@NonNull
private FeedFilter filter;
private long feedID;
private boolean autoDownload;
private AutoDownloadSetting autoDownload;
private boolean keepUpdated;
private AutoDeleteAction autoDeleteAction;
private VolumeAdaptionSetting volumeAdaptionSetting;
@ -95,7 +123,7 @@ public class FeedPreferences implements Serializable {
private boolean showEpisodeNotification;
private final Set<String> tags = new HashSet<>();
public FeedPreferences(long feedID, boolean autoDownload, AutoDeleteAction autoDeleteAction,
public FeedPreferences(long feedID, AutoDownloadSetting autoDownload, AutoDeleteAction autoDeleteAction,
VolumeAdaptionSetting volumeAdaptionSetting, NewEpisodesAction newEpisodesAction,
String username, String password) {
this(feedID, autoDownload, true, autoDeleteAction, volumeAdaptionSetting, username, password,
@ -103,7 +131,7 @@ public class FeedPreferences implements Serializable {
false, newEpisodesAction, new HashSet<>());
}
public FeedPreferences(long feedID, boolean autoDownload, boolean keepUpdated,
public FeedPreferences(long feedID, AutoDownloadSetting autoDownload, boolean keepUpdated,
AutoDeleteAction autoDeleteAction, VolumeAdaptionSetting volumeAdaptionSetting,
String username, String password, @NonNull FeedFilter filter,
float feedPlaybackSpeed, int feedSkipIntro, int feedSkipEnding, SkipSilence feedSkipSilence,
@ -168,12 +196,30 @@ public class FeedPreferences implements Serializable {
this.feedID = feedID;
}
public boolean getAutoDownload() {
return autoDownload;
/**
* This function returns the calculated auto-download state for the given FeedPreference.
* By supplying the global default, the returned value will present the actionable state of the
* download-state choosen by the user. No further checks need to be made.
* @param globalDefault Global Setting for automatic downloading of items.
* @return whether this item should be downloaded
*/
public boolean isAutoDownload(boolean globalDefault) {
return switch (this.autoDownload) {
case ENABLED -> true;
case DISABLED -> false;
default -> globalDefault;
};
}
public void setAutoDownload(boolean autoDownload) {
this.autoDownload = autoDownload;
/**
* @return The autodownload settings value for this item.
*/
public AutoDownloadSetting getAutoDownload() {
return this.autoDownload;
}
public void setAutoDownload(AutoDownloadSetting setting) {
this.autoDownload = setting;
}
public AutoDeleteAction getAutoDeleteAction() {

View File

@ -2,26 +2,30 @@ package de.danoeh.antennapod.model.feed;
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
public class SubscriptionsFilter {
private static final String divider = ",";
private final String[] properties;
private boolean showIfCounterGreaterZero = false;
private boolean hideNonSubscribedFeeds = true;
public final boolean showIfCounterGreaterZero;
public final boolean hideNonSubscribedFeeds;
public final boolean showAutoDownloadEnabled;
public final boolean showAutoDownloadDisabled;
public final boolean showUpdatedEnabled;
public final boolean showUpdatedDisabled;
public final boolean showEpisodeNotificationEnabled;
public final boolean showEpisodeNotificationDisabled;
private boolean showAutoDownloadEnabled = false;
private boolean showAutoDownloadDisabled = false;
private boolean showUpdatedEnabled = false;
private boolean showUpdatedDisabled = false;
private boolean showEpisodeNotificationEnabled = false;
private boolean showEpisodeNotificationDisabled = false;
public static final String COUNTER_GREATER_ZERO = "counter_greater_zero";
public static final String ENABLED_AUTO_DOWNLOAD = "enabled_auto_download";
public static final String DISABLED_AUTO_DOWNLOAD = "disabled_auto_download";
public static final String ENABLED_UPDATES = "enabled_updates";
public static final String DISABLED_UPDATES = "disabled_updates";
public static final String EPISODE_NOTIFICATION_ENABLED = "episode_notification_enabled";
public static final String EPISODE_NOTIFICATION_DISABLED = "episode_notification_disabled";
public static final String SHOW_NON_SUBSCRIBED_FEEDS = "show_non_subscribed";
public SubscriptionsFilter(String properties) {
this(TextUtils.split(properties, divider));
@ -30,88 +34,24 @@ public class SubscriptionsFilter {
public SubscriptionsFilter(String[] properties) {
this.properties = properties;
for (String property : properties) {
// see R.arrays.feed_filter_values
switch (property) {
case "counter_greater_zero":
showIfCounterGreaterZero = true;
break;
case "enabled_auto_download":
showAutoDownloadEnabled = true;
break;
case "disabled_auto_download":
showAutoDownloadDisabled = true;
break;
case "enabled_updates":
showUpdatedEnabled = true;
break;
case "disabled_updates":
showUpdatedDisabled = true;
break;
case "episode_notification_enabled":
showEpisodeNotificationEnabled = true;
break;
case "episode_notification_disabled":
showEpisodeNotificationDisabled = true;
break;
default:
break;
}
}
showIfCounterGreaterZero = hasProperty(COUNTER_GREATER_ZERO);
showAutoDownloadEnabled = hasProperty(ENABLED_AUTO_DOWNLOAD);
showAutoDownloadDisabled = hasProperty(DISABLED_AUTO_DOWNLOAD);
showUpdatedEnabled = hasProperty(ENABLED_UPDATES);
showUpdatedDisabled = hasProperty(DISABLED_UPDATES);
showEpisodeNotificationEnabled = hasProperty(EPISODE_NOTIFICATION_ENABLED);
showEpisodeNotificationDisabled = hasProperty(EPISODE_NOTIFICATION_DISABLED);
hideNonSubscribedFeeds = !hasProperty(SHOW_NON_SUBSCRIBED_FEEDS);
}
private boolean hasProperty(String property) {
return Arrays.asList(properties).contains(property);
}
public boolean isEnabled() {
return properties.length > 0;
}
/**
* Run a list of feed items through the filter.
*/
public List<Feed> filter(List<Feed> items, Map<Long, Integer> feedCounters) {
List<Feed> result = new ArrayList<>();
for (Feed item : items) {
FeedPreferences itemPreferences = item.getPreferences();
// If the item does not meet a requirement, skip it.
if (showAutoDownloadEnabled && !itemPreferences.getAutoDownload()) {
continue;
} else if (showAutoDownloadDisabled && itemPreferences.getAutoDownload()) {
continue;
}
if (showUpdatedEnabled && !itemPreferences.getKeepUpdated()) {
continue;
} else if (showUpdatedDisabled && itemPreferences.getKeepUpdated()) {
continue;
}
if (showEpisodeNotificationEnabled && !itemPreferences.getShowEpisodeNotification()) {
continue;
} else if (showEpisodeNotificationDisabled && itemPreferences.getShowEpisodeNotification()) {
continue;
}
if (hideNonSubscribedFeeds && item.getState() != Feed.STATE_SUBSCRIBED) {
continue;
}
// If the item reaches here, it meets all criteria (except counter > 0)
result.add(item);
}
if (showIfCounterGreaterZero) {
for (int i = result.size() - 1; i >= 0; i--) {
if (!feedCounters.containsKey(result.get(i).getId())
|| feedCounters.get(result.get(i).getId()) <= 0) {
result.remove(i);
}
}
}
return result;
}
public String[] getValues() {
return properties.clone();
}

View File

@ -40,8 +40,7 @@ public class AutomaticDownloadAlgorithm {
return () -> {
// true if we should auto download based on network status
boolean networkShouldAutoDl = NetworkUtils.isAutoDownloadAllowed()
&& UserPreferences.isEnableAutodownload();
boolean networkShouldAutoDl = NetworkUtils.isAutoDownloadAllowed();
// true if we should auto download based on power status
boolean powerShouldAutoDl = deviceCharging(context) || UserPreferences.isEnableAutodownloadOnBattery();
@ -59,7 +58,7 @@ public class AutomaticDownloadAlgorithm {
candidates.addAll(queue);
for (FeedItem newItem : newItems) {
FeedPreferences feedPrefs = newItem.getFeed().getPreferences();
if (feedPrefs.getAutoDownload()
if (feedPrefs.isAutoDownload(UserPreferences.isEnableAutodownloadGlobal())
&& !candidates.contains(newItem)
&& feedPrefs.getFilter().shouldAutoDownload(newItem)) {
candidates.add(newItem);

View File

@ -4,9 +4,6 @@ import de.danoeh.antennapod.storage.preferences.UserPreferences;
public abstract class EpisodeCleanupAlgorithmFactory {
public static EpisodeCleanupAlgorithm build() {
if (!UserPreferences.isEnableAutodownload()) {
return new APNullCleanupAlgorithm();
}
int cleanupValue = UserPreferences.getEpisodeCleanupValue();
switch (cleanupValue) {
case UserPreferences.EPISODE_CLEANUP_EXCEPT_FAVORITE:

View File

@ -28,6 +28,7 @@ import androidx.annotation.VisibleForTesting;
import androidx.documentfile.provider.DocumentFile;
import de.danoeh.antennapod.model.MediaMetadataRetrieverCompat;
import de.danoeh.antennapod.model.download.DownloadResult;
import de.danoeh.antennapod.model.feed.FeedPreferences;
import de.danoeh.antennapod.net.download.service.R;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.FeedDatabaseWriter;
@ -125,7 +126,7 @@ public class LocalFeedUpdater {
feed.setImageUrl(getImageUrl(allFiles, folderUri));
feed.getPreferences().setAutoDownload(false);
feed.getPreferences().setAutoDownload(FeedPreferences.AutoDownloadSetting.DISABLED);
feed.setDescription(context.getString(R.string.local_feed_description));
feed.setAuthor(context.getString(R.string.local_folder));

View File

@ -40,9 +40,9 @@ public class FeedParserTask implements Callable<FeedHandlerResult> {
Feed feed = new Feed(request.getSource(), request.getLastModified());
feed.setLocalFileUrl(request.getDestination());
feed.setId(request.getFeedfileId());
feed.setPreferences(new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL,
VolumeAdaptionSetting.OFF, FeedPreferences.NewEpisodesAction.GLOBAL, request.getUsername(),
request.getPassword()));
feed.setPreferences(new FeedPreferences(0, FeedPreferences.AutoDownloadSetting.GLOBAL,
FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF,
FeedPreferences.NewEpisodesAction.GLOBAL, request.getUsername(), request.getPassword()));
feed.setPageNr(request.getArguments().getInt(DownloadRequest.REQUEST_ARG_PAGE_NR, 0));
DownloadError reason = null;

View File

@ -78,7 +78,7 @@ public class DbCleanupTests {
.getDefaultSharedPreferences(context.getApplicationContext()).edit();
prefEdit.putString(UserPreferences.PREF_EPISODE_CACHE_SIZE, Integer.toString(EPISODE_CACHE_SIZE));
prefEdit.putString(UserPreferences.PREF_EPISODE_CLEANUP, Integer.toString(cleanupAlgorithm));
prefEdit.putBoolean(UserPreferences.PREF_ENABLE_AUTODL, true);
prefEdit.putBoolean(UserPreferences.PREF_AUTODL_GLOBAL, true);
prefEdit.commit();
UserPreferences.init(context);

View File

@ -673,7 +673,7 @@ public final class DBReader {
if (subscriptionsFilter == null) {
subscriptionsFilter = new SubscriptionsFilter("");
}
feeds = subscriptionsFilter.filter(feeds, feedCounters);
feeds = SubscriptionsFilterExecutor.filter(feeds, feedCounters, subscriptionsFilter);
Comparator<Feed> comparator;
switch (feedOrder) {

View File

@ -471,7 +471,7 @@ public class PodDBAdapter {
throw new IllegalArgumentException("Feed ID of preference must not be null");
}
ContentValues values = new ContentValues();
values.put(KEY_AUTO_DOWNLOAD_ENABLED, prefs.getAutoDownload());
values.put(KEY_AUTO_DOWNLOAD_ENABLED, prefs.getAutoDownload().code);
values.put(KEY_KEEP_UPDATED, prefs.getKeepUpdated());
values.put(KEY_AUTO_DELETE_ACTION, prefs.getAutoDeleteAction().code);
values.put(KEY_FEED_VOLUME_ADAPTION, prefs.getVolumeAdaptionSetting().toInteger());

View File

@ -0,0 +1,58 @@
package de.danoeh.antennapod.storage.database;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedPreferences;
import de.danoeh.antennapod.model.feed.SubscriptionsFilter;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public abstract class SubscriptionsFilterExecutor {
public static List<Feed> filter(List<Feed> items, Map<Long, Integer> feedCounters, SubscriptionsFilter filter) {
List<Feed> result = new ArrayList<>();
for (Feed item : items) {
FeedPreferences itemPreferences = item.getPreferences();
boolean globalAutodownload = UserPreferences.isEnableAutodownloadGlobal();
boolean shouldItemAutoDownload = itemPreferences.isAutoDownload(globalAutodownload);
// If the item does not meet a requirement, skip it.
if (filter.showAutoDownloadEnabled && !shouldItemAutoDownload) {
continue;
} else if (filter.showAutoDownloadDisabled && shouldItemAutoDownload) {
continue;
}
if (filter.showUpdatedEnabled && !itemPreferences.getKeepUpdated()) {
continue;
} else if (filter.showUpdatedDisabled && itemPreferences.getKeepUpdated()) {
continue;
}
if (filter.showEpisodeNotificationEnabled && !itemPreferences.getShowEpisodeNotification()) {
continue;
} else if (filter.showEpisodeNotificationDisabled && itemPreferences.getShowEpisodeNotification()) {
continue;
}
if (filter.hideNonSubscribedFeeds && item.getState() != Feed.STATE_SUBSCRIBED) {
continue;
}
// If the item reaches here, it meets all criteria (except counter > 0)
result.add(item);
}
if (filter.showIfCounterGreaterZero) {
for (int i = result.size() - 1; i >= 0; i--) {
if (!feedCounters.containsKey(result.get(i).getId()) || feedCounters.get(result.get(i).getId()) <= 0) {
result.remove(i);
}
}
}
return result;
}
}

View File

@ -66,7 +66,7 @@ public class FeedPreferencesCursor extends CursorWrapper {
}
return new FeedPreferences(
getLong(indexId),
getInt(indexAutoDownload) > 0,
FeedPreferences.AutoDownloadSetting.fromInteger(getInt(indexAutoDownload)),
getInt(indexAutoRefresh) > 0,
FeedPreferences.AutoDeleteAction.fromCode(getInt(indexAutoDeleteAction)),
VolumeAdaptionSetting.fromInteger(getInt(indexVolumeAdaption)),

View File

@ -98,7 +98,7 @@ public abstract class UserPreferences {
private static final String PREF_MOBILE_UPDATE = "prefMobileUpdateTypes";
public static final String PREF_EPISODE_CLEANUP = "prefEpisodeCleanup";
public static final String PREF_EPISODE_CACHE_SIZE = "prefEpisodeCacheSize";
public static final String PREF_ENABLE_AUTODL = "prefEnableAutoDl";
public static final String PREF_AUTODL_GLOBAL = "prefEnableAutoDl";
public static final String PREF_ENABLE_AUTODL_ON_BATTERY = "prefEnableAutoDownloadOnBattery";
private static final String PREF_PROXY_TYPE = "prefProxyType";
private static final String PREF_PROXY_HOST = "prefProxyHost";
@ -535,8 +535,8 @@ public abstract class UserPreferences {
return Integer.parseInt(prefs.getString(PREF_EPISODE_CACHE_SIZE, "20"));
}
public static boolean isEnableAutodownload() {
return prefs.getBoolean(PREF_ENABLE_AUTODL, false);
public static boolean isEnableAutodownloadGlobal() {
return prefs.getBoolean(PREF_AUTODL_GLOBAL, false);
}
public static boolean isEnableAutodownloadOnBattery() {

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/action_icon_color"
android:pathData="M10 14C8.9 14 8 13.1 8 12C8 10.9 8.9 10 10 10C11.1 10 12 10.9 12 12S11.1 14 10 14M10 4C5.6 4 2 7.6 2 12S5.6 20 10 20 18 16.4 18 12 14.4 4 10 4M20 13H22V7H20M20 17H22V15H20V17Z" />
</vector>

View File

@ -16,14 +16,11 @@
<string name="favorite_episodes_label">Favorites</string>
<string name="settings_label">Settings</string>
<string name="downloads_label">Downloads</string>
<string name="open_autodownload_settings">Open settings</string>
<string name="downloads_log_label">Download log</string>
<string name="subscriptions_label">Subscriptions</string>
<string name="subscriptions_list_label">Subscriptions list (side menu only)</string>
<string name="cancel_download_label">Cancel download</string>
<string name="playback_history_label">Playback history</string>
<string name="episode_cache_full_title">Episode cache full</string>
<string name="episode_cache_full_message">The episode cache limit has been reached. You can increase the cache size in the Settings.</string>
<string name="years_statistics_label">Years</string>
<string name="notification_pref_fragment">Notifications</string>
<string name="current_playing_episode">Current</string>
@ -117,8 +114,11 @@
<string name="cancel_label">Cancel</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="enabled">Enabled</string>
<string name="disabled">Disabled</string>
<string name="reset">Reset</string>
<string name="global_default">Global default</string>
<string name="global_default_with_value">Global default (%1$s)</string>
<string name="url_label">URL</string>
<string name="support_funding_label">Support</string>
<string name="support_podcast">Support this podcast</string>
@ -472,6 +472,7 @@
<string name="pref_nav_drawer_feed_counter_title">Set subscription counter</string>
<string name="pref_nav_drawer_feed_counter_sum">Change the information displayed by the subscription counter. Also affects the sorting of subscriptions if \'Subscription Order\' is set to \'Counter\'.</string>
<string name="pref_automatic_download_title">Automatic download</string>
<string name="pref_automatic_download_global_description">Automatically download new episodes. Can be overridden per podcast.</string>
<string name="pref_automatic_download_sum">Configure the automatic download of episodes</string>
<string name="pref_automatic_download_on_battery_title">Download when not charging</string>
<string name="pref_automatic_download_on_battery_sum">Allow automatic download when the battery is not charging</string>
@ -746,7 +747,6 @@
<string name="exclude_episodes_shorter_than">Exclude episodes shorter than</string>
<string name="keep_updated">Keep updated</string>
<string name="keep_updated_summary">Include this podcast when (auto-)refreshing all podcasts</string>
<string name="auto_download_disabled_globally">Auto download is disabled in the main AntennaPod settings</string>
<plurals name="statistics_episodes_started">
<item quantity="one">started</item>
<item quantity="other">started</item>

View File

@ -1,42 +0,0 @@
package de.danoeh.antennapod.ui.preferences.preference;
import android.content.Context;
import android.graphics.Typeface;
import androidx.preference.SwitchPreferenceCompat;
import androidx.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.widget.TextView;
import de.danoeh.antennapod.ui.common.ThemeUtils;
import de.danoeh.antennapod.ui.preferences.R;
public class MasterSwitchPreference extends SwitchPreferenceCompat {
public MasterSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MasterSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public MasterSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MasterSwitchPreference(Context context) {
super(context);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.itemView.setBackgroundColor(ThemeUtils.getColorFromAttr(getContext(), R.attr.colorSurfaceVariant));
TextView title = (TextView) holder.findViewById(android.R.id.title);
if (title != null) {
title.setTypeface(title.getTypeface(), Typeface.BOLD);
}
}
}

View File

@ -2,7 +2,6 @@ package de.danoeh.antennapod.ui.preferences.screen;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.preferences.R;
public class AutoDownloadPreferencesFragment extends AnimatedPreferenceFragment {
@ -10,15 +9,6 @@ public class AutoDownloadPreferencesFragment extends AnimatedPreferenceFragment
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences_autodownload);
checkAutodownloadItemVisibility(UserPreferences.isEnableAutodownload());
findPreference(UserPreferences.PREF_ENABLE_AUTODL).setOnPreferenceChangeListener(
(preference, newValue) -> {
if (newValue instanceof Boolean) {
checkAutodownloadItemVisibility((Boolean) newValue);
}
return true;
});
}
@Override
@ -26,9 +16,4 @@ public class AutoDownloadPreferencesFragment extends AnimatedPreferenceFragment
super.onStart();
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(R.string.pref_automatic_download_title);
}
private void checkAutodownloadItemVisibility(boolean autoDownload) {
findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setEnabled(autoDownload);
findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY).setEnabled(autoDownload);
}
}

View File

@ -13,6 +13,18 @@
<item>never</item>
</string-array>
<string-array name="spnEnableAutoDownloadItems">
<item>@string/global_default</item>
<item>@string/enabled</item>
<item>@string/disabled</item>
</string-array>
<string-array name="spnEnableAutoDownloadValues">
<item>global</item>
<item>enabled</item>
<item>disabled</item>
</string-array>
<string-array name="spnVolumeAdaptationItems">
<item>@string/feed_volume_reduction_heavy</item>
<item>@string/feed_volume_reduction_light</item>

View File

@ -21,7 +21,7 @@
android:summary="@string/pref_favorite_keeps_episodes_sum"
android:title="@string/pref_favorite_keeps_episodes_title"/>
<de.danoeh.antennapod.ui.preferences.preference.MaterialListPreference
android:defaultValue="-1"
android:defaultValue="-2"
android:entries="@array/episode_cleanup_entries"
android:key="prefEpisodeCleanup"
android:title="@string/pref_episode_cleanup_title"

View File

@ -1,13 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:search="http://schemas.android.com/apk/com.bytehamster.lib.preferencesearch">
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<de.danoeh.antennapod.ui.preferences.preference.MasterSwitchPreference
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="prefEnableAutoDl"
android:title="@string/pref_automatic_download_title"
search:summary="@string/pref_automatic_download_sum"
android:defaultValue="false"/>
android:summary="@string/pref_automatic_download_global_description"/>
<de.danoeh.antennapod.ui.preferences.preference.MaterialListPreference
android:defaultValue="25"
android:entries="@array/episode_cache_size_entries"