summaryrefslogtreecommitdiff
path: root/app/src/main/java/de
diff options
context:
space:
mode:
authorH. Lehmann <ByteHamster@users.noreply.github.com>2020-03-26 17:17:52 +0100
committerGitHub <noreply@github.com>2020-03-26 17:17:52 +0100
commit11ef58f5920cadadeb8e3f34fce14ce8ff005dc8 (patch)
tree940b22047564d71f76e8a2340b1c2d0821ae2a15 /app/src/main/java/de
parent9637734000d399ffaa8739f5a3f1c1624b2a6a37 (diff)
parentb4b2b45247a92e7f7e43ab224598ef646608c7be (diff)
downloadAntennaPod-11ef58f5920cadadeb8e3f34fce14ce8ff005dc8.zip
Merge branch 'develop' into NotificationForAutoDownloads
Diffstat (limited to 'app/src/main/java/de')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java136
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java80
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java70
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java133
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java282
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java23
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java101
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java58
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java505
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java66
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java41
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java19
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java3
-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.java32
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java86
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/OnSwipeGesture.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedIndicatorView.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/viewholder/DownloadItemViewHolder.java3
42 files changed, 910 insertions, 937 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
deleted file mode 100644
index ae8634516..000000000
--- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package de.danoeh.antennapod.activity;
-
-import android.content.Intent;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import de.danoeh.antennapod.core.feed.MediaType;
-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.dialog.VariableSpeedDialog;
-
-import java.text.DecimalFormat;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Activity for playing audio files.
- */
-public class AudioplayerActivity extends MediaplayerInfoActivity {
- private static final String TAG = "AudioPlayerActivity";
- private static final float EPSILON = 0.001f;
-
- private final AtomicBoolean isSetup = new AtomicBoolean(false);
-
- @Override
- protected void onResume() {
- super.onResume();
- if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
- playExternalMedia(getIntent(), MediaType.AUDIO);
- } else if (PlaybackService.isCasting()) {
- Intent intent = PlaybackService.getPlayerActivityIntent(this);
- if (intent.getComponent() != null
- && !intent.getComponent().getClassName().equals(AudioplayerActivity.class.getName())) {
- saveCurrentFragment();
- finish();
- startActivity(intent);
- }
- }
- }
-
- @Override
- protected void onReloadNotification(int notificationCode) {
- if (notificationCode == PlaybackService.EXTRA_CODE_CAST) {
- Log.d(TAG, "ReloadNotification received, switching to Castplayer now");
- saveCurrentFragment();
- finish();
- startActivity(new Intent(this, CastplayerActivity.class));
-
- } else {
- super.onReloadNotification(notificationCode);
- }
- }
-
- @Override
- protected void updatePlaybackSpeedButton() {
- if (butPlaybackSpeed == null) {
- return;
- }
- if (controller == null) {
- butPlaybackSpeed.setVisibility(View.GONE);
- txtvPlaybackSpeed.setVisibility(View.GONE);
- return;
- }
- updatePlaybackSpeedButtonText();
- butPlaybackSpeed.setAlpha(controller.canSetPlaybackSpeed() ? 1.0f : 0.5f);
- butPlaybackSpeed.setVisibility(View.VISIBLE);
- txtvPlaybackSpeed.setVisibility(View.VISIBLE);
- }
-
- @Override
- protected void updatePlaybackSpeedButtonText() {
- if (butPlaybackSpeed == null) {
- return;
- }
- if (controller == null) {
- butPlaybackSpeed.setVisibility(View.GONE);
- txtvPlaybackSpeed.setVisibility(View.GONE);
- return;
- }
- float speed = 1.0f;
- if (controller.canSetPlaybackSpeed()) {
- speed = PlaybackSpeedUtils.getCurrentPlaybackSpeed(controller.getMedia());
- }
- String speedStr = new DecimalFormat("0.00").format(speed);
- txtvPlaybackSpeed.setText(speedStr);
- butPlaybackSpeed.setSpeed(speed);
- }
-
- @Override
- protected void setupGUI() {
- if (isSetup.getAndSet(true)) {
- return;
- }
- super.setupGUI();
- if (butPlaybackSpeed != null) {
- butPlaybackSpeed.setOnClickListener(v -> {
- if (controller == null) {
- return;
- }
- if (controller.canSetPlaybackSpeed()) {
- float[] availableSpeeds = UserPreferences.getPlaybackSpeedArray();
- float currentSpeed = controller.getCurrentPlaybackSpeedMultiplier();
-
- int newSpeedIndex = 0;
- while (newSpeedIndex < availableSpeeds.length
- && availableSpeeds[newSpeedIndex] < currentSpeed + EPSILON) {
- newSpeedIndex++;
- }
-
- float newSpeed;
- if (availableSpeeds.length == 0) {
- newSpeed = 1.0f;
- } else if (newSpeedIndex == availableSpeeds.length) {
- newSpeed = availableSpeeds[0];
- } else {
- newSpeed = availableSpeeds[newSpeedIndex];
- }
-
- PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(newSpeed);
- UserPreferences.setPlaybackSpeed(newSpeed);
- controller.setPlaybackSpeed(newSpeed);
- onPositionObserverUpdate();
- } else {
- VariableSpeedDialog.showGetPluginDialog(this);
- }
- });
- butPlaybackSpeed.setOnLongClickListener(v -> {
- VariableSpeedDialog.showDialog(this);
- return true;
- });
- butPlaybackSpeed.setVisibility(View.VISIBLE);
- txtvPlaybackSpeed.setVisibility(View.VISIBLE);
- }
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java
deleted file mode 100644
index bbab235c8..000000000
--- a/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package de.danoeh.antennapod.activity;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
-
-/**
- * Activity for controlling the remote playback on a Cast device.
- */
-public class CastplayerActivity extends MediaplayerInfoActivity {
- private static final String TAG = "CastPlayerActivity";
-
- private final AtomicBoolean isSetup = new AtomicBoolean(false);
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (!PlaybackService.isCasting()) {
- Intent intent = PlaybackService.getPlayerActivityIntent(this);
- if (!intent.getComponent().getClassName().equals(CastplayerActivity.class.getName())) {
- finish();
- startActivity(intent);
- }
- }
- }
-
- @Override
- protected void onReloadNotification(int notificationCode) {
- if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO) {
- Log.d(TAG, "ReloadNotification received, switching to Audioplayer now");
- saveCurrentFragment();
- finish();
- startActivity(new Intent(this, AudioplayerActivity.class));
- } else {
- super.onReloadNotification(notificationCode);
- }
- }
-
- @Override
- protected void setupGUI() {
- if(isSetup.getAndSet(true)) {
- return;
- }
- super.setupGUI();
- if (butPlaybackSpeed != null) {
- butPlaybackSpeed.setVisibility(View.GONE);
- txtvPlaybackSpeed.setVisibility(View.GONE);
- }
- }
-
- @Override
- protected void onResume() {
- if (!PlaybackService.isCasting()) {
- Intent intent = PlaybackService.getPlayerActivityIntent(this);
- if (!intent.getComponent().getClassName().equals(CastplayerActivity.class.getName())) {
- saveCurrentFragment();
- finish();
- startActivity(intent);
- }
- }
- super.onResume();
- }
-
- @Override
- protected void onBufferStart() {
- //sbPosition.setIndeterminate(true);
- sbPosition.setEnabled(false);
- }
-
- @Override
- protected void onBufferEnd() {
- //sbPosition.setIndeterminate(false);
- sbPosition.setEnabled(true);
- }
-}
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 6dab5ab45..403198bea 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -23,6 +23,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.bumptech.glide.Glide;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.event.MessageEvent;
@@ -31,9 +32,9 @@ import de.danoeh.antennapod.core.util.Flavors;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.dialog.RatingDialog;
import de.danoeh.antennapod.fragment.AddFeedFragment;
+import de.danoeh.antennapod.fragment.AudioPlayerFragment;
import de.danoeh.antennapod.fragment.DownloadsFragment;
import de.danoeh.antennapod.fragment.EpisodesFragment;
-import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
import de.danoeh.antennapod.fragment.NavDrawerFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
@@ -41,6 +42,7 @@ import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
import de.danoeh.antennapod.fragment.TransitionEffect;
import de.danoeh.antennapod.preferences.PreferenceUpgrader;
+import de.danoeh.antennapod.view.LockableBottomSheetBehavior;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
import org.greenrobot.eventbus.EventBus;
@@ -61,12 +63,14 @@ public class MainActivity extends CastEnabledActivity {
public static final String EXTRA_FRAGMENT_TAG = "fragment_tag";
public static final String EXTRA_FRAGMENT_ARGS = "fragment_args";
public static final String EXTRA_FEED_ID = "fragment_feed_id";
+ public static final String EXTRA_OPEN_PLAYER = "open_player";
private static final String SAVE_BACKSTACK_COUNT = "backstackCount";
private DrawerLayout drawerLayout;
private View navDrawer;
private ActionBarDrawerToggle drawerToggle;
+ private LockableBottomSheetBehavior sheetBehavior;
private long lastBackButtonPressTime = 0;
@NonNull
@@ -111,15 +115,34 @@ public class MainActivity extends CastEnabledActivity {
}
}
}
- ExternalPlayerFragment externalPlayerFragment = new ExternalPlayerFragment();
- transaction.replace(R.id.playerFragment, externalPlayerFragment, ExternalPlayerFragment.TAG);
NavDrawerFragment navDrawerFragment = new NavDrawerFragment();
transaction.replace(R.id.navDrawerFragment, navDrawerFragment, NavDrawerFragment.TAG);
-
+ AudioPlayerFragment audioPlayerFragment = new AudioPlayerFragment();
+ transaction.replace(R.id.audioplayerFragment, audioPlayerFragment, AudioPlayerFragment.TAG);
transaction.commit();
checkFirstLaunch();
PreferenceUpgrader.checkUpgrades(this);
+ View bottomSheet = findViewById(R.id.audioplayerFragment);
+ sheetBehavior = (LockableBottomSheetBehavior) BottomSheetBehavior.from(bottomSheet);
+ sheetBehavior.setPeekHeight((int) getResources().getDimension(R.dimen.external_player_height));
+ sheetBehavior.setHideable(false);
+ sheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
+ @Override
+ public void onStateChanged(@NonNull View view, int state) {
+
+ }
+
+ @Override
+ public void onSlide(@NonNull View view, float slideOffset) {
+ AudioPlayerFragment audioPlayer =
+ (AudioPlayerFragment) getSupportFragmentManager().findFragmentByTag(AudioPlayerFragment.TAG);
+ float condensedSlideOffset = Math.max(0.0f, Math.min(0.1f, slideOffset - 0.5f)) / 0.1f;
+ audioPlayer.getExternalPlayerHolder().setAlpha(1 - condensedSlideOffset);
+ audioPlayer.getExternalPlayerHolder().setVisibility(
+ condensedSlideOffset > 0.99f ? View.GONE : View.VISIBLE);
+ }
+ });
}
@Override
@@ -151,6 +174,10 @@ public class MainActivity extends CastEnabledActivity {
return drawerLayout != null && navDrawer != null && drawerLayout.isDrawerOpen(navDrawer);
}
+ public LockableBottomSheetBehavior getBottomSheet() {
+ return sheetBehavior;
+ }
+
public void loadFragment(String tag, Bundle args) {
Log.d(TAG, "loadFragment(tag: " + tag + ", args: " + args + ")");
Fragment fragment;
@@ -176,6 +203,7 @@ public class MainActivity extends CastEnabledActivity {
default:
// default to the queue
fragment = new QueueFragment();
+ tag = QueueFragment.TAG;
args = null;
break;
}
@@ -183,6 +211,7 @@ public class MainActivity extends CastEnabledActivity {
if (args != null) {
fragment.setArguments(args);
}
+ NavDrawerFragment.saveLastNavFragment(this, tag);
loadFragment(fragment);
}
@@ -191,6 +220,7 @@ public class MainActivity extends CastEnabledActivity {
if (args != null) {
fragment.setArguments(args);
}
+ NavDrawerFragment.saveLastNavFragment(this, String.valueOf(feedId));
loadFragment(fragment);
}
@@ -299,29 +329,6 @@ public class MainActivity extends CastEnabledActivity {
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- boolean retVal = super.onCreateOptionsMenu(menu);
- if (Flavors.FLAVOR == Flavors.PLAY) {
- switch (NavDrawerFragment.getLastNavFragment(this)) {
- case QueueFragment.TAG:
- case EpisodesFragment.TAG:
- requestCastButton(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- return retVal;
- case DownloadsFragment.TAG:
- case PlaybackHistoryFragment.TAG:
- case AddFeedFragment.TAG:
- case SubscriptionFragment.TAG:
- return retVal;
- default:
- requestCastButton(MenuItem.SHOW_AS_ACTION_NEVER);
- return retVal;
- }
- } else {
- return retVal;
- }
- }
-
- @Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
@@ -339,6 +346,8 @@ public class MainActivity extends CastEnabledActivity {
public void onBackPressed() {
if (isDrawerOpen()) {
drawerLayout.closeDrawer(navDrawer);
+ } else if (sheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
+ sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
} else if (getSupportFragmentManager().getBackStackEntryCount() != 0) {
super.onBackPressed();
} else {
@@ -367,7 +376,6 @@ public class MainActivity extends CastEnabledActivity {
super.onBackPressed();
} else {
loadFragment(UserPreferences.getBackButtonGoToPage(), null);
- NavDrawerFragment.saveLastNavFragment(this, UserPreferences.getBackButtonGoToPage());
}
break;
default: super.onBackPressed();
@@ -398,9 +406,11 @@ public class MainActivity extends CastEnabledActivity {
} else if (feedId > 0) {
loadFeedFragmentById(feedId, args);
}
- // to avoid handling the intent twice when the configuration changes
- setIntent(new Intent(MainActivity.this, MainActivity.class));
+ } else if (intent.hasExtra(EXTRA_OPEN_PLAYER)) {
+ sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
+ // to avoid handling the intent twice when the configuration changes
+ setIntent(new Intent(MainActivity.this, MainActivity.class));
}
@Override
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 c0ba75ba6..55aadc60b 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -2,7 +2,6 @@ package de.danoeh.antennapod.activity;
import android.Manifest;
import android.annotation.TargetApi;
-import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@@ -22,9 +21,12 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
+import androidx.arch.core.util.Function;
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;
@@ -35,15 +37,12 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.util.Consumer;
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.Function;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.core.util.StorageUtils;
-import de.danoeh.antennapod.core.util.Supplier;
import de.danoeh.antennapod.core.util.TimeSpeedConverter;
import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
@@ -52,6 +51,7 @@ 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.SkipPreferenceDialog;
import de.danoeh.antennapod.dialog.SleepTimerDialog;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -141,16 +141,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
}
@Override
- public void postStatusMsg(int msg, boolean showToast) {
- MediaplayerActivity.this.postStatusMsg(msg, showToast);
- }
-
- @Override
- public void clearStatusMsg() {
- MediaplayerActivity.this.clearStatusMsg();
- }
-
- @Override
public boolean loadMediaInfo() {
return MediaplayerActivity.this.loadMediaInfo();
}
@@ -198,13 +188,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
onPositionObserverUpdate();
}
- private static TextView getTxtvFFFromActivity(MediaplayerActivity activity) {
- return activity.txtvFF;
- }
- private static TextView getTxtvRevFromActivity(MediaplayerActivity activity) {
- return activity.txtvRev;
- }
-
private void onSetSpeedAbilityChanged() {
Log.d(TAG, "onSetSpeedAbilityChanged()");
updatePlaybackSpeedButton();
@@ -258,12 +241,16 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
* Should be used to inform the user that the PlaybackService is currently
* buffering.
*/
- protected abstract void onBufferStart();
+ protected void onBufferStart() {
+
+ }
/**
* Should be used to hide the view that was showing the 'buffering'-message.
*/
- protected abstract void onBufferEnd();
+ protected void onBufferEnd() {
+
+ }
private void onBufferUpdate(float progress) {
if (sbPosition != null) {
@@ -311,9 +298,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
- if (Flavors.FLAVOR == Flavors.PLAY) {
- requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS);
- }
+ requestCastButton(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mediaplayer, menu);
return true;
@@ -478,10 +463,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
*/
protected abstract void onAwaitingVideoSurface();
- protected abstract void postStatusMsg(int resId, boolean showToast);
-
- protected abstract void clearStatusMsg();
-
void onPositionObserverUpdate() {
if (controller == null || txtvPosition == null || txtvLength == null) {
return;
@@ -543,92 +524,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
// Only meaningful on AudioplayerActivity, where it is overridden.
}
- /**
- * Abstract directions to skip forward or back (rewind) and encapsulates behavior to get or set preference (including update of UI on the skip buttons).
- */
- public enum SkipDirection {
- SKIP_FORWARD(
- UserPreferences::getFastForwardSecs,
- MediaplayerActivity::getTxtvFFFromActivity,
- UserPreferences::setFastForwardSecs,
- R.string.pref_fast_forward),
- SKIP_REWIND(UserPreferences::getRewindSecs,
- MediaplayerActivity::getTxtvRevFromActivity,
- UserPreferences::setRewindSecs,
- R.string.pref_rewind);
-
- private final Supplier<Integer> getPrefSecsFn;
- private final Function<MediaplayerActivity, TextView> getTextViewFn;
- private final Consumer<Integer> setPrefSecsFn;
- private final int titleResourceID;
-
- /**
- * Constructor for skip direction enum. Stores references to utility functions and resource
- * id's that vary dependending on the direction.
- *
- * @param getPrefSecsFn Handle to function that retrieves current seconds of the skip delta
- * @param getTextViewFn Handle to function that gets the TextView which displays the current skip delta value
- * @param setPrefSecsFn Handle to function that sets the preference (setting) for the skip delta value (and optionally updates the button label with the current values)
- * @param titleResourceID ID of the resource string with the title for a view
- */
- SkipDirection(Supplier<Integer> getPrefSecsFn, Function<MediaplayerActivity, TextView> getTextViewFn, Consumer<Integer> setPrefSecsFn, int titleResourceID) {
- this.getPrefSecsFn = getPrefSecsFn;
- this.getTextViewFn = getTextViewFn;
- this.setPrefSecsFn = setPrefSecsFn;
- this.titleResourceID = titleResourceID;
- }
-
-
- public int getPrefSkipSeconds() {
- return(getPrefSecsFn.get());
- }
-
- /**
- * Updates preferences for a forward or backward skip depending on the direction of the instance, optionally updating the UI.
- *
- * @param seconds Number of seconds to set the preference associated with the direction of the instance.
- * @param activity MediaplyerActivity that contains textview to update the display of the skip delta setting (or null if nothing to update)
- */
- public void setPrefSkipSeconds(int seconds, @Nullable Activity activity) {
- setPrefSecsFn.accept(seconds);
-
- if (activity != null && activity instanceof MediaplayerActivity) {
- TextView tv = getTextViewFn.apply((MediaplayerActivity)activity);
- if (tv != null) tv.setText(String.valueOf(seconds));
- }
- }
- public int getTitleResourceID() {
- return titleResourceID;
- }
- }
-
- public static void showSkipPreference(Activity activity, SkipDirection direction) {
- int checked = 0;
- int skipSecs = direction.getPrefSkipSeconds();
- final int[] values = activity.getResources().getIntArray(R.array.seek_delta_values);
- final String[] choices = new String[values.length];
- for (int i = 0; i < values.length; i++) {
- if (skipSecs == values[i]) {
- checked = i;
- }
- choices[i] = String.valueOf(values[i]) + " " + activity.getString(R.string.time_seconds);
- }
-
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setTitle(direction.getTitleResourceID());
- builder.setSingleChoiceItems(choices, checked, null);
- builder.setNegativeButton(R.string.cancel_label, null);
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
- int choice = ((AlertDialog)dialog).getListView().getCheckedItemPosition();
- if (choice < 0 || choice >= values.length) {
- System.err.printf("Choice in showSkipPreference is out of bounds %d", choice);
- } else {
- direction.setPrefSkipSeconds(values[choice], activity);
- }
- });
- builder.create().show();
- }
-
void setupGUI() {
setContentView(getContentViewResourceId());
sbPosition = findViewById(R.id.sbPosition);
@@ -688,7 +583,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
if (butRev != null) {
butRev.setOnClickListener(v -> onRewind());
butRev.setOnLongClickListener(v -> {
- showSkipPreference(MediaplayerActivity.this, SkipDirection.SKIP_REWIND);
+ SkipPreferenceDialog.showSkipPreference(MediaplayerActivity.this,
+ SkipPreferenceDialog.SkipDirection.SKIP_REWIND, txtvRev);
return true;
});
}
@@ -698,7 +594,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
if (butFF != null) {
butFF.setOnClickListener(v -> onFastForward());
butFF.setOnLongClickListener(v -> {
- showSkipPreference(MediaplayerActivity.this, SkipDirection.SKIP_FORWARD);
+ SkipPreferenceDialog.showSkipPreference(MediaplayerActivity.this,
+ SkipPreferenceDialog.SkipDirection.SKIP_FORWARD, txtvFF);
return false;
});
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
deleted file mode 100644
index 1a7631813..000000000
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java
+++ /dev/null
@@ -1,282 +0,0 @@
-package de.danoeh.antennapod.activity;
-
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.TextView;
-import android.widget.Toast;
-import androidx.appcompat.app.ActionBarDrawerToggle;
-import androidx.appcompat.widget.Toolbar;
-import androidx.drawerlayout.widget.DrawerLayout;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentStatePagerAdapter;
-import androidx.viewpager.widget.ViewPager;
-import com.google.android.material.snackbar.Snackbar;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.event.MessageEvent;
-import de.danoeh.antennapod.core.feed.Chapter;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
-import de.danoeh.antennapod.core.util.playback.PlaybackController;
-import de.danoeh.antennapod.fragment.ChaptersFragment;
-import de.danoeh.antennapod.fragment.CoverFragment;
-import de.danoeh.antennapod.fragment.ItemDescriptionFragment;
-import de.danoeh.antennapod.fragment.NavDrawerFragment;
-import de.danoeh.antennapod.view.PagerIndicatorView;
-import de.danoeh.antennapod.view.PlaybackSpeedIndicatorView;
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
-
-import java.util.List;
-
-/**
- * Activity for playing files that do not require a video surface.
- */
-public abstract class MediaplayerInfoActivity extends MediaplayerActivity {
-
- private static final String TAG = "MediaplayerInfoActivity";
-
- private static final int POS_COVER = 0;
- private static final int POS_DESCR = 1;
- private static final int POS_CHAPTERS = 2;
- private static final int NUM_CONTENT_FRAGMENTS = 3;
-
- private static final String PREFS = "AudioPlayerActivityPreferences";
- private static final String PREF_KEY_SELECTED_FRAGMENT_POSITION = "selectedFragmentPosition";
-
- PlaybackSpeedIndicatorView butPlaybackSpeed;
- TextView txtvPlaybackSpeed;
- private DrawerLayout drawerLayout;
- private View navDrawer;
- private ActionBarDrawerToggle drawerToggle;
- private ViewPager pager;
- private PagerIndicatorView pageIndicator;
- private MediaplayerInfoPagerAdapter pagerAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- supportPostponeEnterTransition();
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- Log.d(TAG, "onStop()");
- saveCurrentFragment();
- }
-
- @Override
- public void onDestroy() {
- Log.d(TAG, "onDestroy()");
- super.onDestroy();
- // don't risk creating memory leaks
- drawerLayout = null;
- navDrawer = null;
- drawerToggle = null;
- pager = null;
- pagerAdapter = null;
- }
-
- @Override
- protected void chooseTheme() {
- setTheme(UserPreferences.getNoTitleTheme());
- }
-
- void saveCurrentFragment() {
- if (pager == null) {
- return;
- }
- Log.d(TAG, "Saving preferences");
- SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
- prefs.edit()
- .putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, pager.getCurrentItem())
- .apply();
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- if (drawerToggle != null) {
- drawerToggle.onConfigurationChanged(newConfig);
- }
- }
-
- private void loadLastFragment() {
- Log.d(TAG, "Restoring instance state");
- SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
- int lastPosition = prefs.getInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, -1);
- pager.setCurrentItem(lastPosition);
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- setIntent(intent);
- }
-
- @Override
- protected void onAwaitingVideoSurface() {
- Log.d(TAG, "onAwaitingVideoSurface was called in audio player -> switching to video player");
- startActivity(new Intent(this, VideoplayerActivity.class));
- }
-
- @Override
- protected void postStatusMsg(int resId, boolean showToast) {
- if (resId == R.string.player_preparing_msg
- || resId == R.string.player_seeking_msg
- || resId == R.string.player_buffering_msg) {
- // TODO Show progress bar here
- }
- if (showToast) {
- Toast.makeText(this, resId, Toast.LENGTH_SHORT).show();
- }
- }
-
- @Override
- protected void clearStatusMsg() {
- // TODO Hide progress bar here
- }
-
-
- @Override
- protected void setupGUI() {
- super.setupGUI();
- Toolbar toolbar = findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setTitle("");
- drawerLayout = findViewById(R.id.drawer_layout);
- navDrawer = findViewById(R.id.navDrawerFragment);
- butPlaybackSpeed = findViewById(R.id.butPlaybackSpeed);
- txtvPlaybackSpeed = findViewById(R.id.txtvPlaybackSpeed);
-
- drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close);
- drawerToggle.setDrawerIndicatorEnabled(false);
- drawerLayout.addDrawerListener(drawerToggle);
- drawerToggle.syncState();
-
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.navDrawerFragment, new NavDrawerFragment(), NavDrawerFragment.TAG)
- .commit();
-
- pager = findViewById(R.id.pager);
- pager.setOffscreenPageLimit(3);
- pagerAdapter = new MediaplayerInfoPagerAdapter(getSupportFragmentManager());
- pager.setAdapter(pagerAdapter);
- pageIndicator = findViewById(R.id.page_indicator);
- pageIndicator.setViewPager(pager);
- pageIndicator.setOnClickListener(v
- -> pager.setCurrentItem((pager.getCurrentItem() + 1) % pager.getChildCount()));
- loadLastFragment();
- pager.onSaveInstanceState();
-
- pager.post(this::supportStartPostponedEnterTransition);
- }
-
- @Override
- boolean loadMediaInfo() {
- if (controller != null && controller.getMedia() != null) {
- List<Chapter> chapters = controller.getMedia().getChapters();
- boolean hasChapters = chapters != null && !chapters.isEmpty();
- pageIndicator.setDisabledPage(hasChapters ? -1 : 2);
- }
- return super.loadMediaInfo();
- }
-
- @Override
- protected void onReloadNotification(int notificationCode) {
- if (notificationCode == PlaybackService.EXTRA_CODE_VIDEO) {
- Log.d(TAG, "ReloadNotification received, switching to Videoplayer now");
- finish();
- startActivity(new Intent(this, VideoplayerActivity.class));
-
- }
- }
-
- @Override
- protected void onBufferStart() {
- postStatusMsg(R.string.player_buffering_msg, false);
- }
-
- @Override
- protected void onBufferEnd() {
- clearStatusMsg();
- }
-
- public PlaybackController getPlaybackController() {
- return controller;
- }
-
- public boolean isDrawerOpen() {
- return drawerLayout != null && navDrawer != null && drawerLayout.isDrawerOpen(navDrawer);
- }
-
- @Override
- protected int getContentViewResourceId() {
- return R.layout.mediaplayerinfo_activity;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- return (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) || super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onBackPressed() {
- if (isDrawerOpen()) {
- drawerLayout.closeDrawer(navDrawer);
- } else if (pager == null || pager.getCurrentItem() == 0) {
- // If the user is currently looking at the first step, allow the system to handle the
- // Back button. This calls finish() on this activity and pops the back stack.
- super.onBackPressed();
- } else {
- // Otherwise, select the previous step.
- pager.setCurrentItem(pager.getCurrentItem() - 1);
- }
- }
-
- @Subscribe(threadMode = ThreadMode.MAIN)
- public void onEventMainThread(MessageEvent event) {
- Log.d(TAG, "onEvent(" + event + ")");
- View parentLayout = findViewById(R.id.drawer_layout);
- Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT);
- if (event.action != null) {
- snackbar.setAction(getString(R.string.undo), v -> event.action.run());
- }
- snackbar.show();
- }
-
- private static class MediaplayerInfoPagerAdapter extends FragmentStatePagerAdapter {
- private static final String TAG = "MPInfoPagerAdapter";
-
- public MediaplayerInfoPagerAdapter(FragmentManager fm) {
- super(fm);
- }
-
- @Override
- public Fragment getItem(int position) {
- Log.d(TAG, "getItem(" + position + ")");
- switch (position) {
- case POS_COVER:
- return new CoverFragment();
- case POS_DESCR:
- return new ItemDescriptionFragment();
- case POS_CHAPTERS:
- return new ChaptersFragment();
- default:
- return null;
- }
- }
-
- @Override
- public int getCount() {
- return NUM_CONTENT_FRAGMENTS;
- }
- }
-}
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 1f0039189..821defd86 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -113,6 +113,9 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
listView = findViewById(R.id.listview);
progressBar = findViewById(R.id.progressBar);
+ findViewById(R.id.transparentBackground).setOnClickListener(v -> finish());
+ findViewById(R.id.card).setOnClickListener(null);
+
String feedUrl = null;
if (getIntent().hasExtra(ARG_FEEDURL)) {
feedUrl = getIntent().getStringExtra(ARG_FEEDURL);
@@ -615,7 +618,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
private final String feedUrl;
FeedViewAuthenticationDialog(Context context, int titleRes, String feedUrl) {
- super(context, titleRes, true, false, null, null);
+ super(context, titleRes, true, null, null);
this.feedUrl = feedUrl;
}
@@ -626,7 +629,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
}
@Override
- protected void onConfirmed(String username, String password, boolean saveUsernamePassword) {
+ protected void onConfirmed(String username, String password) {
startFeedDownload(feedUrl, username, password);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
index 03e6b89db..f4d312a4f 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
@@ -57,6 +57,7 @@ public class OpmlImportActivity extends AppCompatActivity {
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "Received result");
if (resultCode == RESULT_CANCELED) {
Log.d(TAG, "Activity was cancelled");
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java
index 8527949b0..d1cd50608 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java
@@ -121,8 +121,9 @@ public class StorageErrorActivity extends AppCompatActivity {
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == Activity.RESULT_OK &&
- requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (resultCode == Activity.RESULT_OK
+ && requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) {
String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR);
File path;
@@ -131,19 +132,19 @@ public class StorageErrorActivity extends AppCompatActivity {
} else {
path = getExternalFilesDir(null);
}
- if(path == null) {
+ if (path == null) {
return;
}
String message = null;
- if(!path.exists()) {
+ if (!path.exists()) {
message = String.format(getString(R.string.folder_does_not_exist_error), dir);
- } else if(!path.canRead()) {
+ } else if (!path.canRead()) {
message = String.format(getString(R.string.folder_not_readable_error), dir);
- } else if(!path.canWrite()) {
+ } else if (!path.canWrite()) {
message = String.format(getString(R.string.folder_not_writable_error), dir);
}
- if(message == null) {
+ if (message == null) {
Log.d(TAG, "Setting data folder: " + dir);
UserPreferences.setDataFolder(dir);
leaveErrorState();
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 a1a4e0374..212cb2f75 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -171,20 +171,6 @@ public class VideoplayerActivity extends MediaplayerActivity {
}
}
- @Override
- protected void postStatusMsg(int resId, boolean showToast) {
- if (resId == R.string.player_preparing_msg) {
- progressIndicator.setVisibility(View.VISIBLE);
- } else {
- progressIndicator.setVisibility(View.INVISIBLE);
- }
- }
-
- @Override
- protected void clearStatusMsg() {
- progressIndicator.setVisibility(View.INVISIBLE);
- }
-
private final View.OnTouchListener onVideoviewTouched = (v, event) -> {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (PictureInPictureUtil.isInPictureInPictureMode(this)) {
@@ -292,16 +278,11 @@ public class VideoplayerActivity extends MediaplayerActivity {
}
return;
}
- if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO) {
- Log.d(TAG, "ReloadNotification received, switching to Audioplayer now");
- destroyingDueToReload = true;
- finish();
- startActivity(new Intent(this, AudioplayerActivity.class));
- } else if (notificationCode == PlaybackService.EXTRA_CODE_CAST) {
+ if (notificationCode == PlaybackService.EXTRA_CODE_CAST) {
Log.d(TAG, "ReloadNotification received, switching to Castplayer now");
destroyingDueToReload = true;
finish();
- startActivity(new Intent(this, CastplayerActivity.class));
+ startActivity(new Intent(this, MainActivity.class).putExtra(MainActivity.EXTRA_OPEN_PLAYER, true));
}
}
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 c79c611ce..224b8d182 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
@@ -190,8 +190,6 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity {
final AtomicReference<List<GpodnetDevice>> devices = new AtomicReference<>();
new AsyncTask<GpodnetService, Void, List<GpodnetDevice>>() {
- private volatile Exception exception;
-
@Override
protected void onPreExecute() {
super.onPreExecute();
@@ -226,7 +224,6 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity {
return params[0].getDevices(username);
} catch (GpodnetServiceException e) {
e.printStackTrace();
- exception = e;
return null;
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
index 1171acaa5..cb72a9150 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
@@ -5,37 +5,34 @@ import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
+import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.FitCenter;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Chapter;
-import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
-import de.danoeh.antennapod.core.util.ChapterUtils;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.EmbeddedChapterImage;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.playback.Playable;
-public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
- private static final String TAG = "ChapterListAdapter";
-
+public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapter.ChapterHolder> {
private Playable media;
private final Callback callback;
+ private final Context context;
private int currentChapterIndex = -1;
private boolean hasImages = false;
- public ChaptersListAdapter(Context context, int textViewResourceId, Callback callback) {
- super(context, textViewResourceId);
+ public ChaptersListAdapter(Context context, Callback callback) {
this.callback = callback;
+ this.context = context;
}
public void setMedia(Playable media) {
@@ -51,34 +48,10 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
notifyDataSetChanged();
}
- @NonNull
- @Override
- public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
- Holder holder;
+ @Override
+ public void onBindViewHolder(@NonNull ChapterHolder holder, int position) {
Chapter sc = getItem(position);
-
- // Inflate Layout
- if (convertView == null) {
- holder = new Holder();
- LayoutInflater inflater = (LayoutInflater) getContext()
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- convertView = inflater.inflate(R.layout.simplechapter_item, parent, false);
- holder.view = convertView;
- holder.title = convertView.findViewById(R.id.txtvTitle);
- holder.start = convertView.findViewById(R.id.txtvStart);
- holder.link = convertView.findViewById(R.id.txtvLink);
- holder.image = convertView.findViewById(R.id.imgvCover);
- holder.duration = convertView.findViewById(R.id.txtvDuration);
- holder.secondaryActionButton = convertView.findViewById(R.id.secondaryActionButton);
- holder.secondaryActionIcon = convertView.findViewById(R.id.secondaryActionIcon);
- convertView.setTag(holder);
- } else {
- holder = (Holder) convertView.getTag();
-
- }
-
holder.title.setText(sc.getTitle());
holder.start.setText(Converter.getDurationStringLong((int) sc
.getStart()));
@@ -89,7 +62,7 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
} else {
duration = media.getDuration() - sc.getStart();
}
- holder.duration.setText(getContext().getString(R.string.chapter_duration,
+ holder.duration.setText(context.getString(R.string.chapter_duration,
Converter.getDurationStringLong((int) duration)));
if (sc.getLink() == null) {
@@ -97,9 +70,9 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
} else {
holder.link.setVisibility(View.VISIBLE);
holder.link.setText(sc.getLink());
- holder.link.setOnClickListener(v -> IntentUtils.openInBrowser(getContext(), sc.getLink()));
+ holder.link.setOnClickListener(v -> IntentUtils.openInBrowser(context, sc.getLink()));
}
- holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(getContext(), R.attr.av_play));
+ holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.av_play));
holder.secondaryActionButton.setOnClickListener(v -> {
if (callback != null) {
callback.onPlayChapterButtonClicked(position);
@@ -107,46 +80,40 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
});
if (position == currentChapterIndex) {
- int playingBackGroundColor = ThemeUtils.getColorFromAttr(getContext(), R.attr.currently_playing_background);
- holder.view.setBackgroundColor(playingBackGroundColor);
+ int playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background);
+ holder.itemView.setBackgroundColor(playingBackGroundColor);
} else {
- holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
+ holder.itemView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent));
}
if (hasImages) {
holder.image.setVisibility(View.VISIBLE);
if (TextUtils.isEmpty(sc.getImageUrl())) {
- Glide.with(getContext()).clear(holder.image);
+ Glide.with(context).clear(holder.image);
} else {
- Glide.with(getContext())
+ Glide.with(context)
.load(EmbeddedChapterImage.getModelFor(media, position))
.apply(new RequestOptions()
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
.dontAnimate()
.transforms(new FitCenter(), new RoundedCorners((int)
- (4 * getContext().getResources().getDisplayMetrics().density))))
+ (4 * context.getResources().getDisplayMetrics().density))))
.into(holder.image);
}
} else {
holder.image.setVisibility(View.GONE);
}
-
- return convertView;
}
- static class Holder {
- View view;
- TextView title;
- TextView start;
- TextView link;
- TextView duration;
- ImageView image;
- View secondaryActionButton;
- ImageView secondaryActionIcon;
+ @NonNull
+ @Override
+ public ChapterHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ LayoutInflater inflater = LayoutInflater.from(context);
+ return new ChapterHolder(inflater.inflate(R.layout.simplechapter_item, parent, false));
}
@Override
- public int getCount() {
+ public int getItemCount() {
if (media == null || media.getChapters() == null) {
return 0;
}
@@ -160,6 +127,27 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
return counter;
}
+ static class ChapterHolder extends RecyclerView.ViewHolder {
+ final TextView title;
+ final TextView start;
+ final TextView link;
+ final TextView duration;
+ final ImageView image;
+ final View secondaryActionButton;
+ final ImageView secondaryActionIcon;
+
+ public ChapterHolder(@NonNull View itemView) {
+ super(itemView);
+ title = itemView.findViewById(R.id.txtvTitle);
+ start = itemView.findViewById(R.id.txtvStart);
+ link = itemView.findViewById(R.id.txtvLink);
+ image = itemView.findViewById(R.id.imgvCover);
+ duration = itemView.findViewById(R.id.txtvDuration);
+ secondaryActionButton = itemView.findViewById(R.id.secondaryActionButton);
+ secondaryActionIcon = itemView.findViewById(R.id.secondaryActionIcon);
+ }
+ }
+
public void notifyChapterChanged(int newChapterIndex) {
currentChapterIndex = newChapterIndex;
notifyDataSetChanged();
@@ -169,7 +157,6 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
return media.getDuration() > 0 && media.getDuration() < c.getStart();
}
- @Override
public Chapter getItem(int position) {
int i = 0;
for (Chapter chapter : media.getChapters()) {
@@ -181,7 +168,7 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
}
}
}
- return super.getItem(position);
+ return null;
}
public interface Callback {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java
index 5f019d1db..2b498cd47 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java
@@ -38,13 +38,6 @@ public abstract class StatisticsListAdapter extends RecyclerView.Adapter<Recycle
return statisticsData.size() + 1;
}
- public StatisticsItem getItem(int position) {
- if (position == 0) {
- return null;
- }
- return statisticsData.get(position - 1);
- }
-
@Override
public int getItemViewType(int position) {
return position == 0 ? TYPE_HEADER : TYPE_FEED;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
index 62b22879a..3edc23e37 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
@@ -10,6 +10,8 @@ import android.widget.TextView;
import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.resource.bitmap.FitCenter;
+import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import org.apache.commons.lang3.StringUtils;
@@ -57,7 +59,9 @@ public class PodcastListAdapter extends ArrayAdapter<GpodnetPodcast> {
.placeholder(R.color.light_gray)
.error(R.color.light_gray)
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
- .fitCenter()
+ .transforms(new FitCenter(),
+ new RoundedCorners((int) (4 * convertView.getContext()
+ .getResources().getDisplayMetrics().density)))
.dontAnimate())
.into(holder.image);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
index 7917c264f..1968c0b62 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
@@ -11,6 +11,8 @@ import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.load.resource.bitmap.FitCenter;
+import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import de.danoeh.antennapod.discovery.PodcastSearchResult;
@@ -83,7 +85,8 @@ public class ItunesAdapter extends ArrayAdapter<PodcastSearchResult> {
.apply(new RequestOptions()
.placeholder(R.color.light_gray)
.diskCacheStrategy(DiskCacheStrategy.NONE)
- .fitCenter()
+ .transforms(new FitCenter(),
+ new RoundedCorners((int) (4 * context.getResources().getDisplayMetrics().density)))
.dontAnimate())
.into(viewHolder.coverView);
diff --git a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
index e264a3602..b810b390a 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
@@ -53,11 +53,6 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
}
@Override
- public void onFeedParsed(Context context, Feed feed) {
- // do nothing
- }
-
- @Override
public boolean shouldCreateReport() {
return true;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
index c3f5d898c..44f18e9da 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
@@ -4,27 +4,22 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.AudioplayerActivity;
-import de.danoeh.antennapod.activity.CastplayerActivity;
+import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.VideoplayerActivity;
import de.danoeh.antennapod.core.PlaybackServiceCallbacks;
import de.danoeh.antennapod.core.feed.MediaType;
-
public class PlaybackServiceCallbacksImpl implements PlaybackServiceCallbacks {
@Override
public Intent getPlayerActivityIntent(Context context, MediaType mediaType, boolean remotePlayback) {
- if (remotePlayback) {
- return new Intent(context, CastplayerActivity.class);
- }
- if (mediaType == MediaType.VIDEO) {
+ if (mediaType == MediaType.AUDIO || remotePlayback) {
+ return new Intent(context, MainActivity.class).putExtra(MainActivity.EXTRA_OPEN_PLAYER, true);
+ } else {
Intent i = new Intent(context, VideoplayerActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
i.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
}
return i;
- } else {
- return new Intent(context, AudioplayerActivity.class);
}
}
@@ -33,8 +28,4 @@ public class PlaybackServiceCallbacksImpl implements PlaybackServiceCallbacks {
return true;
}
- @Override
- public int getNotificationIconResource(Context context) {
- return R.drawable.ic_antenna;
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java
index 073f7b550..fb2f92742 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java
@@ -3,7 +3,6 @@ package de.danoeh.antennapod.dialog;
import android.app.AlertDialog;
import android.content.Context;
import android.view.View;
-import android.widget.CheckBox;
import android.widget.EditText;
import de.danoeh.antennapod.R;
@@ -13,8 +12,7 @@ import de.danoeh.antennapod.R;
public abstract class AuthenticationDialog extends AlertDialog.Builder {
public AuthenticationDialog(Context context, int titleRes, boolean enableUsernameField,
- boolean showSaveCredentialsCheckbox, String usernameInitialValue,
- String passwordInitialValue) {
+ String usernameInitialValue, String passwordInitialValue) {
super(context);
setTitle(titleRes);
View rootView = View.inflate(context, R.layout.authentication_dialog, null);
@@ -22,14 +20,8 @@ public abstract class AuthenticationDialog extends AlertDialog.Builder {
final EditText etxtUsername = rootView.findViewById(R.id.etxtUsername);
final EditText etxtPassword = rootView.findViewById(R.id.etxtPassword);
- final CheckBox saveUsernamePassword = rootView.findViewById(R.id.chkSaveUsernamePassword);
etxtUsername.setEnabled(enableUsernameField);
- if (showSaveCredentialsCheckbox) {
- saveUsernamePassword.setVisibility(View.VISIBLE);
- } else {
- saveUsernamePassword.setVisibility(View.GONE);
- }
if (usernameInitialValue != null) {
etxtUsername.setText(usernameInitialValue);
}
@@ -39,13 +31,12 @@ public abstract class AuthenticationDialog extends AlertDialog.Builder {
setOnCancelListener(dialog -> onCancelled());
setNegativeButton(R.string.cancel_label, null);
setPositiveButton(R.string.confirm_label, (dialog, which)
- -> onConfirmed(etxtUsername.getText().toString(), etxtPassword.getText().toString(),
- showSaveCredentialsCheckbox && saveUsernamePassword.isChecked()));
+ -> onConfirmed(etxtUsername.getText().toString(), etxtPassword.getText().toString()));
}
protected void onCancelled() {
}
- protected abstract void onConfirmed(String username, String password, boolean saveUsernamePassword);
+ protected abstract void onConfirmed(String username, String password);
}
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 d48a6a4a6..7e052b445 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -313,7 +313,7 @@ public class EpisodesApplyActionFragment extends Fragment {
}
}
if (resId != 0) {
- Snackbar.make(getActivity().findViewById(R.id.content), resId, Snackbar.LENGTH_SHORT)
+ Snackbar.make(getActivity().findViewById(android.R.id.content), resId, Snackbar.LENGTH_SHORT)
.show();
return true;
} else {
@@ -469,7 +469,7 @@ public class EpisodesApplyActionFragment extends Fragment {
private void close(@PluralsRes int msgId, int numItems) {
if (numItems > 0) {
- Snackbar.make(getActivity().findViewById(R.id.content),
+ Snackbar.make(getActivity().findViewById(android.R.id.content),
getResources().getQuantityString(msgId, numItems, numItems),
Snackbar.LENGTH_LONG
)
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 11256f2de..0c25e3e9f 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
@@ -84,16 +84,16 @@ public class ProxyDialog {
String host = etHost.getText().toString();
String port = etPort.getText().toString();
String username = etUsername.getText().toString();
- if(TextUtils.isEmpty(username)) {
+ if (TextUtils.isEmpty(username)) {
username = null;
}
String password = etPassword.getText().toString();
- if(TextUtils.isEmpty(password)) {
+ if (TextUtils.isEmpty(password)) {
password = null;
}
int portValue = 0;
- if(!TextUtils.isEmpty(port)) {
- portValue = Integer.valueOf(port);
+ if (!TextUtils.isEmpty(port)) {
+ portValue = Integer.parseInt(port);
}
if (Proxy.Type.valueOf(type) == Proxy.Type.SOCKS) {
proxy = ProxyConfig.socks(host, portValue, username, password);
@@ -257,8 +257,8 @@ public class ProxyDialog {
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
int portValue = 8080;
- if(!TextUtils.isEmpty(port)) {
- portValue = Integer.valueOf(port);
+ if (!TextUtils.isEmpty(port)) {
+ portValue = Integer.parseInt(port);
}
SocketAddress address = InetSocketAddress.createUnresolved(host, portValue);
Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase());
@@ -268,7 +268,7 @@ public class ProxyDialog {
.proxy(proxy);
builder.interceptors().clear();
OkHttpClient client = builder.build();
- if(!TextUtils.isEmpty(username)) {
+ if (!TextUtils.isEmpty(username)) {
String credentials = Credentials.basic(username, password);
client.interceptors().add(chain -> {
Request request = chain.request().newBuilder()
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java
new file mode 100644
index 000000000..7bb8f5ad6
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java
@@ -0,0 +1,58 @@
+package de.danoeh.antennapod.dialog;
+
+import android.content.Context;
+import android.widget.TextView;
+import androidx.appcompat.app.AlertDialog;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+
+/**
+ * Shows the dialog that allows setting the skip time.
+ */
+public class SkipPreferenceDialog {
+ public static void showSkipPreference(Context context, SkipDirection direction, TextView textView) {
+ int checked = 0;
+
+ int skipSecs;
+ if (direction == SkipDirection.SKIP_FORWARD) {
+ skipSecs = UserPreferences.getFastForwardSecs();
+ } else {
+ skipSecs = UserPreferences.getRewindSecs();
+ }
+
+ final int[] values = context.getResources().getIntArray(R.array.seek_delta_values);
+ final String[] choices = new String[values.length];
+ for (int i = 0; i < values.length; i++) {
+ if (skipSecs == values[i]) {
+ checked = i;
+ }
+ choices[i] = values[i] + " " + context.getString(R.string.time_seconds);
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(direction == SkipDirection.SKIP_FORWARD ? R.string.pref_fast_forward : R.string.pref_rewind);
+ builder.setSingleChoiceItems(choices, checked, null);
+ builder.setNegativeButton(R.string.cancel_label, null);
+ builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
+ int choice = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
+ if (choice < 0 || choice >= values.length) {
+ System.err.printf("Choice in showSkipPreference is out of bounds %d", choice);
+ } else {
+ int seconds = values[choice];
+ if (direction == SkipDirection.SKIP_FORWARD) {
+ UserPreferences.setFastForwardSecs(seconds);
+ } else {
+ UserPreferences.setRewindSecs(seconds);
+ }
+ if (textView != null) {
+ textView.setText(String.valueOf(seconds));
+ }
+ }
+ });
+ builder.create().show();
+ }
+
+ public enum SkipDirection {
+ SKIP_FORWARD, SKIP_REWIND
+ }
+}
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 216c8cc57..05f38000c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -25,7 +25,6 @@ import java.util.Set;
* supports swiping to mark as read.
*/
public class AllEpisodesFragment extends EpisodesListFragment {
- public static final String TAG = "AllEpisodesFragment";
private static final String PREF_NAME = "PrefAllEpisodesFragment";
private static final String PREF_FILTER = "filter";
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
new file mode 100644
index 000000000..ed136af3c
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
@@ -0,0 +1,505 @@
+package de.danoeh.antennapod.fragment;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.ProgressBar;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.CastEnabledActivity;
+import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.core.event.FavoritesEvent;
+import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
+import de.danoeh.antennapod.core.feed.Chapter;
+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;
+import de.danoeh.antennapod.core.util.IntentUtils;
+import de.danoeh.antennapod.core.util.TimeSpeedConverter;
+import de.danoeh.antennapod.core.util.playback.MediaPlayerError;
+import de.danoeh.antennapod.core.util.playback.Playable;
+import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.dialog.PlaybackControlsDialog;
+import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
+import de.danoeh.antennapod.dialog.SleepTimerDialog;
+import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.view.PagerIndicatorView;
+import de.danoeh.antennapod.view.PlaybackSpeedIndicatorView;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.text.DecimalFormat;
+import java.util.List;
+
+/**
+ * Shows the audio player.
+ */
+public class AudioPlayerFragment extends Fragment implements
+ SeekBar.OnSeekBarChangeListener, Toolbar.OnMenuItemClickListener {
+ public static final String TAG = "AudioPlayerFragment";
+ private static final int POS_COVER = 0;
+ private static final int POS_DESCR = 1;
+ private static final int POS_CHAPTERS = 2;
+ private static final int NUM_CONTENT_FRAGMENTS = 3;
+ private static final String PREFS = "AudioPlayerFragmentPreferences";
+ private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft";
+ private static final float EPSILON = 0.001f;
+
+ PlaybackSpeedIndicatorView butPlaybackSpeed;
+ TextView txtvPlaybackSpeed;
+ private ViewPager pager;
+ private PagerIndicatorView pageIndicator;
+ private TextView txtvPosition;
+ private TextView txtvLength;
+ private SeekBar sbPosition;
+ private ImageButton butRev;
+ private TextView txtvRev;
+ private ImageButton butPlay;
+ private ImageButton butFF;
+ private TextView txtvFF;
+ private ImageButton butSkip;
+ private Toolbar toolbar;
+ private ProgressBar progressIndicator;
+
+ private PlaybackController controller;
+ private boolean showTimeLeft;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ View root = inflater.inflate(R.layout.audioplayer_fragment, container, false);
+ toolbar = root.findViewById(R.id.toolbar);
+ toolbar.setTitle("");
+ toolbar.setNavigationOnClickListener(v ->
+ ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED));
+ toolbar.setOnMenuItemClickListener(this);
+ setupOptionsMenu();
+
+ ExternalPlayerFragment externalPlayerFragment = new ExternalPlayerFragment();
+ getFragmentManager().beginTransaction()
+ .replace(R.id.playerFragment, externalPlayerFragment, ExternalPlayerFragment.TAG)
+ .commit();
+
+ butPlaybackSpeed = root.findViewById(R.id.butPlaybackSpeed);
+ txtvPlaybackSpeed = root.findViewById(R.id.txtvPlaybackSpeed);
+ sbPosition = root.findViewById(R.id.sbPosition);
+ txtvPosition = root.findViewById(R.id.txtvPosition);
+ txtvLength = root.findViewById(R.id.txtvLength);
+ butRev = root.findViewById(R.id.butRev);
+ txtvRev = root.findViewById(R.id.txtvRev);
+ butPlay = root.findViewById(R.id.butPlay);
+ butFF = root.findViewById(R.id.butFF);
+ txtvFF = root.findViewById(R.id.txtvFF);
+ butSkip = root.findViewById(R.id.butSkip);
+ progressIndicator = root.findViewById(R.id.progLoading);
+
+ setupLengthTextView();
+ setupControlButtons();
+ setupPlaybackSpeedButton();
+ txtvRev.setText(String.valueOf(UserPreferences.getRewindSecs()));
+ txtvFF.setText(String.valueOf(UserPreferences.getFastForwardSecs()));
+ sbPosition.setOnSeekBarChangeListener(this);
+
+ pager = root.findViewById(R.id.pager);
+ AudioPlayerPagerAdapter pagerAdapter = new AudioPlayerPagerAdapter(getFragmentManager());
+ pager.setAdapter(pagerAdapter);
+ // Required for getChildAt(int) in ViewPagerBottomSheetBehavior to return the correct page
+ pager.setOffscreenPageLimit(NUM_CONTENT_FRAGMENTS);
+ pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
+ @Override
+ public void onPageSelected(int position) {
+ pager.post(() -> ((MainActivity) getActivity()).getBottomSheet().updateScrollingChild());
+ }
+ });
+ pageIndicator = root.findViewById(R.id.page_indicator);
+ pageIndicator.setViewPager(pager);
+ pageIndicator.setOnClickListener(v ->
+ pager.setCurrentItem((pager.getCurrentItem() + 1) % pager.getChildCount()));
+ return root;
+ }
+
+ public View getExternalPlayerHolder() {
+ return getView().findViewById(R.id.playerFragment);
+ }
+
+ private void setupControlButtons() {
+ butRev.setOnClickListener(v -> {
+ if (controller != null) {
+ int curr = controller.getPosition();
+ controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000);
+ }
+ });
+ butRev.setOnLongClickListener(v -> {
+ SkipPreferenceDialog.showSkipPreference(getContext(),
+ SkipPreferenceDialog.SkipDirection.SKIP_REWIND, txtvRev);
+ return true;
+ });
+ butPlay.setOnClickListener(v -> {
+ if (controller != null) {
+ controller.init();
+ controller.playPause();
+ }
+ });
+ butFF.setOnClickListener(v -> {
+ if (controller != null) {
+ int curr = controller.getPosition();
+ controller.seekTo(curr + UserPreferences.getFastForwardSecs() * 1000);
+ }
+ });
+ butFF.setOnLongClickListener(v -> {
+ SkipPreferenceDialog.showSkipPreference(getContext(),
+ SkipPreferenceDialog.SkipDirection.SKIP_FORWARD, txtvFF);
+ return false;
+ });
+ butSkip.setOnClickListener(v ->
+ IntentUtils.sendLocalBroadcast(getActivity(), PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
+ }
+
+ private void setupLengthTextView() {
+ SharedPreferences prefs = getContext().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
+ showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false);
+ txtvLength.setOnClickListener(v -> {
+ if (controller == null) {
+ return;
+ }
+ showTimeLeft = !showTimeLeft;
+ prefs.edit().putBoolean(PREF_SHOW_TIME_LEFT, showTimeLeft).apply();
+ updatePosition(new PlaybackPositionEvent(controller.getPosition(), controller.getDuration()));
+ });
+ }
+
+ private void setupPlaybackSpeedButton() {
+ butPlaybackSpeed.setOnClickListener(v -> {
+ if (controller == null) {
+ return;
+ }
+ if (!controller.canSetPlaybackSpeed()) {
+ VariableSpeedDialog.showGetPluginDialog(getContext());
+ return;
+ }
+ float[] availableSpeeds = UserPreferences.getPlaybackSpeedArray();
+ float currentSpeed = controller.getCurrentPlaybackSpeedMultiplier();
+
+ int newSpeedIndex = 0;
+ while (newSpeedIndex < availableSpeeds.length && availableSpeeds[newSpeedIndex] < currentSpeed + EPSILON) {
+ newSpeedIndex++;
+ }
+
+ float newSpeed;
+ if (availableSpeeds.length == 0) {
+ newSpeed = 1.0f;
+ } else if (newSpeedIndex == availableSpeeds.length) {
+ newSpeed = availableSpeeds[0];
+ } else {
+ newSpeed = availableSpeeds[newSpeedIndex];
+ }
+
+ PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(newSpeed);
+ UserPreferences.setPlaybackSpeed(newSpeed);
+ controller.setPlaybackSpeed(newSpeed);
+ updateUi();
+ });
+ butPlaybackSpeed.setOnLongClickListener(v -> {
+ VariableSpeedDialog.showDialog(getContext());
+ return true;
+ });
+ butPlaybackSpeed.setVisibility(View.VISIBLE);
+ txtvPlaybackSpeed.setVisibility(View.VISIBLE);
+ }
+
+ protected void updatePlaybackSpeedButton() {
+ if (butPlaybackSpeed == null || controller == null) {
+ return;
+ }
+ float speed = 1.0f;
+ if (controller.canSetPlaybackSpeed()) {
+ speed = PlaybackSpeedUtils.getCurrentPlaybackSpeed(controller.getMedia());
+ }
+ String speedStr = new DecimalFormat("0.00").format(speed);
+ txtvPlaybackSpeed.setText(speedStr);
+ butPlaybackSpeed.setSpeed(speed);
+ butPlaybackSpeed.setAlpha(controller.canSetPlaybackSpeed() ? 1.0f : 0.5f);
+ butPlaybackSpeed.setVisibility(View.VISIBLE);
+ txtvPlaybackSpeed.setVisibility(View.VISIBLE);
+ }
+
+ private PlaybackController newPlaybackController() {
+ return new PlaybackController(getActivity(), false) {
+
+ @Override
+ public void setupGUI() {
+ updateUi();
+ }
+
+ @Override
+ public void onBufferStart() {
+ progressIndicator.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onBufferEnd() {
+ progressIndicator.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onBufferUpdate(float progress) {
+ sbPosition.setSecondaryProgress((int) (progress * sbPosition.getMax()));
+ }
+
+ @Override
+ public void handleError(int code) {
+ final AlertDialog.Builder errorDialog = new AlertDialog.Builder(getContext());
+ errorDialog.setTitle(R.string.error_label);
+ errorDialog.setMessage(MediaPlayerError.getErrorString(getContext(), code));
+ errorDialog.setNeutralButton(android.R.string.ok,
+ (dialog, which) -> {
+ dialog.dismiss();
+ ((MainActivity) getActivity()).getBottomSheet()
+ .setState(BottomSheetBehavior.STATE_COLLAPSED);
+ }
+ );
+ errorDialog.create().show();
+ }
+
+ @Override
+ public void onSleepTimerUpdate() {
+ setupOptionsMenu();
+ }
+
+ @Override
+ public ImageButton getPlayButton() {
+ return butPlay;
+ }
+
+ @Override
+ public boolean loadMediaInfo() {
+ updateUi();
+ return true;
+ }
+
+ @Override
+ public void onShutdownNotification() {
+ ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED);
+ }
+
+ @Override
+ public void onPlaybackEnd() {
+ ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED);
+ }
+
+ @Override
+ public void onPlaybackSpeedChange() {
+ updatePlaybackSpeedButton();
+ }
+
+ @Override
+ public void onSetSpeedAbilityChanged() {
+ updatePlaybackSpeedButton();
+ }
+ };
+ }
+
+ private void updateUi() {
+ if (controller == null) {
+ return;
+ }
+ updatePosition(new PlaybackPositionEvent(controller.getPosition(), controller.getDuration()));
+ updatePlaybackSpeedButton();
+ setupOptionsMenu();
+
+ if (controller.getMedia() != null) {
+ List<Chapter> chapters = controller.getMedia().getChapters();
+ boolean hasChapters = chapters != null && !chapters.isEmpty();
+ pageIndicator.setDisabledPage(hasChapters ? -1 : 2);
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setRetainInstance(true);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ controller = newPlaybackController();
+ controller.init();
+ updateUi();
+ EventBus.getDefault().register(this);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ controller.release();
+ controller = null;
+ EventBus.getDefault().unregister(this);
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void updatePosition(PlaybackPositionEvent event) {
+ if (controller == null || txtvPosition == null || txtvLength == null || sbPosition == null) {
+ return;
+ }
+
+ TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
+ int currentPosition = converter.convert(event.getPosition());
+ int duration = converter.convert(event.getDuration());
+ int remainingTime = converter.convert(event.getDuration() - event.getPosition());
+ Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition));
+ if (currentPosition == PlaybackService.INVALID_TIME || duration == PlaybackService.INVALID_TIME) {
+ Log.w(TAG, "Could not react to position observer update because of invalid time");
+ return;
+ }
+ txtvPosition.setText(Converter.getDurationStringLong(currentPosition));
+ if (showTimeLeft) {
+ txtvLength.setText("-" + Converter.getDurationStringLong(remainingTime));
+ } else {
+ txtvLength.setText(Converter.getDurationStringLong(duration));
+ }
+ float progress = ((float) event.getPosition()) / event.getDuration();
+ sbPosition.setProgress((int) (progress * sbPosition.getMax()));
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void favoritesChanged(FavoritesEvent event) {
+ setupOptionsMenu();
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (controller == null || txtvLength == null) {
+ return;
+ }
+ if (fromUser) {
+ float prog = progress / ((float) seekBar.getMax());
+ int duration = controller.getDuration();
+ TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
+ int position = converter.convert((int) (prog * duration));
+ txtvPosition.setText(Converter.getDurationStringLong(position));
+
+ if (showTimeLeft && prog != 0) {
+ int timeLeft = converter.convert(duration - (int) (prog * duration));
+ String length = "-" + Converter.getDurationStringLong(timeLeft);
+ txtvLength.setText(length);
+ }
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ // interrupt position Observer, restart later
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ if (controller != null) {
+ float prog = seekBar.getProgress() / ((float) seekBar.getMax());
+ controller.seekTo((int) (prog * controller.getDuration()));
+ }
+ }
+
+ public void setupOptionsMenu() {
+ if (toolbar.getMenu().size() == 0) {
+ toolbar.inflateMenu(R.menu.mediaplayer);
+ }
+ if (controller == null) {
+ return;
+ }
+ Playable media = controller.getMedia();
+ boolean isFeedMedia = media instanceof FeedMedia;
+ toolbar.getMenu().findItem(R.id.open_feed_item).setVisible(isFeedMedia);
+ if (isFeedMedia) {
+ FeedItemMenuHandler.onPrepareMenu(toolbar.getMenu(), ((FeedMedia) media).getItem());
+ }
+
+ toolbar.getMenu().findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive());
+ toolbar.getMenu().findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive());
+
+ ((CastEnabledActivity) getActivity()).requestCastButton(toolbar.getMenu());
+ }
+
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ if (controller == null) {
+ return false;
+ }
+ Playable media = controller.getMedia();
+ if (media == null) {
+ return false;
+ }
+
+ final @Nullable FeedItem feedItem = (media instanceof FeedMedia) ? ((FeedMedia) media).getItem() : null;
+ if (feedItem != null && FeedItemMenuHandler.onMenuItemClicked(this, item.getItemId(), feedItem)) {
+ return true;
+ }
+ switch (item.getItemId()) {
+ case R.id.disable_sleeptimer_item: // Fall-through
+ case R.id.set_sleeptimer_item:
+ new SleepTimerDialog().show(getFragmentManager(), "SleepTimerDialog");
+ return true;
+ case R.id.audio_controls:
+ PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance(false);
+ dialog.show(getFragmentManager(), "playback_controls");
+ return true;
+ case R.id.open_feed_item:
+ if (feedItem != null) {
+ Intent intent = MainActivity.getIntentToOpenFeed(getContext(), feedItem.getFeedId());
+ startActivity(intent);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private static class AudioPlayerPagerAdapter extends FragmentPagerAdapter {
+ private static final String TAG = "AudioPlayerPagerAdapter";
+
+ public AudioPlayerPagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ Log.d(TAG, "getItem(" + position + ")");
+ switch (position) {
+ case POS_COVER:
+ return new CoverFragment();
+ case POS_DESCR:
+ return new ItemDescriptionFragment();
+ case POS_CHAPTERS:
+ return new ChaptersFragment();
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return NUM_CONTENT_FRAGMENTS;
+ }
+ }
+}
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 9940ccbdd..0aba568d1 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -1,24 +1,24 @@
package de.danoeh.antennapod.fragment;
import android.os.Bundle;
-import androidx.fragment.app.ListFragment;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.View;
-import android.widget.ListView;
-
-import de.danoeh.antennapod.core.util.ChapterUtils;
-import java.util.List;
-import java.util.ListIterator;
-
+import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.ChaptersListAdapter;
-import de.danoeh.antennapod.adapter.QueueRecyclerAdapter;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
+import de.danoeh.antennapod.core.util.ChapterUtils;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
-
import de.danoeh.antennapod.view.EmptyViewHandler;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -28,38 +28,43 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
-public class ChaptersFragment extends ListFragment {
+public class ChaptersFragment extends Fragment {
private static final String TAG = "ChaptersFragment";
private ChaptersListAdapter adapter;
private PlaybackController controller;
private Disposable disposable;
private int focusedChapter = -1;
private Playable media;
+ private LinearLayoutManager layoutManager;
+ @Nullable
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- // add padding
- final ListView lv = getListView();
- lv.setClipToPadding(false);
- final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding);
- lv.setPadding(0, vertPadding, 0, vertPadding);
-
- EmptyViewHandler emptyView = new EmptyViewHandler(getContext());
- emptyView.attachToListView(lv);
- emptyView.setIcon(R.attr.ic_bookmark);
- emptyView.setTitle(R.string.no_chapters_head_label);
- emptyView.setMessage(R.string.no_chapters_label);
-
- adapter = new ChaptersListAdapter(getActivity(), 0, pos -> {
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View root = inflater.inflate(R.layout.simple_list_fragment, container, false);
+ root.findViewById(R.id.toolbar).setVisibility(View.GONE);
+ 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 -> {
if (controller.getStatus() != PlayerStatus.PLAYING) {
controller.playPause();
}
- Chapter chapter = (Chapter) getListAdapter().getItem(pos);
+ Chapter chapter = adapter.getItem(pos);
controller.seekToChapter(chapter);
updateChapterSelection(pos);
});
- setListAdapter(adapter);
+ recyclerView.setAdapter(adapter);
+
+ EmptyViewHandler emptyView = new EmptyViewHandler(getContext());
+ emptyView.attachToRecyclerView(recyclerView);
+ emptyView.setIcon(R.attr.ic_bookmark);
+ emptyView.setTitle(R.string.no_chapters_head_label);
+ emptyView.setMessage(R.string.no_chapters_label);
+
+ return root;
}
@Override
@@ -136,7 +141,6 @@ public class ChaptersFragment extends ListFragment {
return;
}
adapter.setMedia(media);
- adapter.notifyDataSetChanged();
int positionOfCurrentChapter = getCurrentChapter(media);
updateChapterSelection(positionOfCurrentChapter);
}
@@ -149,9 +153,9 @@ public class ChaptersFragment extends ListFragment {
if (position != -1 && focusedChapter != position) {
focusedChapter = position;
adapter.notifyChapterChanged(focusedChapter);
- if (getListView().getFirstVisiblePosition() >= position
- || getListView().getLastVisiblePosition() <= position) {
- getListView().setSelectionFromTop(position, 100);
+ if (layoutManager.findFirstCompletelyVisibleItemPosition() >= position
+ || layoutManager.findLastCompletelyVisibleItemPosition() <= position) {
+ layoutManager.scrollToPositionWithOffset(position, 100);
}
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
index ce2232a55..03b1d6f8f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
@@ -1,9 +1,7 @@
package de.danoeh.antennapod.fragment;
import android.content.Intent;
-import android.os.Build;
import android.os.Bundle;
-import androidx.core.app.ActivityOptionsCompat;
import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
@@ -17,7 +15,9 @@ import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
@@ -40,7 +40,6 @@ import org.greenrobot.eventbus.ThreadMode;
public class ExternalPlayerFragment extends Fragment {
public static final String TAG = "ExternalPlayerFragment";
- private ViewGroup fragmentLayout;
private ImageView imgvCover;
private TextView txtvTitle;
private ImageButton butPlay;
@@ -56,26 +55,21 @@ public class ExternalPlayerFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View root = inflater.inflate(R.layout.external_player_fragment,
- container, false);
- fragmentLayout = root.findViewById(R.id.fragmentLayout);
+ View root = inflater.inflate(R.layout.external_player_fragment, container, false);
imgvCover = root.findViewById(R.id.imgvCover);
txtvTitle = root.findViewById(R.id.txtvTitle);
butPlay = root.findViewById(R.id.butPlay);
mFeedName = root.findViewById(R.id.txtvAuthor);
mProgressBar = root.findViewById(R.id.episodeProgress);
- fragmentLayout.setOnClickListener(v -> {
+ root.findViewById(R.id.fragmentLayout).setOnClickListener(v -> {
Log.d(TAG, "layoutInfo was clicked");
if (controller != null && controller.getMedia() != null) {
- Intent intent = PlaybackService.getPlayerActivityIntent(getActivity(), controller.getMedia());
-
if (controller.getMedia().getMediaType() == MediaType.AUDIO) {
- ActivityOptionsCompat options = ActivityOptionsCompat
- .makeSceneTransitionAnimation(getActivity(), imgvCover, "coverTransition");
- startActivity(intent, options.toBundle());
+ ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_EXPANDED);
} else {
+ Intent intent = PlaybackService.getPlayerActivityIntent(getActivity(), controller.getMedia());
startActivity(intent);
}
}
@@ -178,9 +172,7 @@ public class ExternalPlayerFragment extends Fragment {
}
private void playbackDone() {
- if (fragmentLayout != null) {
- fragmentLayout.setVisibility(View.GONE);
- }
+ clearUi();
if (controller != null) {
controller.release();
}
@@ -217,10 +209,22 @@ public class ExternalPlayerFragment extends Fragment {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(media -> updateUi((Playable) media),
error -> Log.e(TAG, Log.getStackTraceString(error)),
- () -> fragmentLayout.setVisibility(View.GONE));
+ this::clearUi);
return true;
}
+ private void clearUi() {
+ if (txtvTitle == null || mFeedName == null || mProgressBar == null || butPlay == null) {
+ return;
+ }
+ txtvTitle.setText(R.string.no_media_playing_label);
+ mFeedName.setText("");
+ butPlay.setVisibility(View.GONE);
+ mProgressBar.setProgress(0);
+ Glide.with(getActivity()).clear(imgvCover);
+ ((MainActivity) getActivity()).getBottomSheet().setLocked(true);
+ }
+
private void updateUi(Playable media) {
if (media != null) {
txtvTitle.setText(media.getEpisodeTitle());
@@ -236,12 +240,13 @@ public class ExternalPlayerFragment extends Fragment {
.fitCenter()
.dontAnimate())
.into(imgvCover);
-
- fragmentLayout.setVisibility(View.VISIBLE);
if (controller != null && controller.isPlayingVideoLocally()) {
butPlay.setVisibility(View.GONE);
+ ((MainActivity) getActivity()).getBottomSheet().setLocked(true);
+ ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED);
} else {
butPlay.setVisibility(View.VISIBLE);
+ ((MainActivity) getActivity()).getBottomSheet().setLocked(false);
}
} else {
Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!");
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 2cddc10cb..23b8b7f19 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
@@ -200,10 +200,10 @@ public class FeedSettingsFragment extends Fragment {
private void setupAuthentificationPreference() {
findPreference("authentication").setOnPreferenceClickListener(preference -> {
new AuthenticationDialog(getContext(),
- R.string.authentication_label, true, false,
+ R.string.authentication_label, true,
feedPreferences.getUsername(), feedPreferences.getPassword()) {
@Override
- protected void onConfirmed(String username, String password, boolean saveUsernamePassword) {
+ protected void onConfirmed(String username, String password) {
feedPreferences.setUsername(username);
feedPreferences.setPassword(password);
feed.savePreferences();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index 256615199..58cc9290c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -10,6 +10,7 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
+import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
import de.danoeh.antennapod.core.util.playback.Timeline;
import de.danoeh.antennapod.view.ShownotesWebView;
@@ -35,7 +36,8 @@ public class ItemDescriptionFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "Creating view");
- webvDescription = new ShownotesWebView(getActivity().getApplicationContext());
+ View root = inflater.inflate(R.layout.item_description_fragment, container, false);
+ webvDescription = root.findViewById(R.id.webview);
webvDescription.setTimecodeSelectedListener(time -> {
if (controller != null) {
controller.seekTo(time);
@@ -46,7 +48,7 @@ public class ItemDescriptionFragment extends Fragment {
webvDescription.postDelayed(ItemDescriptionFragment.this::restoreFromPreference, 50);
});
registerForContextMenu(webvDescription);
- return webvDescription;
+ return root;
}
@Override
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 f251de5ec..aac89a65f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java
@@ -41,16 +41,6 @@ public class ItemPagerFragment extends Fragment {
/**
* Creates a new instance of an ItemPagerFragment.
*
- * @param feeditem The ID of the FeedItem that should be displayed.
- * @return The ItemFragment instance
- */
- public static ItemPagerFragment newInstance(long feeditem) {
- return newInstance(new long[] { feeditem }, 0);
- }
-
- /**
- * Creates a new instance of an ItemPagerFragment.
- *
* @param feeditems The IDs of the FeedItems that belong to the same list
* @param feedItemPos The position of the FeedItem that is currently shown
* @return The ItemFragment instance
@@ -146,9 +136,6 @@ public class ItemPagerFragment extends Fragment {
return;
}
super.onCreateOptionsMenu(menu, inflater);
- if (Flavors.FLAVOR == Flavors.PLAY) {
- ((CastEnabledActivity) getActivity()).requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS);
- }
inflater.inflate(R.menu.feeditem_options, menu);
if (item.hasMedia()) {
FeedItemMenuHandler.onPrepareMenu(menu, item);
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 63969345c..0dff8f24b 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
@@ -48,7 +48,7 @@ import org.greenrobot.eventbus.Subscribe;
import java.util.List;
public class NavDrawerFragment extends Fragment implements AdapterView.OnItemClickListener,
- AdapterView.OnItemLongClickListener {
+ AdapterView.OnItemLongClickListener, SharedPreferences.OnSharedPreferenceChangeListener {
@VisibleForTesting
public static final String PREF_LAST_FRAGMENT_TAG = "prefLastFragmentTag";
@VisibleForTesting
@@ -88,6 +88,8 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
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;
}
@@ -124,6 +126,8 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
if (disposable != null) {
disposable.dispose();
}
+ getContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
+ .unregisterOnSharedPreferenceChangeListener(this);
}
@Override
@@ -192,7 +196,6 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
} else {
showMainActivity(EpisodesFragment.TAG);
}
- saveLastNavFragment(getContext(), EpisodesFragment.TAG);
}
}
};
@@ -371,7 +374,6 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
} else {
showMainActivity(tag);
}
- saveLastNavFragment(getContext(), tag);
} else {
int pos = position - navAdapter.getSubscriptionOffset();
long feedId = navDrawerData.feeds.get(pos).getId();
@@ -382,10 +384,7 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
intent.putExtra(MainActivity.EXTRA_FEED_ID, feedId);
startActivity(intent);
}
- saveLastNavFragment(getContext(), String.valueOf(feedId));
}
- selectedNavListIndex = position;
- navAdapter.notifyDataSetChanged();
}
}
@@ -418,4 +417,12 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
Log.d(TAG, "getLastNavFragment() -> " + lastFragment);
return lastFragment;
}
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (PREF_LAST_FRAGMENT_TAG.equals(key)) {
+ updateSelection();
+ navAdapter.notifyDataSetChanged();
+ }
+ }
}
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 0a752b855..0411fd01b 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -416,11 +416,11 @@ public class QueueFragment extends Fragment {
recyclerAdapter.setLocked(locked);
}
if (locked) {
- Snackbar.make(getActivity().findViewById(R.id.content), R.string
- .queue_locked, Snackbar.LENGTH_SHORT).show();
+ Snackbar.make(getActivity().findViewById(android.R.id.content),
+ R.string.queue_locked, Snackbar.LENGTH_SHORT).show();
} else {
- Snackbar.make(getActivity().findViewById(R.id.content), R.string
- .queue_unlocked, Snackbar.LENGTH_SHORT).show();
+ Snackbar.make(getActivity().findViewById(android.R.id.content),
+ R.string.queue_unlocked, Snackbar.LENGTH_SHORT).show();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
index e34f1ea1c..3ebdd80d8 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.fragment.gpodnet;
-import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -28,7 +27,7 @@ public class GpodnetMainFragment extends Fragment {
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
ViewPager viewPager = root.findViewById(R.id.viewpager);
- GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(getChildFragmentManager(), getResources());
+ GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
@@ -39,18 +38,13 @@ public class GpodnetMainFragment extends Fragment {
}
public class GpodnetPagerAdapter extends FragmentPagerAdapter {
-
-
private static final int NUM_PAGES = 2;
private static final int POS_TOPLIST = 0;
private static final int POS_TAGS = 1;
private static final int POS_SUGGESTIONS = 2;
- final Resources resources;
-
- public GpodnetPagerAdapter(FragmentManager fm, Resources resources) {
+ public GpodnetPagerAdapter(FragmentManager fm) {
super(fm);
- this.resources = resources;
}
@Override
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 1e51380ca..271b31fad 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
@@ -63,11 +63,11 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
findPreference(PREF_GPODNET_SETLOGIN_INFORMATION)
.setOnPreferenceClickListener(preference -> {
AuthenticationDialog dialog = new AuthenticationDialog(activity,
- R.string.pref_gpodnet_setlogin_information_title, false, false, GpodnetPreferences.getUsername(),
+ R.string.pref_gpodnet_setlogin_information_title, false, GpodnetPreferences.getUsername(),
null) {
@Override
- protected void onConfirmed(String username, String password, boolean saveUsernamePassword) {
+ protected void onConfirmed(String username, String password) {
GpodnetPreferences.setPassword(password);
}
};
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
index 1ca8f63aa..f9015c006 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
@@ -96,8 +96,7 @@ public class NetworkPreferencesFragment extends PreferenceFragmentCompat {
private void setParallelDownloadsText(int downloads) {
final Resources res = getActivity().getResources();
- String s = Integer.toString(downloads)
- + res.getString(R.string.parallel_downloads_suffix);
+ String s = downloads + res.getString(R.string.parallel_downloads_suffix);
findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS).setSummary(s);
}
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 34684ac49..6b2255b52 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
@@ -9,11 +9,11 @@ import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.MediaplayerActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
+import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
import de.danoeh.antennapod.preferences.PreferenceControllerFlavorHelper;
import java.util.Map;
@@ -48,11 +48,11 @@ public class PlaybackPreferencesFragment extends PreferenceFragmentCompat {
return true;
});
findPreference(PREF_PLAYBACK_REWIND_DELTA_LAUNCHER).setOnPreferenceClickListener(preference -> {
- MediaplayerActivity.showSkipPreference(activity, MediaplayerActivity.SkipDirection.SKIP_REWIND);
+ SkipPreferenceDialog.showSkipPreference(activity, SkipPreferenceDialog.SkipDirection.SKIP_REWIND, null);
return true;
});
findPreference(PREF_PLAYBACK_FAST_FORWARD_DELTA_LAUNCHER).setOnPreferenceClickListener(preference -> {
- MediaplayerActivity.showSkipPreference(activity, MediaplayerActivity.SkipDirection.SKIP_FORWARD);
+ SkipPreferenceDialog.showSkipPreference(activity, SkipPreferenceDialog.SkipDirection.SKIP_FORWARD, null);
return true;
});
if (!PictureInPictureUtil.supportsPictureInPicture(activity)) {
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 c3611d683..0ea8d5b93 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
@@ -8,7 +8,6 @@ import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.PreferenceFragmentCompat;
import android.widget.ListView;
-import android.widget.Toast;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
@@ -19,7 +18,6 @@ import org.apache.commons.lang3.ArrayUtils;
import java.util.List;
public class UserInterfacePreferencesFragment extends PreferenceFragmentCompat {
- private static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
@@ -59,26 +57,26 @@ public class UserInterfacePreferencesFragment extends PreferenceFragmentCompat {
findPreference(UserPreferences.PREF_BACK_BUTTON_BEHAVIOR)
.setOnPreferenceChangeListener((preference, newValue) -> {
- if (newValue.equals("page")) {
- final Context context = getActivity();
- final String[] navTitles = context.getResources().getStringArray(R.array.back_button_go_to_pages);
- final String[] navTags = context.getResources().getStringArray(R.array.back_button_go_to_pages_tags);
- final String[] choice = { UserPreferences.getBackButtonGoToPage() };
+ if (!newValue.equals("page")) {
+ return true;
+ }
+ final Context context = getActivity();
+ final String[] navTitles = context.getResources().getStringArray(R.array.back_button_go_to_pages);
+ final String[] navTags = context.getResources().getStringArray(R.array.back_button_go_to_pages_tags);
+ final String[] choice = { UserPreferences.getBackButtonGoToPage() };
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.back_button_go_to_page_title);
- builder.setSingleChoiceItems(navTitles, ArrayUtils.indexOf(navTags, UserPreferences.getBackButtonGoToPage()), (dialogInterface, i) -> {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.back_button_go_to_page_title);
+ builder.setSingleChoiceItems(navTitles, ArrayUtils.indexOf(navTags,
+ UserPreferences.getBackButtonGoToPage()), (dialogInterface, i) -> {
if (i >= 0) {
choice[0] = navTags[i];
}
});
- builder.setPositiveButton(R.string.confirm_label, (dialogInterface, i) -> UserPreferences.setBackButtonGoToPage(choice[0]));
- builder.setNegativeButton(R.string.cancel_label, null);
- builder.create().show();
- return true;
- } else {
- return true;
- }
+ builder.setPositiveButton(R.string.confirm_label, (dialogInterface, i) -> UserPreferences.setBackButtonGoToPage(choice[0]));
+ builder.setNegativeButton(R.string.cancel_label, null);
+ builder.create().show();
+ return true;
});
if (Build.VERSION.SDK_INT >= 26) {
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 4d3e1ff72..edd594385 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -41,8 +41,7 @@ public class FeedItemMenuHandler {
* @param selectedItem The FeedItem for which the menu is supposed to be prepared
* @return Returns true if selectedItem is not null.
*/
- public static boolean onPrepareMenu(Menu menu,
- FeedItem selectedItem) {
+ public static boolean onPrepareMenu(Menu menu, FeedItem selectedItem) {
if (menu == null || selectedItem == null) {
return false;
}
@@ -146,15 +145,13 @@ public class FeedItemMenuHandler {
}
/**
- * The same method as onPrepareMenu(MenuInterface, FeedItem, boolean, QueueAccess), but lets the
+ * The same method as {@link #onPrepareMenu(Menu, FeedItem)}, but lets the
* caller also specify a list of menu items that should not be shown.
*
* @param excludeIds Menu item that should be excluded
* @return true if selectedItem is not null.
*/
- public static boolean onPrepareMenu(Menu menu,
- FeedItem selectedItem,
- int... excludeIds) {
+ public static boolean onPrepareMenu(Menu menu, FeedItem selectedItem, int... excludeIds) {
if (menu == null || selectedItem == null ) {
return false;
}
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 5fa6588d9..1f28b5c49 100644
--- a/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java
+++ b/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java
@@ -6,8 +6,6 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
-import org.apache.commons.lang3.Validate;
-
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.receiver.SPAReceiver;
@@ -22,7 +20,6 @@ public class SPAUtil {
private SPAUtil() {
}
-
/**
* Sends an ACTION_SP_APPS_QUERY_FEEDS intent to all AntennaPod Single Purpose apps.
* The receiving single purpose apps will then send their feeds back to AntennaPod via an
@@ -53,17 +50,4 @@ public class SPAUtil {
return false;
}
}
-
- /**
- * Resets all preferences created by this class. Should only be used for debug purposes.
- */
- public static void resetSPAPreferences(Context c) {
- if (BuildConfig.DEBUG) {
- Validate.notNull(c);
- SharedPreferences.Editor editor = PreferenceManager
- .getDefaultSharedPreferences(c.getApplicationContext()).edit();
- editor.putBoolean(PREF_HAS_QUERIED_SP_APPS, false);
- editor.apply();
- }
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java b/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
index f41b036b2..f755a4c84 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
@@ -18,6 +18,7 @@ public class CircularProgressBar extends View {
private float percentage = 0;
private float targetPercentage = 0;
private Object tag = null;
+ private final RectF bounds = new RectF();
public CircularProgressBar(Context context) {
super(context);
@@ -70,7 +71,7 @@ public class CircularProgressBar extends View {
float padding = getHeight() * 0.07f;
paintBackground.setStrokeWidth(getHeight() * 0.02f);
paintProgress.setStrokeWidth(padding);
- RectF bounds = new RectF(padding, padding, getWidth() - padding, getHeight() - padding);
+ bounds.set(padding, padding, getWidth() - padding, getHeight() - padding);
canvas.drawArc(bounds, 0, 360, false, paintBackground);
if (percentage > EPSILON && 1 - percentage > EPSILON) {
diff --git a/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java b/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java
new file mode 100644
index 000000000..8e8d98fc9
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java
@@ -0,0 +1,86 @@
+package de.danoeh.antennapod.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+import com.google.android.material.bottomsheet.ViewPagerBottomSheetBehavior;
+
+/**
+ * Based on https://stackoverflow.com/a/40798214
+ */
+public class LockableBottomSheetBehavior<V extends View> extends ViewPagerBottomSheetBehavior<V> {
+ private boolean isLocked = false;
+
+ public LockableBottomSheetBehavior() {}
+
+ public LockableBottomSheetBehavior(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void setLocked(boolean locked) {
+ isLocked = locked;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
+ boolean handled = false;
+
+ if (!isLocked) {
+ handled = super.onInterceptTouchEvent(parent, child, event);
+ }
+
+ return handled;
+ }
+
+ @Override
+ public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
+ boolean handled = false;
+
+ if (!isLocked) {
+ handled = super.onTouchEvent(parent, child, event);
+ }
+
+ return handled;
+ }
+
+ @Override
+ public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild,
+ View target, int nestedScrollAxes) {
+ boolean handled = false;
+
+ if (!isLocked) {
+ handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
+ }
+
+ return handled;
+ }
+
+ @Override
+ public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target,
+ int dx, int dy, int[] consumed) {
+ if (!isLocked) {
+ super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
+ }
+ }
+
+ @Override
+ public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
+ if (!isLocked) {
+ super.onStopNestedScroll(coordinatorLayout, child, target);
+ }
+ }
+
+ @Override
+ public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target,
+ float velocityX, float velocityY) {
+ boolean handled = false;
+
+ if (!isLocked) {
+ handled = super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
+ }
+
+ return handled;
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/OnSwipeGesture.java b/app/src/main/java/de/danoeh/antennapod/view/OnSwipeGesture.java
deleted file mode 100644
index eb72a7135..000000000
--- a/app/src/main/java/de/danoeh/antennapod/view/OnSwipeGesture.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package de.danoeh.antennapod.view;
-
-public interface OnSwipeGesture {
-
- boolean onSwipeLeftToRight();
-
- boolean onSwipeRightToLeft();
-
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedIndicatorView.java b/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedIndicatorView.java
index d5c4e3c6d..d7f1eac1d 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedIndicatorView.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedIndicatorView.java
@@ -20,10 +20,11 @@ public class PlaybackSpeedIndicatorView extends View {
private final Paint indicatorPaint = new Paint();
private final Path trianglePath = new Path();
private float angle = VALUE_UNSET;
- private float targetAngle = 0.5f;
+ private float targetAngle = VALUE_UNSET;
private float degreePerFrame = 2;
private float paddingArc = 20;
private float paddingIndicator = 10;
+ private RectF arcBounds = new RectF();
public PlaybackSpeedIndicatorView(Context context) {
super(context);
@@ -41,6 +42,9 @@ public class PlaybackSpeedIndicatorView extends View {
}
private void setup() {
+ setSpeed(1.0f); // Set default angle to 1.0
+ targetAngle = VALUE_UNSET; // Do not move to first value that is set externally
+
int[] colorAttrs = new int[] {R.attr.action_icon_color };
TypedArray a = getContext().obtainStyledAttributes(colorAttrs);
arcPaint.setColor(a.getColor(0, 0xffffffff));
@@ -61,10 +65,11 @@ public class PlaybackSpeedIndicatorView extends View {
float maxAnglePerDirection = 90 + 45 - 2 * paddingArc;
// Speed values above 3 are probably not too common. Cap at 3 for better differentiation
float normalizedValue = Math.min(2.5f, value - 0.5f) / 2.5f; // Linear between 0 and 1
- targetAngle = -maxAnglePerDirection + 2 * maxAnglePerDirection * normalizedValue;
- if (angle == VALUE_UNSET) {
- angle = targetAngle;
+ float target = -maxAnglePerDirection + 2 * maxAnglePerDirection * normalizedValue;
+ if (targetAngle == VALUE_UNSET) {
+ angle = target;
}
+ targetAngle = target;
degreePerFrame = Math.abs(targetAngle - angle) / 20;
invalidate();
}
@@ -96,11 +101,11 @@ public class PlaybackSpeedIndicatorView extends View {
canvas.drawPath(trianglePath, indicatorPaint);
arcPaint.setStrokeWidth(getHeight() / 15f);
- RectF arcBounds = new RectF(paddingArc, paddingArc, getWidth() - paddingArc, getHeight() - paddingArc);
+ arcBounds.set(paddingArc, paddingArc, getWidth() - paddingArc, getHeight() - paddingArc);
canvas.drawArc(arcBounds, -180 - 45, 90 + 45 + angle - PADDING_ANGLE, false, arcPaint);
canvas.drawArc(arcBounds, -90 + PADDING_ANGLE + angle, 90 + 45 - PADDING_ANGLE - angle, false, arcPaint);
- if (Math.abs(angle - targetAngle) > 0.5) {
+ if (Math.abs(angle - targetAngle) > 0.5 && targetAngle != VALUE_UNSET) {
angle += Math.signum(targetAngle - angle) * Math.min(degreePerFrame, Math.abs(targetAngle - angle));
invalidate();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java b/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java
index 3ea57eb5e..88efc1f84 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java
@@ -15,11 +15,9 @@ import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import androidx.core.content.ContextCompat;
+import androidx.core.util.Consumer;
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.Consumer;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.NetworkUtils;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/viewholder/DownloadItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/view/viewholder/DownloadItemViewHolder.java
index d48db196f..274dd4ea8 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/viewholder/DownloadItemViewHolder.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/viewholder/DownloadItemViewHolder.java
@@ -11,12 +11,10 @@ import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.joanzapata.iconify.widget.IconTextView;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.view.CircularProgressBar;
public class DownloadItemViewHolder extends RecyclerView.ViewHolder {
public final View secondaryActionButton;
public final ImageView secondaryActionIcon;
- public final CircularProgressBar secondaryActionProgress;
public final IconTextView icon;
public final TextView title;
public final TextView type;
@@ -29,7 +27,6 @@ public class DownloadItemViewHolder extends RecyclerView.ViewHolder {
type = itemView.findViewById(R.id.txtvType);
icon = itemView.findViewById(R.id.txtvIcon);
reason = itemView.findViewById(R.id.txtvReason);
- secondaryActionProgress = itemView.findViewById(R.id.secondaryActionProgress);
secondaryActionButton = itemView.findViewById(R.id.secondaryActionButton);
secondaryActionIcon = itemView.findViewById(R.id.secondaryActionIcon);
title = itemView.findViewById(R.id.txtvTitle);