Rewrite include/exclude filter dialog (#6057)

This commit is contained in:
ByteHamster 2022-09-18 22:25:06 +02:00 committed by GitHub
parent bd0f54dbf6
commit 097a491504
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 275 additions and 170 deletions

View File

@ -0,0 +1,57 @@
package de.danoeh.antennapod.adapter;
import android.content.Context;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.chip.Chip;
import de.danoeh.antennapod.R;
import java.util.List;
public abstract class SimpleChipAdapter extends RecyclerView.Adapter<SimpleChipAdapter.ViewHolder> {
private final Context context;
public SimpleChipAdapter(Context context) {
this.context = context;
setHasStableIds(true);
}
protected abstract List<String> getChips();
protected abstract void onRemoveClicked(int position);
@Override
@NonNull
public SimpleChipAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Chip chip = new Chip(context);
chip.setCloseIconVisible(true);
chip.setCloseIconResource(R.drawable.ic_delete);
return new SimpleChipAdapter.ViewHolder(chip);
}
@Override
public void onBindViewHolder(@NonNull SimpleChipAdapter.ViewHolder holder, int position) {
holder.chip.setText(getChips().get(position));
holder.chip.setOnCloseIconClickListener(v -> onRemoveClicked(position));
}
@Override
public int getItemCount() {
return getChips().size();
}
@Override
public long getItemId(int position) {
return getChips().get(position).hashCode();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
Chip chip;
ViewHolder(Chip itemView) {
super(itemView);
chip = itemView;
}
}
}

View File

@ -1,75 +1,108 @@
package de.danoeh.antennapod.dialog; package de.danoeh.antennapod.dialog;
import android.content.Context; import android.content.Context;
import android.view.View; import android.content.DialogInterface;
import android.widget.CheckBox; import android.text.TextUtils;
import android.widget.EditText; import android.view.LayoutInflater;
import android.widget.RadioButton; import androidx.recyclerview.widget.GridLayoutManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.SimpleChipAdapter;
import de.danoeh.antennapod.databinding.EpisodeFilterDialogBinding;
import de.danoeh.antennapod.model.feed.FeedFilter; import de.danoeh.antennapod.model.feed.FeedFilter;
import de.danoeh.antennapod.view.ItemOffsetDecoration;
import java.util.List;
/** /**
* Displays a dialog with a text box for filtering episodes and two radio buttons for exclusion/inclusion * Displays a dialog with a text box for filtering episodes and two radio buttons for exclusion/inclusion
*/ */
public abstract class EpisodeFilterDialog extends MaterialAlertDialogBuilder { public abstract class EpisodeFilterDialog extends MaterialAlertDialogBuilder {
private final FeedFilter initialFilter; private final EpisodeFilterDialogBinding viewBinding;
private final List<String> termList;
public EpisodeFilterDialog(Context context, FeedFilter filter) { public EpisodeFilterDialog(Context context, FeedFilter filter) {
super(context); super(context);
initialFilter = filter; viewBinding = EpisodeFilterDialogBinding.inflate(LayoutInflater.from(context));
setTitle(R.string.episode_filters_label); setTitle(R.string.episode_filters_label);
View rootView = View.inflate(context, R.layout.episode_filter_dialog, null); setView(viewBinding.getRoot());
setView(rootView);
final EditText etxtEpisodeFilterText = rootView.findViewById(R.id.etxtEpisodeFilterText); if (filter.hasMinimalDurationFilter()) {
final EditText etxtEpisodeFilterDurationText = rootView.findViewById(R.id.etxtEpisodeFilterDurationText); viewBinding.durationCheckBox.setChecked(true);
final RadioButton radioInclude = rootView.findViewById(R.id.radio_filter_include);
final RadioButton radioExclude = rootView.findViewById(R.id.radio_filter_exclude);
final CheckBox checkboxDuration = rootView.findViewById(R.id.checkbox_filter_duration);
if (initialFilter.includeOnly()) {
radioInclude.setChecked(true);
etxtEpisodeFilterText.setText(initialFilter.getIncludeFilter());
} else if(initialFilter.excludeOnly()) {
radioExclude.setChecked(true);
etxtEpisodeFilterText.setText(initialFilter.getExcludeFilter());
} else {
radioExclude.setChecked(false);
radioInclude.setChecked(false);
etxtEpisodeFilterText.setText("");
}
if (initialFilter.hasMinimalDurationFilter()) {
checkboxDuration.setChecked(true);
// Store minimal duration in seconds, show in minutes // Store minimal duration in seconds, show in minutes
etxtEpisodeFilterDurationText.setText(String.valueOf(initialFilter.getMinimalDurationFilter() / 60)); viewBinding.episodeFilterDurationText
.setText(String.valueOf(filter.getMinimalDurationFilter() / 60));
} }
if (filter.excludeOnly()) {
termList = filter.getExcludeFilter();
viewBinding.excludeRadio.setChecked(true);
} else {
termList = filter.getIncludeFilter();
viewBinding.includeRadio.setChecked(true);
}
setupWordsList();
setNegativeButton(R.string.cancel_label, null); setNegativeButton(R.string.cancel_label, null);
setPositiveButton(R.string.confirm_label, (dialog, which) -> { setPositiveButton(R.string.confirm_label, this::onConfirmClick);
String includeString = "";
String excludeString = "";
int minimalDuration = -1;
if (radioInclude.isChecked()) {
includeString = etxtEpisodeFilterText.getText().toString();
} else {
excludeString = etxtEpisodeFilterText.getText().toString();
} }
if (checkboxDuration.isChecked()) {
private void setupWordsList() {
viewBinding.termsRecycler.setLayoutManager(new GridLayoutManager(getContext(), 2));
viewBinding.termsRecycler.addItemDecoration(new ItemOffsetDecoration(getContext(), 4));
SimpleChipAdapter adapter = new SimpleChipAdapter(getContext()) {
@Override
protected List<String> getChips() {
return termList;
}
@Override
protected void onRemoveClicked(int position) {
termList.remove(position);
notifyDataSetChanged();
}
};
viewBinding.termsRecycler.setAdapter(adapter);
viewBinding.termsTextInput.setEndIconOnClickListener(v -> {
String newWord = viewBinding.termsTextInput.getEditText().getText().toString().replace("\"", "").trim();
if (TextUtils.isEmpty(newWord) || termList.contains(newWord)) {
return;
}
termList.add(newWord);
viewBinding.termsTextInput.getEditText().setText("");
adapter.notifyDataSetChanged();
});
}
protected abstract void onConfirmed(FeedFilter filter);
private void onConfirmClick(DialogInterface dialog, int which) {
int minimalDuration = -1;
if (viewBinding.durationCheckBox.isChecked()) {
try { try {
// Store minimal duration in seconds // Store minimal duration in seconds
minimalDuration = Integer.parseInt(etxtEpisodeFilterDurationText.getText().toString()) * 60; minimalDuration = Integer.parseInt(
viewBinding.episodeFilterDurationText.getText().toString()) * 60;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// Do not change anything on error // Do not change anything on error
} }
} }
onConfirmed(new FeedFilter(includeString, excludeString, minimalDuration)); String excludeFilter = "";
String includeFilter = "";
if (viewBinding.includeRadio.isChecked()) {
includeFilter = toFilterString(termList);
} else {
excludeFilter = toFilterString(termList);
} }
); onConfirmed(new FeedFilter(includeFilter, excludeFilter, minimalDuration));
} }
protected abstract void onConfirmed(FeedFilter filter); private String toFilterString(List<String> words) {
StringBuilder result = new StringBuilder();
for (String word : words) {
result.append("\"").append(word).append("\" ");
}
return result.toString();
}
} }

View File

@ -6,21 +6,19 @@ import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.chip.Chip;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.SimpleChipAdapter;
import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.model.feed.FeedPreferences;
import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.databinding.EditTagsDialogBinding; import de.danoeh.antennapod.databinding.EditTagsDialogBinding;
import de.danoeh.antennapod.model.feed.FeedPreferences;
import de.danoeh.antennapod.view.ItemOffsetDecoration; import de.danoeh.antennapod.view.ItemOffsetDecoration;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
@ -36,7 +34,7 @@ public class TagSettingsDialog extends DialogFragment {
private static final String ARG_FEED_PREFERENCES = "feed_preferences"; private static final String ARG_FEED_PREFERENCES = "feed_preferences";
private List<String> displayedTags; private List<String> displayedTags;
private EditTagsDialogBinding viewBinding; private EditTagsDialogBinding viewBinding;
private TagSelectionAdapter adapter; private SimpleChipAdapter adapter;
public static TagSettingsDialog newInstance(List<FeedPreferences> preferencesList) { public static TagSettingsDialog newInstance(List<FeedPreferences> preferencesList) {
TagSettingsDialog fragment = new TagSettingsDialog(); TagSettingsDialog fragment = new TagSettingsDialog();
@ -62,12 +60,22 @@ public class TagSettingsDialog extends DialogFragment {
viewBinding = EditTagsDialogBinding.inflate(getLayoutInflater()); viewBinding = EditTagsDialogBinding.inflate(getLayoutInflater());
viewBinding.tagsRecycler.setLayoutManager(new GridLayoutManager(getContext(), 2)); viewBinding.tagsRecycler.setLayoutManager(new GridLayoutManager(getContext(), 2));
viewBinding.tagsRecycler.addItemDecoration(new ItemOffsetDecoration(getContext(), 4)); viewBinding.tagsRecycler.addItemDecoration(new ItemOffsetDecoration(getContext(), 4));
adapter = new TagSelectionAdapter(); adapter = new SimpleChipAdapter(getContext()) {
adapter.setHasStableIds(true); @Override
protected List<String> getChips() {
return displayedTags;
}
@Override
protected void onRemoveClicked(int position) {
displayedTags.remove(position);
notifyDataSetChanged();
}
};
viewBinding.tagsRecycler.setAdapter(adapter); viewBinding.tagsRecycler.setAdapter(adapter);
viewBinding.rootFolderCheckbox.setChecked(commonTags.contains(FeedPreferences.TAG_ROOT)); viewBinding.rootFolderCheckbox.setChecked(commonTags.contains(FeedPreferences.TAG_ROOT));
viewBinding.newTagButton.setOnClickListener(v -> viewBinding.newTagTextInput.setEndIconOnClickListener(v ->
addTag(viewBinding.newTagEditText.getText().toString().trim())); addTag(viewBinding.newTagEditText.getText().toString().trim()));
loadTags(); loadTags();
@ -140,44 +148,4 @@ public class TagSettingsDialog extends DialogFragment {
DBWriter.setFeedPreferences(preferences); DBWriter.setFeedPreferences(preferences);
} }
} }
public class TagSelectionAdapter extends RecyclerView.Adapter<TagSelectionAdapter.ViewHolder> {
@Override
@NonNull
public TagSelectionAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Chip chip = new Chip(getContext());
chip.setCloseIconVisible(true);
chip.setCloseIconResource(R.drawable.ic_delete);
return new TagSelectionAdapter.ViewHolder(chip);
}
@Override
public void onBindViewHolder(@NonNull TagSelectionAdapter.ViewHolder holder, int position) {
holder.chip.setText(displayedTags.get(position));
holder.chip.setOnCloseIconClickListener(v -> {
displayedTags.remove(position);
notifyDataSetChanged();
});
}
@Override
public int getItemCount() {
return displayedTags.size();
}
@Override
public long getItemId(int position) {
return displayedTags.get(position).hashCode();
}
public class ViewHolder extends RecyclerView.ViewHolder {
Chip chip;
ViewHolder(Chip itemView) {
super(itemView);
chip = itemView;
}
}
}
} }

View File

@ -28,25 +28,24 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/feed_folders_include_root" /> android:text="@string/feed_folders_include_root" />
<LinearLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/newTagTextInput"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> app:endIconMode="custom"
app:endIconDrawable="@drawable/ic_add"
app:endIconContentDescription="@string/add_tag"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<AutoCompleteTextView <AutoCompleteTextView
android:id="@+id/newTagEditText" android:id="@+id/newTagEditText"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:padding="16dp"
android:inputType="text" android:inputType="text"
android:ems="10" /> android:ems="10" />
<ImageButton </com.google.android.material.textfield.TextInputLayout>
android:id="@+id/newTagButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_add" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -1,60 +1,99 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <ScrollView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"> android:padding="16dp">
<RadioGroup <LinearLayout
android:id="@+id/radio_filter_group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<RadioButton <RadioGroup
android:id="@+id/radio_filter_include" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/episode_filters_include" /> android:layout_marginBottom="8dp"
android:orientation="horizontal">
<RadioButton <RadioButton
android:id="@+id/radio_filter_exclude" android:id="@+id/includeRadio"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/episode_filters_exclude" /> android:layout_weight="1"
android:text="@string/include_terms" />
<RadioButton
android:id="@+id/excludeRadio"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/exclude_terms" />
</RadioGroup> </RadioGroup>
<EditText <androidx.recyclerview.widget.RecyclerView
android:id="@+id/etxtEpisodeFilterText" android:id="@+id/termsRecycler"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" tools:itemCount="2" />
android:cursorVisible="true"
android:focusable="true" <com.google.android.material.textfield.TextInputLayout
android:focusableInTouchMode="true" android:id="@+id/termsTextInput"
android:hint="@string/episode_filters_hint" android:layout_width="match_parent"
android:lines="8" android:layout_height="wrap_content"
android:maxLines="20" app:endIconMode="custom"
android:minLines="1" app:endIconDrawable="@drawable/ic_add"
android:scrollbars="vertical" /> app:endIconContentDescription="@string/add_term"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<CheckBox <CheckBox
android:id="@+id/checkbox_filter_duration" android:id="@+id/durationCheckBox"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/episode_filters_duration" /> android:layout_weight="1"
android:text="@string/exclude_episodes_shorter_than" />
<EditText <EditText
android:id="@+id/etxtEpisodeFilterDurationText" android:id="@+id/episodeFilterDurationText"
android:layout_width="match_parent" android:layout_width="50dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center"
android:cursorVisible="true" android:cursorVisible="true"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:inputType="numberSigned" android:inputType="numberSigned"
android:lines="1" /> android:lines="1" />
</LinearLayout> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/time_minutes" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -21,8 +21,8 @@ public class FeedFilterTest {
assertFalse(filter.excludeOnly()); assertFalse(filter.excludeOnly());
assertFalse(filter.includeOnly()); assertFalse(filter.includeOnly());
assertEquals("", filter.getExcludeFilter()); assertEquals("", filter.getExcludeFilterRaw());
assertEquals("", filter.getIncludeFilter()); assertEquals("", filter.getIncludeFilterRaw());
assertTrue(filter.shouldAutoDownload(item)); assertTrue(filter.shouldAutoDownload(item));
} }
@ -38,8 +38,8 @@ public class FeedFilterTest {
assertFalse(filter.excludeOnly()); assertFalse(filter.excludeOnly());
assertTrue(filter.includeOnly()); assertTrue(filter.includeOnly());
assertEquals("", filter.getExcludeFilter()); assertEquals("", filter.getExcludeFilterRaw());
assertEquals(includeFilter, filter.getIncludeFilter()); assertEquals(includeFilter, filter.getIncludeFilterRaw());
assertTrue(filter.shouldAutoDownload(item)); assertTrue(filter.shouldAutoDownload(item));
assertFalse(filter.shouldAutoDownload(item2)); assertFalse(filter.shouldAutoDownload(item2));
} }
@ -56,8 +56,8 @@ public class FeedFilterTest {
assertTrue(filter.excludeOnly()); assertTrue(filter.excludeOnly());
assertFalse(filter.includeOnly()); assertFalse(filter.includeOnly());
assertEquals(excludeFilter, filter.getExcludeFilter()); assertEquals(excludeFilter, filter.getExcludeFilterRaw());
assertEquals("", filter.getIncludeFilter()); assertEquals("", filter.getIncludeFilterRaw());
assertFalse(filter.shouldAutoDownload(item)); assertFalse(filter.shouldAutoDownload(item));
assertTrue(filter.shouldAutoDownload(item2)); assertTrue(filter.shouldAutoDownload(item2));
} }
@ -77,8 +77,8 @@ public class FeedFilterTest {
assertFalse(filter.excludeOnly()); assertFalse(filter.excludeOnly());
assertTrue(filter.includeOnly()); assertTrue(filter.includeOnly());
assertEquals("", filter.getExcludeFilter()); assertEquals("", filter.getExcludeFilterRaw());
assertEquals(includeFilter, filter.getIncludeFilter()); assertEquals(includeFilter, filter.getIncludeFilterRaw());
assertTrue(filter.shouldAutoDownload(item)); assertTrue(filter.shouldAutoDownload(item));
assertFalse(filter.shouldAutoDownload(item2)); assertFalse(filter.shouldAutoDownload(item2));
assertTrue(filter.shouldAutoDownload(item3)); assertTrue(filter.shouldAutoDownload(item3));
@ -99,8 +99,8 @@ public class FeedFilterTest {
assertTrue(filter.excludeOnly()); assertTrue(filter.excludeOnly());
assertFalse(filter.includeOnly()); assertFalse(filter.includeOnly());
assertEquals(excludeFilter, filter.getExcludeFilter()); assertEquals(excludeFilter, filter.getExcludeFilterRaw());
assertEquals("", filter.getIncludeFilter()); assertEquals("", filter.getIncludeFilterRaw());
assertFalse(filter.shouldAutoDownload(item)); assertFalse(filter.shouldAutoDownload(item));
assertTrue(filter.shouldAutoDownload(item2)); assertTrue(filter.shouldAutoDownload(item2));
assertFalse(filter.shouldAutoDownload(item3)); assertFalse(filter.shouldAutoDownload(item3));

View File

@ -102,14 +102,22 @@ public class FeedFilter implements Serializable {
return false; return false;
} }
public String getIncludeFilter() { public String getIncludeFilterRaw() {
return includeFilter; return includeFilter;
} }
public String getExcludeFilter() { public String getExcludeFilterRaw() {
return excludeFilter; return excludeFilter;
} }
public List<String> getIncludeFilter() {
return includeFilter == null ? new ArrayList<>() : parseTerms(includeFilter);
}
public List<String> getExcludeFilter() {
return excludeFilter == null ? new ArrayList<>() : parseTerms(excludeFilter);
}
public int getMinimalDurationFilter() { public int getMinimalDurationFilter() {
return minimalDuration; return minimalDuration;
} }

View File

@ -448,8 +448,8 @@ public class PodDBAdapter {
values.put(KEY_FEED_VOLUME_ADAPTION, prefs.getVolumeAdaptionSetting().toInteger()); values.put(KEY_FEED_VOLUME_ADAPTION, prefs.getVolumeAdaptionSetting().toInteger());
values.put(KEY_USERNAME, prefs.getUsername()); values.put(KEY_USERNAME, prefs.getUsername());
values.put(KEY_PASSWORD, prefs.getPassword()); values.put(KEY_PASSWORD, prefs.getPassword());
values.put(KEY_INCLUDE_FILTER, prefs.getFilter().getIncludeFilter()); values.put(KEY_INCLUDE_FILTER, prefs.getFilter().getIncludeFilterRaw());
values.put(KEY_EXCLUDE_FILTER, prefs.getFilter().getExcludeFilter()); values.put(KEY_EXCLUDE_FILTER, prefs.getFilter().getExcludeFilterRaw());
values.put(KEY_MINIMAL_DURATION_FILTER, prefs.getFilter().getMinimalDurationFilter()); values.put(KEY_MINIMAL_DURATION_FILTER, prefs.getFilter().getMinimalDurationFilter());
values.put(KEY_FEED_PLAYBACK_SPEED, prefs.getFeedPlaybackSpeed()); values.put(KEY_FEED_PLAYBACK_SPEED, prefs.getFeedPlaybackSpeed());
values.put(KEY_FEED_TAGS, prefs.getTagsAsString()); values.put(KEY_FEED_TAGS, prefs.getTagsAsString());

View File

@ -190,6 +190,7 @@
<item quantity="other">%d subscriptions updated.</item> <item quantity="other">%d subscriptions updated.</item>
</plurals> </plurals>
<string name="edit_tags">Edit tags</string> <string name="edit_tags">Edit tags</string>
<string name="add_tag">Add tag</string>
<string name="rename_tag_label">Rename tag</string> <string name="rename_tag_label">Rename tag</string>
<string name="confirm_mobile_feed_refresh_dialog_message">Refreshing podcasts over mobile data connection is disabled in the settings.\n\nDo you want to refresh anyway?</string> <string name="confirm_mobile_feed_refresh_dialog_message">Refreshing podcasts over mobile data connection is disabled in the settings.\n\nDo you want to refresh anyway?</string>
@ -690,10 +691,10 @@
<string name="auto_download_settings_label">Auto Download Settings</string> <string name="auto_download_settings_label">Auto Download Settings</string>
<string name="episode_filters_label">Episode Filter</string> <string name="episode_filters_label">Episode Filter</string>
<string name="episode_filters_description">List of terms used to decide if an episode should be included or excluded when auto downloading</string> <string name="episode_filters_description">List of terms used to decide if an episode should be included or excluded when auto downloading</string>
<string name="episode_filters_include">Include</string> <string name="add_term">Add Term</string>
<string name="episode_filters_exclude">Exclude</string> <string name="exclude_terms">Exclude episodes containing any of the terms below</string>
<string name="episode_filters_duration">Minimal Duration (in minutes)</string> <string name="include_terms">Include only episodes containing any of the terms below</string>
<string name="episode_filters_hint">Single words \n\"Multiple Words\"</string> <string name="exclude_episodes_shorter_than">Exclude episodes shorter than</string>
<string name="keep_updated">Keep Updated</string> <string name="keep_updated">Keep Updated</string>
<string name="keep_updated_summary">Include this podcast when (auto-)refreshing all podcasts</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> <string name="auto_download_disabled_globally">Auto download is disabled in the main AntennaPod settings</string>