Show feed new items and refresh failure

This commit is contained in:
Martin Fietz 2015-04-26 12:59:01 +02:00 committed by Martin Fietz
parent e68ca0529b
commit 406dab0a24
17 changed files with 257 additions and 135 deletions

View File

@ -110,22 +110,8 @@ public class FeedItemlistAdapter extends BaseAdapter {
} }
holder.title.setText(buffer.toString()); holder.title.setText(buffer.toString());
FeedItem.State state = item.getState(); if(item.isRead()) {
switch (state) { holder.statusUnread.setVisibility(View.INVISIBLE);
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;
} }
holder.published.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL)); holder.published.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL));
@ -153,7 +139,9 @@ public class FeedItemlistAdapter extends BaseAdapter {
holder.episodeProgress.setProgress(((ItemAccess) itemAccess).getItemDownloadProgressPercent(item)); holder.episodeProgress.setProgress(((ItemAccess) itemAccess).getItemDownloadProgressPercent(item));
holder.published.setVisibility(View.GONE); holder.published.setVisibility(View.GONE);
} else { } else {
holder.episodeProgress.setVisibility(View.GONE); if(media.getPosition() == 0) {
holder.episodeProgress.setVisibility(View.GONE);
}
holder.published.setVisibility(View.VISIBLE); holder.published.setVisibility(View.VISIBLE);
} }
@ -217,6 +205,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
} }
public interface ItemAccess { public interface ItemAccess {
boolean isInQueue(FeedItem item); boolean isInQueue(FeedItem item);
int getItemDownloadProgressPercent(FeedItem item); int getItemDownloadProgressPercent(FeedItem item);
@ -224,6 +213,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
int getCount(); int getCount();
FeedItem getItem(int position); FeedItem getItem(int position);
} }
} }

View File

@ -10,6 +10,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.IconTextView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@ -26,6 +27,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.fragment.AddFeedFragment; import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.AllEpisodesFragment; import de.danoeh.antennapod.fragment.AllEpisodesFragment;
import de.danoeh.antennapod.fragment.DownloadsFragment; import de.danoeh.antennapod.fragment.DownloadsFragment;
@ -190,9 +192,9 @@ public class NavListAdapter extends BaseAdapter
convertView = inflater.inflate(R.layout.nav_listitem, parent, false); 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.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.count = (TextView) convertView.findViewById(R.id.txtvCount); holder.count = (TextView) convertView.findViewById(R.id.txtvCount);
holder.image = (ImageView) convertView.findViewById(R.id.imgvCover);
convertView.setTag(holder); convertView.setTag(holder);
} else { } else {
holder = (NavHolder) convertView.getTag(); holder = (NavHolder) convertView.getTag();
@ -248,45 +250,57 @@ public class NavListAdapter extends BaseAdapter
convertView = inflater.inflate(R.layout.nav_feedlistitem, parent, false); 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.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); convertView.setTag(holder);
} else { } else {
holder = (FeedHolder) convertView.getTag(); holder = (FeedHolder) convertView.getTag();
} }
holder.title.setText(feed.getTitle());
Picasso.with(context) Picasso.with(context)
.load(feed.getImageUri()) .load(feed.getImageUri())
.fit() .fit()
.into(holder.image); .into(holder.image);
holder.title.setText(feed.getTitle());
int feedUnreadItems = DBReader.getNumberOfUnreadItems(context, feed.getId());
if(feed.hasLastUpdateFailed()) {
holder.failure.setVisibility(View.VISIBLE);
} else {
holder.failure.setVisibility(View.GONE);
}
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; return convertView;
} }
static class NavHolder { static class NavHolder {
ImageView image;
TextView title; TextView title;
TextView count; TextView count;
ImageView image;
} }
static class FeedHolder { static class FeedHolder {
TextView title;
ImageView image; ImageView image;
TextView title;
IconTextView failure;
TextView count;
} }
public interface ItemAccess { public interface ItemAccess {
public int getCount(); int getCount();
Feed getItem(int position);
public Feed getItem(int position); int getSelectedItemIndex();
int getQueueSize();
public int getSelectedItemIndex(); int getNumberOfUnreadItems();
public int getQueueSize();
public int getNumberOfUnreadItems();
} }
} }

View File

@ -125,6 +125,7 @@ public class StorageCallbacksImpl implements StorageCallbacks {
PodDBAdapter.KEY_CHAPTER_TYPE)); PodDBAdapter.KEY_CHAPTER_TYPE));
} }
if(oldVersion <= 14) { if(oldVersion <= 14) {
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
+ " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " INTEGER"); + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " INTEGER");
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
@ -133,8 +134,14 @@ public class StorageCallbacksImpl implements StorageCallbacks {
+ " FROM " + PodDBAdapter.TABLE_NAME_FEEDS + " FROM " + PodDBAdapter.TABLE_NAME_FEEDS
+ " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_ID + " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_ID
+ " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + ")"); + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + ")");
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
+ " ADD COLUMN " + PodDBAdapter.KEY_HIDE + " TEXT"); + " ADD COLUMN " + PodDBAdapter.KEY_HIDE + " TEXT");
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
+ " ADD COLUMN " + PodDBAdapter.KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0");
} }
} }
} }

View File

@ -19,6 +19,7 @@ import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.IconTextView;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListAdapter; import android.widget.ListAdapter;
@ -91,6 +92,8 @@ public class ItemlistFragment extends ListFragment {
private MoreContentListFooterUtil listFooter; private MoreContentListFooterUtil listFooter;
private boolean isUpdatingFeed; private boolean isUpdatingFeed;
private IconTextView txtvFailure;
private TextView txtvInformation; private TextView txtvInformation;
@ -309,7 +312,7 @@ public class ItemlistFragment extends ListFragment {
@Override @Override
public void update(EventDistributor eventDistributor, Integer arg) { public void update(EventDistributor eventDistributor, Integer arg) {
if ((EVENTS & arg) != 0) { if ((EVENTS & arg) != 0) {
Log.d(TAG, "Received contentUpdate Intent."); Log.d(TAG, "Received contentUpdate Intent. arg " + arg);
if ((EventDistributor.DOWNLOAD_QUEUED & arg) != 0) { if ((EventDistributor.DOWNLOAD_QUEUED & arg) != 0) {
updateProgressBarVisibility(); updateProgressBarVisibility();
} else { } else {
@ -358,6 +361,11 @@ public class ItemlistFragment extends ListFragment {
} }
private void refreshHeaderView() { private void refreshHeaderView() {
if(feed.hasLastUpdateFailed()) {
txtvFailure.setVisibility(View.VISIBLE);
} else {
txtvFailure.setVisibility(View.GONE);
}
if(feed.getItemFilter() != null) { if(feed.getItemFilter() != null) {
FeedItemFilter filter = feed.getItemFilter(); FeedItemFilter filter = feed.getItemFilter();
if(filter.getValues().length > 0) { if(filter.getValues().length > 0) {
@ -368,6 +376,7 @@ public class ItemlistFragment extends ListFragment {
txtvInformation.setVisibility(View.GONE); txtvInformation.setVisibility(View.GONE);
} }
} else { } else {
txtvInformation.setVisibility(View.GONE); txtvInformation.setVisibility(View.GONE);
} }
} }
@ -407,6 +416,7 @@ public class ItemlistFragment extends ListFragment {
ImageView imgvCover = (ImageView) header.findViewById(R.id.imgvCover); ImageView imgvCover = (ImageView) header.findViewById(R.id.imgvCover);
ImageButton butShowInfo = (ImageButton) header.findViewById(R.id.butShowInfo); ImageButton butShowInfo = (ImageButton) header.findViewById(R.id.butShowInfo);
txtvInformation = (TextView) header.findViewById(R.id.txtvInformation); txtvInformation = (TextView) header.findViewById(R.id.txtvInformation);
txtvFailure = (IconTextView) header.findViewById(R.id.txtvFailure);
txtvTitle.setText(feed.getTitle()); txtvTitle.setText(feed.getTitle());
txtvAuthor.setText(feed.getAuthor()); txtvAuthor.setText(feed.getAuthor());
@ -437,6 +447,7 @@ public class ItemlistFragment extends ListFragment {
}); });
} }
private void setupFooterView() { private void setupFooterView() {
if (getListView() == null || feed == null) { if (getListView() == null || feed == null) {
Log.e(TAG, "Unable to setup listview: listView = null or feed = null"); Log.e(TAG, "Unable to setup listview: listView = null or feed = null");

View File

@ -418,7 +418,6 @@ public class QueueFragment extends Fragment {
Log.d(TAG, "remove(" + which + ")"); Log.d(TAG, "remove(" + which + ")");
stopItemLoader(); stopItemLoader();
FeedItem item = (FeedItem) listView.getAdapter().getItem(which); FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
DBWriter.markItemRead(getActivity(), item.getId(), true);
DBWriter.removeQueueItem(getActivity(), item, true); DBWriter.removeQueueItem(getActivity(), item, true);
} }
}); });
@ -433,7 +432,6 @@ public class QueueFragment extends Fragment {
if (token != null) { if (token != null) {
long itemId = token.getFeedItemId(); long itemId = token.getFeedItemId();
int position = token.getPosition(); int position = token.getPosition();
DBWriter.markItemRead(context, itemId, false);
DBWriter.addQueueItemAt(context, itemId, position, false); DBWriter.addQueueItemAt(context, itemId, position, false);
} }
} }

View File

@ -15,7 +15,6 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBTasks;
@ -39,8 +38,7 @@ public class FeedMenuHandler {
return true; return true;
} }
if (BuildConfig.DEBUG) Log.d(TAG, "Preparing options menu");
Log.d(TAG, "Preparing options menu");
menu.findItem(R.id.mark_all_read_item).setVisible( menu.findItem(R.id.mark_all_read_item).setVisible(
selectedFeed.hasNewItems(true)); selectedFeed.hasNewItems(true));
if (selectedFeed.getPaymentLink() != null && selectedFeed.getFlattrStatus().flattrable()) if (selectedFeed.getPaymentLink() != null && selectedFeed.getFlattrStatus().flattrable())

View File

@ -78,6 +78,21 @@
tools:text="Podcast author" tools:text="Podcast author"
tools:background="@android:color/holo_green_dark" /> tools:background="@android:color/holo_green_dark" />
<IconTextView
android:id="@+id/txtvFailure"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/imgvBackground"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:background="@color/download_failed_red"
android:gravity="center"
android:textColor="@color/white"
android:visibility="gone"
android:text="@string/refresh_failed_msg"
tools:text="(!) Last refresh failed"
/>
<TextView <TextView
android:id="@+id/txtvInformation" android:id="@+id/txtvInformation"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -22,8 +22,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_margin="16dp" android:layout_marginTop="16dp"
tools:text="Status unread" android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
tools:text="NEW"
tools:background="@android:color/white" /> tools:background="@android:color/white" />
<TextView <TextView
@ -36,34 +38,9 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding"
android:layout_toLeftOf="@id/statusUnread" android:layout_toLeftOf="@id/statusUnread"
tools:text="Feed item name" tools:text="Episode title"
tools:background="@android:color/holo_green_dark" /> tools:background="@android:color/holo_green_dark" />
<ImageView
android:id="@+id/imgvInPlaylist"
android:layout_width="@dimen/enc_icons_size"
android:layout_height="@dimen/enc_icons_size"
android:layout_alignParentRight="true"
android:layout_below="@id/txtvItemname"
android:layout_marginRight="4dp"
android:contentDescription="@string/in_queue_label"
android:src="?attr/stat_playlist"
android:visibility="visible"
tools:src="@drawable/ic_list_white_24dp"
tools:background="@android:color/holo_red_light" />
<ImageView
android:id="@+id/imgvType"
android:layout_width="@dimen/enc_icons_size"
android:layout_height="@dimen/enc_icons_size"
android:layout_below="@id/txtvItemname"
android:layout_marginRight="4dp"
android:layout_toLeftOf="@+id/imgvInPlaylist"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_hearing_white_18dp"
tools:background="@android:color/holo_red_light" />
<TextView <TextView
android:id="@+id/txtvLenSize" android:id="@+id/txtvLenSize"
style="@style/AntennaPod.TextView.ListItemSecondaryTitle" style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
@ -74,18 +51,29 @@
tools:text="00:42:23" tools:text="00:42:23"
tools:background="@android:color/holo_green_dark" /> tools:background="@android:color/holo_green_dark" />
<ProgressBar <ImageView
android:id="@+id/pbar_episode_progress" android:id="@+id/imgvInPlaylist"
style="?android:attr/progressBarStyleHorizontal" android:layout_width="@dimen/enc_icons_size"
android:layout_width="0dp" android:layout_height="@dimen/enc_icons_size"
android:layout_height="wrap_content" android:layout_alignParentRight="true"
android:layout_below="@id/txtvItemname" android:layout_below="@id/txtvItemname"
android:layout_marginLeft="4dp" android:layout_marginRight="8dp"
android:layout_marginRight="4dp" android:contentDescription="@string/in_queue_label"
android:layout_toLeftOf="@id/imgvType" android:src="?attr/stat_playlist"
android:layout_toRightOf="@id/txtvLenSize" android:visibility="visible"
tools:background="@android:color/holo_blue_light" /> tools:src="@drawable/ic_list_white_24dp"
tools:background="@android:color/holo_red_light" />
<ImageView
android:id="@+id/imgvType"
android:layout_width="@dimen/enc_icons_size"
android:layout_height="@dimen/enc_icons_size"
android:layout_below="@id/txtvItemname"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/imgvInPlaylist"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_hearing_white_18dp"
tools:background="@android:color/holo_red_light" />
<TextView <TextView
android:id="@+id/txtvPublished" android:id="@+id/txtvPublished"
@ -93,10 +81,30 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/txtvItemname" android:layout_below="@id/txtvItemname"
android:layout_marginRight="4dp" android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/imgvType" android:layout_toLeftOf="@id/imgvType"
tools:text="Jan 23" tools:text="Jan 23"
tools:background="@android:color/holo_green_dark" /> tools:background="@android:color/holo_green_dark" />
<ProgressBar
android:id="@+id/pbar_episode_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/txtvPublished"
android:layout_toRightOf="@id/txtvLenSize"
android:layout_alignTop="@id/txtvPublished"
android:layout_alignBottom="@id/txtvPublished"
tools:background="@android:color/holo_blue_light"
android:max="100"
android:progress="42"
android:indeterminate="false"
/>
</RelativeLayout> </RelativeLayout>
<include layout="@layout/vertical_list_divider"/> <include layout="@layout/vertical_list_divider"/>

View File

@ -7,7 +7,6 @@
android:layout_height="@dimen/listitem_iconwithtext_height" android:layout_height="@dimen/listitem_iconwithtext_height"
tools:background="@android:color/darker_gray"> tools:background="@android:color/darker_gray">
<ImageView <ImageView
android:id="@+id/imgvCover" android:id="@+id/imgvCover"
android:contentDescription="@string/cover_label" android:contentDescription="@string/cover_label"
@ -24,7 +23,6 @@
tools:src="@drawable/ic_stat_antenna_default" tools:src="@drawable/ic_stat_antenna_default"
tools:background="@android:color/holo_green_dark"/> tools:background="@android:color/holo_green_dark"/>
<TextView <TextView
android:id="@+id/txtvTitle" android:id="@+id/txtvTitle"
android:lines="1" android:lines="1"
@ -39,6 +37,34 @@
android:layout_marginRight="@dimen/listitem_icon_rightpadding" android:layout_marginRight="@dimen/listitem_icon_rightpadding"
android:layout_toRightOf="@id/imgvCover" android:layout_toRightOf="@id/imgvCover"
tools:text="Navigation feed item title" tools:text="Navigation feed item title"
tools:background="@android:color/holo_green_dark" tools:background="@android:color/holo_green_dark"/>
/>
</RelativeLayout> <TextView
android:id="@+id/txtvCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"
android:textColor="?android:attr/textColorTertiary"
android:textSize="@dimen/text_size_navdrawer"
android:layout_marginLeft="8dp"
android:layout_marginRight="@dimen/listitem_icon_rightpadding"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
tools:text="23"
tools:background="@android:color/holo_green_dark"/>
<IconTextView
android:id="@+id/itxtvFailure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/txtvCount"
android:lines="1"
android:text="{fa-exclamation-circle}"
android:textColor="@color/download_failed_red"
android:textSize="@dimen/text_size_navdrawer"
android:layout_marginLeft="8dp"
android:layout_centerVertical="true"
tools:text="!"
tools:background="@android:color/holo_green_dark"/>
</RelativeLayout>

View File

@ -37,7 +37,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentTop="true" /> android:layout_alignParentTop="true"
android:layout_marginLeft="8dp"/>
<TextView <TextView
android:id="@+id/txtvTitle" android:id="@+id/txtvTitle"
@ -60,38 +61,26 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
tools:background="@android:color/holo_red_light" > tools:background="@android:color/holo_red_light" >
<TextView
android:id="@+id/txtvDuration"
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
tools:text="00:42:23"
tools:background="@android:color/holo_blue_dark" />
<ImageView <ImageView
android:id="@id/imgvInPlaylist" android:id="@+id/imgvInPlaylist"
android:layout_width="@dimen/enc_icons_size" android:layout_width="@dimen/enc_icons_size"
android:layout_height="@dimen/enc_icons_size" android:layout_height="@dimen/enc_icons_size"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:contentDescription="@string/in_queue_label" android:contentDescription="@string/in_queue_label"
android:src="?attr/stat_playlist" android:src="?attr/stat_playlist"
tools:src="@drawable/ic_list_grey600_24dp" tools:src="@drawable/ic_list_grey600_24dp"
tools:background="@android:color/black" /> tools:background="@android:color/black" />
<ProgressBar
android:id="@+id/pbar_download_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/imgvInPlaylist"
android:max="100" />
<TextView
android:id="@+id/txtvDuration"
style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@id/imgvInPlaylist"
tools:text="00:42:23"
tools:background="@android:color/holo_blue_dark" />
<TextView <TextView
android:id="@+id/txtvPublished" android:id="@+id/txtvPublished"
style="@style/AntennaPod.TextView.ListItemSecondaryTitle" style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
@ -103,6 +92,17 @@
tools:text="Jan 23" tools:text="Jan 23"
tools:background="@android:color/holo_green_dark" /> tools:background="@android:color/holo_green_dark" />
<ProgressBar
android:id="@+id/pbar_download_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/txtvPublished"
android:layout_toRightOf="@id/txtvDuration"
android:max="100" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>

View File

@ -79,6 +79,8 @@ public class Feed extends FeedFile implements FlattrThing, PicassoImageResource
*/ */
private String nextPageLink; private String nextPageLink;
private boolean lastUpdateFailed;
/** /**
* Contains property strings. If such a property applies to a feed item, it is not shown in the feed list * Contains property strings. If such a property applies to a feed item, it is not shown in the feed list
*/ */
@ -90,7 +92,7 @@ public class Feed extends FeedFile implements FlattrThing, PicassoImageResource
public Feed(long id, Date lastUpdate, String title, String link, String description, String paymentLink, public Feed(long id, Date lastUpdate, String title, String link, String description, String paymentLink,
String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl, String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl,
String downloadUrl, boolean downloaded, FlattrStatus status, boolean paged, String nextPageLink, String downloadUrl, boolean downloaded, FlattrStatus status, boolean paged, String nextPageLink,
String filter) { String filter, boolean lastUpdateFailed) {
super(fileUrl, downloadUrl, downloaded); super(fileUrl, downloadUrl, downloaded);
this.id = id; this.id = id;
this.title = title; this.title = title;
@ -110,13 +112,13 @@ public class Feed extends FeedFile implements FlattrThing, PicassoImageResource
this.flattrStatus = status; this.flattrStatus = status;
this.paged = paged; this.paged = paged;
this.nextPageLink = nextPageLink; this.nextPageLink = nextPageLink;
this.items = new ArrayList<FeedItem>();
if(filter != null) { if(filter != null) {
this.itemfilter = new FeedItemFilter(filter); this.itemfilter = new FeedItemFilter(filter);
} else { } else {
this.itemfilter = new FeedItemFilter(new String[0]); this.itemfilter = new FeedItemFilter(new String[0]);
} }
this.lastUpdateFailed = lastUpdateFailed;
items = new ArrayList<FeedItem>();
} }
/** /**
@ -126,7 +128,7 @@ public class Feed extends FeedFile implements FlattrThing, PicassoImageResource
String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl, String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl,
String downloadUrl, boolean downloaded) { String downloadUrl, boolean downloaded) {
this(id, lastUpdate, title, link, description, paymentLink, author, language, type, feedIdentifier, image, this(id, lastUpdate, title, link, description, paymentLink, author, language, type, feedIdentifier, image,
fileUrl, downloadUrl, downloaded, new FlattrStatus(), false, null, null); fileUrl, downloadUrl, downloaded, new FlattrStatus(), false, null, null, false);
} }
/** /**
@ -134,7 +136,6 @@ public class Feed extends FeedFile implements FlattrThing, PicassoImageResource
*/ */
public Feed() { public Feed() {
super(); super();
items = new ArrayList<FeedItem>();
lastUpdate = new Date(); lastUpdate = new Date();
this.flattrStatus = new FlattrStatus(); this.flattrStatus = new FlattrStatus();
} }
@ -483,14 +484,23 @@ public class Feed extends FeedFile implements FlattrThing, PicassoImageResource
this.nextPageLink = nextPageLink; this.nextPageLink = nextPageLink;
} }
public FeedItemFilter getItemFilter() { public FeedItemFilter getItemFilter() {
return itemfilter; return itemfilter;
} }
public void setFeedItemsFilter(String[] filter) { public void setFeedItemsFilter(String[] filter) {
if(filter != null) { if (filter != null) {
this.itemfilter = new FeedItemFilter(filter); this.itemfilter = new FeedItemFilter(filter);
} }
} }
public boolean hasLastUpdateFailed() {
return this.lastUpdateFailed;
}
public void setLastUpdateFailed(boolean lastUpdateFailed) {
this.lastUpdateFailed = lastUpdateFailed;
}
} }

View File

@ -193,7 +193,7 @@ public class PlaybackServiceMediaPlayer {
if(oldMedia.hasAlmostEnded()) { if(oldMedia.hasAlmostEnded()) {
Log.d(TAG, "smart mark as read"); Log.d(TAG, "smart mark as read");
FeedItem item = oldMedia.getItem(); FeedItem item = oldMedia.getItem();
DBWriter.markItemRead(context, item, true, false); // DBWriter.markItemRead(context, item, true, false);
DBWriter.removeQueueItem(context, item, false); DBWriter.removeQueueItem(context, item, false);
DBWriter.addItemToPlaybackHistory(context, oldMedia); DBWriter.addItemToPlaybackHistory(context, oldMedia);
if (UserPreferences.isAutoDelete()) { if (UserPreferences.isAutoDelete()) {

View File

@ -318,6 +318,7 @@ public final class DBReader {
cursor.getInt(PodDBAdapter.IDX_FEED_SEL_STD_IS_PAGED) > 0, cursor.getInt(PodDBAdapter.IDX_FEED_SEL_STD_IS_PAGED) > 0,
cursor.getString(PodDBAdapter.IDX_FEED_SEL_STD_NEXT_PAGE_LINK), cursor.getString(PodDBAdapter.IDX_FEED_SEL_STD_NEXT_PAGE_LINK),
cursor.getString(cursor.getColumnIndex(PodDBAdapter.KEY_HIDE)) cursor.getString(cursor.getColumnIndex(PodDBAdapter.KEY_HIDE))
cursor.getInt(PodDBAdapter.IDX_FEED_SEL_STD_LAST_UPDATE_FAILED) > 0
); );
if (image != null) { if (image != null) {
@ -964,6 +965,20 @@ public final class DBReader {
return result; return result;
} }
/**
* Returns the number of unread items.
*
* @param context A context that is used for opening a database connection.
* @return The number of unread items.
*/
public static int getNumberOfUnreadItems(final Context context, long feedId) {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
final int result = adapter.getNumberOfUnreadItems(feedId);
adapter.close();
return result;
}
/** /**
* Searches the DB for a FeedImage of the given id. * Searches the DB for a FeedImage of the given id.
* *

View File

@ -20,7 +20,6 @@ import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.asynctask.FlattrClickWorker; import de.danoeh.antennapod.core.asynctask.FlattrClickWorker;
import de.danoeh.antennapod.core.asynctask.FlattrStatusFetcher; import de.danoeh.antennapod.core.asynctask.FlattrStatusFetcher;
@ -221,8 +220,7 @@ public final class DBTasks {
* @param context Used for DB access. * @param context Used for DB access.
*/ */
public static void refreshExpiredFeeds(final Context context) { public static void refreshExpiredFeeds(final Context context) {
if (BuildConfig.DEBUG) Log.d(TAG, "Refreshing expired feeds");
Log.d(TAG, "Refreshing expired feeds");
new Thread() { new Thread() {
public void run() { public void run() {
@ -620,6 +618,7 @@ public final class DBTasks {
// update attributes // update attributes
savedFeed.setLastUpdate(newFeed.getLastUpdate()); savedFeed.setLastUpdate(newFeed.getLastUpdate());
savedFeed.setType(newFeed.getType()); savedFeed.setType(newFeed.getType());
savedFeed.setLastUpdateFailed(false);
updatedFeedsList.add(savedFeed); updatedFeedsList.add(savedFeed);
resultFeeds[feedIdx] = savedFeed; resultFeeds[feedIdx] = savedFeed;

View File

@ -354,30 +354,16 @@ public class DBWriter {
FeedItem item = null; FeedItem item = null;
if (queue != null) { if (queue != null) {
boolean queueModified = false;
boolean unreadItemsModified = false;
if (!itemListContains(queue, itemId)) { if (!itemListContains(queue, itemId)) {
item = DBReader.getFeedItem(context, itemId); item = DBReader.getFeedItem(context, itemId);
if (item != null) { if (item != null) {
queue.add(index, item); queue.add(index, item);
queueModified = true; adapter.setQueue(queue);
if (!item.isRead()) { EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED, item, index));
item.setRead(true);
unreadItemsModified = true;
}
} }
} }
if (queueModified) {
adapter.setQueue(queue);
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED, item, index));
}
if (unreadItemsModified && item != null) {
adapter.setSingleFeedItem(item);
EventDistributor.getInstance()
.sendUnreadItemsUpdateBroadcast();
}
} }
adapter.close(); adapter.close();
if (performAutoDownload) { if (performAutoDownload) {
DBTasks.autodownloadUndownloadedItems(context); DBTasks.autodownloadUndownloadedItems(context);
@ -935,6 +921,26 @@ public class DBWriter {
}); });
} }
/**
* Saves if a feed's last update failed
*
* @param lastUpdateFailed true if last update failed
*/
public static Future<?> setFeedLastUpdateFailed(final Context context,
final long feedId,
final boolean lastUpdateFailed) {
return dbExec.submit(new Runnable() {
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
adapter.setFeedLastUpdateFailed(feedId, lastUpdateFailed);
adapter.close();
}
});
}
/** /**
* format an url for querying the database * format an url for querying the database
* (postfix a / and apply percent-encoding) * (postfix a / and apply percent-encoding)

View File

@ -29,6 +29,8 @@ import de.danoeh.antennapod.core.feed.FeedPreferences;
import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus; import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
;
// TODO Remove media column from feeditem table // TODO Remove media column from feeditem table
/** /**
@ -151,6 +153,7 @@ public class PodDBAdapter {
public static final String KEY_IS_PAGED = "is_paged"; public static final String KEY_IS_PAGED = "is_paged";
public static final String KEY_NEXT_PAGE_LINK = "next_page_link"; public static final String KEY_NEXT_PAGE_LINK = "next_page_link";
public static final String KEY_HIDE = "hide"; public static final String KEY_HIDE = "hide";
public static final String KEY_LAST_UPDATE_FAILED = "last_update_failed";
// Table names // Table names
public static final String TABLE_NAME_FEEDS = "Feeds"; public static final String TABLE_NAME_FEEDS = "Feeds";
@ -250,7 +253,8 @@ public class PodDBAdapter {
TABLE_NAME_FEEDS + "." + KEY_NEXT_PAGE_LINK, TABLE_NAME_FEEDS + "." + KEY_NEXT_PAGE_LINK,
TABLE_NAME_FEEDS + "." + KEY_USERNAME, TABLE_NAME_FEEDS + "." + KEY_USERNAME,
TABLE_NAME_FEEDS + "." + KEY_PASSWORD, TABLE_NAME_FEEDS + "." + KEY_PASSWORD,
TABLE_NAME_FEEDS + "." + KEY_HIDE TABLE_NAME_FEEDS + "." + KEY_HIDE,
TABLE_NAME_FEEDS + "." + KEY_LAST_UPDATE_FAILED,
}; };
// column indices for FEED_SEL_STD // column indices for FEED_SEL_STD
@ -274,6 +278,7 @@ public class PodDBAdapter {
public static final int IDX_FEED_SEL_STD_NEXT_PAGE_LINK = 17; public static final int IDX_FEED_SEL_STD_NEXT_PAGE_LINK = 17;
public static final int IDX_FEED_SEL_PREFERENCES_USERNAME = 18; public static final int IDX_FEED_SEL_PREFERENCES_USERNAME = 18;
public static final int IDX_FEED_SEL_PREFERENCES_PASSWORD = 19; public static final int IDX_FEED_SEL_PREFERENCES_PASSWORD = 19;
public static final int IDX_FEED_SEL_STD_LAST_UPDATE_FAILED = 20;
/** /**
@ -408,6 +413,7 @@ public class PodDBAdapter {
values.put(KEY_IS_PAGED, feed.isPaged()); values.put(KEY_IS_PAGED, feed.isPaged());
values.put(KEY_NEXT_PAGE_LINK, feed.getNextPageLink()); values.put(KEY_NEXT_PAGE_LINK, feed.getNextPageLink());
values.put(KEY_HIDE, StringUtils.join(feed.getItemFilter(), ",")); values.put(KEY_HIDE, StringUtils.join(feed.getItemFilter(), ","));
values.put(KEY_LAST_UPDATE_FAILED, feed.hasLastUpdateFailed());
if (feed.getId() == 0) { if (feed.getId() == 0) {
// Create new entry // Create new entry
Log.d(this.toString(), "Inserting new Feed into db"); Log.d(this.toString(), "Inserting new Feed into db");
@ -779,6 +785,12 @@ public class PodDBAdapter {
} }
} }
public void setFeedLastUpdateFailed(long feedId, boolean failed) {
ContentValues values = new ContentValues();
values.put(KEY_LAST_UPDATE_FAILED, failed ? 1 : 0);
db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(feedId)});
}
/** /**
* Inserts or updates a download status. * Inserts or updates a download status.
*/ */
@ -1149,7 +1161,7 @@ public class PodDBAdapter {
} }
public final Cursor getFeedItemCursor(final String id) { public final Cursor getFeedItemCursor(final String id) {
return getFeedItemCursor(new String[] { id }); return getFeedItemCursor(new String[]{id});
} }
public final Cursor getFeedItemCursor(final String[] ids) { public final Cursor getFeedItemCursor(final String[] ids) {
@ -1211,6 +1223,18 @@ public class PodDBAdapter {
return result; return result;
} }
public final int getNumberOfUnreadItems(long feedId) {
final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_ITEMS +
" WHERE " + KEY_FEED + " = " + feedId + " AND " + KEY_READ + " = 0";
Cursor c = db.rawQuery(query, null);
int result = 0;
if (c.moveToFirst()) {
result = c.getInt(0);
}
c.close();
return result;
}
public final int getNumberOfDownloadedEpisodes() { public final int getNumberOfDownloadedEpisodes() {
final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_MEDIA + final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_MEDIA +
" WHERE " + KEY_DOWNLOADED + " > 0"; " WHERE " + KEY_DOWNLOADED + " > 0";

View File

@ -100,6 +100,7 @@
<string name="hide_downloaded_episodes_label">Downloaded</string> <string name="hide_downloaded_episodes_label">Downloaded</string>
<string name="hide_not_downloaded_episodes_label">Not downloaded</string> <string name="hide_not_downloaded_episodes_label">Not downloaded</string>
<string name="filtered_label">Filtered</string> <string name="filtered_label">Filtered</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Last refresh failed</string>
<!-- actions on feeditems --> <!-- actions on feeditems -->
<string name="download_label">Download</string> <string name="download_label">Download</string>