From 4561f16f11ed2f27d711d3ea42f5e84bcccc002c Mon Sep 17 00:00:00 2001 From: Martin Fietz Date: Mon, 11 May 2015 17:14:42 +0200 Subject: Redone new indicator --- .../antennapod/adapter/AllEpisodesListAdapter.java | 185 +++++++++++++++++++++ .../antennapod/adapter/FeedItemlistAdapter.java | 6 +- .../antennapod/adapter/NewEpisodesListAdapter.java | 179 -------------------- .../antennapod/config/StorageCallbacksImpl.java | 6 + .../antennapod/fragment/AllEpisodesFragment.java | 33 +++- .../antennapod/fragment/ItemlistFragment.java | 31 ++-- .../fragment/PlaybackHistoryFragment.java | 5 + .../menuhandler/FeedItemMenuHandler.java | 2 +- 8 files changed, 246 insertions(+), 201 deletions(-) create mode 100644 app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java (limited to 'app/src/main/java/de') diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java new file mode 100644 index 000000000..ea0c96be9 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java @@ -0,0 +1,185 @@ +package de.danoeh.antennapod.adapter; + +import android.content.Context; +import android.text.format.DateUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.squareup.picasso.Picasso; + +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; +import de.danoeh.antennapod.core.util.Converter; + +/** + * List adapter for the list of new episodes + */ +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 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 + public int getCount() { + return itemAccess.getCount(); + } + + @Override + public Object getItem(int position) { + return itemAccess.getItem(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Holder holder; + final FeedItem item = (FeedItem) getItem(position); + if (item == null) return null; + + if (convertView == null) { + holder = new Holder(); + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = inflater.inflate(R.layout.new_episodes_listitem, + parent, false); + holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.pubDate = (TextView) convertView + .findViewById(R.id.txtvPublished); + holder.statusUnread = convertView.findViewById(R.id.statusUnread); + holder.butSecondary = (ImageButton) convertView + .findViewById(R.id.butSecondaryAction); + holder.queueStatus = (ImageView) convertView + .findViewById(R.id.imgvInPlaylist); + holder.downloadProgress = (ProgressBar) convertView + .findViewById(R.id.pbar_download_progress); + holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage); + holder.txtvDuration = (TextView) convertView.findViewById(R.id.txtvDuration); + convertView.setTag(holder); + } else { + holder = (Holder) convertView.getTag(); + } + + holder.title.setText(item.getTitle()); + holder.pubDate.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL)); + if (showOnlyNewEpisodes || item.isRead() || false == itemAccess.isNew(item)) { + holder.statusUnread.setVisibility(View.INVISIBLE); + } else { + holder.statusUnread.setVisibility(View.VISIBLE); + } + + FeedMedia media = item.getMedia(); + if (media != null) { + final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media); + + if (media.getDuration() > 0) { + holder.txtvDuration.setText(Converter.getDurationStringLong(media.getDuration())); + } else if (media.getSize() > 0) { + holder.txtvDuration.setText(Converter.byteToString(media.getSize())); + } else { + holder.txtvDuration.setText(""); + } + + if (isDownloadingMedia) { + holder.downloadProgress.setVisibility(View.VISIBLE); + holder.txtvDuration.setVisibility(View.GONE); + holder.pubDate.setVisibility(View.GONE); + } else { + holder.txtvDuration.setVisibility(View.VISIBLE); + holder.pubDate.setVisibility(View.VISIBLE); + holder.downloadProgress.setVisibility(View.GONE); + } + + if (!media.isDownloaded()) { + if (isDownloadingMedia) { + // item is being downloaded + holder.downloadProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item)); + } + } + } else { + holder.downloadProgress.setVisibility(View.GONE); + holder.txtvDuration.setVisibility(View.GONE); + } + + if (itemAccess.isInQueue(item)) { + holder.queueStatus.setVisibility(View.VISIBLE); + } else { + holder.queueStatus.setVisibility(View.INVISIBLE); + } + + actionButtonUtils.configureActionButton(holder.butSecondary, item); + holder.butSecondary.setFocusable(false); + holder.butSecondary.setTag(item); + holder.butSecondary.setOnClickListener(secondaryActionListener); + + Picasso.with(context) + .load(item.getImageUri()) + .fit() + .into(holder.imageView); + + return convertView; + } + + private View.OnClickListener secondaryActionListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + FeedItem item = (FeedItem) v.getTag(); + actionButtonCallback.onActionButtonPressed(item); + } + }; + + + static class Holder { + TextView title; + TextView pubDate; + View statusUnread; + ImageView queueStatus; + ImageView imageView; + ProgressBar downloadProgress; + TextView txtvDuration; + ImageButton butSecondary; + } + + public interface ItemAccess { + + int getCount(); + + FeedItem getItem(int position); + + int getItemDownloadProgressPercent(FeedItem item); + + boolean isInQueue(FeedItem item); + + boolean isNew(FeedItem item); + + } +} 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 30e0b0b57..4a640f112 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java @@ -110,7 +110,9 @@ public class FeedItemlistAdapter extends BaseAdapter { } holder.title.setText(buffer.toString()); - if(item.isRead()) { + if(false == item.isRead() && itemAccess.isNew(item)) { + holder.statusUnread.setVisibility(View.VISIBLE); + } else { holder.statusUnread.setVisibility(View.INVISIBLE); } @@ -214,6 +216,8 @@ public class FeedItemlistAdapter extends BaseAdapter { FeedItem getItem(int position); + boolean isNew(FeedItem item); + } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java deleted file mode 100644 index 7ad40340d..000000000 --- a/app/src/main/java/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java +++ /dev/null @@ -1,179 +0,0 @@ -package de.danoeh.antennapod.adapter; - -import android.content.Context; -import android.text.format.DateUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.TextView; - -import com.squareup.picasso.Picasso; - -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; -import de.danoeh.antennapod.core.util.Converter; - -/** - * List adapter for the list of new episodes - */ -public class NewEpisodesListAdapter extends BaseAdapter { - - private final Context context; - private final ItemAccess itemAccess; - private final ActionButtonCallback actionButtonCallback; - private final ActionButtonUtils actionButtonUtils; - - public NewEpisodesListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) { - super(); - this.context = context; - this.itemAccess = itemAccess; - this.actionButtonUtils = new ActionButtonUtils(context); - this.actionButtonCallback = actionButtonCallback; - } - - @Override - public int getCount() { - return itemAccess.getCount(); - } - - @Override - public Object getItem(int position) { - return itemAccess.getItem(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public int getViewTypeCount() { - return 1; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - Holder holder; - final FeedItem item = (FeedItem) getItem(position); - if (item == null) return null; - - if (convertView == null) { - holder = new Holder(); - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - convertView = inflater.inflate(R.layout.new_episodes_listitem, - parent, false); - holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); - holder.pubDate = (TextView) convertView - .findViewById(R.id.txtvPublished); - holder.statusUnread = convertView.findViewById(R.id.statusUnread); - holder.butSecondary = (ImageButton) convertView - .findViewById(R.id.butSecondaryAction); - holder.queueStatus = (ImageView) convertView - .findViewById(R.id.imgvInPlaylist); - holder.downloadProgress = (ProgressBar) convertView - .findViewById(R.id.pbar_download_progress); - holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage); - holder.txtvDuration = (TextView) convertView.findViewById(R.id.txtvDuration); - convertView.setTag(holder); - } else { - holder = (Holder) convertView.getTag(); - } - - holder.title.setText(item.getTitle()); - holder.pubDate.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL)); - if (item.isRead()) { - holder.statusUnread.setVisibility(View.INVISIBLE); - } else { - holder.statusUnread.setVisibility(View.VISIBLE); - } - - FeedMedia media = item.getMedia(); - if (media != null) { - final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media); - - if (media.getDuration() > 0) { - holder.txtvDuration.setText(Converter.getDurationStringLong(media.getDuration())); - } else if (media.getSize() > 0) { - holder.txtvDuration.setText(Converter.byteToString(media.getSize())); - } else { - holder.txtvDuration.setText(""); - } - - if (isDownloadingMedia) { - holder.downloadProgress.setVisibility(View.VISIBLE); - holder.txtvDuration.setVisibility(View.GONE); - holder.pubDate.setVisibility(View.GONE); - } else { - holder.txtvDuration.setVisibility(View.VISIBLE); - holder.pubDate.setVisibility(View.VISIBLE); - holder.downloadProgress.setVisibility(View.GONE); - } - - if (!media.isDownloaded()) { - if (isDownloadingMedia) { - // item is being downloaded - holder.downloadProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item)); - } - } - } else { - holder.downloadProgress.setVisibility(View.GONE); - holder.txtvDuration.setVisibility(View.GONE); - } - - if (itemAccess.isInQueue(item)) { - holder.queueStatus.setVisibility(View.VISIBLE); - } else { - holder.queueStatus.setVisibility(View.INVISIBLE); - } - - actionButtonUtils.configureActionButton(holder.butSecondary, item); - holder.butSecondary.setFocusable(false); - holder.butSecondary.setTag(item); - holder.butSecondary.setOnClickListener(secondaryActionListener); - - Picasso.with(context) - .load(item.getImageUri()) - .fit() - .into(holder.imageView); - - return convertView; - } - - private View.OnClickListener secondaryActionListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - FeedItem item = (FeedItem) v.getTag(); - actionButtonCallback.onActionButtonPressed(item); - } - }; - - - static class Holder { - TextView title; - TextView pubDate; - View statusUnread; - ImageView queueStatus; - ImageView imageView; - ProgressBar downloadProgress; - TextView txtvDuration; - ImageButton butSecondary; - } - - public interface ItemAccess { - - int getCount(); - - FeedItem getItem(int position); - - int getItemDownloadProgressPercent(FeedItem item); - - boolean isInQueue(FeedItem item); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java index 3445b109f..943e05690 100644 --- a/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java +++ b/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java @@ -142,6 +142,12 @@ public class StorageCallbacksImpl implements StorageCallbacks { db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " + PodDBAdapter.KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0"); + // create indexes + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED); + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE); + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM); + db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM); + db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM); } } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java index 91e3df106..8a5cad137 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -29,7 +29,7 @@ import java.util.concurrent.atomic.AtomicReference; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; -import de.danoeh.antennapod.adapter.NewEpisodesListAdapter; +import de.danoeh.antennapod.adapter.AllEpisodesListAdapter; import de.danoeh.antennapod.core.asynctask.DownloadObserver; import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.feed.EventDistributor; @@ -64,12 +64,13 @@ public class AllEpisodesFragment extends Fragment { private String prefName; protected DragSortListView listView; - private NewEpisodesListAdapter listAdapter; + private AllEpisodesListAdapter listAdapter; private TextView txtvEmpty; private ProgressBar progLoading; private List episodes; - private LongList queueAccess; + private LongList queuedItemsIds; + private LongList newItemsIds; private List downloaderList; private boolean itemsLoaded = false; @@ -308,7 +309,8 @@ public class AllEpisodesFragment extends Fragment { private void onFragmentLoaded() { if (listAdapter == null) { - listAdapter = new NewEpisodesListAdapter(activity.get(), itemAccess, new DefaultActionButtonCallback(activity.get())); + listAdapter = new AllEpisodesListAdapter(activity.get(), itemAccess, + new DefaultActionButtonCallback(activity.get()), showOnlyNewEpisodes); listView.setAdapter(listAdapter); listView.setEmptyView(txtvEmpty); downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback); @@ -337,7 +339,7 @@ public class AllEpisodesFragment extends Fragment { } }; - private NewEpisodesListAdapter.ItemAccess itemAccess = new NewEpisodesListAdapter.ItemAccess() { + private AllEpisodesListAdapter.ItemAccess itemAccess = new AllEpisodesListAdapter.ItemAccess() { @Override public int getCount() { @@ -371,7 +373,17 @@ public class AllEpisodesFragment extends Fragment { @Override public boolean isInQueue(FeedItem item) { if (itemsLoaded) { - return queueAccess.contains(item.getId()); + return queuedItemsIds.contains(item.getId()); + } else { + return false; + } + } + + @Override + public boolean isNew(FeedItem item) { + if (itemsLoaded) { + // should actually never be called in NewEpisodesFragment, but better safe than sorry + return showOnlyNewEpisodes || newItemsIds.contains(item.getId()); } else { return false; } @@ -436,12 +448,14 @@ public class AllEpisodesFragment extends Fragment { if(showOnlyNewEpisodes) { return new Object[] { DBReader.getNewItemsList(context), - DBReader.getQueueIDList(context) + DBReader.getQueueIDList(context), + null // see ItemAccess.isNew }; } else { return new Object[]{ DBReader.getRecentlyPublishedEpisodes(context, RECENT_EPISODES_LIMIT), - DBReader.getQueueIDList(context) + DBReader.getQueueIDList(context), + DBReader.getNewItemIds(context) }; } } else { @@ -457,7 +471,8 @@ public class AllEpisodesFragment extends Fragment { if (lists != null) { episodes = (List) lists[0]; - queueAccess = (LongList) lists[1]; + queuedItemsIds = (LongList) lists[1]; + newItemsIds = (LongList) lists[2]; itemsLoaded = true; if (viewsCreated && activity.get() != null) { onFragmentLoaded(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java index aaa8cd645..463d06376 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java @@ -9,8 +9,8 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.ListFragment; -import android.support.v4.util.Pair; import android.support.v4.view.MenuItemCompat; + import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.util.Log; @@ -85,7 +85,9 @@ public class ItemlistFragment extends ListFragment { private long feedID; private Feed feed; - private LongList queue; + private LongList queuedItemsIds; + private LongList newItemsIds; + private boolean itemsLoaded = false; private boolean viewsCreated = false; @@ -299,7 +301,7 @@ public class ItemlistFragment extends ListFragment { } contextMenu = menu; - FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, false, queue); + FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, false, queuedItemsIds); } @Override @@ -547,7 +549,12 @@ public class ItemlistFragment extends ListFragment { @Override public boolean isInQueue(FeedItem item) { - return (queue != null) && queue.contains(item.getId()); + return (queuedItemsIds != null) && queuedItemsIds.contains(item.getId()); + } + + @Override + public boolean isNew(FeedItem item) { + return (newItemsIds != null) && newItemsIds.contains(item.getId()); } @Override @@ -580,9 +587,9 @@ public class ItemlistFragment extends ListFragment { } } - private class ItemLoader extends AsyncTask> { + private class ItemLoader extends AsyncTask { @Override - protected Pair doInBackground(Long... params) { + protected Object[] doInBackground(Long... params) { long feedID = params[0]; Context context = getActivity(); if (context != null) { @@ -591,19 +598,21 @@ public class ItemlistFragment extends ListFragment { FeedItemFilter filter = feed.getItemFilter(); feed.setItems(filter.filter(context, feed.getItems())); } - LongList queue = DBReader.getQueueIDList(context); - return Pair.create(feed, queue); + LongList queuedItemsIds = DBReader.getQueueIDList(context); + LongList newItemsIds = DBReader.getNewItemIds(context); + return new Object[] { feed, queuedItemsIds, newItemsIds }; } else { return null; } } @Override - protected void onPostExecute(Pair res) { + protected void onPostExecute(Object[] res) { super.onPostExecute(res); if (res != null) { - feed = res.first; - queue = res.second; + feed = (Feed) res[0]; + queuedItemsIds = (LongList) res[1]; + newItemsIds = res[2] == null ? null : (LongList) res[2]; itemsLoaded = true; if (viewsCreated) { onFragmentLoaded(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java index 440e38636..9099829d8 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -225,6 +225,11 @@ public class PlaybackHistoryFragment extends ListFragment { return (queue != null) ? queue.contains(item.getId()) : false; } + @Override + public boolean isNew(FeedItem item) { + return false; + } + @Override public int getItemDownloadProgressPercent(FeedItem item) { if (downloaderList != null) { diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java index 974a7d4bf..a58666056 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java @@ -88,7 +88,7 @@ public class FeedItemMenuHandler { mi.setItemVisibility(R.id.share_link_item, false); } - if (!(state == FeedItem.State.NEW || state == FeedItem.State.IN_PROGRESS)) { + if (!(state == FeedItem.State.UNREAD || state == FeedItem.State.IN_PROGRESS)) { mi.setItemVisibility(R.id.mark_read_item, false); } if (!(state == FeedItem.State.IN_PROGRESS || state == FeedItem.State.READ)) { -- cgit v1.2.3