summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh/antennapod/adapter
diff options
context:
space:
mode:
authorH. Lehmann <ByteHamster@users.noreply.github.com>2019-05-27 22:53:53 +0200
committerGitHub <noreply@github.com>2019-05-27 22:53:53 +0200
commit0e3a0862fef23d3cc64b13f61e30d069a3788632 (patch)
tree041c58656aed9678c59e32bec5a40fc83f64f0aa /app/src/main/java/de/danoeh/antennapod/adapter
parentc327fd59c92992411395bc76586a50b5b2478c93 (diff)
parent2450b0817bbe9f22b811110dae77607048780974 (diff)
downloadAntennaPod-0e3a0862fef23d3cc64b13f61e30d069a3788632.zip
Merge pull request #3160 from andersonvom/refactor-action-button
Refactor action button logic
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/adapter')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonCallback.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java97
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java139
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java24
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/AddToQueueActionButton.java32
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/CancelDownloadActionButton.java44
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java74
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java63
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MarkAsPlayedActionButton.java41
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MobileDownloadHelper.java60
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java63
13 files changed, 391 insertions, 295 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonCallback.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonCallback.java
deleted file mode 100644
index e6b42efcb..000000000
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonCallback.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package de.danoeh.antennapod.adapter;
-
-import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.util.LongList;
-
-interface ActionButtonCallback {
- /** Is called when the action button of a list item has been pressed. */
- void onActionButtonPressed(FeedItem item, LongList queueIds);
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
deleted file mode 100644
index a915692d1..000000000
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package de.danoeh.antennapod.adapter;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.view.View;
-import android.widget.ImageButton;
-
-import org.apache.commons.lang3.Validate;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.storage.DownloadRequester;
-
-/**
- * Utility methods for the action button that is displayed on the right hand side
- * of a listitem.
- */
-class ActionButtonUtils {
-
- private final int[] labels;
- private final TypedArray drawables;
- private final Context context;
-
- public ActionButtonUtils(Context context) {
- Validate.notNull(context);
-
- this.context = context.getApplicationContext();
- drawables = context.obtainStyledAttributes(new int[] {
- R.attr.av_play,
- R.attr.navigation_cancel,
- R.attr.av_download,
- R.attr.av_pause,
- R.attr.navigation_accept,
- R.attr.content_new
- });
- labels = new int[] {
- R.string.play_label,
- R.string.cancel_download_label,
- R.string.download_label,
- R.string.mark_read_label,
- R.string.add_to_queue_label
- };
- }
-
- /**
- * Sets the displayed bitmap and content description of the given
- * action button so that it matches the state of the FeedItem.
- */
- @SuppressWarnings("ResourceType")
- public void configureActionButton(ImageButton butSecondary, FeedItem item, boolean isInQueue) {
- Validate.isTrue(butSecondary != null && item != null, "butSecondary or item was null");
-
- final FeedMedia media = item.getMedia();
- if (media != null) {
- final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media);
- if (!media.isDownloaded()) {
- if (isDownloadingMedia) {
- // item is being downloaded
- butSecondary.setVisibility(View.VISIBLE);
- butSecondary.setImageDrawable(drawables.getDrawable(1));
- butSecondary.setContentDescription(context.getString(labels[1]));
- } else {
- // item is not downloaded and not being downloaded
- if(DefaultActionButtonCallback.userAllowedMobileDownloads() ||
- !DefaultActionButtonCallback.userChoseAddToQueue() || isInQueue) {
- butSecondary.setVisibility(View.VISIBLE);
- butSecondary.setImageDrawable(drawables.getDrawable(2));
- butSecondary.setContentDescription(context.getString(labels[2]));
- } else {
- // mobile download not allowed yet, item is not in queue and user chose add to queue
- butSecondary.setVisibility(View.VISIBLE);
- butSecondary.setImageDrawable(drawables.getDrawable(5));
- butSecondary.setContentDescription(context.getString(labels[4]));
- }
- }
- } else {
- // item is downloaded
- butSecondary.setVisibility(View.VISIBLE);
- if (media.isCurrentlyPlaying()) {
- butSecondary.setImageDrawable(drawables.getDrawable(3));
- } else {
- butSecondary.setImageDrawable(drawables.getDrawable(0));
- }
- butSecondary.setContentDescription(context.getString(labels[0]));
- }
- } else {
- if (item.isPlayed()) {
- butSecondary.setVisibility(View.INVISIBLE);
- } else {
- butSecondary.setVisibility(View.VISIBLE);
- butSecondary.setImageDrawable(drawables.getDrawable(4));
- butSecondary.setContentDescription(context.getString(labels[3]));
- }
- }
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java
index 0b2b81edb..8866d987e 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.adapter;
+import android.content.Context;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
@@ -26,6 +27,7 @@ import java.lang.ref.WeakReference;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.storage.DownloadRequester;
@@ -46,8 +48,6 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
private final WeakReference<MainActivity> mainActivityRef;
private final ItemAccess itemAccess;
- private final ActionButtonCallback actionButtonCallback;
- private final ActionButtonUtils actionButtonUtils;
private final boolean showOnlyNewEpisodes;
private FeedItem selectedItem;
@@ -57,13 +57,10 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
public AllEpisodesRecycleAdapter(MainActivity mainActivity,
ItemAccess itemAccess,
- ActionButtonCallback actionButtonCallback,
boolean showOnlyNewEpisodes) {
super();
this.mainActivityRef = new WeakReference<>(mainActivity);
this.itemAccess = itemAccess;
- this.actionButtonUtils = new ActionButtonUtils(mainActivity);
- this.actionButtonCallback = actionButtonCallback;
this.showOnlyNewEpisodes = showOnlyNewEpisodes;
playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background);
@@ -186,10 +183,11 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
holder.queueStatus.setVisibility(View.INVISIBLE);
}
- actionButtonUtils.configureActionButton(holder.butSecondary, item, isInQueue);
+ ItemActionButton actionButton = ItemActionButton.forItem(item, isInQueue);
+ actionButton.configure(holder.butSecondary, mainActivityRef.get());
+
holder.butSecondary.setFocusable(false);
holder.butSecondary.setTag(item);
- holder.butSecondary.setOnClickListener(secondaryActionListener);
new CoverLoader(mainActivityRef.get())
.withUri(item.getImageLocation())
@@ -215,14 +213,6 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
return itemAccess.getCount();
}
- private final View.OnClickListener secondaryActionListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- FeedItem item = (FeedItem) v.getTag();
- actionButtonCallback.onActionButtonPressed(item, itemAccess.getQueueIds());
- }
- };
-
public class Holder extends RecyclerView.ViewHolder
implements View.OnClickListener,
View.OnCreateContextMenuListener,
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
deleted file mode 100644
index 1286d9dc7..000000000
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package de.danoeh.antennapod.adapter;
-
-import android.content.Context;
-import android.support.annotation.NonNull;
-import android.content.Intent;
-import android.widget.Toast;
-
-import com.afollestad.materialdialogs.MaterialDialog;
-
-import org.apache.commons.lang3.Validate;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
-import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.FeedMedia;
-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.DBTasks;
-import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.storage.DownloadRequestException;
-import de.danoeh.antennapod.core.storage.DownloadRequester;
-import de.danoeh.antennapod.core.util.IntentUtils;
-import de.danoeh.antennapod.core.util.LongList;
-import de.danoeh.antennapod.core.util.NetworkUtils;
-import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
-
-/**
- * Default implementation of an ActionButtonCallback
- */
-public class DefaultActionButtonCallback implements ActionButtonCallback {
-
- private static final String TAG = "DefaultActionButtonCallback";
-
- private final Context context;
-
- private static final int TEN_MINUTES_IN_MILLIS = 60 * 1000 * 10;
-
- // remember timestamp when user allowed downloading via mobile connection
- private static long allowMobileDownloadsTimestamp;
- private static long onlyAddToQueueTimeStamp;
-
- public DefaultActionButtonCallback(Context context) {
- Validate.notNull(context);
- this.context = context;
- }
-
- public static boolean userAllowedMobileDownloads() {
- return System.currentTimeMillis() - allowMobileDownloadsTimestamp < TEN_MINUTES_IN_MILLIS;
- }
-
- public static boolean userChoseAddToQueue() {
- return System.currentTimeMillis() - onlyAddToQueueTimeStamp < TEN_MINUTES_IN_MILLIS;
- }
-
- @Override
- public void onActionButtonPressed(final FeedItem item, final LongList queueIds) {
-
- if (item.hasMedia()) {
- final FeedMedia media = item.getMedia();
- boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
- if (!isDownloading && !media.isDownloaded()) {
- if (NetworkUtils.isDownloadAllowed() || userAllowedMobileDownloads()) {
- try {
- DBTasks.downloadFeedItems(context, item);
- Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
- } catch (DownloadRequestException e) {
- e.printStackTrace();
- DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
- }
- } else if(userChoseAddToQueue() && !queueIds.contains(item.getId())) {
- DBWriter.addQueueItem(context, item);
- Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
- } else {
- confirmMobileDownload(context, item);
- }
- } else if (isDownloading) {
- DownloadRequester.getInstance().cancelDownload(context, media);
- if(UserPreferences.isEnableAutodownload()) {
- DBWriter.setFeedItemAutoDownload(media.getItem(), false);
- Toast.makeText(context, R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_LONG).show();
- } else {
- Toast.makeText(context, R.string.download_canceled_msg, Toast.LENGTH_LONG).show();
- }
- } else { // media is downloaded
- if (media.isCurrentlyPlaying()) {
- new PlaybackServiceStarter(context, media)
- .startWhenPrepared(true)
- .shouldStream(false)
- .start();
- IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
- } else if (media.isCurrentlyPaused()) {
- new PlaybackServiceStarter(context, media)
- .startWhenPrepared(true)
- .shouldStream(false)
- .start();
- IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_RESUME_PLAY_CURRENT_EPISODE);
- } else {
- DBTasks.playMedia(context, media, false, true, false);
- }
- }
- } else {
- if (!item.isPlayed()) {
- DBWriter.markItemPlayed(item, FeedItem.PLAYED, true);
- }
- }
- }
-
- private void confirmMobileDownload(final Context context, final FeedItem item) {
- MaterialDialog.Builder builder = new MaterialDialog.Builder(context);
- builder
- .title(R.string.confirm_mobile_download_dialog_title)
- .content(R.string.confirm_mobile_download_dialog_message)
- .positiveText(context.getText(R.string.confirm_mobile_download_dialog_enable_temporarily))
- .onPositive((dialog, which) -> {
- allowMobileDownloadsTimestamp = System.currentTimeMillis();
- try {
- DBTasks.downloadFeedItems(context, item);
- Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
- } catch (DownloadRequestException e) {
- e.printStackTrace();
- DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
- }
- });
- LongList queueIds = DBReader.getQueueIDList();
- if(!queueIds.contains(item.getId())) {
- builder
- .content(R.string.confirm_mobile_download_dialog_message_not_in_queue)
- .neutralText(R.string.confirm_mobile_download_dialog_only_add_to_queue)
- .onNeutral((dialog, which) -> {
- onlyAddToQueueTimeStamp = System.currentTimeMillis();
- DBWriter.addQueueItem(context, item);
- Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
- });
- }
- builder.show();
- }
-
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
index 738a0a636..a365b1b2e 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
@@ -7,7 +7,6 @@ import android.support.v4.content.ContextCompat;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.BaseAdapter;
@@ -18,6 +17,7 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
@@ -31,14 +31,12 @@ import de.danoeh.antennapod.core.util.ThemeUtils;
*/
public class FeedItemlistAdapter extends BaseAdapter {
- private final ActionButtonCallback callback;
private final ItemAccess itemAccess;
private final Context context;
private final boolean showFeedtitle;
private final int selectedItemIndex;
/** true if played items should be made partially transparent */
private final boolean makePlayedItemsTransparent;
- private final ActionButtonUtils actionButtonUtils;
private static final int SELECTION_NONE = -1;
@@ -47,16 +45,13 @@ public class FeedItemlistAdapter extends BaseAdapter {
public FeedItemlistAdapter(Context context,
ItemAccess itemAccess,
- ActionButtonCallback callback,
boolean showFeedtitle,
boolean makePlayedItemsTransparent) {
super();
- this.callback = callback;
this.context = context;
this.itemAccess = itemAccess;
this.showFeedtitle = showFeedtitle;
this.selectedItemIndex = SELECTION_NONE;
- this.actionButtonUtils = new ActionButtonUtils(context);
this.makePlayedItemsTransparent = makePlayedItemsTransparent;
playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background);
@@ -199,10 +194,11 @@ public class FeedItemlistAdapter extends BaseAdapter {
}
}
- actionButtonUtils.configureActionButton(holder.butAction, item, isInQueue);
+ ItemActionButton actionButton = ItemActionButton.forItem(item, isInQueue);
+ actionButton.configure(holder.butAction, context);
+
holder.butAction.setFocusable(false);
holder.butAction.setTag(item);
- holder.butAction.setOnClickListener(butActionListener);
} else {
convertView.setVisibility(View.GONE);
@@ -210,14 +206,6 @@ public class FeedItemlistAdapter extends BaseAdapter {
return convertView;
}
- private final OnClickListener butActionListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- FeedItem item = (FeedItem) v.getTag();
- callback.onActionButtonPressed(item, itemAccess.getQueueIds());
- }
- };
-
static class Holder {
LinearLayout container;
TextView title;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
index df8cafb9d..d9d54ac15 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.adapter;
+import android.content.Context;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
@@ -22,8 +23,6 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.request.RequestOptions;
import com.joanzapata.iconify.Iconify;
import org.apache.commons.lang3.ArrayUtils;
@@ -32,9 +31,9 @@ import java.lang.ref.WeakReference;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
@@ -54,8 +53,6 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
private final WeakReference<MainActivity> mainActivity;
private final ItemAccess itemAccess;
- private final ActionButtonCallback actionButtonCallback;
- private final ActionButtonUtils actionButtonUtils;
private final ItemTouchHelper itemTouchHelper;
private boolean locked;
@@ -67,13 +64,10 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
public QueueRecyclerAdapter(MainActivity mainActivity,
ItemAccess itemAccess,
- ActionButtonCallback actionButtonCallback,
ItemTouchHelper itemTouchHelper) {
super();
this.mainActivity = new WeakReference<>(mainActivity);
this.itemAccess = itemAccess;
- this.actionButtonUtils = new ActionButtonUtils(mainActivity);
- this.actionButtonCallback = actionButtonCallback;
this.itemTouchHelper = itemTouchHelper;
locked = UserPreferences.isQueueLocked();
@@ -287,10 +281,11 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
}
}
- actionButtonUtils.configureActionButton(butSecondary, item, true);
+ ItemActionButton actionButton = ItemActionButton.forItem(item, true);
+ actionButton.configure(butSecondary, mainActivity.get());
+
butSecondary.setFocusable(false);
butSecondary.setTag(item);
- butSecondary.setOnClickListener(secondaryActionListener);
new CoverLoader(mainActivity.get())
.withUri(item.getImageLocation())
@@ -302,15 +297,6 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
}
- private final View.OnClickListener secondaryActionListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- FeedItem item = (FeedItem) v.getTag();
- actionButtonCallback.onActionButtonPressed(item, itemAccess.getQueueIds());
- }
- };
-
-
public interface ItemAccess {
FeedItem getItem(int position);
int getCount();
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/AddToQueueActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/AddToQueueActionButton.java
new file mode 100644
index 000000000..3299db3ab
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/AddToQueueActionButton.java
@@ -0,0 +1,32 @@
+package de.danoeh.antennapod.adapter.actionbutton;
+
+import android.content.Context;
+import android.support.annotation.AttrRes;
+import android.support.annotation.StringRes;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedItem;
+
+class AddToQueueActionButton extends ItemActionButton {
+
+ AddToQueueActionButton(FeedItem item) {
+ super(item);
+ }
+
+ @Override
+ @StringRes
+ public int getLabel() {
+ return R.string.add_to_queue_label;
+ }
+
+ @Override
+ @AttrRes
+ public int getDrawable() {
+ return R.attr.content_new;
+ }
+
+ @Override
+ public void onClick(Context context) {
+ MobileDownloadHelper.confirmMobileDownload(context, item);
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/CancelDownloadActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/CancelDownloadActionButton.java
new file mode 100644
index 000000000..1275a799b
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/CancelDownloadActionButton.java
@@ -0,0 +1,44 @@
+package de.danoeh.antennapod.adapter.actionbutton;
+
+import android.content.Context;
+import android.support.annotation.AttrRes;
+import android.support.annotation.StringRes;
+import android.widget.Toast;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.storage.DownloadRequester;
+
+class CancelDownloadActionButton extends ItemActionButton {
+
+ CancelDownloadActionButton(FeedItem item) {
+ super(item);
+ }
+
+ @Override
+ @StringRes
+ public int getLabel() {
+ return R.string.cancel_download_label;
+ }
+
+ @Override
+ @AttrRes
+ public int getDrawable() {
+ return R.attr.navigation_cancel;
+ }
+
+ @Override
+ public void onClick(Context context) {
+ FeedMedia media = item.getMedia();
+ DownloadRequester.getInstance().cancelDownload(context, media);
+ if (UserPreferences.isEnableAutodownload()) {
+ DBWriter.setFeedItemAutoDownload(media.getItem(), false);
+ Toast.makeText(context, R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_LONG).show();
+ } else {
+ Toast.makeText(context, R.string.download_canceled_msg, Toast.LENGTH_LONG).show();
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java
new file mode 100644
index 000000000..202a41161
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java
@@ -0,0 +1,74 @@
+package de.danoeh.antennapod.adapter.actionbutton;
+
+import android.content.Context;
+import android.support.annotation.AttrRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
+import android.widget.Toast;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.storage.DBTasks;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.storage.DownloadRequestException;
+import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.util.NetworkUtils;
+
+class DownloadActionButton extends ItemActionButton {
+ private boolean isInQueue;
+
+ DownloadActionButton(FeedItem item, boolean isInQueue) {
+ super(item);
+ this.isInQueue = isInQueue;
+ }
+
+ @Override
+ @StringRes
+ public int getLabel() {
+ return R.string.download_label;
+ }
+
+ @Override
+ @AttrRes
+ public int getDrawable() {
+ return R.attr.av_download;
+ }
+
+ @Override
+ public void onClick(Context context) {
+ final FeedMedia media = item.getMedia();
+ if (media == null || shouldNotDownload(media)) {
+ return;
+ }
+
+ if (NetworkUtils.isDownloadAllowed() || MobileDownloadHelper.userAllowedMobileDownloads()) {
+ downloadEpisode(context);
+ } else if (MobileDownloadHelper.userChoseAddToQueue() && !isInQueue) {
+ addEpisodeToQueue(context);
+ } else {
+ MobileDownloadHelper.confirmMobileDownload(context, item);
+ }
+ }
+
+ private boolean shouldNotDownload(@NonNull FeedMedia media) {
+ boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
+ return isDownloading || media.isDownloaded();
+ }
+
+ private void addEpisodeToQueue(Context context) {
+ DBWriter.addQueueItem(context, item);
+ Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
+ }
+
+ private void downloadEpisode(Context context) {
+ try {
+ DBTasks.downloadFeedItems(context, item);
+ Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java
new file mode 100644
index 000000000..da5ebf6e1
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java
@@ -0,0 +1,63 @@
+package de.danoeh.antennapod.adapter.actionbutton;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.annotation.AttrRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
+import android.view.View;
+import android.widget.ImageButton;
+
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.storage.DownloadRequester;
+
+public abstract class ItemActionButton {
+ FeedItem item;
+
+ ItemActionButton(FeedItem item) {
+ this.item = item;
+ }
+
+ @StringRes
+ abstract public int getLabel();
+
+ @AttrRes
+ abstract public int getDrawable();
+
+ abstract public void onClick(Context context);
+
+ public int getVisibility() {
+ return View.VISIBLE;
+ }
+
+ @NonNull
+ public static ItemActionButton forItem(@NonNull FeedItem item, boolean isInQueue) {
+ final FeedMedia media = item.getMedia();
+ if (media == null) {
+ return new MarkAsPlayedActionButton(item);
+ }
+
+ final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media);
+ if (media.isDownloaded()) {
+ return new PlayActionButton(item);
+ } else if (isDownloadingMedia) {
+ return new CancelDownloadActionButton(item);
+ } else if (MobileDownloadHelper.userAllowedMobileDownloads() || !MobileDownloadHelper.userChoseAddToQueue() || isInQueue) {
+ return new DownloadActionButton(item, isInQueue);
+ } else {
+ return new AddToQueueActionButton(item);
+ }
+ }
+
+ public void configure(@NonNull ImageButton button, Context context) {
+ TypedArray drawables = context.obtainStyledAttributes(new int[]{getDrawable()});
+
+ button.setVisibility(getVisibility());
+ button.setContentDescription(context.getString(getLabel()));
+ button.setImageDrawable(drawables.getDrawable(0));
+ button.setOnClickListener((view) -> onClick(context));
+
+ drawables.recycle();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MarkAsPlayedActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MarkAsPlayedActionButton.java
new file mode 100644
index 000000000..4d906cee5
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MarkAsPlayedActionButton.java
@@ -0,0 +1,41 @@
+package de.danoeh.antennapod.adapter.actionbutton;
+
+import android.content.Context;
+import android.support.annotation.AttrRes;
+import android.support.annotation.StringRes;
+import android.view.View;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.storage.DBWriter;
+
+class MarkAsPlayedActionButton extends ItemActionButton {
+
+ MarkAsPlayedActionButton(FeedItem item) {
+ super(item);
+ }
+
+ @Override
+ @StringRes
+ public int getLabel() {
+ return R.string.mark_read_label;
+ }
+
+ @Override
+ @AttrRes
+ public int getDrawable() {
+ return R.attr.navigation_accept;
+ }
+
+ @Override
+ public void onClick(Context context) {
+ if (!item.isPlayed()) {
+ DBWriter.markItemPlayed(item, FeedItem.PLAYED, true);
+ }
+ }
+
+ @Override
+ public int getVisibility() {
+ return (item.isPlayed()) ? View.INVISIBLE : View.VISIBLE;
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MobileDownloadHelper.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MobileDownloadHelper.java
new file mode 100644
index 000000000..f8d2a139e
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MobileDownloadHelper.java
@@ -0,0 +1,60 @@
+package de.danoeh.antennapod.adapter.actionbutton;
+
+import android.content.Context;
+import android.widget.Toast;
+
+import com.afollestad.materialdialogs.MaterialDialog;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBTasks;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.storage.DownloadRequestException;
+
+class MobileDownloadHelper {
+ private static long addToQueueTimestamp;
+ private static long allowMobileDownloadTimestamp;
+ private static final int TEN_MINUTES_IN_MILLIS = 10 * 60 * 1000;
+
+ static boolean userChoseAddToQueue() {
+ return System.currentTimeMillis() - addToQueueTimestamp < TEN_MINUTES_IN_MILLIS;
+ }
+
+ static boolean userAllowedMobileDownloads() {
+ return System.currentTimeMillis() - allowMobileDownloadTimestamp < TEN_MINUTES_IN_MILLIS;
+ }
+
+ static void confirmMobileDownload(final Context context, final FeedItem item) {
+ MaterialDialog.Builder builder = new MaterialDialog.Builder(context)
+ .title(R.string.confirm_mobile_download_dialog_title)
+ .content(R.string.confirm_mobile_download_dialog_message)
+ .positiveText(context.getText(R.string.confirm_mobile_download_dialog_enable_temporarily))
+ .onPositive((dialog, which) -> downloadFeedItems(context, item));
+ if (!DBReader.getQueueIDList().contains(item.getId())) {
+ builder
+ .content(R.string.confirm_mobile_download_dialog_message_not_in_queue)
+ .neutralText(R.string.confirm_mobile_download_dialog_only_add_to_queue)
+ .onNeutral((dialog, which) -> addToQueue(context, item));
+ }
+ builder.show();
+ }
+
+ private static void addToQueue(Context context, FeedItem item) {
+ addToQueueTimestamp = System.currentTimeMillis();
+ DBWriter.addQueueItem(context, item);
+ Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
+ }
+
+ private static void downloadFeedItems(Context context, FeedItem item) {
+ allowMobileDownloadTimestamp = System.currentTimeMillis();
+ try {
+ DBTasks.downloadFeedItems(context, item);
+ Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java
new file mode 100644
index 000000000..3992c7240
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java
@@ -0,0 +1,63 @@
+package de.danoeh.antennapod.adapter.actionbutton;
+
+import android.content.Context;
+import android.support.annotation.AttrRes;
+import android.support.annotation.StringRes;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.storage.DBTasks;
+import de.danoeh.antennapod.core.util.IntentUtils;
+import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
+
+import static de.danoeh.antennapod.core.service.playback.PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE;
+import static de.danoeh.antennapod.core.service.playback.PlaybackService.ACTION_RESUME_PLAY_CURRENT_EPISODE;
+
+class PlayActionButton extends ItemActionButton {
+
+ PlayActionButton(FeedItem item) {
+ super(item);
+ }
+
+ @Override
+ @StringRes
+ public int getLabel() {
+ return R.string.play_label;
+ }
+
+ @Override
+ @AttrRes
+ public int getDrawable() {
+ FeedMedia media = item.getMedia();
+ if (media != null && media.isCurrentlyPlaying()) {
+ return R.attr.av_pause;
+ } else {
+ return R.attr.av_play;
+ }
+ }
+
+ @Override
+ public void onClick(Context context) {
+ FeedMedia media = item.getMedia();
+ if (media == null) {
+ return;
+ }
+
+ if (media.isPlaying()) {
+ togglePlayPause(context, media);
+ } else {
+ DBTasks.playMedia(context, media, false, true, false);
+ }
+ }
+
+ private void togglePlayPause(Context context, FeedMedia media) {
+ new PlaybackServiceStarter(context, media)
+ .startWhenPrepared(true)
+ .shouldStream(false)
+ .start();
+
+ String pauseOrResume = media.isCurrentlyPlaying() ? ACTION_PAUSE_PLAY_CURRENT_EPISODE : ACTION_RESUME_PLAY_CURRENT_EPISODE;
+ IntentUtils.sendLocalBroadcast(context, pauseOrResume);
+ }
+}