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); + } +}