summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh/antennapod
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java80
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java58
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java18
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/FeedFilterDialog.java38
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/FeedSortDialog.java38
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java60
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java87
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java11
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/ShareDialog.java112
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java201
-rw-r--r--app/src/main/java/de/danoeh/antennapod/discovery/PodcastIndexPodcastSearcher.java126
-rw-r--r--app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java45
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java24
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java62
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java23
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java45
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java18
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java34
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java43
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java31
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java36
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java24
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java86
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/RecursiveRadioGroup.java67
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java8
64 files changed, 1201 insertions, 443 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
index fde7c0484..d2618eb08 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
@@ -42,9 +42,8 @@ public class BugReportActivity extends AppCompatActivity {
}
crashDetailsTextView.setText(crashDetailsText);
- findViewById(R.id.btn_open_bug_tracker).setOnClickListener(v -> {
- IntentUtils.openInBrowser(BugReportActivity.this, "https://github.com/AntennaPod/AntennaPod/issues");
- });
+ findViewById(R.id.btn_open_bug_tracker).setOnClickListener(v -> IntentUtils.openInBrowser(
+ BugReportActivity.this, "https://github.com/AntennaPod/AntennaPod/issues"));
findViewById(R.id.btn_copy_log).setOnClickListener(v -> {
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
index 810005d2d..1d3d9bf11 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
@@ -3,6 +3,8 @@ package de.danoeh.antennapod.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
+
+import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.Button;
@@ -86,7 +88,7 @@ public class DownloadAuthenticationActivity extends AppCompatActivity {
}
@Override
- protected void onSaveInstanceState(Bundle outState) {
+ protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("username", etxtUsername.getText().toString());
outState.putString("password", etxtPassword.getText().toString());
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
index eaa423708..f772cb084 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -5,10 +5,13 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.TypedValue;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -31,6 +34,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.StorageUtils;
+import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
import de.danoeh.antennapod.dialog.RatingDialog;
import de.danoeh.antennapod.fragment.AddFeedFragment;
@@ -68,9 +72,9 @@ public class MainActivity extends CastEnabledActivity {
public static final String EXTRA_OPEN_PLAYER = "open_player";
public static final String EXTRA_REFRESH_ON_START = "refresh_on_start";
- private DrawerLayout drawerLayout;
+ private @Nullable DrawerLayout drawerLayout;
+ private @Nullable ActionBarDrawerToggle drawerToggle;
private View navDrawer;
- private ActionBarDrawerToggle drawerToggle;
private LockableBottomSheetBehavior sheetBehavior;
private long lastBackButtonPressTime = 0;
private RecyclerView.RecycledViewPool recycledViewPool = new RecyclerView.RecycledViewPool();
@@ -95,10 +99,17 @@ public class MainActivity extends CastEnabledActivity {
drawerLayout = findViewById(R.id.drawer_layout);
navDrawer = findViewById(R.id.navDrawerFragment);
+ setNavDrawerSize();
final FragmentManager fm = getSupportFragmentManager();
- fm.addOnBackStackChangedListener(() ->
- drawerToggle.setDrawerIndicatorEnabled(fm.getBackStackEntryCount() == 0));
+ fm.addOnBackStackChangedListener(() -> {
+ boolean showArrow = fm.getBackStackEntryCount() != 0;
+ if (drawerToggle != null) { // Tablet layout does not have a drawer
+ drawerToggle.setDrawerIndicatorEnabled(!showArrow);
+ } else if (getActionBar() != null) {
+ getActionBar().setDisplayHomeAsUpEnabled(showArrow);
+ }
+ });
if (fm.findFragmentByTag(MAIN_FRAGMENT_TAG) == null) {
String lastFragment = NavDrawerFragment.getLastNavFragment(this);
@@ -151,12 +162,18 @@ public class MainActivity extends CastEnabledActivity {
@Override
public void setSupportActionBar(@Nullable Toolbar toolbar) {
- drawerLayout.removeDrawerListener(drawerToggle);
- drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
- R.string.drawer_open, R.string.drawer_close);
- drawerLayout.addDrawerListener(drawerToggle);
- drawerToggle.syncState();
- drawerToggle.setDrawerIndicatorEnabled(getSupportFragmentManager().getBackStackEntryCount() == 0);
+ if (drawerLayout != null) { // Tablet layout does not have a drawer
+ drawerLayout.removeDrawerListener(drawerToggle);
+ drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
+ R.string.drawer_open, R.string.drawer_close);
+ drawerLayout.addDrawerListener(drawerToggle);
+ drawerToggle.syncState();
+ drawerToggle.setDrawerIndicatorEnabled(getSupportFragmentManager().getBackStackEntryCount() == 0);
+ } else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
+ toolbar.setNavigationIcon(null);
+ } else {
+ toolbar.setNavigationIcon(ThemeUtils.getDrawableFromAttr(this, R.attr.homeAsUpIndicator));
+ }
super.setSupportActionBar(toolbar);
}
@@ -164,7 +181,11 @@ public class MainActivity extends CastEnabledActivity {
SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
if (prefs.getBoolean(PREF_IS_FIRST_LAUNCH, true)) {
loadFragment(AddFeedFragment.TAG, null);
- new Handler().postDelayed(() -> drawerLayout.openDrawer(navDrawer), 1500);
+ new Handler().postDelayed(() -> {
+ if (drawerLayout != null) { // Tablet layout does not have a drawer
+ drawerLayout.openDrawer(navDrawer);
+ }
+ }, 1500);
// for backward compatibility, we only change defaults for fresh installs
UserPreferences.setUpdateInterval(12);
@@ -258,7 +279,10 @@ public class MainActivity extends CastEnabledActivity {
// not commit anything in an AsyncTask, but that's a bigger
// change than we want now.
t.commitAllowingStateLoss();
- drawerLayout.closeDrawer(navDrawer);
+
+ if (drawerLayout != null) { // Tablet layout does not have a drawer
+ drawerLayout.closeDrawer(navDrawer);
+ }
}
public void loadChildFragment(Fragment fragment, TransitionEffect transition) {
@@ -292,13 +316,35 @@ public class MainActivity extends CastEnabledActivity {
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
- drawerToggle.syncState();
+ if (drawerToggle != null) { // Tablet layout does not have a drawer
+ drawerToggle.syncState();
+ }
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- drawerToggle.onConfigurationChanged(newConfig);
+ if (drawerToggle != null) { // Tablet layout does not have a drawer
+ drawerToggle.onConfigurationChanged(newConfig);
+ }
+ setNavDrawerSize();
+ }
+
+ private void setNavDrawerSize() {
+ if (drawerToggle == null) { // Tablet layout does not have a drawer
+ return;
+ }
+ float screenPercent = getResources().getInteger(R.integer.nav_drawer_screen_size_percent) * 0.01f;
+ int width = (int) (getScreenWidth() * screenPercent);
+ int maxWidth = (int) getResources().getDimension(R.dimen.nav_drawer_max_screen_size);
+
+ navDrawer.getLayoutParams().width = Math.min(width, maxWidth);
+ }
+
+ private int getScreenWidth() {
+ DisplayMetrics displayMetrics = new DisplayMetrics();
+ getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
+ return displayMetrics.widthPixels;
}
@Override
@@ -351,7 +397,7 @@ public class MainActivity extends CastEnabledActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- if (drawerToggle.onOptionsItemSelected(item)) {
+ if (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) { // Tablet layout does not have a drawer
return true;
} else if (item.getItemId() == android.R.id.home) {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
@@ -374,7 +420,9 @@ public class MainActivity extends CastEnabledActivity {
} else {
switch (UserPreferences.getBackButtonBehavior()) {
case OPEN_DRAWER:
- drawerLayout.openDrawer(navDrawer);
+ if (drawerLayout != null) { // Tablet layout does not have drawer
+ drawerLayout.openDrawer(navDrawer);
+ }
break;
case SHOW_PROMPT:
new AlertDialog.Builder(this)
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
index 34c7e3aba..b03d1e5cd 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -18,16 +18,23 @@ import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
+
+import com.bumptech.glide.Glide;
+
+import org.apache.commons.lang3.StringUtils;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.text.NumberFormat;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
-import androidx.arch.core.util.Function;
+import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.content.ContextCompat;
-import androidx.core.util.Consumer;
-import androidx.core.util.Supplier;
-import com.bumptech.glide.Glide;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
@@ -39,7 +46,6 @@ import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.core.util.Flavors;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.core.util.StorageUtils;
@@ -51,18 +57,13 @@ import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
import de.danoeh.antennapod.dialog.PlaybackControlsDialog;
+import de.danoeh.antennapod.dialog.ShareDialog;
import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
import de.danoeh.antennapod.dialog.SleepTimerDialog;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
-import org.apache.commons.lang3.StringUtils;
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
-
-import java.text.NumberFormat;
/**
@@ -304,7 +305,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
return false;
}
Playable media = controller.getMedia();
- boolean isFeedMedia = media != null && (media instanceof FeedMedia);
+ boolean isFeedMedia = (media instanceof FeedMedia);
menu.findItem(R.id.open_feed_item).setVisible(isFeedMedia); // FeedMedia implies it belongs to a Feed
@@ -313,13 +314,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
boolean isItemAndHasLink = isFeedMedia &&
ShareUtils.hasLinkToShare(((FeedMedia) media).getItem());
- menu.findItem(R.id.share_link_item).setVisible(isItemAndHasLink);
- menu.findItem(R.id.share_link_with_position_item).setVisible(isItemAndHasLink);
boolean isItemHasDownloadLink = isFeedMedia && ((FeedMedia) media).getDownload_url() != null;
- menu.findItem(R.id.share_download_url_item).setVisible(isItemHasDownloadLink);
- menu.findItem(R.id.share_download_url_with_position_item).setVisible(isItemHasDownloadLink);
- menu.findItem(R.id.share_file).setVisible(isFeedMedia && ((FeedMedia) media).fileExists());
menu.findItem(R.id.share_item).setVisible(hasWebsiteLink || isItemAndHasLink || isItemHasDownloadLink);
@@ -380,8 +376,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
new SleepTimerDialog().show(getSupportFragmentManager(), "SleepTimerDialog");
break;
case R.id.audio_controls:
- boolean isPlayingVideo = controller.getMedia().getMediaType() == MediaType.VIDEO;
- PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance(isPlayingVideo);
+ PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance();
dialog.show(getSupportFragmentManager(), "playback_controls");
break;
case R.id.open_feed_item:
@@ -393,29 +388,10 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
case R.id.visit_website_item:
IntentUtils.openInBrowser(MediaplayerActivity.this, getWebsiteLinkWithFallback(media));
break;
- case R.id.share_link_item:
- if (feedItem != null) {
- ShareUtils.shareFeedItemLink(this, feedItem);
- }
- break;
- case R.id.share_download_url_item:
- if (feedItem != null) {
- ShareUtils.shareFeedItemDownloadLink(this, feedItem);
- }
- break;
- case R.id.share_link_with_position_item:
+ case R.id.share_item:
if (feedItem != null) {
- ShareUtils.shareFeedItemLink(this, feedItem, true);
- }
- break;
- case R.id.share_download_url_with_position_item:
- if (feedItem != null) {
- ShareUtils.shareFeedItemDownloadLink(this, feedItem, true);
- }
- break;
- case R.id.share_file:
- if (media instanceof FeedMedia) {
- ShareUtils.shareFeedItemFile(this, ((FeedMedia) media));
+ ShareDialog shareDialog = ShareDialog.newInstance(feedItem);
+ shareDialog.show(getSupportFragmentManager(), "ShareEpisodeDialog");
}
break;
default:
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
index beb6e0a9f..f6623d5dc 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -227,15 +227,14 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- Intent destIntent = new Intent(this, MainActivity.class);
- if (NavUtils.shouldUpRecreateTask(this, destIntent)) {
- startActivity(destIntent);
- } else {
- NavUtils.navigateUpFromSameTask(this);
- }
- return true;
+ if (item.getItemId() == android.R.id.home) {
+ Intent destIntent = new Intent(this, MainActivity.class);
+ if (NavUtils.shouldUpRecreateTask(this, destIntent)) {
+ startActivity(destIntent);
+ } else {
+ NavUtils.navigateUpFromSameTask(this);
+ }
+ return true;
}
return super.onOptionsItemSelected(item);
}
@@ -606,9 +605,8 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
}
final List<String> titles = new ArrayList<>();
- final List<String> urls = new ArrayList<>();
- urls.addAll(urlsMap.keySet());
+ final List<String> urls = new ArrayList<>(urlsMap.keySet());
for (String url : urls) {
titles.add(urlsMap.get(url));
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
index e2db81739..c3cb6b0ba 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -188,7 +188,7 @@ public class VideoplayerActivity extends MediaplayerActivity {
videoControlsHider.stop();
if (System.currentTimeMillis() - lastScreenTap < 300) {
- if (event.getX() > v.getMeasuredWidth() / 2) {
+ if (event.getX() > v.getMeasuredWidth() / 2.0f) {
onFastForward();
showSkipAnimation(true);
} else {
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
index 337880317..cfd6ec702 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
@@ -88,10 +88,9 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- finish();
- return true;
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
}
return super.onOptionsItemSelected(item);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
index 690bb9e3d..6bfd34d5c 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
@@ -7,6 +7,10 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
@@ -32,8 +36,9 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter<FeedItem> {
super(context, resource, objects);
}
+ @NonNull
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
+ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Holder holder;
FeedItem item = getItem(position);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
index e66032e11..a53adc719 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -5,7 +5,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
-import android.preference.PreferenceManager;
+import androidx.preference.PreferenceManager;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
@@ -61,7 +61,7 @@ public class NavListAdapter extends BaseAdapter
private final ItemAccess itemAccess;
private final WeakReference<Activity> activity;
- private boolean showSubscriptionList = true;
+ public boolean showSubscriptionList = true;
public NavListAdapter(ItemAccess itemAccess, Activity context) {
this.itemAccess = itemAccess;
@@ -194,7 +194,7 @@ public class NavListAdapter extends BaseAdapter
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int viewType = getItemViewType(position);
- View v = null;
+ View v;
if (viewType == VIEW_TYPE_NAV) {
v = getNavView((String) getItem(position), position, convertView, parent);
} else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
@@ -296,9 +296,17 @@ public class NavListAdapter extends BaseAdapter
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.nav_section_item, parent, false);
+ TextView feedsFilteredMsg = convertView.findViewById(R.id.nav_feeds_filtered_message);
- convertView.setEnabled(false);
- convertView.setOnClickListener(null);
+ if (UserPreferences.getFeedFilter() != UserPreferences.FEED_FILTER_NONE && showSubscriptionList) {
+ convertView.setEnabled(true);
+ feedsFilteredMsg.setText("{md-info-outline} " + context.getString(R.string.subscriptions_are_filtered));
+ Iconify.addIcons(feedsFilteredMsg);
+ feedsFilteredMsg.setVisibility(View.VISIBLE);
+ } else {
+ convertView.setEnabled(false);
+ feedsFilteredMsg.setVisibility(View.GONE);
+ }
return convertView;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
index 428a968c6..7ce086694 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
@@ -20,16 +20,17 @@ public class QueueRecyclerAdapter extends EpisodeItemListAdapter {
private static final String TAG = "QueueRecyclerAdapter";
private final ItemTouchHelper itemTouchHelper;
- private boolean locked;
+ private boolean dragDropEnabled;
+
public QueueRecyclerAdapter(MainActivity mainActivity, ItemTouchHelper itemTouchHelper) {
super(mainActivity);
this.itemTouchHelper = itemTouchHelper;
- locked = UserPreferences.isQueueLocked();
+ dragDropEnabled = ! (UserPreferences.isQueueKeepSorted() || UserPreferences.isQueueLocked());
}
- public void setLocked(boolean locked) {
- this.locked = locked;
+ public void updateDragDropEnabled() {
+ dragDropEnabled = ! (UserPreferences.isQueueKeepSorted() || UserPreferences.isQueueLocked());
notifyDataSetChanged();
}
@@ -37,14 +38,14 @@ public class QueueRecyclerAdapter extends EpisodeItemListAdapter {
@SuppressLint("ClickableViewAccessibility")
protected void afterBindViewHolder(EpisodeItemViewHolder holder, int pos) {
View.OnTouchListener startDragTouchListener = (v1, event) -> {
- if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
Log.d(TAG, "startDrag()");
itemTouchHelper.startDrag(holder);
}
return false;
};
- if (locked) {
+ if (!dragDropEnabled) {
holder.dragHandle.setVisibility(View.GONE);
holder.dragHandle.setOnTouchListener(null);
holder.coverHolder.setOnTouchListener(null);
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
index ac1e94437..c3177668a 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -220,7 +220,7 @@ public class EpisodesApplyActionFragment extends Fragment {
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.episodes_apply_action_options, menu);
@@ -236,7 +236,7 @@ public class EpisodesApplyActionFragment extends Fragment {
}
@Override
- public void onPrepareOptionsMenu(Menu menu) {
+ public void onPrepareOptionsMenu(@NonNull Menu menu) {
// Prepare icon for select toggle button
int[] icon = new int[1];
@@ -413,7 +413,7 @@ public class EpisodesApplyActionFragment extends Fragment {
boolean checked = checkedIds.contains(episode.getId());
mListView.setItemChecked(i, checked);
}
- ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity());
+ getActivity().invalidateOptionsMenu();
toolbar.setTitle(getResources().getQuantityString(R.plurals.num_selected_label,
checkedIds.size(), checkedIds.size()));
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FeedFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/FeedFilterDialog.java
new file mode 100644
index 000000000..3b0e2d04b
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/FeedFilterDialog.java
@@ -0,0 +1,38 @@
+package de.danoeh.antennapod.dialog;
+
+import android.content.Context;
+
+import androidx.appcompat.app.AlertDialog;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.util.Arrays;
+import java.util.List;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+
+public class FeedFilterDialog {
+ public static void showDialog(Context context) {
+ AlertDialog.Builder dialog = new AlertDialog.Builder(context);
+ dialog.setTitle(context.getString(R.string.pref_filter_feed_title));
+ dialog.setNegativeButton(android.R.string.cancel, (d, listener) -> d.dismiss());
+
+ int selected = UserPreferences.getFeedFilter();
+ List<String> entryValues =
+ Arrays.asList(context.getResources().getStringArray(R.array.nav_drawer_feed_filter_values));
+ final int selectedIndex = entryValues.indexOf("" + selected);
+
+ String[] items = context.getResources().getStringArray(R.array.nav_drawer_feed_filter_options);
+ dialog.setSingleChoiceItems(items, selectedIndex, (d, which) -> {
+ if (selectedIndex != which) {
+ UserPreferences.setFeedFilter(entryValues.get(which));
+ //Update subscriptions
+ EventBus.getDefault().post(new UnreadItemsUpdateEvent());
+ }
+ d.dismiss();
+ });
+ dialog.show();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FeedSortDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/FeedSortDialog.java
new file mode 100644
index 000000000..96d1b9b67
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/FeedSortDialog.java
@@ -0,0 +1,38 @@
+package de.danoeh.antennapod.dialog;
+
+import android.content.Context;
+
+import androidx.appcompat.app.AlertDialog;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.util.Arrays;
+import java.util.List;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+
+public class FeedSortDialog {
+ public static void showDialog(Context context) {
+ AlertDialog.Builder dialog = new AlertDialog.Builder(context);
+ dialog.setTitle(context.getString(R.string.pref_nav_drawer_feed_order_title));
+ dialog.setNegativeButton(android.R.string.cancel, (d, listener) -> d.dismiss());
+
+ int selected = UserPreferences.getFeedOrder();
+ List<String> entryValues =
+ Arrays.asList(context.getResources().getStringArray(R.array.nav_drawer_feed_order_values));
+ final int selectedIndex = entryValues.indexOf("" + selected);
+
+ String[] items = context.getResources().getStringArray(R.array.nav_drawer_feed_order_options);
+ dialog.setSingleChoiceItems(items, selectedIndex, (d, which) -> {
+ if (selectedIndex != which) {
+ UserPreferences.setFeedOrder(entryValues.get(which));
+ //Update subscriptions
+ EventBus.getDefault().post(new UnreadItemsUpdateEvent());
+ }
+ d.dismiss();
+ });
+ dialog.show();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
index d2912f90f..82010637f 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
@@ -1,8 +1,12 @@
package de.danoeh.antennapod.dialog;
import android.content.Context;
-import androidx.appcompat.app.AlertDialog;
import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+
+import androidx.appcompat.app.AlertDialog;
import java.util.Arrays;
import java.util.HashSet;
@@ -10,6 +14,8 @@ import java.util.Set;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItemFilter;
+import de.danoeh.antennapod.core.feed.FeedItemFilterGroup;
+import de.danoeh.antennapod.view.RecursiveRadioGroup;
public abstract class FilterDialog {
@@ -22,36 +28,46 @@ public abstract class FilterDialog {
}
public void openDialog() {
- final String[] items = context.getResources().getStringArray(R.array.episode_filter_options);
- final String[] values = context.getResources().getStringArray(R.array.episode_filter_values);
- final boolean[] checkedItems = new boolean[items.length];
final Set<String> filterValues = new HashSet<>(Arrays.asList(filter.getValues()));
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.filter);
- // make sure we have no empty strings in the filter list
- for (String filterValue : filterValues) {
- if (TextUtils.isEmpty(filterValue)) {
- filterValues.remove(filterValue);
- }
+ LayoutInflater inflater = LayoutInflater.from(this.context);
+ LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.filter_dialog, null, false);
+ builder.setView(layout);
+
+ for (FeedItemFilterGroup item : FeedItemFilterGroup.values()) {
+ RecursiveRadioGroup row = (RecursiveRadioGroup) inflater.inflate(R.layout.filter_dialog_row, null);
+ RadioButton filter1 = row.findViewById(R.id.filter_dialog_radioButton1);
+ RadioButton filter2 = row.findViewById(R.id.filter_dialog_radioButton2);
+ filter1.setText(item.values[0].displayName);
+ filter1.setTag(item.values[0].filterId);
+ filter2.setText(item.values[1].displayName);
+ filter2.setTag(item.values[1].filterId);
+ layout.addView(row);
}
- for (int i = 0; i < values.length; i++) {
- String value = values[i];
- if (filterValues.contains(value)) {
- checkedItems[i] = true;
+ for (String filterId : filterValues) {
+ if (!TextUtils.isEmpty(filterId)) {
+ ((RadioButton) layout.findViewWithTag(filterId)).setChecked(true);
}
}
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.filter);
- builder.setMultiChoiceItems(items, checkedItems, (dialog, which, isChecked) -> {
- if (isChecked) {
- filterValues.add(values[which]);
- } else {
- filterValues.remove(values[which]);
- }
- });
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
+ filterValues.clear();
+ for (int i = 0; i < layout.getChildCount(); i++) {
+ if (!(layout.getChildAt(i) instanceof RecursiveRadioGroup)) {
+ continue;
+ }
+ RecursiveRadioGroup group = (RecursiveRadioGroup) layout.getChildAt(i);
+ if (group.getCheckedButton() != null) {
+ String tag = (String) group.getCheckedButton().getTag();
+ if (tag != null) { // Clear buttons use no tag
+ filterValues.add((String) group.getCheckedButton().getTag());
+ }
+ }
+ }
updateFilter(filterValues);
});
builder.setNegativeButton(R.string.cancel_label, null);
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java
index d1ffdc148..7b41652bd 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java
@@ -11,27 +11,21 @@ import android.widget.Button;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.Converter;
-import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.view.PlaybackSpeedSeekBar;
import java.util.List;
import java.util.Locale;
public class PlaybackControlsDialog extends DialogFragment {
- private static final String ARGUMENT_IS_PLAYING_VIDEO = "isPlayingVideo";
-
private PlaybackController controller;
private AlertDialog dialog;
- private boolean isPlayingVideo;
- public static PlaybackControlsDialog newInstance(boolean isPlayingVideo) {
+ public static PlaybackControlsDialog newInstance() {
Bundle arguments = new Bundle();
- arguments.putBoolean(ARGUMENT_IS_PLAYING_VIDEO, isPlayingVideo);
PlaybackControlsDialog dialog = new PlaybackControlsDialog();
dialog.setArguments(arguments);
return dialog;
@@ -65,8 +59,6 @@ public class PlaybackControlsDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
- isPlayingVideo = getArguments() != null && getArguments().getBoolean(ARGUMENT_IS_PLAYING_VIDEO);
-
dialog = new AlertDialog.Builder(getContext())
.setTitle(R.string.audio_controls)
.setView(R.layout.audio_controls)
@@ -79,68 +71,18 @@ public class PlaybackControlsDialog extends DialogFragment {
}
private void setupUi() {
- final SeekBar barPlaybackSpeed = dialog.findViewById(R.id.playback_speed);
- final TextView butDecSpeed = dialog.findViewById(R.id.butDecSpeed);
- butDecSpeed.setOnClickListener(v -> {
- if (controller != null && controller.canSetPlaybackSpeed()) {
- barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() - 2);
- } else {
- VariableSpeedDialog.showGetPluginDialog(getContext());
- }
- });
- final TextView butIncSpeed = dialog.findViewById(R.id.butIncSpeed);
- butIncSpeed.setOnClickListener(v -> {
- if (controller != null && controller.canSetPlaybackSpeed()) {
- barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() + 2);
- } else {
- VariableSpeedDialog.showGetPluginDialog(getContext());
- }
- });
-
final TextView txtvPlaybackSpeed = dialog.findViewById(R.id.txtvPlaybackSpeed);
- float currentSpeed = getCurrentSpeed();
- txtvPlaybackSpeed.setText(String.format(Locale.getDefault(), "%.2fx", currentSpeed));
- barPlaybackSpeed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- if (controller != null && controller.canSetPlaybackSpeed()) {
- float playbackSpeed = (progress + 10) / 20.0f;
- controller.setPlaybackSpeed(playbackSpeed);
-
- PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(playbackSpeed);
- if (isPlayingVideo) {
- UserPreferences.setVideoPlaybackSpeed(playbackSpeed);
- } else {
- UserPreferences.setPlaybackSpeed(playbackSpeed);
- }
-
- String speedStr = String.format(Locale.getDefault(), "%.2fx", playbackSpeed);
- txtvPlaybackSpeed.setText(speedStr);
- } else if (fromUser) {
- float speed = getCurrentSpeed();
- barPlaybackSpeed.post(() -> barPlaybackSpeed.setProgress(Math.round((20 * speed) - 10)));
- }
- }
+ PlaybackSpeedSeekBar speedSeekBar = dialog.findViewById(R.id.speed_seek_bar);
+ speedSeekBar.setController(controller);
+ speedSeekBar.setProgressChangedListener(speed
+ -> txtvPlaybackSpeed.setText(String.format(Locale.getDefault(), "%.2fx", speed)));
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- if (controller != null && !controller.canSetPlaybackSpeed()) {
- VariableSpeedDialog.showGetPluginDialog(getContext());
- }
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
- });
- barPlaybackSpeed.setProgress(Math.round((20 * currentSpeed) - 10));
-
- final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left);
+ final SeekBar barLeftVolume = dialog.findViewById(R.id.volume_left);
barLeftVolume.setProgress(UserPreferences.getLeftVolumePercentage());
- final SeekBar barRightVolume = (SeekBar) dialog.findViewById(R.id.volume_right);
+ final SeekBar barRightVolume = dialog.findViewById(R.id.volume_right);
barRightVolume.setProgress(UserPreferences.getRightVolumePercentage());
- final CheckBox stereoToMono = (CheckBox) dialog.findViewById(R.id.stereo_to_mono);
+ final CheckBox stereoToMono = dialog.findViewById(R.id.stereo_to_mono);
stereoToMono.setChecked(UserPreferences.stereoToMono());
if (controller != null && !controller.canDownmix()) {
stereoToMono.setEnabled(false);
@@ -152,7 +94,7 @@ public class PlaybackControlsDialog extends DialogFragment {
barRightVolume.setEnabled(false);
}
- final CheckBox skipSilence = (CheckBox) dialog.findViewById(R.id.skipSilence);
+ final CheckBox skipSilence = dialog.findViewById(R.id.skipSilence);
skipSilence.setChecked(UserPreferences.isSkipSilence());
if (!UserPreferences.useExoplayer()) {
skipSilence.setEnabled(false);
@@ -220,13 +162,4 @@ public class PlaybackControlsDialog extends DialogFragment {
new Handler().postDelayed(this::setupAudioTracks, 500);
});
}
-
- private float getCurrentSpeed() {
- Playable media = null;
- if (controller != null) {
- media = controller.getMedia();
- }
-
- return PlaybackSpeedUtils.getCurrentPlaybackSpeed(media);
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
index 0c25e3e9f..d0fb91692 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
@@ -23,6 +23,7 @@ import java.net.Proxy;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.R;
@@ -63,6 +64,8 @@ public class ProxyDialog {
public Dialog show() {
View content = View.inflate(context, R.layout.proxy_settings, null);
+ spType = content.findViewById(R.id.spType);
+
dialog = new AlertDialog.Builder(context)
.setTitle(R.string.pref_proxy_title)
.setView(content)
@@ -76,7 +79,7 @@ public class ProxyDialog {
test();
return;
}
- String type = (String) ((Spinner) content.findViewById(R.id.spType)).getSelectedItem();
+ String type = (String) spType.getSelectedItem();
ProxyConfig proxy;
if (Proxy.Type.valueOf(type) == Proxy.Type.DIRECT) {
proxy = ProxyConfig.direct();
@@ -106,7 +109,6 @@ public class ProxyDialog {
dialog.dismiss();
});
- spType = content.findViewById(R.id.spType);
List<String> types = new ArrayList<>();
types.add(Proxy.Type.DIRECT.name());
types.add(Proxy.Type.HTTP.name());
@@ -227,12 +229,11 @@ public class ProxyDialog {
if(required) {
testSuccessful = false;
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.proxy_test_label);
- dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
} else {
testSuccessful = true;
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(android.R.string.ok);
- dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}
+ dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}
private void test() {
@@ -261,7 +262,7 @@ public class ProxyDialog {
portValue = Integer.parseInt(port);
}
SocketAddress address = InetSocketAddress.createUnresolved(host, portValue);
- Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase());
+ Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase(Locale.US));
Proxy proxy = new Proxy(proxyType, address);
OkHttpClient.Builder builder = AntennapodHttpClient.newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ShareDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/ShareDialog.java
new file mode 100644
index 000000000..8104d3539
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/ShareDialog.java
@@ -0,0 +1,112 @@
+package de.danoeh.antennapod.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.util.ShareUtils;
+
+public class ShareDialog extends DialogFragment {
+
+ private static final String ARGUMENT_FEED_ITEM = "feedItem";
+
+ private static final String TAG = "ShareDialog";
+ private Context ctx;
+ private FeedItem item;
+
+ private static final String PREF_SHARE_DIALOG_OPTION = "prefShareDialogOption";
+ private static final String PREF_SHARE_EPISODE_START_AT = "prefShareEpisodeStartAt";
+
+ private RadioGroup radioGroup;
+ private RadioButton radioEpisodeWebsite;
+ private RadioButton radioMediaFile;
+ private CheckBox checkBoxStartAt;
+ private SharedPreferences prefs;
+
+ public ShareDialog() {
+ // Empty constructor required for DialogFragment
+ }
+
+ public static ShareDialog newInstance(FeedItem item) {
+ Bundle arguments = new Bundle();
+ arguments.putSerializable(ARGUMENT_FEED_ITEM, item);
+ ShareDialog dialog = new ShareDialog();
+ dialog.setArguments(arguments);
+ return dialog;
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ if (getArguments() != null) {
+ ctx = getActivity();
+ item = (FeedItem) getArguments().getSerializable(ARGUMENT_FEED_ITEM);
+ prefs = getActivity().getSharedPreferences("ShareDialog", Context.MODE_PRIVATE);
+ }
+
+ View content = View.inflate(ctx, R.layout.share_episode_dialog, null);
+ AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
+ builder.setTitle(R.string.share_label);
+ builder.setView(content);
+
+ radioGroup = content.findViewById(R.id.share_dialog_radio_group);
+ radioEpisodeWebsite = content.findViewById(R.id.share_episode_website_radio);
+ radioMediaFile = content.findViewById(R.id.share_media_file_radio);
+ checkBoxStartAt = content.findViewById(R.id.share_start_at_timer_dialog);
+
+ setupOptions();
+
+ builder.setPositiveButton(R.string.share_label, (dialog, id) -> {
+ boolean includePlaybackPosition = checkBoxStartAt.isChecked();
+ if (radioEpisodeWebsite.isChecked()) {
+ ShareUtils.shareFeedItemLink(ctx, item, includePlaybackPosition);
+ prefs.edit().putString(PREF_SHARE_DIALOG_OPTION, "website").apply();
+ } else {
+ ShareUtils.shareFeedItemDownloadLink(ctx, item, includePlaybackPosition);
+ prefs.edit().putString(PREF_SHARE_DIALOG_OPTION, "media").apply();
+ }
+ prefs.edit().putBoolean(PREF_SHARE_EPISODE_START_AT, includePlaybackPosition).apply();
+ }).setNegativeButton(R.string.cancel_label, (dialog, id) -> dialog.dismiss());
+
+ return builder.create();
+ }
+
+ private void setupOptions() {
+ final boolean hasMedia = item.getMedia() != null;
+
+ if (!ShareUtils.hasLinkToShare(item)) {
+ radioEpisodeWebsite.setVisibility(View.GONE);
+ radioMediaFile.setChecked(true);
+ }
+
+ if (!hasMedia || item.getMedia().getDownload_url() == null) {
+ radioMediaFile.setVisibility(View.GONE);
+ radioEpisodeWebsite.setChecked(true);
+ }
+
+ if (radioEpisodeWebsite.getVisibility() == View.VISIBLE && radioMediaFile.getVisibility() == View.VISIBLE) {
+ String option = prefs.getString(PREF_SHARE_DIALOG_OPTION, "website");
+ if (option.equals("website")) {
+ radioEpisodeWebsite.setChecked(true);
+ radioMediaFile.setChecked(false);
+ } else {
+ radioEpisodeWebsite.setChecked(false);
+ radioMediaFile.setChecked(true);
+ }
+ }
+
+ boolean switchIsChecked = prefs.getBoolean(PREF_SHARE_EPISODE_START_AT, false);
+ checkBoxStartAt.setChecked(switchIsChecked);
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
index a9c54e879..274c3b7bd 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.dialog;
+import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -137,6 +138,7 @@ public class SleepTimerDialog extends DialogFragment {
if (controller != null) {
controller.setSleepTimer(time);
}
+ closeKeyboard(content);
} catch (NumberFormatException e) {
e.printStackTrace();
Snackbar.make(content, R.string.time_dialog_invalid_input, Snackbar.LENGTH_LONG).show();
@@ -153,4 +155,9 @@ public class SleepTimerDialog extends DialogFragment {
timeDisplay.setVisibility(controller.sleepTimerActive() ? View.VISIBLE : View.GONE);
time.setText(Converter.getDurationStringLong((int) controller.getSleepTimerTimeLeft()));
}
+
+ private void closeKeyboard(View content) {
+ InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(content.getWindowToken(), 0);
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java
index 3a6ba183f..1fc7a77b2 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java
@@ -1,97 +1,170 @@
package de.danoeh.antennapod.dialog;
+import android.app.Dialog;
import android.content.Context;
-import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import com.google.android.material.chip.Chip;
+import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.view.ItemOffsetDecoration;
+import de.danoeh.antennapod.view.PlaybackSpeedSeekBar;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
-public class VariableSpeedDialog {
+public class VariableSpeedDialog extends DialogFragment {
+ private SpeedSelectionAdapter adapter;
+ private final DecimalFormat speedFormat;
+ private PlaybackController controller;
+ private final List<Float> selectedSpeeds;
+ private PlaybackSpeedSeekBar speedSeekBar;
+ private Chip addCurrentSpeedChip;
- private VariableSpeedDialog() {
- }
-
- public static void showDialog(final Context context) {
- if (UserPreferences.useSonic()
- || UserPreferences.useExoplayer()
- || Build.VERSION.SDK_INT >= 23) {
- showSpeedSelectorDialog(context);
- } else {
- showGetPluginDialog(context, true);
- }
+ public VariableSpeedDialog() {
+ DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.US);
+ format.setDecimalSeparator('.');
+ speedFormat = new DecimalFormat("0.00", format);
+ selectedSpeeds = new ArrayList<>(UserPreferences.getPlaybackSpeedArray());
}
public static void showGetPluginDialog(final Context context) {
- showGetPluginDialog(context, false);
- }
-
- private static void showGetPluginDialog(final Context context, boolean showSpeedSelector) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.no_playback_plugin_title);
builder.setMessage(R.string.no_playback_plugin_or_sonic_msg);
- builder.setPositiveButton(R.string.enable_sonic, (dialog, which) -> {
- UserPreferences.enableSonic();
- if (showSpeedSelector) {
- showSpeedSelectorDialog(context);
- }
- });
+ builder.setPositiveButton(R.string.enable_sonic, (dialog, which) ->
+ UserPreferences.enableSonic());
builder.setNeutralButton(R.string.close_label, null);
builder.show();
}
- private static void showSpeedSelectorDialog(final Context context) {
- DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.US);
- format.setDecimalSeparator('.');
- DecimalFormat speedFormat = new DecimalFormat("0.00", format);
-
- final String[] speedValues = context.getResources().getStringArray(
- R.array.playback_speed_values);
- // According to Java spec these get initialized to false on creation
- final boolean[] speedChecked = new boolean[speedValues.length];
-
- // Build the "isChecked" array so that multiChoice dialog is populated correctly
- List<String> selectedSpeedList = new ArrayList<>();
- float[] selectedSpeeds = UserPreferences.getPlaybackSpeedArray();
- for (float speed : selectedSpeeds) {
- selectedSpeedList.add(speedFormat.format(speed));
+ @Override
+ public void onStart() {
+ super.onStart();
+ controller = new PlaybackController(getActivity()) {
+ @Override
+ public void setupGUI() {
+ updateSpeed();
+ }
+
+ @Override
+ public void onPlaybackSpeedChange() {
+ updateSpeed();
+ }
+ };
+ controller.init();
+ speedSeekBar.setController(controller);
+ }
+
+ private void updateSpeed() {
+ speedSeekBar.updateSpeed();
+ addCurrentSpeedChip.setText(speedFormat.format(controller.getCurrentPlaybackSpeedMultiplier()));
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ controller.release();
+ controller = null;
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+ builder.setPositiveButton(R.string.close_label, null);
+
+ View root = View.inflate(getContext(), R.layout.speed_select_dialog, null);
+ speedSeekBar = root.findViewById(R.id.speed_seek_bar);
+ RecyclerView selectedSpeedsGrid = root.findViewById(R.id.selected_speeds_grid);
+ selectedSpeedsGrid.setLayoutManager(new GridLayoutManager(getContext(), 3));
+ selectedSpeedsGrid.addItemDecoration(new ItemOffsetDecoration(getContext(), 4));
+ adapter = new SpeedSelectionAdapter();
+ adapter.setHasStableIds(true);
+ selectedSpeedsGrid.setAdapter(adapter);
+
+ addCurrentSpeedChip = root.findViewById(R.id.add_current_speed_chip);
+ addCurrentSpeedChip.setCloseIconVisible(true);
+ addCurrentSpeedChip.setCloseIconResource(R.drawable.ic_add_black);
+ addCurrentSpeedChip.setOnCloseIconClickListener(v -> addCurrentSpeed());
+ addCurrentSpeedChip.setOnClickListener(v -> addCurrentSpeed());
+
+ builder.setView(root);
+ return builder.create();
+ }
+
+ private void addCurrentSpeed() {
+ float newSpeed = controller.getCurrentPlaybackSpeedMultiplier();
+ if (selectedSpeeds.contains(newSpeed)) {
+ Snackbar.make(addCurrentSpeedChip,
+ getString(R.string.preset_already_exists, newSpeed), Snackbar.LENGTH_LONG).show();
+ } else {
+ selectedSpeeds.add(newSpeed);
+ Collections.sort(selectedSpeeds);
+ UserPreferences.setPlaybackSpeedArray(selectedSpeeds);
+ adapter.notifyDataSetChanged();
}
+ }
- for (int i = 0; i < speedValues.length; i++) {
- speedChecked[i] = selectedSpeedList.contains(speedValues[i]);
+ public class SpeedSelectionAdapter extends RecyclerView.Adapter<SpeedSelectionAdapter.ViewHolder> {
+
+ @Override
+ @NonNull
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ Chip chip = new Chip(getContext());
+ chip.setCloseIconVisible(true);
+ chip.setCloseIconResource(R.drawable.ic_delete_black);
+ return new ViewHolder(chip);
}
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.set_playback_speed_label);
- builder.setMultiChoiceItems(R.array.playback_speed_values,
- speedChecked, (dialog, which, isChecked) -> speedChecked[which] = isChecked);
- builder.setNegativeButton(android.R.string.cancel, null);
- builder.setPositiveButton(android.R.string.ok,
- (dialog, which) -> {
- int choiceCount = 0;
- for (boolean checked : speedChecked) {
- if (checked) {
- choiceCount++;
- }
- }
- String[] newSpeedValues = new String[choiceCount];
- int newSpeedIndex = 0;
- for (int i = 0; i < speedChecked.length; i++) {
- if (speedChecked[i]) {
- newSpeedValues[newSpeedIndex++] = speedValues[i];
- }
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ float speed = selectedSpeeds.get(position);
+
+ holder.chip.setText(speedFormat.format(speed));
+ holder.chip.setOnCloseIconClickListener(v -> {
+ selectedSpeeds.remove(speed);
+ UserPreferences.setPlaybackSpeedArray(selectedSpeeds);
+ notifyDataSetChanged();
+ });
+ holder.chip.setOnClickListener(v -> {
+ if (controller != null) {
+ controller.setPlaybackSpeed(speed);
+ notifyDataSetChanged();
}
+ });
+ }
- UserPreferences.setPlaybackSpeedArray(newSpeedValues);
+ @Override
+ public int getItemCount() {
+ return selectedSpeeds.size();
+ }
- });
- builder.create().show();
- }
+ @Override
+ public long getItemId(int position) {
+ return selectedSpeeds.get(position).hashCode();
+ }
+
+ public class ViewHolder extends RecyclerView.ViewHolder {
+ Chip chip;
+ ViewHolder(Chip itemView) {
+ super(itemView);
+ chip = itemView;
+ }
+ }
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastIndexPodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastIndexPodcastSearcher.java
new file mode 100644
index 000000000..c8e5dc4ef
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastIndexPodcastSearcher.java
@@ -0,0 +1,126 @@
+package de.danoeh.antennapod.discovery;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import de.danoeh.antennapod.BuildConfig;
+import de.danoeh.antennapod.core.ClientConfig;
+import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
+import io.reactivex.Single;
+import io.reactivex.SingleOnSubscribe;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+public class PodcastIndexPodcastSearcher implements PodcastSearcher {
+ private static final String PODCASTINDEX_API_URL = "https://api.podcastindex.org/api/1.0/search/byterm?q=%s";
+
+ public PodcastIndexPodcastSearcher() {
+ }
+
+ @Override
+ public Single<List<PodcastSearchResult>> search(String query) {
+ return Single.create((SingleOnSubscribe<List<PodcastSearchResult>>) subscriber -> {
+
+ Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ calendar.clear();
+ Date now = new Date();
+ calendar.setTime(now);
+ long secondsSinceEpoch = calendar.getTimeInMillis() / 1000L;
+ String apiHeaderTime = String.valueOf(secondsSinceEpoch);
+ String data4Hash = BuildConfig.PODCASTINDEX_API_KEY + BuildConfig.PODCASTINDEX_API_SECRET + apiHeaderTime;
+ String hashString = sha1(data4Hash);
+
+ String encodedQuery;
+ try {
+ encodedQuery = URLEncoder.encode(query, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // this won't ever be thrown
+ encodedQuery = query;
+ }
+
+ String formattedUrl = String.format(PODCASTINDEX_API_URL, encodedQuery);
+
+ OkHttpClient client = AntennapodHttpClient.getHttpClient();
+ Request.Builder httpReq = new Request.Builder()
+ .addHeader("X-Auth-Date", apiHeaderTime)
+ .addHeader("X-Auth-Key", BuildConfig.PODCASTINDEX_API_KEY)
+ .addHeader("Authorization", hashString)
+ .addHeader("User-Agent", ClientConfig.USER_AGENT)
+ .url(formattedUrl);
+ List<PodcastSearchResult> podcasts = new ArrayList<>();
+ try {
+ Response response = client.newCall(httpReq.build()).execute();
+
+ if (response.isSuccessful()) {
+ String resultString = response.body().string();
+ JSONObject result = new JSONObject(resultString);
+ JSONArray j = result.getJSONArray("feeds");
+
+ for (int i = 0; i < j.length(); i++) {
+ JSONObject podcastJson = j.getJSONObject(i);
+ PodcastSearchResult podcast = PodcastSearchResult.fromPodcastIndex(podcastJson);
+ if (podcast.feedUrl != null) {
+ podcasts.add(podcast);
+ }
+ }
+ } else {
+ subscriber.onError(new IOException(response.toString()));
+ }
+ } catch (IOException | JSONException e) {
+ subscriber.onError(e);
+ }
+ subscriber.onSuccess(podcasts);
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread());
+ }
+
+ @Override
+ public Single<String> lookupUrl(String url) {
+ return Single.just(url);
+ }
+
+ @Override
+ public boolean urlNeedsLookup(String url) {
+ return false;
+ }
+
+ @Override
+ public String getName() {
+ return "Podcastindex.org";
+ }
+
+ private static String sha1(String clearString) {
+ try {
+ MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+ messageDigest.update(clearString.getBytes("UTF-8"));
+ return toHex(messageDigest.digest());
+ } catch (Exception ignored) {
+ ignored.printStackTrace();
+ return null;
+ }
+ }
+
+ private static String toHex(byte[] bytes) {
+ StringBuilder buffer = new StringBuilder();
+ for (byte b : bytes) {
+ buffer.append(String.format(Locale.getDefault(), "%02x", b));
+ }
+ return buffer.toString();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java
index 0f0c864b1..bba438d1d 100644
--- a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java
+++ b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java
@@ -103,4 +103,12 @@ public class PodcastSearchResult {
searchHit.getUrl(),
searchHit.getAuthor());
}
+
+ public static PodcastSearchResult fromPodcastIndex(JSONObject json) {
+ String title = json.optString("title", "");
+ String imageUrl = json.optString("image", null);
+ String feedUrl = json.optString("url", null);
+ String author = json.optString("author", null);
+ return new PodcastSearchResult(title, imageUrl, feedUrl, author);
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java
index 3f738424b..ad574cab6 100644
--- a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java
+++ b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java
@@ -19,6 +19,7 @@ public class PodcastSearcherRegistry {
searchProviders.add(new SearcherInfo(new ItunesPodcastSearcher(), 1.f));
searchProviders.add(new SearcherInfo(new FyydPodcastSearcher(), 1.f));
searchProviders.add(new SearcherInfo(new GpodnetPodcastSearcher(), 0.0f));
+ searchProviders.add(new SearcherInfo(new PodcastIndexPodcastSearcher(), 0.0f));
}
return searchProviders;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
index 546684f14..a4646ad64 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
@@ -12,9 +12,13 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
@@ -22,6 +26,7 @@ import de.danoeh.antennapod.activity.OpmlImportActivity;
import de.danoeh.antennapod.discovery.CombinedSearcher;
import de.danoeh.antennapod.discovery.FyydPodcastSearcher;
import de.danoeh.antennapod.discovery.ItunesPodcastSearcher;
+import de.danoeh.antennapod.discovery.PodcastIndexPodcastSearcher;
import de.danoeh.antennapod.fragment.gpodnet.GpodnetMainFragment;
/**
@@ -36,7 +41,10 @@ public class AddFeedFragment extends Fragment {
private MainActivity activity;
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ @Nullable
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.addfeed, container, false);
activity = (MainActivity) getActivity();
@@ -48,6 +56,8 @@ public class AddFeedFragment extends Fragment {
-> activity.loadChildFragment(OnlineSearchFragment.newInstance(FyydPodcastSearcher.class)));
root.findViewById(R.id.btn_search_gpodder).setOnClickListener(v
-> activity.loadChildFragment(new GpodnetMainFragment()));
+ root.findViewById(R.id.btn_search_podcastindex).setOnClickListener(v
+ -> activity.loadChildFragment(OnlineSearchFragment.newInstance(PodcastIndexPodcastSearcher.class)));
combinedFeedSearchBox = root.findViewById(R.id.combinedFeedSearchBox);
combinedFeedSearchBox.setOnEditorActionListener((v, actionId, event) -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
index 05f38000c..4a1c12e0a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -45,20 +45,18 @@ public class AllEpisodesFragment extends EpisodesListFragment {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
- switch (item.getItemId()) {
- case R.id.filter_items:
- showFilterDialog();
- return true;
- default:
- return false;
+ if (item.getItemId() == R.id.filter_items) {
+ showFilterDialog();
+ return true;
}
+ return false;
} else {
return true;
}
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.findItem(R.id.filter_items).setVisible(true);
menu.findItem(R.id.mark_all_read_item).setVisible(true);
@@ -69,7 +67,7 @@ public class AllEpisodesFragment extends EpisodesListFragment {
super.onFragmentLoaded(episodes);
if (feedItemFilter.getValues().length > 0) {
- txtvInformation.setText("{fa-info-circle} " + this.getString(R.string.filtered_label));
+ txtvInformation.setText("{md-info-outline} " + this.getString(R.string.filtered_label));
Iconify.addIcons(txtvInformation);
txtvInformation.setVisibility(View.VISIBLE);
} else {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
index e32fdb095..3129aa43c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
@@ -13,7 +13,6 @@ import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
@@ -21,17 +20,8 @@ import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
-
import com.google.android.material.bottomsheet.BottomSheetBehavior;
-
import com.google.android.material.snackbar.Snackbar;
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
-
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.CastEnabledActivity;
import de.danoeh.antennapod.activity.MainActivity;
@@ -40,7 +30,6 @@ import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.util.Converter;
@@ -60,6 +49,13 @@ import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.List;
/**
* Shows the audio player.
@@ -96,7 +92,9 @@ public class AudioPlayerFragment extends Fragment implements
private boolean showTimeLeft;
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.audioplayer_fragment, container, false);
toolbar = root.findViewById(R.id.toolbar);
@@ -204,30 +202,29 @@ public class AudioPlayerFragment extends Fragment implements
VariableSpeedDialog.showGetPluginDialog(getContext());
return;
}
- float[] availableSpeeds = UserPreferences.getPlaybackSpeedArray();
+ List<Float> availableSpeeds = UserPreferences.getPlaybackSpeedArray();
float currentSpeed = controller.getCurrentPlaybackSpeedMultiplier();
int newSpeedIndex = 0;
- while (newSpeedIndex < availableSpeeds.length && availableSpeeds[newSpeedIndex] < currentSpeed + EPSILON) {
+ while (newSpeedIndex < availableSpeeds.size()
+ && availableSpeeds.get(newSpeedIndex) < currentSpeed + EPSILON) {
newSpeedIndex++;
}
float newSpeed;
- if (availableSpeeds.length == 0) {
+ if (availableSpeeds.size() == 0) {
newSpeed = 1.0f;
- } else if (newSpeedIndex == availableSpeeds.length) {
- newSpeed = availableSpeeds[0];
+ } else if (newSpeedIndex == availableSpeeds.size()) {
+ newSpeed = availableSpeeds.get(0);
} else {
- newSpeed = availableSpeeds[newSpeedIndex];
+ newSpeed = availableSpeeds.get(newSpeedIndex);
}
- PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(newSpeed);
- UserPreferences.setPlaybackSpeed(newSpeed);
controller.setPlaybackSpeed(newSpeed);
loadMediaInfo();
});
butPlaybackSpeed.setOnLongClickListener(v -> {
- VariableSpeedDialog.showDialog(getContext());
+ new VariableSpeedDialog().show(getChildFragmentManager(), null);
return true;
});
butPlaybackSpeed.setVisibility(View.VISIBLE);
@@ -492,11 +489,11 @@ public class AudioPlayerFragment extends Fragment implements
switch (item.getItemId()) {
case R.id.disable_sleeptimer_item: // Fall-through
case R.id.set_sleeptimer_item:
- new SleepTimerDialog().show(getFragmentManager(), "SleepTimerDialog");
+ new SleepTimerDialog().show(getChildFragmentManager(), "SleepTimerDialog");
return true;
case R.id.audio_controls:
- PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance(false);
- dialog.show(getFragmentManager(), "playback_controls");
+ PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance();
+ dialog.show(getChildFragmentManager(), "playback_controls");
return true;
case R.id.open_feed_item:
if (feedItem != null) {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
index 48c25552f..6911687dd 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -45,7 +45,6 @@ public class ChaptersFragment extends Fragment {
RecyclerView recyclerView = root.findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
- recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build());
adapter = new ChaptersListAdapter(getActivity(), pos -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
index 13941dd2c..55a5d744e 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
@@ -17,16 +17,21 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
import de.danoeh.antennapod.adapter.actionbutton.DeleteActionButton;
+import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloadLogEvent;
import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.FeedItemUtil;
+import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.view.EmptyViewHandler;
import de.danoeh.antennapod.view.EpisodeItemListRecyclerView;
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
@@ -58,6 +63,8 @@ public class CompletedDownloadsFragment extends Fragment {
private Disposable disposable;
private EmptyViewHandler emptyView;
+ private boolean isUpdatingFeeds = false;
+
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
@@ -104,10 +111,11 @@ public class CompletedDownloadsFragment extends Fragment {
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.downloads_completed, menu);
menu.findItem(R.id.episode_actions).setVisible(items.size() > 0);
+ isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
}
@Override
@@ -116,10 +124,24 @@ public class CompletedDownloadsFragment extends Fragment {
((MainActivity) requireActivity())
.loadChildFragment(EpisodesApplyActionFragment.newInstance(items, ACTION_DELETE | ACTION_ADD_TO_QUEUE));
return true;
+ } else if (item.getItemId() == R.id.refresh_item) {
+ AutoUpdateManager.runImmediate(requireContext());
+ return true;
}
return false;
}
+ @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
+ public void onEventMainThread(DownloadEvent event) {
+ Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
+ if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
+ getActivity().invalidateOptionsMenu();
+ }
+ }
+
+ private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker =
+ () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
+
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
FeedItem selectedItem = adapter.getSelectedItem();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
index 312e3cb62..055d88285 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
@@ -1,11 +1,16 @@
package de.danoeh.antennapod.fragment;
import android.app.Dialog;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.ListFragment;
-import androidx.core.view.MenuItemCompat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@@ -17,14 +22,21 @@ import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
+import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.DownloadLogAdapter;
+import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloadLogEvent;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
+import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.view.EmptyViewHandler;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -32,6 +44,7 @@ import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
/**
* Shows the download log
@@ -44,6 +57,8 @@ public class DownloadLogFragment extends ListFragment {
private DownloadLogAdapter adapter;
private Disposable disposable;
+ private boolean isUpdatingFeeds = false;
+
@Override
public void onStart() {
super.onStart();
@@ -65,7 +80,7 @@ public class DownloadLogFragment extends ListFragment {
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// add padding
final ListView lv = getListView();
@@ -93,11 +108,11 @@ public class DownloadLogFragment extends ListFragment {
private void onFragmentLoaded() {
setListShown(true);
adapter.notifyDataSetChanged();
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
}
@Override
- public void onListItemClick(ListView l, View v, int position, long id) {
+ public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) {
super.onListItemClick(l, v, position, id);
DownloadStatus status = adapter.getItem(position);
@@ -119,10 +134,17 @@ public class DownloadLogFragment extends ListFragment {
message = status.getReasonDetailed();
}
+ String messageFull = getString(R.string.download_error_details_message, message, url);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.download_error_details);
- builder.setMessage(getString(R.string.download_error_details_message, message, url));
+ builder.setMessage(messageFull);
builder.setPositiveButton(android.R.string.ok, null);
+ builder.setNeutralButton(R.string.copy_to_clipboard, (dialog, which) -> {
+ ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ ClipData clip = ClipData.newPlainText(getString(R.string.download_error_details), messageFull);
+ clipboard.setPrimaryClip(clip);
+ ((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT);
+ });
Dialog dialog = builder.show();
((TextView) dialog.findViewById(android.R.id.message)).setTextIsSelectable(true);
}
@@ -150,20 +172,14 @@ public class DownloadLogFragment extends ListFragment {
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- if (!isAdded()) {
- return;
- }
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- MenuItem clearHistory = menu.add(Menu.NONE, R.id.clear_history_item, Menu.CATEGORY_CONTAINER, R.string.clear_history_label);
- MenuItemCompat.setShowAsAction(clearHistory, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
- TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.ic_delete});
- clearHistory.setIcon(drawables.getDrawable(0));
- drawables.recycle();
+ inflater.inflate(R.menu.downloads_log, menu);
+ isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
}
@Override
- public void onPrepareOptionsMenu(Menu menu) {
+ public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem menuItem = menu.findItem(R.id.clear_history_item);
if (menuItem != null) {
@@ -172,12 +188,15 @@ public class DownloadLogFragment extends ListFragment {
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
switch (item.getItemId()) {
case R.id.clear_history_item:
DBWriter.clearDownloadLog();
return true;
+ case R.id.refresh_item:
+ AutoUpdateManager.runImmediate(requireContext());
+ return true;
default:
return false;
}
@@ -186,6 +205,17 @@ public class DownloadLogFragment extends ListFragment {
}
}
+ @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
+ public void onEventMainThread(DownloadEvent event) {
+ Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
+ if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
+ getActivity().invalidateOptionsMenu();
+ }
+ }
+
+ private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker =
+ () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
+
private void loadItems() {
if (disposable != null) {
disposable.dispose();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java
index 37b842e0c..bc2d85452 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java
@@ -8,6 +8,7 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
@@ -39,7 +40,9 @@ public class DownloadsFragment extends Fragment {
private TabLayout tabLayout;
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.pager_fragment, container, false);
Toolbar toolbar = root.findViewById(R.id.toolbar);
@@ -77,7 +80,7 @@ public class DownloadsFragment extends Fragment {
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
int tab = getArguments().getInt(ARG_SELECTED_TAB);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
index 29b6a1b16..44f6c8827 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
@@ -120,7 +120,7 @@ public abstract class EpisodesListFragment extends Fragment {
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
if (!isAdded()) {
return;
}
@@ -131,7 +131,7 @@ public abstract class EpisodesListFragment extends Fragment {
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
switch (item.getItemId()) {
case R.id.refresh_item:
@@ -176,7 +176,7 @@ public abstract class EpisodesListFragment extends Fragment {
}
@Override
- public boolean onContextItemSelected(MenuItem item) {
+ public boolean onContextItemSelected(@NonNull MenuItem item) {
Log.d(TAG, "onContextItemSelected() called with: " + "item = [" + item + "]");
if (!getUserVisibleHint()) {
return false;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
index 4f8b4f00c..d50be88c5 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
@@ -53,12 +53,14 @@ public class FavoriteEpisodesFragment extends EpisodesListFragment {
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT) {
@Override
- public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
+ public boolean onMove(@NonNull RecyclerView recyclerView,
+ @NonNull RecyclerView.ViewHolder viewHolder,
+ @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
- public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
+ public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int swipeDir) {
EpisodeItemViewHolder holder = (EpisodeItemViewHolder) viewHolder;
Log.d(TAG, String.format("remove(%s)", holder.getFeedItem().getId()));
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
index c58e6c15f..ae03b5032 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.fragment;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Configuration;
import android.graphics.LightingColorFilter;
import android.net.Uri;
import android.os.Bundle;
@@ -47,9 +48,6 @@ import io.reactivex.MaybeOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
-import org.apache.commons.lang3.StringUtils;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
/**
* Displays information about a feed.
@@ -71,6 +69,8 @@ public class FeedInfoFragment extends Fragment {
private TextView txtvUrl;
private TextView txtvAuthorHeader;
private ImageView imgvBackground;
+ private View infoContainer;
+ private View header;
private Menu optionsMenu;
private ToolbarIconTintManager iconTintManager;
@@ -124,6 +124,8 @@ public class FeedInfoFragment extends Fragment {
txtvTitle = root.findViewById(R.id.txtvTitle);
txtvAuthorHeader = root.findViewById(R.id.txtvAuthor);
imgvBackground = root.findViewById(R.id.imgvBackground);
+ header = root.findViewById(R.id.headerContainer);
+ infoContainer = root.findViewById(R.id.infoContainer);
root.findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
root.findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
// https://github.com/bumptech/glide/issues/529
@@ -159,6 +161,15 @@ public class FeedInfoFragment extends Fragment {
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
}
+ @Override
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ int horizontalSpacing = (int) getResources().getDimension(R.dimen.additional_horizontal_spacing);
+ header.setPadding(horizontalSpacing, header.getPaddingTop(), horizontalSpacing, header.getPaddingBottom());
+ infoContainer.setPadding(horizontalSpacing, infoContainer.getPaddingTop(),
+ horizontalSpacing, infoContainer.getPaddingBottom());
+ }
+
private void showFeed() {
Log.d(TAG, "Language is " + feed.getLanguage());
Log.d(TAG, "Author is " + feed.getAuthor());
@@ -216,7 +227,7 @@ public class FeedInfoFragment extends Fragment {
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.feedinfo, menu);
optionsMenu = menu;
@@ -224,7 +235,7 @@ public class FeedInfoFragment extends Fragment {
}
@Override
- public void onPrepareOptionsMenu(Menu menu) {
+ public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null
@@ -232,7 +243,7 @@ public class FeedInfoFragment extends Fragment {
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (feed == null) {
((MainActivity) getActivity()).showSnackbarAbovePlayer(
R.string.please_wait_for_data, Toast.LENGTH_LONG);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
index 67433166c..965cfdc86 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
@@ -2,6 +2,8 @@ package de.danoeh.antennapod.fragment;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.res.Configuration;
+import android.content.Intent;
import android.graphics.LightingColorFilter;
import android.os.Bundle;
import android.util.Log;
@@ -52,6 +54,7 @@ import de.danoeh.antennapod.core.glide.FastBlurTransformation;
import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
+import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.FeedItemPermutors;
@@ -60,6 +63,7 @@ import de.danoeh.antennapod.core.util.Optional;
import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
+import de.danoeh.antennapod.dialog.FilterDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
@@ -77,6 +81,7 @@ import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
+import java.util.Set;
/**
* Displays a list of FeedItems.
@@ -98,6 +103,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
private TextView txtvAuthor;
private ImageButton butShowInfo;
private ImageButton butShowSettings;
+ private View header;
private Menu optionsMenu;
private ToolbarIconTintManager iconTintManager;
@@ -155,6 +161,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
butShowSettings = root.findViewById(R.id.butShowSettings);
txtvInformation = root.findViewById(R.id.txtvInformation);
txtvFailure = root.findViewById(R.id.txtvFailure);
+ header = root.findViewById(R.id.headerContainer);
AppBarLayout appBar = root.findViewById(R.id.appBar);
CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar);
@@ -221,7 +228,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
};
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
if (!isAdded()) {
return;
}
@@ -239,14 +246,21 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
}
@Override
- public void onPrepareOptionsMenu(Menu menu) {
+ public void onPrepareOptionsMenu(@NonNull Menu menu) {
if (feed != null) {
FeedMenuHandler.onPrepareOptionsMenu(menu, feed);
}
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ int horizontalSpacing = (int) getResources().getDimension(R.dimen.additional_horizontal_spacing);
+ header.setPadding(horizontalSpacing, header.getPaddingTop(), horizontalSpacing, header.getPaddingBottom());
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
if (feed == null) {
((MainActivity) getActivity()).showSnackbarAbovePlayer(
@@ -405,7 +419,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
private void updateSyncProgressBarVisibility() {
if (isUpdatingFeed != updateRefreshMenuItemChecker.isRefreshing()) {
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
}
if (!DownloadRequester.getInstance().isDownloadingFeeds()) {
nextPageLoader.getRoot().setVisibility(View.GONE);
@@ -429,7 +443,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
adapter.updateItems(feed.getItems());
}
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
updateSyncProgressBarVisibility();
}
@@ -454,8 +468,19 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) txtvInformation.getLayoutParams();
p.addRule(RelativeLayout.BELOW, R.id.txtvFailure);
}
- txtvInformation.setText("{fa-info-circle} " + this.getString(R.string.filtered_label));
+ txtvInformation.setText("{md-info-outline} " + this.getString(R.string.filtered_label));
Iconify.addIcons(txtvInformation);
+ txtvInformation.setOnClickListener((l) -> {
+ FilterDialog filterDialog = new FilterDialog(requireContext(), feed.getItemFilter()) {
+ @Override
+ protected void updateFilter(Set<String> filterValues) {
+ feed.setItemFilter(filterValues.toArray(new String[0]));
+ DBWriter.setFeedItemsFilter(feed.getId(), filterValues);
+ }
+ };
+
+ filterDialog.openDialog();
+ });
txtvInformation.setVisibility(View.VISIBLE);
} else {
txtvInformation.setVisibility(View.GONE);
@@ -482,6 +507,14 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE);
}
});
+ txtvFailure.setOnClickListener(v -> {
+ Intent intent = new Intent(getContext(), MainActivity.class);
+ intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, DownloadsFragment.TAG);
+ Bundle args = new Bundle();
+ args.putInt(DownloadsFragment.ARG_SELECTED_TAB, DownloadsFragment.POS_LOG);
+ intent.putExtra(MainActivity.EXTRA_FRAGMENT_ARGS, args);
+ startActivity(intent);
+ });
headerCreated = true;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
index 8251e8716..a82c60d6c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
@@ -14,7 +14,7 @@ import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.preference.ListPreference;
import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.SwitchPreference;
+import androidx.preference.SwitchPreferenceCompat;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.settings.SkipIntroEndingChangedEvent;
@@ -66,7 +66,7 @@ public class FeedSettingsFragment extends Fragment {
Toolbar toolbar = root.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
- getFragmentManager().beginTransaction()
+ getParentFragmentManager().beginTransaction()
.replace(R.id.settings_fragment_container,
FeedSettingsPreferenceFragment.newInstance(feedId), "settings_fragment")
.commitAllowingStateLoss();
@@ -322,7 +322,7 @@ public class FeedSettingsFragment extends Fragment {
}
private void setupKeepUpdatedPreference() {
- SwitchPreference pref = findPreference("keepUpdated");
+ SwitchPreferenceCompat pref = findPreference("keepUpdated");
pref.setChecked(feedPreferences.getKeepUpdated());
pref.setOnPreferenceChangeListener((preference, newValue) -> {
@@ -336,7 +336,7 @@ public class FeedSettingsFragment extends Fragment {
private void setupAutoDownloadGlobalPreference() {
if (!UserPreferences.isEnableAutodownload()) {
- SwitchPreference autodl = findPreference("autoDownload");
+ SwitchPreferenceCompat autodl = findPreference("autoDownload");
autodl.setChecked(false);
autodl.setEnabled(false);
autodl.setSummary(R.string.auto_download_disabled_globally);
@@ -345,7 +345,7 @@ public class FeedSettingsFragment extends Fragment {
}
private void setupAutoDownloadPreference() {
- SwitchPreference pref = findPreference("autoDownload");
+ SwitchPreferenceCompat pref = findPreference("autoDownload");
pref.setEnabled(UserPreferences.isEnableAutodownload());
if (UserPreferences.isEnableAutodownload()) {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
index aaf0fc7d4..337c789fe 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -145,9 +145,7 @@ public class ItemFragment extends Fragment {
}
txtvDuration = layout.findViewById(R.id.txtvDuration);
txtvPublished = layout.findViewById(R.id.txtvPublished);
- if (Build.VERSION.SDK_INT >= 14) { // ellipsize is causing problems on old versions, see #448
- txtvTitle.setEllipsize(TextUtils.TruncateAt.END);
- }
+ txtvTitle.setEllipsize(TextUtils.TruncateAt.END);
webvDescription = layout.findViewById(R.id.webvDescription);
webvDescription.setTimecodeSelectedListener(time -> {
if (controller != null && item.getMedia() != null && controller.getMedia() != null
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java
index c198ce258..3b1171df4 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java
@@ -140,13 +140,11 @@ public class ItemPagerFragment extends Fragment {
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
- switch (menuItem.getItemId()) {
- case R.id.open_podcast:
- openPodcast();
- return true;
- default:
- return FeedItemMenuHandler.onMenuItemClicked(this, menuItem.getItemId(), item);
+ if (menuItem.getItemId() == R.id.open_podcast) {
+ openPodcast();
+ return true;
}
+ return FeedItemMenuHandler.onMenuItemClicked(this, menuItem.getItemId(), item);
}
@Subscribe(threadMode = ThreadMode.MAIN)
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
index da5710936..8b7d2b886 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
@@ -37,6 +37,7 @@ import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.IntentUtils;
+import de.danoeh.antennapod.dialog.FeedFilterDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -86,9 +87,8 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
registerForContextMenu(navList);
updateSelection();
- root.findViewById(R.id.nav_settings).setOnClickListener(v -> {
- startActivity(new Intent(getActivity(), PreferenceActivity.class));
- });
+ root.findViewById(R.id.nav_settings).setOnClickListener(v ->
+ startActivity(new Intent(getActivity(), PreferenceActivity.class)));
getContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
.registerOnSharedPreferenceChangeListener(this);
return root;
@@ -388,6 +388,9 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
startActivity(intent);
}
}
+ } else if (UserPreferences.getFeedFilter() != UserPreferences.FEED_FILTER_NONE
+ && navAdapter.showSubscriptionList) {
+ FeedFilterDialog.showDialog(requireContext());
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
index d9c31f993..e8bd5a1e1 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
@@ -107,8 +107,8 @@ public class OnlineSearchFragment extends Fragment {
txtvError = root.findViewById(R.id.txtvError);
butRetry = root.findViewById(R.id.butRetry);
txtvEmpty = root.findViewById(android.R.id.empty);
-
- txtvEmpty.setText(getString(R.string.search_powered_by, searchProvider.getName()));
+ TextView txtvPoweredBy = root.findViewById(R.id.search_powered_by);
+ txtvPoweredBy.setText(getString(R.string.search_powered_by, searchProvider.getName()));
return root;
}
@@ -126,7 +126,7 @@ public class OnlineSearchFragment extends Fragment {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.online_search, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
- final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
+ final SearchView sv = (SearchView) searchItem.getActionView();
sv.setQueryHint(getString(R.string.search_podcast_hint));
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
index dabff7269..db4bda1f5 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -153,7 +153,7 @@ public class PlaybackHistoryFragment extends Fragment {
}
super.onCreateOptionsMenu(menu, inflater);
MenuItem clearHistory = menu.add(Menu.NONE, R.id.clear_history_item, Menu.CATEGORY_CONTAINER, R.string.clear_history_label);
- MenuItemCompat.setShowAsAction(clearHistory, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
+ clearHistory.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.ic_delete});
clearHistory.setIcon(drawables.getDrawable(0));
drawables.recycle();
@@ -171,13 +171,11 @@ public class PlaybackHistoryFragment extends Fragment {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
- switch (item.getItemId()) {
- case R.id.clear_history_item:
- DBWriter.clearPlaybackHistory();
- return true;
- default:
- return false;
+ if (item.getItemId() == R.id.clear_history_item) {
+ DBWriter.clearPlaybackHistory();
+ return true;
}
+ return false;
} else {
return true;
}
@@ -196,18 +194,18 @@ public class PlaybackHistoryFragment extends Fragment {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onHistoryUpdated(PlaybackHistoryEvent event) {
loadItems();
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onPlayerStatusChanged(PlayerStatusEvent event) {
loadItems();
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
}
private void onFragmentLoaded() {
adapter.notifyDataSetChanged();
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
}
private void loadItems() {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
index 49c53627f..283b4b466 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -16,7 +16,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
@@ -136,6 +135,7 @@ public class QueueFragment extends Fragment {
recyclerAdapter.notifyItemInserted(event.position);
break;
case SET_QUEUE:
+ case SORTED: //Deliberate fall-through
queue = event.items;
recyclerAdapter.notifyDataSetChanged();
break;
@@ -149,10 +149,6 @@ public class QueueFragment extends Fragment {
queue.clear();
recyclerAdapter.notifyDataSetChanged();
break;
- case SORTED:
- queue = event.items;
- recyclerAdapter.notifyDataSetChanged();
- break;
case MOVED:
return;
}
@@ -216,7 +212,7 @@ public class QueueFragment extends Fragment {
public void onPlayerStatusChanged(PlayerStatusEvent event) {
loadItems(false);
if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
}
}
@@ -225,7 +221,7 @@ public class QueueFragment extends Fragment {
// Sent when playback position is reset
loadItems(false);
if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
}
}
@@ -339,11 +335,9 @@ public class QueueFragment extends Fragment {
if (keepSortedNew) {
SortOrder sortOrder = UserPreferences.getQueueKeepSortedOrder();
DBWriter.reorderQueue(sortOrder, true);
- if (recyclerAdapter != null) {
- recyclerAdapter.setLocked(true);
- }
- } else if (recyclerAdapter != null) {
- recyclerAdapter.setLocked(UserPreferences.isQueueLocked());
+ }
+ if (recyclerAdapter != null) {
+ recyclerAdapter.updateDragDropEnabled();
}
getActivity().invalidateOptionsMenu();
return true;
@@ -384,14 +378,16 @@ public class QueueFragment extends Fragment {
private void setQueueLocked(boolean locked) {
UserPreferences.setQueueLocked(locked);
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
if (recyclerAdapter != null) {
- recyclerAdapter.setLocked(locked);
+ recyclerAdapter.updateDragDropEnabled();
}
- if (locked) {
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.queue_locked, Snackbar.LENGTH_SHORT);
- } else {
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.queue_unlocked, Snackbar.LENGTH_SHORT);
+ if (queue.size() == 0) {
+ if (locked) {
+ ((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.queue_locked, Snackbar.LENGTH_SHORT);
+ } else {
+ ((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.queue_unlocked, Snackbar.LENGTH_SHORT);
+ }
}
}
@@ -572,7 +568,7 @@ public class QueueFragment extends Fragment {
// we need to refresh the options menu because it sometimes
// needs data that may have just been loaded.
- getActivity().supportInvalidateOptionsMenu();
+ getActivity().invalidateOptionsMenu();
refreshInfoBar();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
index d6bcdd79c..38c068a3f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
@@ -9,7 +9,9 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
+import android.widget.Button;
import android.widget.GridView;
+import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import de.danoeh.antennapod.R;
@@ -33,6 +35,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
private FeedDiscoverAdapter adapter;
private GridView discoverGridLayout;
private TextView errorTextView;
+ private LinearLayout errorView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -44,7 +47,10 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
discoverGridLayout = root.findViewById(R.id.discover_grid);
progressBar = root.findViewById(R.id.discover_progress_bar);
- errorTextView = root.findViewById(R.id.discover_error);
+ errorView = root.findViewById(R.id.discover_error);
+ errorTextView = root.findViewById(R.id.discover_error_txtV);
+ Button errorRetry = root.findViewById(R.id.discover_error_retry_btn);
+ errorRetry.setOnClickListener((listener) -> loadToplist());
adapter = new FeedDiscoverAdapter((MainActivity) getActivity());
discoverGridLayout.setAdapter(adapter);
@@ -81,19 +87,19 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
private void loadToplist() {
progressBar.setVisibility(View.VISIBLE);
discoverGridLayout.setVisibility(View.INVISIBLE);
- errorTextView.setVisibility(View.GONE);
+ errorView.setVisibility(View.GONE);
ItunesTopListLoader loader = new ItunesTopListLoader(getContext());
disposable = loader.loadToplist(NUM_SUGGESTIONS)
.subscribe(podcasts -> {
- errorTextView.setVisibility(View.GONE);
+ errorView.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
discoverGridLayout.setVisibility(View.VISIBLE);
adapter.updateData(podcasts);
}, error -> {
Log.e(TAG, Log.getStackTraceString(error));
errorTextView.setText(error.getLocalizedMessage());
- errorTextView.setVisibility(View.VISIBLE);
+ errorView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
discoverGridLayout.setVisibility(View.INVISIBLE);
});
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
index ddcf09992..ca9fba694 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
@@ -1,8 +1,13 @@
package de.danoeh.antennapod.fragment;
import android.os.Bundle;
+
+import androidx.annotation.NonNull;
import androidx.fragment.app.ListFragment;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
@@ -21,10 +26,13 @@ import de.danoeh.antennapod.core.event.DownloaderUpdate;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadRequest;
+import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
+import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.view.EmptyViewHandler;
import org.greenrobot.eventbus.ThreadMode;
@@ -38,6 +46,8 @@ public class RunningDownloadsFragment extends ListFragment {
private DownloadlistAdapter adapter;
private List<Downloader> downloaderList = new ArrayList<>();
+ private boolean isUpdatingFeeds = false;
+
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
@@ -66,6 +76,12 @@ public class RunningDownloadsFragment extends ListFragment {
}
@Override
+ public void onResume() {
+ super.onResume();
+ setHasOptionsMenu(true);
+ }
+
+ @Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
@@ -77,6 +93,33 @@ public class RunningDownloadsFragment extends ListFragment {
setListAdapter(null);
}
+ @Override
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.downloads_running, menu);
+ isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.refresh_item) {
+ AutoUpdateManager.runImmediate(requireContext());
+ return true;
+ }
+ return false;
+ }
+
+ @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
+ public void onEventMainThread(DownloadEvent event) {
+ Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
+ if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
+ getActivity().invalidateOptionsMenu();
+ }
+ }
+
+ private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker =
+ () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
+
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(DownloadEvent event) {
Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]");
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
index 0d33c1282..0c03d407e 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
@@ -124,7 +124,6 @@ public class SearchFragment extends Fragment {
LinearLayoutManager layoutManagerFeeds = new LinearLayoutManager(getActivity());
layoutManagerFeeds.setOrientation(RecyclerView.HORIZONTAL);
recyclerViewFeeds.setLayoutManager(layoutManagerFeeds);
- recyclerViewFeeds.setHasFixedSize(true);
adapterFeeds = new FeedSearchResultAdapter((MainActivity) getActivity());
recyclerViewFeeds.setAdapter(adapterFeeds);
@@ -174,7 +173,7 @@ public class SearchFragment extends Fragment {
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
- getFragmentManager().popBackStack();
+ getParentFragmentManager().popBackStack();
return true;
}
});
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
index ba5d44b4d..3837c5025 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -19,8 +19,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
+import android.widget.TextView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.joanzapata.iconify.Iconify;
import java.util.concurrent.Callable;
@@ -34,6 +36,7 @@ import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -42,6 +45,8 @@ import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
+import de.danoeh.antennapod.dialog.FeedFilterDialog;
+import de.danoeh.antennapod.dialog.FeedSortDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.view.EmptyViewHandler;
@@ -68,6 +73,7 @@ public class SubscriptionFragment extends Fragment {
private FloatingActionButton subscriptionAddButton;
private ProgressBar progressBar;
private EmptyViewHandler emptyView;
+ private TextView feedsFilteredMsg;
private int mPosition = -1;
private boolean isUpdatingFeeds = false;
@@ -90,10 +96,13 @@ public class SubscriptionFragment extends Fragment {
View root = inflater.inflate(R.layout.fragment_subscriptions, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar));
subscriptionGridLayout = root.findViewById(R.id.subscriptions_grid);
- subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, 3));
+ subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns()));
registerForContextMenu(subscriptionGridLayout);
subscriptionAddButton = root.findViewById(R.id.subscriptions_add);
progressBar = root.findViewById(R.id.progLoading);
+
+ feedsFilteredMsg = root.findViewById(R.id.feeds_filtered_message);
+ feedsFilteredMsg.setOnClickListener((l) -> FeedFilterDialog.showDialog(requireContext()));
return root;
}
@@ -102,7 +111,7 @@ public class SubscriptionFragment extends Fragment {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.subscriptions, menu);
- int columns = prefs.getInt(PREF_NUM_COLUMNS, 3);
+ int columns = prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns());
menu.findItem(R.id.subscription_num_columns_2).setChecked(columns == 2);
menu.findItem(R.id.subscription_num_columns_3).setChecked(columns == 3);
menu.findItem(R.id.subscription_num_columns_4).setChecked(columns == 4);
@@ -120,6 +129,12 @@ public class SubscriptionFragment extends Fragment {
case R.id.refresh_item:
AutoUpdateManager.runImmediate(requireContext());
return true;
+ case R.id.subscriptions_filter:
+ FeedFilterDialog.showDialog(requireContext());
+ return true;
+ case R.id.subscriptions_sort:
+ FeedSortDialog.showDialog(requireContext());
+ return true;
case R.id.subscription_num_columns_2:
setColumnNumber(2);
return true;
@@ -198,6 +213,18 @@ public class SubscriptionFragment extends Fragment {
emptyView.updateVisibility();
progressBar.setVisibility(View.GONE);
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
+
+ if (UserPreferences.getFeedFilter() != UserPreferences.FEED_FILTER_NONE) {
+ feedsFilteredMsg.setText("{md-info-outline} " + getString(R.string.subscriptions_are_filtered));
+ Iconify.addIcons(feedsFilteredMsg);
+ feedsFilteredMsg.setVisibility(View.VISIBLE);
+ } else {
+ feedsFilteredMsg.setVisibility(View.GONE);
+ }
+ }
+
+ private int getDefaultNumOfColumns() {
+ return getResources().getInteger(R.integer.subscriptions_default_num_of_columns);
}
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
index e1c85a2d3..d5cac07f1 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
@@ -56,9 +56,9 @@ public abstract class PodcastListFragment extends Fragment {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.gpodder_podcasts, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
- final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
+ final SearchView sv = (SearchView) searchItem.getActionView();
sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
+ sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
sv.clearFocus();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
index 80f1a6ae0..72a752bf1 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
@@ -48,7 +48,7 @@ public class SearchListFragment extends PodcastListFragment {
super.onCreateOptionsMenu(menu, inflater);
// parent already inflated menu
MenuItem searchItem = menu.findItem(R.id.action_search);
- final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
+ final SearchView sv = (SearchView) searchItem.getActionView();
sv.setQueryHint(getString(R.string.gpodnet_search_hint));
sv.setQuery(query, false);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
index a7a0781ce..53a31b68d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
@@ -38,7 +38,7 @@ public class TagListFragment extends ListFragment {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.gpodder_podcasts, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
- final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
+ final SearchView sv = (SearchView) searchItem.getActionView();
sv.setQueryHint(getString(R.string.gpodnet_search_hint));
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java
index 6b15e4301..0d6e79e84 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.fragment.preferences;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
@@ -85,6 +86,7 @@ public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat {
return val == null ? "" : val;
}
+ @SuppressLint("MissingPermission") // getConfiguredNetworks needs location permission starting with API 29
private void buildAutodownloadSelectedNetworksPreference() {
if (Build.VERSION.SDK_INT >= 29) {
return;
@@ -166,7 +168,7 @@ public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat {
private void buildEpisodeCleanupPreference() {
final Resources res = getActivity().getResources();
- ListPreference pref = (ListPreference) findPreference(UserPreferences.PREF_EPISODE_CLEANUP);
+ ListPreference pref = findPreference(UserPreferences.PREF_EPISODE_CLEANUP);
String[] values = res.getStringArray(
R.array.episode_cleanup_values);
String[] entries = new String[values.length];
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
index 8f8b4675d..546e12e65 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
@@ -3,9 +3,11 @@ package de.danoeh.antennapod.fragment.preferences;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
+import androidx.core.text.HtmlCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
-import android.text.Html;
+
+import android.text.Spanned;
import android.text.format.DateUtils;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
@@ -115,7 +117,8 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
String format = getActivity().getString(R.string.pref_gpodnet_login_status);
String summary = String.format(format, GpodnetPreferences.getUsername(),
GpodnetPreferences.getDeviceID());
- findPreference(PREF_GPODNET_LOGOUT).setSummary(Html.fromHtml(summary));
+ Spanned formattedSummary = HtmlCompat.fromHtml(summary, HtmlCompat.FROM_HTML_MODE_LEGACY);
+ findPreference(PREF_GPODNET_LOGOUT).setSummary(formattedSummary);
updateLastGpodnetSyncReport(SyncService.isLastSyncSuccessful(getContext()),
SyncService.getLastSyncAttempt(getContext()));
} else {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java
index f3b4d3003..5eb4a3aea 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java
@@ -38,6 +38,7 @@ import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
private static final String TAG = "ImportExPrefFragment";
@@ -86,9 +87,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
}
private String dateStampFilename(String fname) {
- return String.format(fname,
- new SimpleDateFormat("yyyy-MM-dd")
- .format(new Date()));
+ return String.format(fname, new SimpleDateFormat("yyyy-MM-dd", Locale.US).format(new Date()));
}
private void setupStorageScreen() {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java
index 05ea521a9..2d640458e 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java
@@ -23,6 +23,7 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
private static final String PREF_FAQ = "prefFaq";
private static final String PREF_VIEW_FORUM = "prefViewForum";
private static final String PREF_SEND_BUG_REPORT = "prefSendBugReport";
+ private static final String PREF_CATEGORY_PROJECT = "project";
private static final String STATISTICS = "statistics";
private static final String PREF_ABOUT = "prefAbout";
@@ -31,6 +32,13 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
addPreferencesFromResource(R.xml.preferences);
setupMainScreen();
setupSearch();
+
+ // If you are writing a spin-off, please update the details on screens like "About" and "Report bug"
+ // and afterwards remove the following lines.
+ String packageName = getContext().getPackageName();
+ if (!"de.danoeh.antennapod".equals(packageName) && !"de.danoeh.antennapod.debug".equals(packageName)) {
+ findPreference(PREF_CATEGORY_PROJECT).setVisible(false);
+ }
}
@Override
@@ -63,14 +71,14 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
findPreference(PREF_ABOUT).setOnPreferenceClickListener(
preference -> {
- getFragmentManager().beginTransaction().replace(R.id.content, new AboutFragment())
+ getParentFragmentManager().beginTransaction().replace(R.id.content, new AboutFragment())
.addToBackStack(getString(R.string.about_pref)).commit();
return true;
}
);
findPreference(STATISTICS).setOnPreferenceClickListener(
preference -> {
- getFragmentManager().beginTransaction().replace(R.id.content, new StatisticsFragment())
+ getParentFragmentManager().beginTransaction().replace(R.id.content, new StatisticsFragment())
.addToBackStack(getString(R.string.statistics_label)).commit();
return true;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java
index 741080cf1..1fa1fed58 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java
@@ -45,7 +45,7 @@ public class PlaybackPreferencesFragment extends PreferenceFragmentCompat {
final Activity activity = getActivity();
findPreference(PREF_PLAYBACK_SPEED_LAUNCHER).setOnPreferenceClickListener(preference -> {
- VariableSpeedDialog.showDialog(activity);
+ new VariableSpeedDialog().show(getChildFragmentManager(), null);
return true;
});
findPreference(PREF_PLAYBACK_REWIND_DELTA_LAUNCHER).setOnPreferenceClickListener(preference -> {
@@ -109,14 +109,14 @@ public class PlaybackPreferencesFragment extends PreferenceFragmentCompat {
private void buildSmartMarkAsPlayedPreference() {
final Resources res = getActivity().getResources();
- ListPreference pref = (ListPreference) findPreference(UserPreferences.PREF_SMART_MARK_AS_PLAYED_SECS);
+ ListPreference pref = findPreference(UserPreferences.PREF_SMART_MARK_AS_PLAYED_SECS);
String[] values = res.getStringArray(R.array.smart_mark_as_played_values);
String[] entries = new String[values.length];
for (int x = 0; x < values.length; x++) {
if(x == 0) {
entries[x] = res.getString(R.string.pref_smart_mark_as_played_disabled);
} else {
- Integer v = Integer.parseInt(values[x]);
+ int v = Integer.parseInt(values[x]);
if(v < 60) {
entries[x] = res.getQuantityString(R.plurals.time_seconds_quantified, v, v);
} else {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java
index a44623f48..12be76ba7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java
@@ -12,6 +12,8 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.dialog.FeedFilterDialog;
+import de.danoeh.antennapod.dialog.FeedSortDialog;
import de.danoeh.antennapod.fragment.NavDrawerFragment;
import org.apache.commons.lang3.ArrayUtils;
@@ -75,6 +77,18 @@ public class UserInterfacePreferencesFragment extends PreferenceFragmentCompat {
return true;
});
+ findPreference(UserPreferences.PREF_FILTER_FEED)
+ .setOnPreferenceClickListener((preference -> {
+ FeedFilterDialog.showDialog(requireContext());
+ return true;
+ }));
+
+ findPreference(UserPreferences.PREF_DRAWER_FEED_ORDER)
+ .setOnPreferenceClickListener((preference -> {
+ FeedSortDialog.showDialog(requireContext());
+ return true;
+ }));
+
if (Build.VERSION.SDK_INT >= 26) {
findPreference(UserPreferences.PREF_EXPANDED_NOTIFICATION).setVisible(false);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
index 1f15f66ec..bddafb75e 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -2,13 +2,14 @@ package de.danoeh.antennapod.menuhandler;
import android.content.Context;
import android.os.Handler;
-import androidx.annotation.NonNull;
-import com.google.android.material.snackbar.Snackbar;
-import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
+import com.google.android.material.snackbar.Snackbar;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.FeedItem;
@@ -23,6 +24,7 @@ import de.danoeh.antennapod.core.sync.model.EpisodeAction;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.ShareUtils;
+import de.danoeh.antennapod.dialog.ShareDialog;
/**
* Handles interactions with the FeedItemMenu.
@@ -61,20 +63,9 @@ public class FeedItemMenuHandler {
}
if (!ShareUtils.hasLinkToShare(selectedItem)) {
setItemVisibility(menu, R.id.visit_website_item, false);
- setItemVisibility(menu, R.id.share_link_item, false);
- setItemVisibility(menu, R.id.share_link_with_position_item, false);
- }
- if (!hasMedia || selectedItem.getMedia().getDownload_url() == null) {
- setItemVisibility(menu, R.id.share_download_url_item, false);
- setItemVisibility(menu, R.id.share_download_url_with_position_item, false);
- }
- if(!hasMedia || selectedItem.getMedia().getPosition() <= 0) {
- setItemVisibility(menu, R.id.share_download_url_with_position_item, false);
- setItemVisibility(menu, R.id.share_link_with_position_item, false);
}
boolean fileDownloaded = hasMedia && selectedItem.getMedia().fileExists();
- setItemVisibility(menu, R.id.share_file, fileDownloaded);
setItemVisibility(menu, R.id.remove_new_flag_item, selectedItem.isNew());
if (selectedItem.isPlayed()) {
@@ -243,20 +234,9 @@ public class FeedItemMenuHandler {
case R.id.visit_website_item:
IntentUtils.openInBrowser(context, FeedItemUtil.getLinkWithFallback(selectedItem));
break;
- case R.id.share_link_item:
- ShareUtils.shareFeedItemLink(context, selectedItem);
- break;
- case R.id.share_download_url_item:
- ShareUtils.shareFeedItemDownloadLink(context, selectedItem);
- break;
- case R.id.share_link_with_position_item:
- ShareUtils.shareFeedItemLink(context, selectedItem, true);
- break;
- case R.id.share_download_url_with_position_item:
- ShareUtils.shareFeedItemDownloadLink(context, selectedItem, true);
- break;
- case R.id.share_file:
- ShareUtils.shareFeedItemFile(context, selectedItem.getMedia());
+ case R.id.share_item:
+ ShareDialog shareDialog = ShareDialog.newInstance(selectedItem);
+ shareDialog.show((fragment.getActivity().getSupportFragmentManager()), "ShareEpisodeDialog");
break;
default:
Log.d(TAG, "Unknown menuItemId: " + menuItemId);
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java b/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java
index 007457c24..94e60ef61 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java
@@ -4,7 +4,7 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
-import androidx.preference.SwitchPreference;
+import androidx.preference.SwitchPreferenceCompat;
import androidx.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.util.TypedValue;
@@ -12,7 +12,7 @@ import android.widget.TextView;
import de.danoeh.antennapod.R;
-public class MasterSwitchPreference extends SwitchPreference {
+public class MasterSwitchPreference extends SwitchPreferenceCompat {
public MasterSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java
index 7a282fc82..64dd03b00 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java
@@ -2,7 +2,7 @@ package de.danoeh.antennapod.preferences;
import android.content.Context;
import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
+import androidx.preference.PreferenceManager;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.error.CrashReportWriter;
diff --git a/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java b/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java
index 1f28b5c49..f9c10041e 100644
--- a/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java
+++ b/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java
@@ -3,7 +3,7 @@ package de.danoeh.antennapod.spa;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
+import androidx.preference.PreferenceManager;
import android.util.Log;
import de.danoeh.antennapod.BuildConfig;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java b/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java
index 58d562616..83d90f98b 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.view;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.View;
import androidx.appcompat.view.ContextThemeWrapper;
@@ -39,6 +40,14 @@ public class EpisodeItemListRecyclerView extends RecyclerView {
setLayoutManager(layoutManager);
setHasFixedSize(true);
addItemDecoration(new HorizontalDividerItemDecoration.Builder(getContext()).build());
+ setClipToPadding(false);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ int horizontalSpacing = (int) getResources().getDimension(R.dimen.additional_horizontal_spacing);
+ setPadding(horizontalSpacing, getPaddingTop(), horizontalSpacing, getPaddingBottom());
}
public void saveScrollPosition(String tag) {
diff --git a/app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java b/app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java
new file mode 100644
index 000000000..4a1267d81
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java
@@ -0,0 +1,24 @@
+package de.danoeh.antennapod.view;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.View;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Source: https://stackoverflow.com/a/30794046
+ */
+public class ItemOffsetDecoration extends RecyclerView.ItemDecoration {
+ private final int itemOffset;
+
+ public ItemOffsetDecoration(@NonNull Context context, int itemOffsetDp) {
+ itemOffset = (int) (itemOffsetDp * context.getResources().getDisplayMetrics().density);
+ }
+
+ @Override
+ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
+ super.getItemOffsets(outRect, view, parent, state);
+ outRect.set(itemOffset, itemOffset, itemOffset, itemOffset);
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java b/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java
index 8e8d98fc9..1b96c7c4f 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java
@@ -47,11 +47,11 @@ public class LockableBottomSheetBehavior<V extends View> extends ViewPagerBottom
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild,
- View target, int nestedScrollAxes) {
+ View target, int axes, int type) {
boolean handled = false;
if (!isLocked) {
- handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
+ handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type);
}
return handled;
@@ -59,16 +59,16 @@ public class LockableBottomSheetBehavior<V extends View> extends ViewPagerBottom
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target,
- int dx, int dy, int[] consumed) {
+ int dx, int dy, int[] consumed, int type) {
if (!isLocked) {
- super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
+ super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
}
}
@Override
- public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
+ public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target, int type) {
if (!isLocked) {
- super.onStopNestedScroll(coordinatorLayout, child, target);
+ super.onStopNestedScroll(coordinatorLayout, child, target, type);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java b/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java
index a4daa9109..0e1846f1c 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java
@@ -54,7 +54,7 @@ class NestedScrollableHost extends FrameLayout {
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
- private int touchSlop = 0;
+ private int touchSlop;
private float initialX = 0f;
private float initialY = 0f;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java b/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java
new file mode 100644
index 000000000..47797e4a4
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java
@@ -0,0 +1,86 @@
+package de.danoeh.antennapod.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.SeekBar;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.util.Consumer;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+
+public class PlaybackSpeedSeekBar extends FrameLayout {
+ private SeekBar seekBar;
+ private PlaybackController controller;
+ private Consumer<Float> progressChangedListener;
+
+ public PlaybackSpeedSeekBar(@NonNull Context context) {
+ super(context);
+ setup();
+ }
+
+ public PlaybackSpeedSeekBar(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ setup();
+ }
+
+ public PlaybackSpeedSeekBar(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setup();
+ }
+
+ private void setup() {
+ View.inflate(getContext(), R.layout.playback_speed_seek_bar, this);
+ seekBar = findViewById(R.id.playback_speed);
+ findViewById(R.id.butDecSpeed).setOnClickListener(v -> seekBar.setProgress(seekBar.getProgress() - 2));
+ findViewById(R.id.butIncSpeed).setOnClickListener(v -> seekBar.setProgress(seekBar.getProgress() + 2));
+
+ seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (controller != null && controller.canSetPlaybackSpeed()) {
+ float playbackSpeed = (progress + 10) / 20.0f;
+ controller.setPlaybackSpeed(playbackSpeed);
+
+ if (progressChangedListener != null) {
+ progressChangedListener.accept(playbackSpeed);
+ }
+ } else if (fromUser) {
+ seekBar.post(() -> updateSpeed());
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ if (controller != null && !controller.canSetPlaybackSpeed()) {
+ VariableSpeedDialog.showGetPluginDialog(getContext());
+ }
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+ });
+ }
+
+ public void updateSpeed() {
+ if (controller != null) {
+ seekBar.setProgress(Math.round((20 * controller.getCurrentPlaybackSpeedMultiplier()) - 10));
+ }
+ }
+
+ public void setController(PlaybackController controller) {
+ this.controller = controller;
+ updateSpeed();
+ if (progressChangedListener != null && controller != null) {
+ progressChangedListener.accept(controller.getCurrentPlaybackSpeedMultiplier());
+ }
+ }
+
+ public void setProgressChangedListener(Consumer<Float> progressChangedListener) {
+ this.progressChangedListener = progressChangedListener;
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/RecursiveRadioGroup.java b/app/src/main/java/de/danoeh/antennapod/view/RecursiveRadioGroup.java
new file mode 100644
index 000000000..ee5e7c51d
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/view/RecursiveRadioGroup.java
@@ -0,0 +1,67 @@
+package de.danoeh.antennapod.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import java.util.ArrayList;
+
+/**
+ * An alternative to {@link android.widget.RadioGroup} that allows to nest children.
+ * Basend on https://stackoverflow.com/a/14309274.
+ */
+public class RecursiveRadioGroup extends LinearLayout {
+ private final ArrayList<RadioButton> radioButtons = new ArrayList<>();
+ private RadioButton checkedButton = null;
+
+ public RecursiveRadioGroup(Context context) {
+ super(context);
+ }
+
+ public RecursiveRadioGroup(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public RecursiveRadioGroup(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void addView(View child, int index, ViewGroup.LayoutParams params) {
+ super.addView(child, index, params);
+ parseChild(child);
+ }
+
+ public void parseChild(final View child) {
+ if (child instanceof RadioButton) {
+ RadioButton button = (RadioButton) child;
+ radioButtons.add(button);
+ button.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if (!isChecked) {
+ return;
+ }
+ checkedButton = (RadioButton) buttonView;
+
+ for (RadioButton view : radioButtons) {
+ if (view != buttonView) {
+ view.setChecked(false);
+ }
+ }
+ });
+ } else if (child instanceof ViewGroup) {
+ parseChildren((ViewGroup) child);
+ }
+ }
+
+ public void parseChildren(final ViewGroup child) {
+ for (int i = 0; i < child.getChildCount(); i++) {
+ parseChild(child.getChildAt(i));
+ }
+ }
+
+ public RadioButton getCheckedButton() {
+ return checkedButton;
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java b/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java
index dcf8ff20d..163100fff 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java
@@ -33,11 +33,15 @@ public abstract class ToolbarIconTintManager implements AppBarLayout.OnOffsetCha
public void updateTint() {
if (isTinted) {
doTint(new ContextThemeWrapper(context, R.style.Theme_AntennaPod_Dark));
- toolbar.getNavigationIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
+ if (toolbar.getNavigationIcon() != null) { // Tablets do not show a navigation icon
+ toolbar.getNavigationIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
+ }
toolbar.getOverflowIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
} else {
doTint(context);
- toolbar.getNavigationIcon().clearColorFilter();
+ if (toolbar.getNavigationIcon() != null) { // Tablets do not show a navigation icon
+ toolbar.getNavigationIcon().clearColorFilter();
+ }
toolbar.getOverflowIcon().clearColorFilter();
}
}