Extract action button utils/callback into classes
This splits the logic in `ActionButtonUtils` and `DefaultActionButtonCallback` into multiple specialized classes to reduce duplication figuring out which button/action to use while at the same time making each individual button to have a single responsability.
This commit is contained in:
parent
c327fd59c9
commit
1d64057fd4
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue