summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh/antennapod/adapter
diff options
context:
space:
mode:
authorTom Hennen <TomHennen@users.noreply.github.com>2015-06-16 20:17:04 -0400
committerTom Hennen <TomHennen@users.noreply.github.com>2015-06-16 20:17:04 -0400
commitec4ed747b6de9ab98d3ad31a0256a77b8e8cc25c (patch)
tree7dfa03fff2e7a7a9fc0d32b74e313668e9b6bcb2 /app/src/main/java/de/danoeh/antennapod/adapter
parentf88c80cced6c3b529a6ef1addafaa930fb41d58f (diff)
parent3d102449bc2bf78b6c5645ee738e6658c9cb155f (diff)
downloadAntennaPod-ec4ed747b6de9ab98d3ad31a0256a77b8e8cc25c.zip
Merge pull request #881 from AntennaPod/develop1.2
Release of 1.2
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/adapter')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java40
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java)46
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java103
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java102
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java50
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java177
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java18
7 files changed, 420 insertions, 116 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
index 8d3e73429..8e347a819 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
@@ -10,7 +10,9 @@ 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.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.util.LongList;
/**
* Utility methods for the action button that is displayed on the right hand side
@@ -26,9 +28,21 @@ public class ActionButtonUtils {
Validate.notNull(context);
this.context = context;
- 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});
- labels = new int[]{R.string.play_label, R.string.cancel_download_label, R.string.download_label, R.string.mark_read_label};
+ 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
+ };
}
/**
@@ -50,18 +64,26 @@ public class ActionButtonUtils {
butSecondary.setContentDescription(context.getString(labels[1]));
} else {
// item is not downloaded and not being downloaded
- butSecondary.setVisibility(View.VISIBLE);
- butSecondary.setImageDrawable(drawables.getDrawable(2));
- butSecondary.setContentDescription(context.getString(labels[2]));
+ LongList queueIds = DBReader.getQueueIDList(context);
+ if(DefaultActionButtonCallback.userAllowedMobileDownloads() ||
+ !DefaultActionButtonCallback.userChoseAddToQueue() || queueIds.contains(item.getId())) {
+ 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 not being downloaded
+ // item is downloaded
butSecondary.setVisibility(View.VISIBLE);
if (media.isCurrentlyPlaying()) {
butSecondary.setImageDrawable(drawables.getDrawable(3));
} else {
- butSecondary
- .setImageDrawable(drawables.getDrawable(0));
+ butSecondary.setImageDrawable(drawables.getDrawable(0));
}
butSecondary.setContentDescription(context.getString(labels[0]));
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java
index 1f98ec158..d96326053 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java
@@ -22,19 +22,22 @@ import de.danoeh.antennapod.core.util.Converter;
/**
* List adapter for the list of new episodes
*/
-public class NewEpisodesListAdapter extends BaseAdapter {
+public class AllEpisodesListAdapter extends BaseAdapter {
private final Context context;
private final ItemAccess itemAccess;
private final ActionButtonCallback actionButtonCallback;
private final ActionButtonUtils actionButtonUtils;
+ private final boolean showOnlyNewEpisodes;
- public NewEpisodesListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) {
+ public AllEpisodesListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback,
+ boolean showOnlyNewEpisodes) {
super();
this.context = context;
this.itemAccess = itemAccess;
this.actionButtonUtils = new ActionButtonUtils(context);
this.actionButtonCallback = actionButtonCallback;
+ this.showOnlyNewEpisodes = showOnlyNewEpisodes;
}
@Override
@@ -77,8 +80,8 @@ public class NewEpisodesListAdapter extends BaseAdapter {
.findViewById(R.id.butSecondaryAction);
holder.queueStatus = (ImageView) convertView
.findViewById(R.id.imgvInPlaylist);
- holder.downloadProgress = (ProgressBar) convertView
- .findViewById(R.id.pbar_download_progress);
+ holder.progress = (ProgressBar) convertView
+ .findViewById(R.id.pbar_progress);
holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
holder.txtvDuration = (TextView) convertView.findViewById(R.id.txtvDuration);
convertView.setTag(holder);
@@ -88,7 +91,7 @@ public class NewEpisodesListAdapter extends BaseAdapter {
holder.title.setText(item.getTitle());
holder.pubDate.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL));
- if (item.isRead()) {
+ if (showOnlyNewEpisodes || item.isRead() || false == itemAccess.isNew(item)) {
holder.statusUnread.setVisibility(View.INVISIBLE);
} else {
holder.statusUnread.setVisibility(View.VISIBLE);
@@ -106,23 +109,27 @@ public class NewEpisodesListAdapter extends BaseAdapter {
holder.txtvDuration.setText("");
}
+ FeedItem.State state = item.getState();
if (isDownloadingMedia) {
- holder.downloadProgress.setVisibility(View.VISIBLE);
- holder.txtvDuration.setVisibility(View.GONE);
- holder.pubDate.setVisibility(View.GONE);
+ holder.progress.setVisibility(View.VISIBLE);
+ // item is being downloaded
+ holder.progress.setProgress(itemAccess.getItemDownloadProgressPercent(item));
+ } else if (state == FeedItem.State.PLAYING
+ || state == FeedItem.State.IN_PROGRESS) {
+ if (media.getDuration() > 0) {
+ int progress = (int) (100.0 * media.getPosition() / media.getDuration());
+ holder.progress.setProgress(progress);
+ holder.progress.setVisibility(View.VISIBLE);
+ }
} else {
- holder.txtvDuration.setVisibility(View.VISIBLE);
- holder.pubDate.setVisibility(View.VISIBLE);
- holder.downloadProgress.setVisibility(View.GONE);
+ holder.progress.setVisibility(View.GONE);
}
- if (!media.isDownloaded()) {
- if (isDownloadingMedia) {
- // item is being downloaded
- holder.downloadProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item));
- }
- }
+ } else {
+ holder.progress.setVisibility(View.GONE);
+ holder.txtvDuration.setVisibility(View.GONE);
}
+
if (itemAccess.isInQueue(item)) {
holder.queueStatus.setVisibility(View.VISIBLE);
} else {
@@ -157,7 +164,7 @@ public class NewEpisodesListAdapter extends BaseAdapter {
View statusUnread;
ImageView queueStatus;
ImageView imageView;
- ProgressBar downloadProgress;
+ ProgressBar progress;
TextView txtvDuration;
ImageButton butSecondary;
}
@@ -171,5 +178,8 @@ public class NewEpisodesListAdapter extends BaseAdapter {
int getItemDownloadProgressPercent(FeedItem item);
boolean isInQueue(FeedItem item);
+
+ boolean isNew(FeedItem item);
+
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
index 14644dd68..223fe17f6 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
@@ -1,6 +1,8 @@
package de.danoeh.antennapod.adapter;
+import android.app.AlertDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.widget.Toast;
@@ -10,43 +12,77 @@ 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.gpoddernet.model.GpodnetEpisodeAction;
+import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
+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.LongList;
+import de.danoeh.antennapod.core.util.NetworkUtils;
/**
* 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) {
-
if (item.hasMedia()) {
final FeedMedia media = item.getMedia();
boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
if (!isDownloading && !media.isDownloaded()) {
- 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(context);
+ if (NetworkUtils.isDownloadAllowed(context) || 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.getId());
+ 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);
- Toast.makeText(context, R.string.download_cancelled_msg, Toast.LENGTH_SHORT).show();
+ if(UserPreferences.isEnableAutodownload()) {
+ DBWriter.setFeedItemAutoDownload(context, 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 (item.hasMedia() && item.getMedia().isCurrentlyPlaying()) {
context.sendBroadcast(new Intent(PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE));
@@ -61,7 +97,58 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
} else {
if (!item.isRead()) {
DBWriter.markItemRead(context, item, true, true);
+
+ if(GpodnetPreferences.loggedIn()) {
+ // gpodder: send played action
+ FeedMedia media = item.getMedia();
+ GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, GpodnetEpisodeAction.Action.PLAY)
+ .currentDeviceId()
+ .currentTimestamp()
+ .started(media.getDuration() / 1000)
+ .position(media.getDuration() / 1000)
+ .total(media.getDuration() / 1000)
+ .build();
+ GpodnetPreferences.enqueueEpisodeAction(action);
+ }
}
}
}
+
+ private void confirmMobileDownload(final Context context, final FeedItem item) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder
+ .setTitle(R.string.confirm_mobile_download_dialog_title)
+ .setMessage(context.getText(R.string.confirm_mobile_download_dialog_message))
+ .setPositiveButton(context.getText(R.string.confirm_mobile_download_dialog_enable_temporarily),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int 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(context);
+ if(!queueIds.contains(item.getId())) {
+ builder.setNeutralButton(context.getText(R.string.confirm_mobile_download_dialog_only_add_to_queue),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onlyAddToQueueTimeStamp = System.currentTimeMillis();
+ DBWriter.addQueueItem(context, item.getId());
+ Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
+ }
+ })
+ .setMessage(context.getText(R.string.confirm_mobile_download_dialog_message_not_in_queue));
+ } else {
+ builder.setMessage(context.getText(R.string.confirm_mobile_download_dialog_message));
+ }
+ builder.create()
+ .show();
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
index f982e86ce..f29cfdf2f 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
@@ -2,20 +2,34 @@ package de.danoeh.antennapod.adapter;
import android.content.Context;
import android.text.format.DateUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import android.widget.Button;
import android.widget.TextView;
+import android.widget.Toast;
+
+import com.joanzapata.android.iconify.Iconify;
+
+import java.util.Date;
+
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBTasks;
+import de.danoeh.antennapod.core.storage.DownloadRequestException;
/** Displays a list of DownloadStatus entries. */
public class DownloadLogAdapter extends BaseAdapter {
+ private final String TAG = "DownloadLogAdapter";
+
private Context context;
private ItemAccess itemAccess;
@@ -35,11 +49,11 @@ public class DownloadLogAdapter extends BaseAdapter {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.downloadlog_item, parent, false);
+ holder.icon = (TextView) convertView.findViewById(R.id.txtvIcon);
+ holder.retry = (Button) convertView.findViewById(R.id.btnRetry);
+ holder.date = (TextView) convertView.findViewById(R.id.txtvDate);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.type = (TextView) convertView.findViewById(R.id.txtvType);
- holder.date = (TextView) convertView.findViewById(R.id.txtvDate);
- holder.successful = (TextView) convertView
- .findViewById(R.id.txtvStatus);
holder.reason = (TextView) convertView
.findViewById(R.id.txtvReason);
convertView.setTag(holder);
@@ -62,33 +76,99 @@ public class DownloadLogAdapter extends BaseAdapter {
status.getCompletionDate().getTime(),
System.currentTimeMillis(), 0, 0));
if (status.isSuccessful()) {
- holder.successful.setTextColor(convertView.getResources().getColor(
+ holder.icon.setTextColor(convertView.getResources().getColor(
R.color.download_success_green));
- holder.successful.setText(R.string.download_successful);
+ holder.icon.setText("{fa-check-circle}");
+ Iconify.addIcons(holder.icon);
+ holder.retry.setVisibility(View.GONE);
holder.reason.setVisibility(View.GONE);
} else {
- holder.successful.setTextColor(convertView.getResources().getColor(
+ holder.icon.setTextColor(convertView.getResources().getColor(
R.color.download_failed_red));
- holder.successful.setText(R.string.download_failed);
+ holder.icon.setText("{fa-times-circle}");
+ Iconify.addIcons(holder.icon);
String reasonText = status.getReason().getErrorString(context);
if (status.getReasonDetailed() != null) {
reasonText += ": " + status.getReasonDetailed();
}
holder.reason.setText(reasonText);
holder.reason.setVisibility(View.VISIBLE);
+ if(status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE &&
+ !newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
+ holder.retry.setVisibility(View.VISIBLE);
+ holder.retry.setText("{fa-repeat}");
+ Iconify.addIcons(holder.retry);
+ holder.retry.setOnClickListener(clickListener);
+ ButtonHolder btnHolder;
+ if(holder.retry.getTag() != null) {
+ btnHolder = (ButtonHolder) holder.retry.getTag();
+ } else {
+ btnHolder = new ButtonHolder();
+ }
+ btnHolder.typeId = status.getFeedfileType();
+ btnHolder.id = status.getFeedfileId();
+ holder.retry.setTag(btnHolder);
+ } else {
+ holder.retry.setVisibility(View.GONE);
+ holder.retry.setOnClickListener(null);
+ holder.retry.setTag(null);
+ }
}
return convertView;
}
+ private final View.OnClickListener clickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ ButtonHolder holder = (ButtonHolder) v.getTag();
+ if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
+ Feed feed = DBReader.getFeed(context, holder.id);
+ feed.setLastUpdate(new Date(0)); // force refresh
+ try {
+ DBTasks.refreshFeed(context, feed);
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ }
+ } else if(holder.typeId == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
+ FeedMedia media = DBReader.getFeedMedia(context, holder.id);
+ try {
+ DBTasks.downloadFeedItems(context, media.getItem());
+ Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
+ }
+ } else {
+ Log.wtf(TAG, "Unexpected type id: " + holder.typeId);
+ }
+ v.setVisibility(View.GONE);
+ }
+ };
+
+ private boolean newerWasSuccessful(int position, int feedTypeId, long id) {
+ for (int i = 0; i < position; i++) {
+ DownloadStatus status = getItem(i);
+ if (status.getFeedfileType() == feedTypeId && status.getFeedfileId() == id &&
+ status.isSuccessful()) return true;
+ }
+ return false;
+ }
+
static class Holder {
+ TextView icon;
+ Button retry;
TextView title;
TextView type;
TextView date;
- TextView successful;
TextView reason;
}
+ static class ButtonHolder {
+ int typeId;
+ long id;
+ }
+
@Override
public int getCount() {
return itemAccess.getCount();
@@ -104,9 +184,9 @@ public class DownloadLogAdapter extends BaseAdapter {
return position;
}
- public static interface ItemAccess {
- public int getCount();
- public DownloadStatus getItem(int position);
+ public interface ItemAccess {
+ int getCount();
+ DownloadStatus getItem(int position);
}
}
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 d56bfc587..b39e23d42 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
@@ -7,9 +7,16 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.widget.*;
+import android.widget.Adapter;
+import android.widget.BaseAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.nineoldandroids.view.ViewHelper;
+
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
@@ -105,22 +112,15 @@ public class FeedItemlistAdapter extends BaseAdapter {
}
holder.title.setText(buffer.toString());
- FeedItem.State state = item.getState();
- switch (state) {
- case PLAYING:
- holder.statusUnread.setVisibility(View.INVISIBLE);
- holder.episodeProgress.setVisibility(View.VISIBLE);
- break;
- case IN_PROGRESS:
- holder.statusUnread.setVisibility(View.INVISIBLE);
- holder.episodeProgress.setVisibility(View.VISIBLE);
- break;
- case NEW:
- holder.statusUnread.setVisibility(View.VISIBLE);
- break;
- default:
- holder.statusUnread.setVisibility(View.INVISIBLE);
- break;
+ if(false == item.isRead() && itemAccess.isNew(item)) {
+ holder.statusUnread.setVisibility(View.VISIBLE);
+ } else {
+ holder.statusUnread.setVisibility(View.INVISIBLE);
+ }
+ if(item.isRead()) {
+ ViewHelper.setAlpha(convertView, 0.5f);
+ } else {
+ ViewHelper.setAlpha(convertView, 1.0f);
}
holder.published.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL));
@@ -146,10 +146,10 @@ public class FeedItemlistAdapter extends BaseAdapter {
item.getMedia())) {
holder.episodeProgress.setVisibility(View.VISIBLE);
holder.episodeProgress.setProgress(((ItemAccess) itemAccess).getItemDownloadProgressPercent(item));
- holder.published.setVisibility(View.GONE);
} else {
- holder.episodeProgress.setVisibility(View.GONE);
- holder.published.setVisibility(View.VISIBLE);
+ if(media.getPosition() == 0) {
+ holder.episodeProgress.setVisibility(View.GONE);
+ }
}
TypedArray typeDrawables = context.obtainStyledAttributes(
@@ -211,14 +211,18 @@ public class FeedItemlistAdapter extends BaseAdapter {
notifyDataSetChanged();
}
- public static interface ItemAccess {
- public boolean isInQueue(FeedItem item);
+ public interface ItemAccess {
+
+ boolean isInQueue(FeedItem item);
int getItemDownloadProgressPercent(FeedItem item);
int getCount();
FeedItem getItem(int position);
+
+ boolean isNew(FeedItem item);
+
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
index 17cd71f86..0d2d5cfa0 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -1,41 +1,52 @@
package de.danoeh.antennapod.adapter;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
+import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import android.widget.IconTextView;
import android.widget.ImageView;
+import android.widget.RelativeLayout;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
+import org.apache.commons.lang3.ArrayUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.fragment.AddFeedFragment;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
+import de.danoeh.antennapod.fragment.DownloadsFragment;
+import de.danoeh.antennapod.fragment.NewEpisodesFragment;
+import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
+import de.danoeh.antennapod.fragment.QueueFragment;
/**
* BaseAdapter for the navigation drawer
*/
-public class NavListAdapter extends BaseAdapter {
+public class NavListAdapter extends BaseAdapter
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final int VIEW_TYPE_COUNT = 3;
public static final int VIEW_TYPE_NAV = 0;
public static final int VIEW_TYPE_SECTION_DIVIDER = 1;
public static final int VIEW_TYPE_SUBSCRIPTION = 2;
- public static final int[] NAV_TITLES = {
- R.string.queue_label,
- R.string.new_episodes_label,
- R.string.all_episodes_label,
- R.string.downloads_label,
- R.string.playback_history_label,
- R.string.add_feed_label};
-
- private final Drawable[] drawables;
-
- public static final int SUBSCRIPTION_OFFSET = 1 + NAV_TITLES.length;
+ private static List<String> tags;
+ private static String[] titles;
private ItemAccess itemAccess;
private Context context;
@@ -44,28 +55,79 @@ public class NavListAdapter extends BaseAdapter {
this.itemAccess = itemAccess;
this.context = context;
- TypedArray ta = context.obtainStyledAttributes(new int[]{
- R.attr.stat_playlist,
- R.attr.ic_new,
- R.attr.feed,
- R.attr.av_download,
- R.attr.ic_history,
- R.attr.content_new});
- drawables = new Drawable[]{ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2),
- ta.getDrawable(3), ta.getDrawable(4), ta.getDrawable(5)};
+ titles = context.getResources().getStringArray(R.array.nav_drawer_titles);
+ loadItems();
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (key.equals(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS)) {
+ loadItems();
+ }
+ }
+
+ private void loadItems() {
+ List<String> newTags = new ArrayList<String>(Arrays.asList(MainActivity.NAV_DRAWER_TAGS));
+ List<String> hiddenFragments = UserPreferences.getHiddenDrawerItems();
+ for(String hidden : hiddenFragments) {
+ newTags.remove(hidden);
+ }
+ tags = newTags;
+ notifyDataSetChanged();
+ }
+
+ public String getLabel(String tag) {
+ int index = ArrayUtils.indexOf(MainActivity.NAV_DRAWER_TAGS, tag);
+ return titles[index];
+ }
+
+ private Drawable getDrawable(String tag) {
+ int icon;
+ switch (tag) {
+ case QueueFragment.TAG:
+ icon = R.attr.stat_playlist;
+ break;
+ case NewEpisodesFragment.TAG:
+ icon = R.attr.ic_new;
+ break;
+ case AllEpisodesFragment.TAG:
+ icon = R.attr.feed;
+ break;
+ case DownloadsFragment.TAG:
+ icon = R.attr.av_download;
+ break;
+ case PlaybackHistoryFragment.TAG:
+ icon = R.attr.ic_history;
+ break;
+ case AddFeedFragment.TAG:
+ icon = R.attr.content_new;
+ break;
+ default:
+ return null;
+ }
+ TypedArray ta = context.obtainStyledAttributes(new int[] { icon } );
+ Drawable result = ta.getDrawable(0);
ta.recycle();
+ return result;
+ }
+
+ public List<String> getTags() {
+ return Collections.unmodifiableList(tags);
}
+
@Override
public int getCount() {
- return NAV_TITLES.length + 1 + itemAccess.getCount();
+ return getSubscriptionOffset() + itemAccess.getCount();
}
@Override
public Object getItem(int position) {
int viewType = getItemViewType(position);
if (viewType == VIEW_TYPE_NAV) {
- return context.getString(NAV_TITLES[position]);
+ return getLabel(tags.get(position));
} else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
return "";
} else {
@@ -80,9 +142,9 @@ public class NavListAdapter extends BaseAdapter {
@Override
public int getItemViewType(int position) {
- if (0 <= position && position < NAV_TITLES.length) {
+ if (0 <= position && position < tags.size()) {
return VIEW_TYPE_NAV;
- } else if (position < NAV_TITLES.length + 1) {
+ } else if (position < getSubscriptionOffset()) {
return VIEW_TYPE_SECTION_DIVIDER;
} else {
return VIEW_TYPE_SUBSCRIPTION;
@@ -94,6 +156,11 @@ public class NavListAdapter extends BaseAdapter {
return VIEW_TYPE_COUNT;
}
+ public int getSubscriptionOffset() {
+ return tags.size() > 0 ? tags.size() + 1 : 0;
+ }
+
+
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int viewType = getItemViewType(position);
@@ -103,7 +170,7 @@ public class NavListAdapter extends BaseAdapter {
} else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
v = getSectionDividerView(convertView, parent);
} else {
- v = getFeedView(position - SUBSCRIPTION_OFFSET, convertView, parent);
+ v = getFeedView(position - getSubscriptionOffset(), convertView, parent);
}
if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) {
TextView txtvTitle = (TextView) v.findViewById(R.id.txtvTitle);
@@ -125,9 +192,9 @@ public class NavListAdapter extends BaseAdapter {
convertView = inflater.inflate(R.layout.nav_listitem, parent, false);
+ holder.image = (ImageView) convertView.findViewById(R.id.imgvCover);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.count = (TextView) convertView.findViewById(R.id.txtvCount);
- holder.image = (ImageView) convertView.findViewById(R.id.imgvCover);
convertView.setTag(holder);
} else {
holder = (NavHolder) convertView.getTag();
@@ -135,7 +202,7 @@ public class NavListAdapter extends BaseAdapter {
holder.title.setText(title);
- if (NAV_TITLES[position] == R.string.queue_label) {
+ if (tags.get(position).equals(QueueFragment.TAG)) {
int queueSize = itemAccess.getQueueSize();
if (queueSize > 0) {
holder.count.setVisibility(View.VISIBLE);
@@ -143,8 +210,8 @@ public class NavListAdapter extends BaseAdapter {
} else {
holder.count.setVisibility(View.GONE);
}
- } else if (NAV_TITLES[position] == R.string.new_episodes_label) {
- int unreadItems = itemAccess.getNumberOfUnreadItems();
+ } else if (tags.get(position).equals(NewEpisodesFragment.TAG)) {
+ int unreadItems = itemAccess.getNumberOfNewItems();
if (unreadItems > 0) {
holder.count.setVisibility(View.VISIBLE);
holder.count.setText(String.valueOf(unreadItems));
@@ -155,7 +222,7 @@ public class NavListAdapter extends BaseAdapter {
holder.count.setVisibility(View.GONE);
}
- holder.image.setImageDrawable(drawables[position]);
+ holder.image.setImageDrawable(getDrawable(tags.get(position)));
return convertView;
}
@@ -183,45 +250,63 @@ public class NavListAdapter extends BaseAdapter {
convertView = inflater.inflate(R.layout.nav_feedlistitem, parent, false);
- holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.image = (ImageView) convertView.findViewById(R.id.imgvCover);
+ holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
+ holder.failure = (IconTextView) convertView.findViewById(R.id.itxtvFailure);
+ holder.count = (TextView) convertView.findViewById(R.id.txtvCount);
convertView.setTag(holder);
} else {
holder = (FeedHolder) convertView.getTag();
}
- holder.title.setText(feed.getTitle());
-
Picasso.with(context)
.load(feed.getImageUri())
.fit()
.into(holder.image);
+ holder.title.setText(feed.getTitle());
+
+
+ if(feed.hasLastUpdateFailed()) {
+ RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) holder.title.getLayoutParams();
+ p.addRule(RelativeLayout.LEFT_OF, R.id.itxtvFailure);
+ holder.failure.setVisibility(View.VISIBLE);
+ } else {
+ RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) holder.title.getLayoutParams();
+ p.addRule(RelativeLayout.LEFT_OF, R.id.txtvCount);
+ holder.failure.setVisibility(View.GONE);
+ }
+ int feedUnreadItems = itemAccess.getNumberOfUnreadFeedItems(feed.getId());
+ if(feedUnreadItems > 0) {
+ holder.count.setVisibility(View.VISIBLE);
+ holder.count.setText(String.valueOf(feedUnreadItems));
+ holder.count.setTypeface(holder.title.getTypeface());
+ } else {
+ holder.count.setVisibility(View.GONE);
+ }
return convertView;
}
static class NavHolder {
+ ImageView image;
TextView title;
TextView count;
- ImageView image;
}
static class FeedHolder {
- TextView title;
ImageView image;
+ TextView title;
+ IconTextView failure;
+ TextView count;
}
-
public interface ItemAccess {
- public int getCount();
-
- public Feed getItem(int position);
-
- public int getSelectedItemIndex();
-
- public int getQueueSize();
-
- public int getNumberOfUnreadItems();
+ int getCount();
+ Feed getItem(int position);
+ int getSelectedItemIndex();
+ int getQueueSize();
+ int getNumberOfNewItems();
+ int getNumberOfUnreadFeedItems(long feedId);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
index a256dc129..bba5a00a9 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
@@ -14,9 +14,9 @@ import android.widget.TextView;
import com.squareup.picasso.Picasso;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.EventDistributor;
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.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
@@ -31,6 +31,8 @@ public class QueueListAdapter extends BaseAdapter {
private final ActionButtonCallback actionButtonCallback;
private final ActionButtonUtils actionButtonUtils;
+ private boolean locked;
+
public QueueListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) {
super();
@@ -38,6 +40,12 @@ public class QueueListAdapter extends BaseAdapter {
this.itemAccess = itemAccess;
this.actionButtonUtils = new ActionButtonUtils(context);
this.actionButtonCallback = actionButtonCallback;
+ locked = UserPreferences.isQueueLocked();
+ }
+
+ public void setLocked(boolean locked) {
+ this.locked = locked;
+ notifyDataSetChanged();
}
@Override
@@ -67,6 +75,7 @@ public class QueueListAdapter extends BaseAdapter {
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.queue_listitem,
parent, false);
+ holder.dragHandle = (ImageView) convertView.findViewById(R.id.drag_handle);
holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate);
@@ -83,6 +92,12 @@ public class QueueListAdapter extends BaseAdapter {
holder = (Holder) convertView.getTag();
}
+ if(locked) {
+ holder.dragHandle.setVisibility(View.GONE);
+ } else {
+ holder.dragHandle.setVisibility(View.VISIBLE);
+ }
+
holder.title.setText(item.getTitle());
FeedMedia media = item.getMedia();
@@ -143,6 +158,7 @@ public class QueueListAdapter extends BaseAdapter {
static class Holder {
+ ImageView dragHandle;
ImageView imageView;
TextView title;
TextView pubDate;