summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hennen <TomHennen@users.noreply.github.com>2015-09-25 17:33:08 -0400
committerTom Hennen <TomHennen@users.noreply.github.com>2015-09-25 17:33:08 -0400
commitf27d14f4b9b1da216aa5dc3dfef72ef47001d502 (patch)
treee0c4b9f514366dc81a1be2b6528ecec08825d6db
parent5e458ec305b4f02a68e1a26ab85a005e28abd2d8 (diff)
parentc00b5f4033f6c4e74d5a30efd253482250510477 (diff)
downloadAntennaPod-f27d14f4b9b1da216aa5dc3dfef72ef47001d502.zip
Merge pull request #1213 from TomHennen/favorites
Favorites
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java8
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java36
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java111
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java18
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java15
-rw-r--r--app/src/main/res/layout/episodes_fragment_with_undo.xml (renamed from app/src/main/res/layout/new_episodes_fragment.xml)0
-rw-r--r--app/src/main/res/menu/allepisodes_context.xml9
-rw-r--r--app/src/main/res/menu/feeditem_options.xml10
-rw-r--r--app/src/main/res/menu/queue_context.xml8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/event/FavoritesEvent.java38
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/event/QueueEvent.java (renamed from core/src/main/java/de/danoeh/antennapod/core/feed/QueueEvent.java)4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java27
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java75
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java57
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java55
-rw-r--r--core/src/main/res/values/strings.xml4
31 files changed, 455 insertions, 73 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
index 869a13127..201ce17c0 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
@@ -12,7 +12,7 @@ import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.service.playback.PlaybackServiceTaskManager;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.playback.Playable;
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
index 6873cb9a6..3988669ce 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
@@ -102,7 +102,7 @@ public class DBReaderTest extends InstrumentationTestCase {
items.add(item);
}
}
- DBReader.loadFeedDataOfFeedItemlist(items);
+ DBReader.loadAdditionalFeedItemListData(items);
for (int i = 0; i < numFeeds; i++) {
for (int j = 0; j < numItems; j++) {
FeedItem item = feeds.get(i).getItems().get(j);
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
index 2a63ef4b3..585e27e0b 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -556,7 +556,7 @@ public class DBWriterTest extends InstrumentationTestCase {
}
List<Future<?>> futures = new ArrayList<Future<?>>();
for (FeedItem item : feed.getItems()) {
- futures.add(DBWriter.addQueueItem(context, item.getId()));
+ futures.add(DBWriter.addQueueItem(context, item));
}
for (Future<?> f : futures) {
f.get(TIMEOUT, TimeUnit.SECONDS);
@@ -577,7 +577,7 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter.close();
assertTrue(item.getId() != 0);
- DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.addQueueItem(context, item).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -601,7 +601,7 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter.close();
assertTrue(item.getId() != 0);
- DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.addQueueItem(context, item).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -611,7 +611,7 @@ public class DBWriterTest extends InstrumentationTestCase {
cursor.close();
adapter.close();
- DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.addQueueItem(context, item).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
cursor = adapter.getQueueIDCursor();
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
index 9859e7534..973426841 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
@@ -26,7 +26,7 @@ import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.greenrobot.event.EventBus;
import de.test.antennapod.util.service.download.HTTPBin;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
index 76d657585..4b3460476 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -43,7 +43,7 @@ import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.ProgressEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
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 f17f0ba0f..445e4832c 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
@@ -67,7 +67,7 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
}
} else if(userChoseAddToQueue() && !queueIds.contains(item.getId())) {
- DBWriter.addQueueItem(context, item.getId());
+ DBWriter.addQueueItem(context, item);
Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
} else {
confirmMobileDownload(context, item);
@@ -124,7 +124,7 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
@Override
public void onClick(DialogInterface dialog, int which) {
onlyAddToQueueTimeStamp = System.currentTimeMillis();
- DBWriter.addQueueItem(context, item.getId());
+ DBWriter.addQueueItem(context, item);
Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
}
})
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
index 37ca0ad26..8e416139e 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -361,13 +361,7 @@ public class EpisodesApplyActionFragment extends Fragment {
}
private void queueChecked() {
- LongList orderedIds = new LongList();
- for(FeedItem episode : episodes) {
- if(checkedIds.contains(episode.getId())) {
- orderedIds.add((episode.getId()));
- }
- }
- DBWriter.addQueueItem(getActivity(), false, orderedIds.toArray());
+ DBWriter.addQueueItem(getActivity(), episodes.toArray(new FeedItem[0]));
close();
}
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 5aed66013..31b24773f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -338,7 +338,6 @@ public class AllEpisodesFragment extends Fragment {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
FeedItem item = itemAccess.getItem(adapterInfo.position);
-
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.allepisodes_context, menu);
@@ -353,11 +352,27 @@ public class AllEpisodesFragment extends Fragment {
@Override
public boolean onContextItemSelected(MenuItem item) {
+ if (!getUserVisibleHint()) {
+ // we're not visible, don't do anything.
+ return false;
+ }
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
- if(menuInfo == null) {
+ if (menuInfo == null) {
menuInfo = lastMenuInfo;
}
- FeedItem selectedItem = itemAccess.getItem(menuInfo.position);
+ if (menuInfo == null) {
+ Log.e(TAG, "menuInfo is null, not doing anything");
+ return false;
+ }
+
+ FeedItem selectedItem = null;
+
+ // make sure the item still makes sense
+ if (menuInfo.position >= 0 && menuInfo.position < itemAccess.getCount()) {
+ selectedItem = itemAccess.getItem(menuInfo.position);
+ } else {
+ Log.d(TAG, "Selected item at position " + menuInfo.position + " does not exist, only " + itemAccess.getCount() + " items available");
+ }
if (selectedItem == null) {
Log.i(TAG, "Selected item at position " + menuInfo.position + " was null, ignoring selection");
@@ -452,12 +467,7 @@ public class AllEpisodesFragment extends Fragment {
};
private void updateShowOnlyEpisodesListViewState() {
- if (showOnlyNewEpisodes) {
- listView.setEmptyView(null);
- txtvEmpty.setVisibility(View.GONE);
- } else {
- listView.setEmptyView(txtvEmpty);
- }
+ listView.setEmptyView(txtvEmpty);
}
protected void loadItems() {
@@ -488,13 +498,9 @@ public class AllEpisodesFragment extends Fragment {
});
}
- private Pair<List<FeedItem>,LongList> loadData() {
+ protected Pair<List<FeedItem>,LongList> loadData() {
List<FeedItem> items;
- if(showOnlyNewEpisodes) {
- items = DBReader.getNewItemsList();
- } else {
- items = DBReader.getRecentlyPublishedEpisodes(RECENT_EPISODES_LIMIT);
- }
+ items = DBReader.getRecentlyPublishedEpisodes(RECENT_EPISODES_LIMIT);
LongList queuedIds = DBReader.getQueueIDList();
return Pair.create(items, queuedIds);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java
index e234d95ad..f23981935 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java
@@ -23,7 +23,8 @@ public class EpisodesFragment extends Fragment {
public static final int POS_NEW_EPISODES = 0;
public static final int POS_ALL_EPISODES = 1;
- public static final int TOTAL_COUNT = 2;
+ public static final int POS_FAV_EPISODES = 2;
+ public static final int TOTAL_COUNT = 3;
private TabLayout tabLayout;
@@ -91,6 +92,8 @@ public class EpisodesFragment extends Fragment {
return new AllEpisodesFragment();
case POS_NEW_EPISODES:
return new NewEpisodesFragment();
+ case POS_FAV_EPISODES:
+ return new FavoriteEpisodesFragment();
}
return null;
}
@@ -107,6 +110,8 @@ public class EpisodesFragment extends Fragment {
return resources.getString(R.string.all_episodes_short_label);
case POS_NEW_EPISODES:
return resources.getString(R.string.new_label);
+ case POS_FAV_EPISODES:
+ return resources.getString(R.string.favorite_episodes_label);
default:
return super.getPageTitle(position);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
new file mode 100644
index 000000000..95f7cfcc1
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
@@ -0,0 +1,111 @@
+package de.danoeh.antennapod.fragment;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.util.Pair;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.List;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.event.FavoritesEvent;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.util.LongList;
+import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken;
+import de.danoeh.antennapod.core.util.gui.UndoBarController;
+import de.greenrobot.event.EventBus;
+
+
+/**
+ * Like 'EpisodesFragment' except that it only shows favorite episodes and
+ * supports swiping to remove from favorites.
+ */
+
+public class FavoriteEpisodesFragment extends AllEpisodesFragment {
+
+ public static final String TAG = "FavoriteEpisodesFrag";
+
+ private static final String PREF_NAME = "PrefFavoriteEpisodesFragment";
+
+ private UndoBarController undoBarController;
+
+ public FavoriteEpisodesFragment() {
+ super(false, PREF_NAME);
+ }
+
+ public void onEvent(FavoritesEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ loadItems();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ EventBus.getDefault().register(this);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ EventBus.getDefault().unregister(this);
+ }
+
+ @Override
+ protected void resetViewState() {
+ super.resetViewState();
+ undoBarController = null;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View root = super.onCreateViewHelper(inflater, container, savedInstanceState,
+ R.layout.episodes_fragment_with_undo);
+
+ listView.setRemoveListener(which -> {
+ Log.d(TAG, "remove(" + which + ")");
+ if (subscription != null) {
+ subscription.unsubscribe();
+ }
+ FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
+
+ DBWriter.removeFavoriteItem(item);
+
+ undoBarController.showUndoBar(false,
+ getString(R.string.removed_item), new FeedItemUndoToken(item,
+ which)
+ );
+ });
+
+ undoBarController = new UndoBarController<FeedItemUndoToken>(root.findViewById(R.id.undobar), new UndoBarController.UndoListener<FeedItemUndoToken>() {
+
+ private final Context context = getActivity();
+
+ @Override
+ public void onUndo(FeedItemUndoToken token) {
+ if (token != null) {
+ long itemId = token.getFeedItemId();
+ DBWriter.addFavoriteItemById(itemId);
+ }
+ }
+
+ @Override
+ public void onHide(FeedItemUndoToken token) {
+ // nothing to do
+ }
+ });
+ return root;
+ }
+
+ @Override
+ protected Pair<List<FeedItem>,LongList> loadData() {
+ List<FeedItem> items;
+ items = DBReader.getFavoriteItemsList();
+ LongList queuedIds = DBReader.getQueueIDList();
+ return Pair.create(items, queuedIds);
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
index 353d8149c..6d28478e9 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -47,7 +47,7 @@ import de.danoeh.antennapod.core.asynctask.DownloadObserver;
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.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.Downloader;
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 3d0ff66f7..d17788dde 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -56,7 +56,7 @@ import de.danoeh.antennapod.core.feed.FeedEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedItemFilter;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.glide.FastBlurTransformation;
import de.danoeh.antennapod.core.preferences.UserPreferences;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
index d454208c1..60d0161b2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment;
import android.content.Context;
import android.os.Bundle;
+import android.support.v4.util.Pair;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -9,12 +10,15 @@ import android.view.ViewGroup;
import com.mobeta.android.dslv.DragSortListView;
+import java.util.List;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken;
import de.danoeh.antennapod.core.util.gui.UndoBarController;
import de.greenrobot.event.EventBus;
@@ -63,13 +67,13 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = super.onCreateViewHelper(inflater, container, savedInstanceState,
- R.layout.new_episodes_fragment);
+ R.layout.episodes_fragment_with_undo);
listView.setRemoveListener(new DragSortListView.RemoveListener() {
@Override
public void remove(int which) {
Log.d(TAG, "remove(" + which + ")");
- if(subscription != null) {
+ if (subscription != null) {
subscription.unsubscribe();
}
FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
@@ -109,4 +113,12 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
return root;
}
+ @Override
+ protected Pair<List<FeedItem>,LongList> loadData() {
+ List<FeedItem> items;
+ items = DBReader.getNewItemsList();
+ LongList queuedIds = DBReader.getQueueIDList();
+ return Pair.create(items, queuedIds);
+ }
+
}
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 e6460309b..d7ffa3e23 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -25,7 +25,7 @@ import de.danoeh.antennapod.core.asynctask.DownloadObserver;
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.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
@@ -277,7 +277,7 @@ public class PlaybackHistoryFragment extends ListFragment {
private Pair<List<FeedItem>, LongList> loadData() {
List<FeedItem> history = DBReader.getPlaybackHistory();
LongList queue = DBReader.getQueueIDList();
- DBReader.loadFeedDataOfFeedItemlist(history);
+ DBReader.loadAdditionalFeedItemListData(history);
return Pair.create(history, queue);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
index 7bcd98dc8..0ac33f8fb 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -37,7 +37,7 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader;
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 510ea2760..da87fb1b9 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -72,7 +72,7 @@ public class FeedItemMenuHandler {
mi.setItemVisibility(R.id.skip_episode_item, false);
}
- boolean isInQueue = queueAccess.contains(selectedItem.getId());
+ boolean isInQueue = selectedItem.isTagged(FeedItem.TAG_QUEUE);
if(queueAccess.size() == 0 || queueAccess.get(0) == selectedItem.getId()) {
mi.setItemVisibility(R.id.move_to_top_item, false);
}
@@ -123,6 +123,11 @@ public class FeedItemMenuHandler {
if (selectedItem.getPaymentLink() == null || !selectedItem.getFlattrStatus().flattrable()) {
mi.setItemVisibility(R.id.support_item, false);
}
+
+ boolean isFavorite = selectedItem.isTagged(FeedItem.TAG_FAVORITE);
+ mi.setItemVisibility(R.id.add_to_favorites_item, !isFavorite);
+ mi.setItemVisibility(R.id.remove_from_favorites_item, isFavorite);
+
return true;
}
@@ -188,11 +193,17 @@ public class FeedItemMenuHandler {
case R.id.move_to_bottom_item:
DBWriter.moveQueueItemToBottom(selectedItem.getId(), true);
case R.id.add_to_queue_item:
- DBWriter.addQueueItem(context, selectedItem.getId());
+ DBWriter.addQueueItem(context, selectedItem);
break;
case R.id.remove_from_queue_item:
DBWriter.removeQueueItem(context, selectedItem, true);
break;
+ case R.id.add_to_favorites_item:
+ DBWriter.addFavoriteItem(selectedItem);
+ break;
+ case R.id.remove_from_favorites_item:
+ DBWriter.removeFavoriteItem(selectedItem);
+ break;
case R.id.reset_position:
selectedItem.getMedia().setPosition(0);
DBWriter.markItemPlayed(selectedItem, FeedItem.UNPLAYED, true);
diff --git a/app/src/main/res/layout/new_episodes_fragment.xml b/app/src/main/res/layout/episodes_fragment_with_undo.xml
index e90171630..e90171630 100644
--- a/app/src/main/res/layout/new_episodes_fragment.xml
+++ b/app/src/main/res/layout/episodes_fragment_with_undo.xml
diff --git a/app/src/main/res/menu/allepisodes_context.xml b/app/src/main/res/menu/allepisodes_context.xml
index 171e509a8..c5356535c 100644
--- a/app/src/main/res/menu/allepisodes_context.xml
+++ b/app/src/main/res/menu/allepisodes_context.xml
@@ -24,7 +24,14 @@
android:id="@+id/remove_from_queue_item"
android:menuCategory="container"
android:title="@string/remove_from_queue_label" />
-
+ <item
+ android:id="@+id/add_to_favorites_item"
+ android:menuCategory="container"
+ android:title="@string/add_to_favorite_label" />
+ <item
+ android:id="@+id/remove_from_favorites_item"
+ android:menuCategory="container"
+ android:title="@string/remove_from_favorite_label" />
<item
android:id="@+id/reset_position"
android:menuCategory="container"
diff --git a/app/src/main/res/menu/feeditem_options.xml b/app/src/main/res/menu/feeditem_options.xml
index 650912ea2..898081486 100644
--- a/app/src/main/res/menu/feeditem_options.xml
+++ b/app/src/main/res/menu/feeditem_options.xml
@@ -31,6 +31,16 @@
</item>
<item
+ android:id="@+id/add_to_favorites_item"
+ android:menuCategory="container"
+ android:title="@string/add_to_favorite_label" />
+
+ <item
+ android:id="@+id/remove_from_favorites_item"
+ android:menuCategory="container"
+ android:title="@string/remove_from_favorite_label" />
+
+ <item
android:id="@+id/reset_position"
custom:showAsAction="collapseActionView"
android:title="@string/reset_position">
diff --git a/app/src/main/res/menu/queue_context.xml b/app/src/main/res/menu/queue_context.xml
index d09f3c84c..3eb1d9d5e 100644
--- a/app/src/main/res/menu/queue_context.xml
+++ b/app/src/main/res/menu/queue_context.xml
@@ -28,6 +28,14 @@
android:title="@string/remove_from_queue_label" />
<item
+ android:id="@+id/add_to_favorites_item"
+ android:menuCategory="container"
+ android:title="@string/add_to_favorite_label" />
+ <item
+ android:id="@+id/remove_from_favorites_item"
+ android:menuCategory="container"
+ android:title="@string/remove_from_favorite_label" />
+ <item
android:id="@+id/reset_position"
android:menuCategory="container"
android:title="@string/reset_position" />
diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/FavoritesEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/FavoritesEvent.java
new file mode 100644
index 000000000..d09f6802f
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/event/FavoritesEvent.java
@@ -0,0 +1,38 @@
+package de.danoeh.antennapod.core.event;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import de.danoeh.antennapod.core.feed.FeedItem;
+
+public class FavoritesEvent {
+
+ public enum Action {
+ ADDED, REMOVED
+ }
+
+ public final Action action;
+ public final FeedItem item;
+
+ private FavoritesEvent(Action action, FeedItem item) {
+ this.action = action;
+ this.item = item;
+ }
+
+ public static FavoritesEvent added(FeedItem item) {
+ return new FavoritesEvent(Action.ADDED, item);
+ }
+
+ public static FavoritesEvent removed(FeedItem item) {
+ return new FavoritesEvent(Action.REMOVED, item);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append("action", action)
+ .append("item", item)
+ .toString();
+ }
+
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/QueueEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/QueueEvent.java
index 97d086e5b..4d59d75eb 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/QueueEvent.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/event/QueueEvent.java
@@ -1,10 +1,12 @@
-package de.danoeh.antennapod.core.feed;
+package de.danoeh.antennapod.core.event;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.List;
+import de.danoeh.antennapod.core.feed.FeedItem;
+
public class QueueEvent {
public enum Action {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java b/core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java
index 20a85d43f..2667a2e12 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/EventDistributor.java
@@ -112,9 +112,7 @@ public class EventDistributor extends Observable {
addEvent(DOWNLOAD_HANDLED);
}
- public void sendPlayerStatusUpdateBroadcast() {
- addEvent(PLAYER_STATUS_UPDATE);
- }
+ public void sendPlayerStatusUpdateBroadcast() { addEvent(PLAYER_STATUS_UPDATE); }
public static abstract class EventListener implements Observer {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
index 5c3ed303f..c54cc1d5b 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java
@@ -7,7 +7,9 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.Callable;
import de.danoeh.antennapod.core.asynctask.ImageResource;
@@ -24,6 +26,11 @@ import de.danoeh.antennapod.core.util.flattr.FlattrThing;
*/
public class FeedItem extends FeedComponent implements ShownotesProvider, FlattrThing, ImageResource {
+ /** tag that indicates this item is in the queue */
+ public static final String TAG_QUEUE = "Queue";
+ /** tag that indicates this item is in favorites */
+ public static final String TAG_FAVORITE = "Favorite";
+
/**
* The id/guid that can be found in the rss/atom feed. Might not be set.
*/
@@ -70,6 +77,11 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
private boolean autoDownload = true;
+ /**
+ * Any tags assigned to this item
+ */
+ private Set<String> tags = new HashSet<>();
+
public FeedItem() {
this.state = UNPLAYED;
this.flattrStatus = new FlattrStatus();
@@ -451,6 +463,21 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
this.getAutoDownload();
}
+ /**
+ * @return true if the item has this tag
+ */
+ public boolean isTagged(String tag) { return tags.contains(tag); }
+
+ /**
+ * @param tag adds this tag to the item. NOTE: does NOT persist to the database
+ */
+ public void addTag(String tag) { tags.add(tag); }
+
+ /**
+ * @param tag the to remove
+ */
+ public void removeTag(String tag) { tags.remove(tag); }
+
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
index 36ea1e222..cb050463e 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
@@ -1129,7 +1129,7 @@ public class DownloadService extends Service {
DBWriter.setFeedMedia(media).get();
if (!DBTasks.isInQueue(DownloadService.this, item.getId())) {
- DBWriter.addQueueItem(DownloadService.this, item.getId()).get();
+ DBWriter.addQueueItem(DownloadService.this, item).get();
}
} catch (ExecutionException e) {
e.printStackTrace();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
index dba66a36d..19ef6ef09 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
@@ -16,7 +16,7 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.greenrobot.event.EventBus;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
index 4ef4ac067..d95e4ff02 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
@@ -104,6 +104,30 @@ public final class DBReader {
return result;
}
+
+ /**
+ * Loads additional data in to the feed items from other database queries
+ * @param items the FeedItems who should have other data loaded
+ */
+ public static void loadAdditionalFeedItemListData(List<FeedItem> items) {
+ loadTagsOfFeedItemList(items);
+ loadFeedDataOfFeedItemList(items);
+ }
+
+ public static void loadTagsOfFeedItemList(List<FeedItem> items) {
+ LongList favoriteIds = getFavoriteIDList();
+ LongList queueIds = getQueueIDList();
+
+ for (FeedItem item : items) {
+ if (favoriteIds.contains(item.getId())) {
+ item.addTag(FeedItem.TAG_FAVORITE);
+ }
+ if (queueIds.contains(item.getId())) {
+ item.addTag(FeedItem.TAG_QUEUE);
+ }
+ }
+ }
+
/**
* Takes a list of FeedItems and loads their corresponding Feed-objects from the database.
* The feedID-attribute of a FeedItem must be set to the ID of its feed or the method will
@@ -111,7 +135,7 @@ public final class DBReader {
*
* @param items The FeedItems whose Feed-objects should be loaded.
*/
- public static void loadFeedDataOfFeedItemlist(List<FeedItem> items) {
+ public static void loadFeedDataOfFeedItemList(List<FeedItem> items) {
List<Feed> feeds = getFeedList();
for (FeedItem item : items) {
for (Feed feed : feeds) {
@@ -251,7 +275,7 @@ public final class DBReader {
Cursor itemlistCursor = adapter.getQueueCursor();
List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
itemlistCursor.close();
- loadFeedDataOfFeedItemlist(items);
+ loadAdditionalFeedItemListData(items);
return items;
}
@@ -316,7 +340,7 @@ public final class DBReader {
List<FeedItem> items = extractItemlistFromCursor(adapter,
itemlistCursor);
itemlistCursor.close();
- loadFeedDataOfFeedItemlist(items);
+ loadAdditionalFeedItemListData(items);
Collections.sort(items, new FeedItemPubdateComparator());
adapter.close();
@@ -338,7 +362,7 @@ public final class DBReader {
List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
itemlistCursor.close();
- loadFeedDataOfFeedItemlist(items);
+ loadAdditionalFeedItemListData(items);
adapter.close();
@@ -360,13 +384,44 @@ public final class DBReader {
List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
itemlistCursor.close();
- loadFeedDataOfFeedItemlist(items);
+ loadAdditionalFeedItemListData(items);
+
+ adapter.close();
+
+ return items;
+ }
+
+ public static List<FeedItem> getFavoriteItemsList() {
+ Log.d(TAG, "getFavoriteItemsList()");
+
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+
+ Cursor itemlistCursor = adapter.getFavoritesCursor();
+ List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
+ itemlistCursor.close();
+
+ loadAdditionalFeedItemListData(items);
adapter.close();
return items;
}
+ static LongList getFavoriteIDList() {
+ PodDBAdapter adapter = PodDBAdapter.getInstance().open();
+ Cursor favoritesCursor = adapter.getFavoritesCursor();
+
+ LongList favoriteIDs = new LongList(favoritesCursor.getCount());
+ if (favoritesCursor.moveToFirst()) {
+ do {
+ favoriteIDs.add(favoritesCursor.getLong(0));
+ } while (favoritesCursor.moveToNext());
+ }
+ favoritesCursor.close();
+ return favoriteIDs;
+ }
+
/**
* Loads a list of FeedItems sorted by pubDate in descending order.
*
@@ -382,7 +437,7 @@ public final class DBReader {
List<FeedItem> items = extractItemlistFromCursor(adapter, itemlistCursor);
itemlistCursor.close();
- loadFeedDataOfFeedItemlist(items);
+ loadAdditionalFeedItemListData(items);
adapter.close();
@@ -411,7 +466,7 @@ public final class DBReader {
mediaCursor.close();
Cursor itemCursor = adapter.getFeedItemCursor(itemIds);
List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor);
- loadFeedDataOfFeedItemlist(items);
+ loadAdditionalFeedItemListData(items);
itemCursor.close();
adapter.close();
@@ -533,7 +588,7 @@ public final class DBReader {
List<FeedItem> list = extractItemlistFromCursor(adapter, itemCursor);
if (list.size() > 0) {
item = list.get(0);
- loadFeedDataOfFeedItemlist(list);
+ loadAdditionalFeedItemListData(list);
if (item.hasChapters()) {
loadChaptersOfFeedItem(adapter, item);
}
@@ -556,7 +611,7 @@ public final class DBReader {
Cursor itemCursor = adapter.getFeedItemCursor(ids);
if (itemCursor.moveToFirst()) {
result = extractItemlistFromCursor(adapter, itemCursor);
- loadFeedDataOfFeedItemlist(result);
+ loadAdditionalFeedItemListData(result);
for(FeedItem item : result) {
if (item.hasChapters()) {
loadChaptersOfFeedItem(adapter, item);
@@ -596,7 +651,7 @@ public final class DBReader {
List<FeedItem> list = extractItemlistFromCursor(adapter, itemCursor);
if (list.size() > 0) {
item = list.get(0);
- loadFeedDataOfFeedItemlist(list);
+ loadAdditionalFeedItemListData(list);
if (item.hasChapters()) {
loadChaptersOfFeedItem(adapter, item);
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
index 96a632d68..3f9cece77 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
@@ -601,7 +601,7 @@ public final class DBTasks {
Cursor searchResult = adapter.searchItemTitles(feedID,
query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
- DBReader.loadFeedDataOfFeedItemlist(items);
+ DBReader.loadAdditionalFeedItemListData(items);
setResult(items);
searchResult.close();
}
@@ -625,7 +625,7 @@ public final class DBTasks {
Cursor searchResult = adapter.searchItemDescriptions(feedID,
query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
- DBReader.loadFeedDataOfFeedItemlist(items);
+ DBReader.loadAdditionalFeedItemListData(items);
setResult(items);
searchResult.close();
}
@@ -649,7 +649,7 @@ public final class DBTasks {
Cursor searchResult = adapter.searchItemContentEncoded(feedID,
query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
- DBReader.loadFeedDataOfFeedItemlist(items);
+ DBReader.loadAdditionalFeedItemListData(items);
setResult(items);
searchResult.close();
}
@@ -672,7 +672,7 @@ public final class DBTasks {
Cursor searchResult = adapter.searchItemChapters(feedID,
query);
List<FeedItem> items = DBReader.extractItemlistFromCursor(searchResult);
- DBReader.loadFeedDataOfFeedItemlist(items);
+ DBReader.loadAdditionalFeedItemListData(items);
setResult(items);
searchResult.close();
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
index 521f960ec..bae31b52b 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
@@ -26,6 +26,7 @@ import java.util.concurrent.Future;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.asynctask.FlattrClickWorker;
+import de.danoeh.antennapod.core.event.FavoritesEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedEvent;
@@ -33,7 +34,7 @@ import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.FeedPreferences;
-import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
@@ -317,6 +318,7 @@ public class DBWriter {
if (item != null) {
queue.add(index, item);
adapter.setQueue(queue);
+ item.addTag(FeedItem.TAG_QUEUE);
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED, item, index));
if (item.isNew()) {
DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
@@ -335,8 +337,13 @@ public class DBWriter {
}
public static Future<?> addQueueItem(final Context context,
- final long... itemIds) {
- return addQueueItem(context, false, itemIds);
+ final FeedItem... items) {
+ LongList itemIds = new LongList(items.length);
+ for (FeedItem item : items) {
+ itemIds.add(item.getId());
+ item.addTag(FeedItem.TAG_QUEUE);
+ }
+ return addQueueItem(context, false, itemIds.toArray());
}
/**
@@ -371,7 +378,7 @@ public class DBWriter {
queue.add(item);
}
queueModified = true;
- if(item.isNew()) {
+ if (item.isNew()) {
markAsUnplayedIds.add(item.getId());
}
}
@@ -380,8 +387,8 @@ public class DBWriter {
if (queueModified) {
adapter.setQueue(queue);
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED_ITEMS, queue));
- if(markAsUnplayedIds.size() > 0) {
- DBWriter.markItemPlayed(FeedItem.UNPLAYED, markAsUnplayedIds.toArray());
+ if (markAsUnplayedIds.size() > 0) {
+ DBWriter.markItemPlayed(FeedItem.UNPLAYED, markAsUnplayedIds.toArray());
}
}
}
@@ -424,9 +431,10 @@ public class DBWriter {
if (queue != null) {
int position = queue.indexOf(item);
- if(position >= 0) {
+ if (position >= 0) {
queue.remove(position);
adapter.setQueue(queue);
+ item.removeTag(FeedItem.TAG_QUEUE);
EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.REMOVED, item, position));
} else {
Log.w(TAG, "Queue was not modified by call to removeQueueItem");
@@ -442,6 +450,41 @@ public class DBWriter {
}
+ public static Future<?> addFavoriteItem(final FeedItem item) {
+ return dbExec.submit(() -> {
+ final PodDBAdapter adapter = PodDBAdapter.getInstance().open();
+ adapter.addFavoriteItem(item);
+ adapter.close();
+ item.addTag(FeedItem.TAG_FAVORITE);
+ EventBus.getDefault().post(FavoritesEvent.added(item));
+ });
+ }
+
+ public static Future<?> addFavoriteItemById(final long itemId) {
+ return dbExec.submit(() -> {
+ final FeedItem item = DBReader.getFeedItem(itemId);
+ if (item == null) {
+ Log.d(TAG, "Can't find item for itemId " + itemId);
+ return;
+ }
+ final PodDBAdapter adapter = PodDBAdapter.getInstance().open();
+ adapter.addFavoriteItem(item);
+ adapter.close();
+ item.addTag(FeedItem.TAG_FAVORITE);
+ EventBus.getDefault().post(FavoritesEvent.added(item));
+ });
+ }
+
+ public static Future<?> removeFavoriteItem(final FeedItem item) {
+ return dbExec.submit(() -> {
+ final PodDBAdapter adapter = PodDBAdapter.getInstance().open();
+ adapter.removeFavoriteItem(item);
+ adapter.close();
+ item.removeTag(FeedItem.TAG_FAVORITE);
+ EventBus.getDefault().post(FavoritesEvent.removed(item));
+ });
+ }
+
/**
* Moves the specified item to the top of the queue.
* @param itemId The item to move to the top of the queue
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
index fa4a5726a..730b02f1d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
@@ -39,7 +39,7 @@ import de.greenrobot.event.EventBus;
/**
* Implements methods for accessing the database
*/
-public class PodDBAdapter {
+public class PodDBAdapter implements AutoCloseable {
private static final String TAG = "PodDBAdapter";
public static final String DATABASE_NAME = "Antennapod.db";
@@ -113,6 +113,7 @@ public class PodDBAdapter {
public static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog";
public static final String TABLE_NAME_QUEUE = "Queue";
public static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters";
+ public static final String TABLE_NAME_FAVORITES = "Favorites";
// SQL Statements for creating new tables
private static final String TABLE_PRIMARY_KEY = KEY_ID
@@ -197,6 +198,10 @@ public class PodDBAdapter {
public static final String CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM = "CREATE INDEX "
+ TABLE_NAME_SIMPLECHAPTERS + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_SIMPLECHAPTERS + " ("
+ KEY_FEEDITEM + ")";
+
+ public static final String CREATE_TABLE_FAVORITES = "CREATE TABLE "
+ + TABLE_NAME_FAVORITES + "(" + KEY_ID + " INTEGER PRIMARY KEY,"
+ + KEY_FEEDITEM + " INTEGER," + KEY_FEED + " INTEGER)";
/**
* Select all columns from the feed-table
@@ -785,6 +790,38 @@ public class PodDBAdapter {
db.execSQL(sql);
}
+ /**
+ * Adds the item to favorites
+ */
+ public void addFavoriteItem(FeedItem item) {
+ // don't add an item that's already there...
+ if (isItemInFavorites(item)) {
+ Log.d(TAG, "item already in favorites");
+ return;
+ }
+ ContentValues values = new ContentValues();
+ values.put(KEY_FEEDITEM, item.getId());
+ values.put(KEY_FEED, item.getFeedId());
+ db.insert(TABLE_NAME_FAVORITES, null, values);
+ }
+
+ public void removeFavoriteItem(FeedItem item) {
+ String deleteClause = String.format("DELETE FROM %s WHERE %s=%s AND %s=%s",
+ TABLE_NAME_FAVORITES,
+ KEY_FEEDITEM, item.getId(),
+ KEY_FEED, item.getFeedId());
+ db.execSQL(deleteClause);
+ }
+
+ public boolean isItemInFavorites(FeedItem item) {
+ String query = String.format("SELECT %s from %s WHERE %s=%d",
+ KEY_ID, TABLE_NAME_FAVORITES, KEY_FEEDITEM, item.getId());
+ Cursor c = db.rawQuery(query, null);
+ int count = c.getCount();
+ c.close();
+ return count > 0;
+ }
+
public long getDownloadLogSize() {
final String query = String.format("SELECT COUNT(%s) FROM %s", KEY_ID, TABLE_NAME_DOWNLOAD_LOG);
Cursor result = db.rawQuery(query, null);
@@ -990,6 +1027,19 @@ public class PodDBAdapter {
return c;
}
+
+ public final Cursor getFavoritesCursor() {
+ Object[] args = new String[] {
+ SEL_FI_SMALL_STR,
+ TABLE_NAME_FEED_ITEMS, TABLE_NAME_FAVORITES,
+ TABLE_NAME_FEED_ITEMS + "." + KEY_ID,
+ TABLE_NAME_FAVORITES + "." + KEY_FEEDITEM,
+ TABLE_NAME_FAVORITES + "." + KEY_ID };
+ String query = String.format("SELECT %s FROM %s INNER JOIN %s ON %s=%s ORDER BY %s", args);
+ Cursor c = db.rawQuery(query, null);
+ return c;
+ }
+
/**
* Returns a cursor which contains all feed items in the unread items list.
* The returned cursor uses the FEEDITEM_SEL_FI_SMALL selection.
@@ -1374,7 +1424,7 @@ public class PodDBAdapter {
*/
private static class PodDBHelper extends SQLiteOpenHelper {
- private final static int VERSION = 1030002;
+ private final static int VERSION = 1040000;
private Context context;
@@ -1400,6 +1450,7 @@ public class PodDBAdapter {
db.execSQL(CREATE_TABLE_DOWNLOAD_LOG);
db.execSQL(CREATE_TABLE_QUEUE);
db.execSQL(CREATE_TABLE_SIMPLECHAPTERS);
+ db.execSQL(CREATE_TABLE_FAVORITES);
db.execSQL(CREATE_INDEX_FEEDITEMS_FEED);
db.execSQL(CREATE_INDEX_FEEDITEMS_IMAGE);
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index ff9891bab..951b0b9ba 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -12,6 +12,7 @@
<string name="new_episodes_label">New Episodes</string>
<string name="all_episodes_label">All Episodes</string>
<string name="all_episodes_short_label">All</string>
+ <string name="favorite_episodes_label">Favorites</string>
<string name="new_label">New</string>
<string name="waiting_list_label">Waiting List</string>
<string name="settings_label">Settings</string>
@@ -137,6 +138,8 @@
<string name="add_to_queue_label">Add to Queue</string>
<string name="added_to_queue_label">Added to Queue</string>
<string name="remove_from_queue_label">Remove from Queue</string>
+ <string name="add_to_favorite_label">Add to Favorites</string>
+ <string name="remove_from_favorite_label">Remove from Favorites</string>
<string name="visit_website_label">Visit Website</string>
<string name="support_label">Flattr this</string>
<string name="enqueue_all_new">Enqueue all</string>
@@ -145,6 +148,7 @@
<string name="activate_auto_download">Activate Auto Download</string>
<string name="deactivate_auto_download">Deactivate Auto Download</string>
<string name="reset_position">Reset Playback Position</string>
+ <string name="removed_item">Item removed</string>
<!-- Download messages and labels -->
<string name="download_successful">successful</string>