summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/build.gradle46
-rw-r--r--app/proguard.cfg12
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java17
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java5
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java19
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java30
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java103
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java4
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java14
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java4
-rw-r--r--app/src/main/AndroidManifest.xml4
-rw-r--r--app/src/main/assets/.gitignore2
-rw-r--r--app/src/main/assets/LICENSE_ANDROID_ICONIFY.txt18
-rw-r--r--app/src/main/assets/LICENSE_EVENTBUS.txt202
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java105
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java42
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java348
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java131
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java39
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java40
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java104
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java102
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java123
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java18
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java21
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java18
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java11
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java23
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java31
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java75
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java55
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java43
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java101
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java22
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java49
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java33
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java37
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java34
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java47
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java37
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java67
-rw-r--r--app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java42
-rw-r--r--app/src/main/res/layout/audioplayer_activity.xml24
-rw-r--r--app/src/main/res/layout/downloadlog_item.xml120
-rw-r--r--app/src/main/res/layout/feedinfo.xml162
-rw-r--r--app/src/main/res/layout/feeditemlist_header.xml15
-rw-r--r--app/src/main/res/layout/nav_feedlistitem.xml6
-rw-r--r--app/src/main/res/layout/nav_list.xml64
-rw-r--r--app/src/main/res/layout/nav_listitem.xml12
-rw-r--r--app/src/main/res/layout/nav_section_item.xml2
-rw-r--r--app/src/main/res/layout/queue_listitem.xml6
-rw-r--r--app/src/main/res/menu/feedlist.xml7
-rw-r--r--app/src/main/res/menu/queue.xml6
-rw-r--r--app/src/main/res/xml/preferences.xml25
-rw-r--r--app/src/main/templates/about.html (renamed from app/src/main/assets/about.html)12
62 files changed, 2018 insertions, 787 deletions
diff --git a/app/build.gradle b/app/build.gradle
index b59106248..bb1fa26b7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,3 +1,5 @@
+import org.apache.tools.ant.filters.ReplaceTokens
+
apply plugin: 'com.android.application'
repositories {
@@ -6,6 +8,7 @@ repositories {
dependencies {
compile 'com.android.support:support-v4:21.0.3'
compile 'com.android.support:appcompat-v7:21.0.3'
+ compile 'com.android.support:gridlayout-v7:21.0.3'
compile 'org.apache.commons:commons-lang3:3.3.2'
compile('org.shredzone.flattr4j:flattr4j-core:2.12') {
exclude group: 'org.json', module: 'json'
@@ -13,14 +16,30 @@ dependencies {
compile 'commons-io:commons-io:2.4'
compile 'com.jayway.android.robotium:robotium-solo:5.2.1'
compile 'org.jsoup:jsoup:1.7.3'
- compile 'com.squareup.picasso:picasso:2.4.0'
- compile 'com.squareup.okhttp:okhttp:2.2.0'
- compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
+ compile 'com.squareup.picasso:picasso:2.5.2'
+ compile 'com.squareup.okhttp:okhttp:2.3.0'
+ compile 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
compile 'com.squareup.okio:okio:1.2.0'
+ compile 'de.greenrobot:eventbus:2.4.0'
+ compile 'com.joanzapata.android:android-iconify:1.0.9'
compile project(':core')
compile project(':library:drag-sort-listview')
}
+def getMyVersionName() {
+ def parsedManifestXml = (new XmlSlurper())
+ .parse('app/src/main/AndroidManifest.xml')
+ .declareNamespace(android:"http://schemas.android.com/apk/res/android")
+ return parsedManifestXml.'@android:versionName'
+}
+
+def getMyVersionCode() {
+ def parsedManifestXml = (new XmlSlurper())
+ .parse('app/src/main/AndroidManifest.xml')
+ .declareNamespace(android:"http://schemas.android.com/apk/res/android")
+ return parsedManifestXml.'@android:versionCode'.toInteger()
+}
+
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
@@ -28,6 +47,8 @@ android {
defaultConfig {
minSdkVersion 10
targetSdkVersion 21
+ versionCode getMyVersionCode()
+ versionName "${getMyVersionName()}"
testApplicationId "de.test.antennapod"
testInstrumentationRunner "de.test.antennapod.AntennaPodTestRunner"
}
@@ -86,4 +107,21 @@ android {
lintOptions {
abortOnError false
}
-} \ No newline at end of file
+}
+
+// about.html is templatized so that we can automatically insert
+// our version string in to it at build time.
+task filterAbout {
+ inputs.files files(['src/main/templates/about.html',
+ 'src/main/AndroidManifest.xml'])
+ outputs.file 'src/main/assets/about.html'
+} << {
+ copy {
+ from 'src/main/templates/about.html'
+ into 'src/main/assets'
+ filter(ReplaceTokens, tokens: [versionname: android.defaultConfig.versionName,
+ versioncode: android.defaultConfig.versionCode.toString()])
+ }
+}
+
+preBuild.dependsOn filterAbout \ No newline at end of file
diff --git a/app/proguard.cfg b/app/proguard.cfg
index d0aa1b6a9..536f54eca 100644
--- a/app/proguard.cfg
+++ b/app/proguard.cfg
@@ -1,5 +1,7 @@
+-dontobfuscate
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
+-optimizations !code/allocation/variable
-dontpreverify
-repackageclasses ''
@@ -78,4 +80,12 @@
public static *** w(...);
public static *** d(...);
public static *** e(...);
-} \ No newline at end of file
+}
+
+# greenrobot EventBus
+-keepclassmembers class ** {
+ public void onEvent*(**);
+}
+
+# android-iconify
+-keep class com.joanzapata.** { *; }
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 81d684595..d74128c2f 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
@@ -2,12 +2,6 @@ package de.test.antennapod.service.playback;
import android.content.Context;
import android.test.InstrumentationTestCase;
-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.service.playback.PlaybackServiceTaskManager;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
-import de.danoeh.antennapod.core.util.playback.Playable;
import java.util.ArrayList;
import java.util.Date;
@@ -15,6 +9,15 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
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.service.playback.PlaybackServiceTaskManager;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.core.util.playback.Playable;
+import de.greenrobot.event.EventBus;
+
/**
* Test class for PlaybackServiceTaskManager
*/
@@ -94,7 +97,7 @@ public class PlaybackServiceTaskManagerTest extends InstrumentationTestCase {
};
EventDistributor.getInstance().register(queueListener);
List<FeedItem> queue = writeTestQueue("a");
- EventDistributor.getInstance().sendQueueUpdateBroadcast();
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED_ITEMS, queue));
countDownLatch.await(5000, TimeUnit.MILLISECONDS);
assertNotNull(queue);
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 1f6a907d4..b90c4e2a1 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
@@ -14,6 +14,7 @@ import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.FeedItemStatistics;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import static de.test.antennapod.storage.DBTestUtils.saveFeedlist;
@@ -44,7 +45,7 @@ public class DBReaderTest extends InstrumentationTestCase {
private void expiredFeedListTestHelper(long lastUpdate, long expirationTime, boolean shouldReturn) {
final Context context = getInstrumentation().getTargetContext();
Feed feed = new Feed(0, new Date(lastUpdate), "feed", "link", "descr", null,
- null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null);
+ null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null, null);
feed.setItems(new ArrayList<FeedItem>());
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
@@ -194,7 +195,7 @@ public class DBReaderTest extends InstrumentationTestCase {
final Context context = getInstrumentation().getTargetContext();
final int numItems = 10;
List<FeedItem> queue = saveQueue(numItems);
- List<Long> ids = DBReader.getQueueIDList(context);
+ LongList ids = DBReader.getQueueIDList(context);
assertNotNull(ids);
assertTrue(queue.size() == ids.size());
for (int i = 0; i < queue.size(); i++) {
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
index e28a7918f..41d3805bd 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
@@ -4,6 +4,14 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.test.InstrumentationTestCase;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
@@ -13,14 +21,7 @@ import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
-import static de.test.antennapod.storage.DBTestUtils.*;
+import static de.test.antennapod.storage.DBTestUtils.saveFeedlist;
/**
* Test class for DBTasks
@@ -296,7 +297,7 @@ public class DBTasksTest extends InstrumentationTestCase {
final Context context = getInstrumentation().getTargetContext();
UserPreferences.setUpdateInterval(context, expirationTime);
Feed feed = new Feed(0, new Date(lastUpdate), "feed", "link", "descr", null,
- null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null);
+ null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null, null);
feed.setItems(new ArrayList<FeedItem>());
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
index 17c926cc2..fba3faa96 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
@@ -47,7 +47,7 @@ public class DBTestUtils {
adapter.open();
for (int i = 0; i < numFeeds; i++) {
Feed f = new Feed(0, new Date(), "feed " + i, "link" + i, "descr", null, null,
- null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null);
+ null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null);
f.setItems(new ArrayList<FeedItem>());
for (int j = 0; j < numItems; j++) {
FeedItem item = new FeedItem(0, "item " + j, "id" + j, "link" + j, new Date(),
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 ec8e19e22..f3b0c9165 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -5,16 +5,6 @@ import android.database.Cursor;
import android.test.InstrumentationTestCase;
import android.util.Log;
-import de.danoeh.antennapod.core.feed.Chapter;
-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.SimpleChapter;
-import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
-
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -25,6 +15,16 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import de.danoeh.antennapod.core.feed.Chapter;
+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.SimpleChapter;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+
/**
* Test class for DBWriter
*/
@@ -674,13 +674,13 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(item.getId() != 0);
}
for (int removeIndex = 0; removeIndex < NUM_ITEMS; removeIndex++) {
- final long id = feed.getItems().get(removeIndex).getId();
+ final FeedItem item = feed.getItems().get(removeIndex);
adapter = new PodDBAdapter(context);
adapter.open();
adapter.setQueue(feed.getItems());
adapter.close();
- DBWriter.removeQueueItem(context, id, false).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.removeQueueItem(context, item, false).get(TIMEOUT, TimeUnit.SECONDS);
adapter = new PodDBAdapter(context);
adapter.open();
Cursor queue = adapter.getQueueIDCursor();
@@ -688,10 +688,10 @@ public class DBWriterTest extends InstrumentationTestCase {
for (int i = 0; i < queue.getCount(); i++) {
assertTrue(queue.moveToPosition(i));
final long queueID = queue.getLong(0);
- assertTrue(queueID != id); // removed item is no longer in queue
+ assertTrue(queueID != item.getId()); // removed item is no longer in queue
boolean idFound = false;
- for (FeedItem item : feed.getItems()) { // items that were not removed are still in the queue
- idFound = idFound | (item.getId() == queueID);
+ for (FeedItem other : feed.getItems()) { // items that were not removed are still in the queue
+ idFound = idFound | (other.getId() == queueID);
}
assertTrue(idFound);
}
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
index bbcc4ce5c..470866c3c 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
@@ -7,11 +7,21 @@ import android.widget.ListView;
import com.robotium.solo.Solo;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.DefaultOnlineFeedViewActivity;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
+import de.danoeh.antennapod.fragment.DownloadsFragment;
+import de.danoeh.antennapod.fragment.NewEpisodesFragment;
+import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
+import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.preferences.PreferenceController;
/**
@@ -22,6 +32,8 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
private Solo solo;
private UITestUtils uiTestUtils;
+ private SharedPreferences prefs;
+
public MainActivityTest() {
super(MainActivity.class);
}
@@ -38,7 +50,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
adapter.close();
// override first launch preference
- SharedPreferences prefs = getInstrumentation().getTargetContext().getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE);
+ prefs = getInstrumentation().getTargetContext().getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE);
prefs.edit().putBoolean(MainActivity.PREF_IS_FIRST_LAUNCH, false).commit();
}
@@ -46,7 +58,12 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
protected void tearDown() throws Exception {
uiTestUtils.tearDown();
solo.finishOpenedActivities();
+
PodDBAdapter.deleteDatabase(getInstrumentation().getTargetContext());
+
+ // reset preferences
+ prefs.edit().clear().commit();
+
super.tearDown();
}
@@ -71,11 +88,13 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
public void testClickNavDrawer() throws Exception {
uiTestUtils.addLocalFeedData(false);
- // all episodes
+ UserPreferences.setHiddenDrawerItems(getInstrumentation().getTargetContext(), new ArrayList<String>());
+
+ // queue
openNavDrawer();
- solo.clickOnText(solo.getString(R.string.all_episodes_label));
+ solo.clickOnText(solo.getString(R.string.queue_label));
solo.waitForView(android.R.id.list);
- assertEquals(solo.getString(R.string.all_episodes_label), getActionbarTitle());
+ assertEquals(solo.getString(R.string.queue_label), getActionbarTitle());
// new episodes
openNavDrawer();
@@ -83,11 +102,11 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
solo.waitForView(android.R.id.list);
assertEquals(solo.getString(R.string.new_episodes_label), getActionbarTitle());
- // queue
+ // all episodes
openNavDrawer();
- solo.clickOnText(solo.getString(R.string.queue_label));
+ solo.clickOnText(solo.getString(R.string.all_episodes_label));
solo.waitForView(android.R.id.list);
- assertEquals(solo.getString(R.string.queue_label), getActionbarTitle());
+ assertEquals(solo.getString(R.string.all_episodes_label), getActionbarTitle());
// downloads
openNavDrawer();
@@ -125,7 +144,75 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
public void testGoToPreferences() {
openNavDrawer();
- solo.clickOnMenuItem(solo.getString(R.string.settings_label));
+ solo.clickOnText(solo.getString(R.string.settings_label));
solo.waitForActivity(PreferenceController.getPreferenceActivity());
}
+
+ public void testDrawerPreferencesHideSomeElements() {
+ UserPreferences.setHiddenDrawerItems(getInstrumentation().getTargetContext(), new ArrayList<String>());
+ openNavDrawer();
+ solo.clickLongOnText(solo.getString(R.string.queue_label));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.all_episodes_label));
+ solo.clickOnText(solo.getString(R.string.playback_history_label));
+ solo.clickOnText(solo.getString(R.string.confirm_label));
+ solo.waitForDialogToClose();
+ List<String> hidden = UserPreferences.getHiddenDrawerItems();
+ assertEquals(2, hidden.size());
+ assertTrue(hidden.contains(AllEpisodesFragment.TAG));
+ assertTrue(hidden.contains(PlaybackHistoryFragment.TAG));
+ }
+
+ public void testDrawerPreferencesUnhideSomeElements() {
+ List<String> hidden = Arrays.asList(NewEpisodesFragment.TAG, DownloadsFragment.TAG);
+ UserPreferences.setHiddenDrawerItems(getInstrumentation().getTargetContext(), hidden);
+ openNavDrawer();
+ solo.clickLongOnText(solo.getString(R.string.queue_label));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.downloads_label));
+ solo.clickOnText(solo.getString(R.string.queue_label));
+ solo.clickOnText(solo.getString(R.string.confirm_label));
+ solo.waitForDialogToClose();
+ hidden = UserPreferences.getHiddenDrawerItems();
+ assertEquals(2, hidden.size());
+ assertTrue(hidden.contains(QueueFragment.TAG));
+ assertTrue(hidden.contains(NewEpisodesFragment.TAG));
+ }
+
+ public void testDrawerPreferencesHideAllElements() {
+ UserPreferences.setHiddenDrawerItems(getInstrumentation().getTargetContext(), new ArrayList<String>());
+ String[] titles = getInstrumentation().getTargetContext().getResources().getStringArray(R.array.nav_drawer_titles);
+
+ openNavDrawer();
+ solo.clickLongOnText(solo.getString(R.string.queue_label));
+ solo.waitForDialogToOpen();
+ for(String title : titles) {
+ solo.clickOnText(title);
+ }
+ solo.clickOnText(solo.getString(R.string.confirm_label));
+ solo.waitForDialogToClose();
+ List<String> hidden = UserPreferences.getHiddenDrawerItems();
+ assertEquals(6, hidden.size());
+ for(String tag : MainActivity.NAV_DRAWER_TAGS) {
+ assertTrue(hidden.contains(tag));
+ }
+ }
+
+ public void testDrawerPreferencesHideCurrentElement() {
+ UserPreferences.setHiddenDrawerItems(getInstrumentation().getTargetContext(), new ArrayList<String>());
+
+ openNavDrawer();
+ String downloads = solo.getString(R.string.downloads_label);
+ solo.clickOnText(downloads);
+ solo.waitForView(android.R.id.list);
+ openNavDrawer();
+ solo.clickLongOnText(downloads);
+ solo.waitForDialogToOpen();
+ solo.clickOnText(downloads);
+ solo.clickOnText(solo.getString(R.string.confirm_label));
+ solo.waitForDialogToClose();
+ List<String> hidden = UserPreferences.getHiddenDrawerItems();
+ assertEquals(1, hidden.size());
+ assertTrue(hidden.contains(DownloadsFragment.TAG));
+ }
}
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 249cb0dd6..85923d40f 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
@@ -25,7 +25,9 @@ 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.storage.PodDBAdapter;
+import de.greenrobot.event.EventBus;
import de.test.antennapod.util.service.download.HTTPBin;
import de.test.antennapod.util.syndication.feedgenerator.RSS2Generator;
@@ -202,6 +204,6 @@ public class UITestUtils {
adapter.setQueue(queue);
adapter.close();
EventDistributor.getInstance().sendFeedUpdateBroadcast();
- EventDistributor.getInstance().sendQueueUpdateBroadcast();
+ EventBus.getDefault().post(new QueueEvent(QueueEvent.Action.ADDED_ITEMS, queue));
}
}
diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java
index 69cc827ec..bd3df0f9d 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java
+++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java
@@ -1,15 +1,17 @@
package de.test.antennapod.util.syndication.feedgenerator;
import android.util.Xml;
-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.syndication.util.SyndDateUtils;
+
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.io.OutputStream;
+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.util.DateUtils;
+
/**
* Creates Atom feeds. See FeedGenerator for more information.
*/
@@ -83,9 +85,9 @@ public class AtomGenerator implements FeedGenerator{
if (item.getPubDate() != null) {
xml.startTag(null, "published");
if ((flags & FEATURE_USE_RFC3339LOCAL) != 0) {
- xml.text(SyndDateUtils.formatRFC3339Local(item.getPubDate()));
+ xml.text(DateUtils.formatRFC3339Local(item.getPubDate()));
} else {
- xml.text(SyndDateUtils.formatRFC3339UTC(item.getPubDate()));
+ xml.text(DateUtils.formatRFC3339UTC(item.getPubDate()));
}
xml.endTag(null, "published");
}
diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java
index d37434f06..27e89620d 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java
+++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java
@@ -3,7 +3,7 @@ package de.test.antennapod.util.syndication.feedgenerator;
import android.util.Xml;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.syndication.util.SyndDateUtils;
+import de.danoeh.antennapod.core.util.DateUtils;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
@@ -79,7 +79,7 @@ public class RSS2Generator implements FeedGenerator{
}
if (item.getPubDate() != null) {
xml.startTag(null, "pubDate");
- xml.text(SyndDateUtils.formatRFC822Date(item.getPubDate()));
+ xml.text(DateUtils.formatRFC822Date(item.getPubDate()));
xml.endTag(null, "pubDate");
}
if ((flags & FEATURE_WRITE_GUID) != 0) {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bbdc5a4d7..97f8bbdad 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.danoeh.antennapod"
- android:versionCode="52"
- android:versionName="1.1.2">
+ android:versionCode="51"
+ android:versionName="1.2">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
diff --git a/app/src/main/assets/.gitignore b/app/src/main/assets/.gitignore
new file mode 100644
index 000000000..328840cfc
--- /dev/null
+++ b/app/src/main/assets/.gitignore
@@ -0,0 +1,2 @@
+# this file is generated automatically
+about.html
diff --git a/app/src/main/assets/LICENSE_ANDROID_ICONIFY.txt b/app/src/main/assets/LICENSE_ANDROID_ICONIFY.txt
new file mode 100644
index 000000000..85a6c0cf2
--- /dev/null
+++ b/app/src/main/assets/LICENSE_ANDROID_ICONIFY.txt
@@ -0,0 +1,18 @@
+Copyright 2013 Joan Zapata
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+It uses FontAwesome font, licensed under OFL 1.1, which is compatible
+with this library's license.
+
+ http://scripts.sil.org/cms/scripts/render_download.php?format=file&media_id=OFL_plaintext&filename=OFL.txt
diff --git a/app/src/main/assets/LICENSE_EVENTBUS.txt b/app/src/main/assets/LICENSE_EVENTBUS.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/app/src/main/assets/LICENSE_EVENTBUS.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
index 821c86044..213afb57a 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
@@ -13,7 +13,6 @@ import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
-import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@@ -29,7 +28,6 @@ import com.squareup.picasso.Picasso;
import org.apache.commons.lang3.StringUtils;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.ChapterListAdapter;
import de.danoeh.antennapod.adapter.NavListAdapter;
@@ -47,7 +45,6 @@ import de.danoeh.antennapod.core.util.playback.PlaybackController;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
import de.danoeh.antennapod.fragment.CoverFragment;
import de.danoeh.antennapod.fragment.ItemDescriptionFragment;
-import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceController;
@@ -96,30 +93,25 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
FragmentTransaction fT = getSupportFragmentManager().beginTransaction();
if (coverFragment != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Removing cover fragment");
+ Log.d(TAG, "Removing cover fragment");
fT.remove(coverFragment);
}
if (descriptionFragment != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Removing description fragment");
+ Log.d(TAG, "Removing description fragment");
fT.remove(descriptionFragment);
}
if (chapterFragment != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Removing chapter fragment");
+ Log.d(TAG, "Removing chapter fragment");
fT.remove(chapterFragment);
}
if (currentlyShownFragment != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Removing currently shown fragment");
+ Log.d(TAG, "Removing currently shown fragment");
fT.remove(currentlyShownFragment);
}
for (int i = 0; i < detachedFragments.length; i++) {
Fragment f = detachedFragments[i];
if (f != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Removing detached fragment");
+ Log.d(TAG, "Removing detached fragment");
fT.remove(f);
}
}
@@ -135,11 +127,9 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
@Override
protected void onStop() {
super.onStop();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "onStop");
+ Log.d(TAG, "onStop()");
cancelLoadTask();
EventDistributor.getInstance().unregister(contentUpdate);
-
}
@Override
@@ -154,8 +144,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
}
private void savePreferences() {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Saving preferences");
+ Log.d(TAG, "Saving preferences");
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
if (currentlyShownPosition >= 0 && controller != null
@@ -182,9 +171,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
@Override
protected void onSaveInstanceState(Bundle outState) {
// super.onSaveInstanceState(outState); would cause crash
- if (BuildConfig.DEBUG)
- Log.d(TAG, "onSaveInstanceState");
-
+ Log.d(TAG, "onSaveInstanceState");
}
@Override
@@ -207,8 +194,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
* @return true if restoreFromPrefernces changed the activity's state
*/
private boolean restoreFromPreferences() {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Restoring instance state");
+ Log.d(TAG, "Restoring instance state");
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
int savedPosition = prefs.getInt(PREF_KEY_SELECTED_FRAGMENT_POSITION,
-1);
@@ -222,15 +208,10 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
switchToFragment(savedPosition);
return true;
} else if (controller == null || controller.getMedia() == null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Couldn't restore from preferences: controller or media was null");
+ Log.d(TAG, "Couldn't restore from preferences: controller or media was null");
} else {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Couldn't restore from preferences: savedPosition was -1 or saved identifier and playable identifier didn't match.\nsavedPosition: "
- + savedPosition + ", id: " + playableId
- );
+ Log.d(TAG, "Couldn't restore from preferences: savedPosition was -1 or saved identifier and playable identifier didn't match.\nsavedPosition: "
+ + savedPosition + ", id: " + playableId);
}
return false;
@@ -241,9 +222,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
super.onResume();
if (StringUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
Intent intent = getIntent();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received VIEW intent: "
- + intent.getData().getPath());
+ Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath());
ExternalMedia media = new ExternalMedia(intent.getData().getPath(),
MediaType.AUDIO);
Intent launchIntent = new Intent(this, PlaybackService.class);
@@ -271,8 +250,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
@Override
protected void onAwaitingVideoSurface() {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "onAwaitingVideoSurface was called in audio player -> switching to video player");
+ Log.d(TAG, "onAwaitingVideoSurface was called in audio player -> switching to video player");
startActivity(new Intent(this, VideoplayerActivity.class));
}
@@ -297,8 +275,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
* @param pos Must be POS_COVER, POS_DESCR, or POS_CHAPTERS
*/
private void switchToFragment(int pos) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Switching contentView to position " + pos);
+ Log.d(TAG, "Switching contentView to position " + pos);
if (currentlyShownPosition != pos && controller != null) {
Playable media = controller.getMedia();
if (media != null) {
@@ -356,9 +333,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
lastShownPosition = currentlyShownPosition;
currentlyShownPosition = pos;
if (detachedFragments[pos] != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Reattaching fragment at position "
- + pos);
+ Log.d(TAG, "Reattaching fragment at position " + pos);
ft.attach(detachedFragments[pos]);
} else {
ft.add(R.id.contentView, currentlyShownFragment);
@@ -436,25 +411,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
butShowCover = (ImageButton) findViewById(R.id.butCover);
txtvTitle = (TextView) findViewById(R.id.txtvTitle);
- drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close) {
- CharSequence currentTitle = getSupportActionBar().getTitle();
-
- @Override
- public void onDrawerOpened(View drawerView) {
- super.onDrawerOpened(drawerView);
- currentTitle = getSupportActionBar().getTitle();
- getSupportActionBar().setTitle(R.string.app_name);
- supportInvalidateOptionsMenu();
- }
-
- @Override
- public void onDrawerClosed(View drawerView) {
- super.onDrawerClosed(drawerView);
- getSupportActionBar().setTitle(currentTitle);
- supportInvalidateOptionsMenu();
- }
- };
-
+ drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close);
drawerToggle.setDrawerIndicatorEnabled(false);
drawerLayout.setDrawerListener(drawerToggle);
@@ -465,10 +422,9 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int viewType = parent.getAdapter().getItemViewType(position);
if (viewType != NavListAdapter.VIEW_TYPE_SECTION_DIVIDER) {
- int relPos = (viewType == NavListAdapter.VIEW_TYPE_NAV) ? position : position - NavListAdapter.SUBSCRIPTION_OFFSET;
Intent intent = new Intent(AudioplayerActivity.this, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_NAV_TYPE, viewType);
- intent.putExtra(MainActivity.EXTRA_NAV_INDEX, relPos);
+ intent.putExtra(MainActivity.EXTRA_NAV_INDEX, position);
startActivity(intent);
}
drawerLayout.closeDrawer(navDrawer);
@@ -632,9 +588,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
@Override
protected void onReloadNotification(int notificationCode) {
if (notificationCode == PlaybackService.EXTRA_CODE_VIDEO) {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "ReloadNotification received, switching to Videoplayer now");
+ Log.d(TAG, "ReloadNotification received, switching to Videoplayer now");
finish();
startActivity(new Intent(this, VideoplayerActivity.class));
@@ -661,24 +615,6 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
return drawerLayout != null && navDrawer != null && drawerLayout.isDrawerOpen(navDrawer);
}
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (!MenuItemUtils.isActivityDrawerOpen(this)) {
- return super.onCreateOptionsMenu(menu);
- } else {
- return false;
- }
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- if (!MenuItemUtils.isActivityDrawerOpen(this)) {
- return super.onPrepareOptionsMenu(menu);
- } else {
- return false;
- }
- }
-
public interface AudioplayerContentFragment {
public void onDataSetChanged(Playable media);
}
@@ -731,8 +667,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((EventDistributor.FEED_LIST_UPDATE & arg) != 0) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received contentUpdate Intent.");
+ Log.d(TAG, "Received contentUpdate Intent.");
loadData();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
index 93c71a868..24b684752 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
@@ -1,5 +1,7 @@
package de.danoeh.antennapod.activity;
+import android.content.ClipData;
+import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
@@ -9,15 +11,17 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
+import android.widget.Toast;
+import com.joanzapata.android.iconify.Iconify;
import com.squareup.picasso.Picasso;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.Feed;
@@ -44,10 +48,32 @@ public class FeedInfoActivity extends ActionBarActivity {
private TextView txtvDescription;
private TextView txtvLanguage;
private TextView txtvAuthor;
+ private TextView txtvUrl;
private EditText etxtUsername;
private EditText etxtPassword;
private CheckBox cbxAutoDownload;
+ private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(feed != null && feed.getDownload_url() != null) {
+ String url = feed.getDownload_url();
+ if (android.os.Build.VERSION.SDK_INT >= 11) {
+ ClipData clipData = ClipData.newPlainText(url, url);
+ android.content.ClipboardManager cm = (android.content.ClipboardManager) FeedInfoActivity.this
+ .getSystemService(Context.CLIPBOARD_SERVICE);
+ cm.setPrimaryClip(clipData);
+ } else {
+ android.text.ClipboardManager cm = (android.text.ClipboardManager) FeedInfoActivity.this
+ .getSystemService(Context.CLIPBOARD_SERVICE);
+ cm.setText(url);
+ }
+ Toast t = Toast.makeText(FeedInfoActivity.this, R.string.copied_url_msg, Toast.LENGTH_SHORT);
+ t.show();
+ }
+ }
+ };
+
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
@@ -61,10 +87,13 @@ public class FeedInfoActivity extends ActionBarActivity {
txtvDescription = (TextView) findViewById(R.id.txtvDescription);
txtvLanguage = (TextView) findViewById(R.id.txtvLanguage);
txtvAuthor = (TextView) findViewById(R.id.txtvAuthor);
+ txtvUrl = (TextView) findViewById(R.id.txtvUrl);
cbxAutoDownload = (CheckBox) findViewById(R.id.cbxAutoDownload);
etxtUsername = (EditText) findViewById(R.id.etxtUsername);
etxtPassword = (EditText) findViewById(R.id.etxtPassword);
+ txtvUrl.setOnClickListener(copyUrlToClipboard);
+
AsyncTask<Long, Void, Feed> loadTask = new AsyncTask<Long, Void, Feed>() {
@Override
@@ -76,10 +105,9 @@ public class FeedInfoActivity extends ActionBarActivity {
protected void onPostExecute(Feed result) {
if (result != null) {
feed = result;
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Language is " + feed.getLanguage());
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Author is " + feed.getAuthor());
+ Log.d(TAG, "Language is " + feed.getLanguage());
+ Log.d(TAG, "Author is " + feed.getAuthor());
+ Log.d(TAG, "URL is " + feed.getDownload_url());
imgvCover.post(new Runnable() {
@Override
@@ -92,7 +120,7 @@ public class FeedInfoActivity extends ActionBarActivity {
});
txtvTitle.setText(feed.getTitle());
- txtvDescription.setText(feed.getDescription());
+ txtvDescription.setText(feed.getDescription().trim());
if (feed.getAuthor() != null) {
txtvAuthor.setText(feed.getAuthor());
}
@@ -100,6 +128,8 @@ public class FeedInfoActivity extends ActionBarActivity {
txtvLanguage.setText(LangUtils
.getLanguageString(feed.getLanguage()));
}
+ txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
+ Iconify.addIcons(txtvUrl);
cbxAutoDownload.setEnabled(UserPreferences.isEnableAutodownload());
cbxAutoDownload.setChecked(feed.getPreferences().getAutoDownload());
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 6f6b68579..dfecfc837 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -1,8 +1,11 @@
package de.danoeh.antennapod.activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
+import android.database.DataSetObserver;
import android.media.AudioManager;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -21,15 +24,16 @@ import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
+import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
import java.util.List;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.NavListAdapter;
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.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.StorageUtils;
@@ -43,37 +47,40 @@ import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.danoeh.antennapod.preferences.PreferenceController;
+import de.greenrobot.event.EventBus;
/**
* The activity that is shown when the user launches the app.
*/
public class MainActivity extends ActionBarActivity implements NavDrawerActivity {
+
private static final String TAG = "MainActivity";
+
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED
| EventDistributor.DOWNLOAD_QUEUED
| EventDistributor.FEED_LIST_UPDATE
- | EventDistributor.UNREAD_ITEMS_UPDATE
- | EventDistributor.QUEUE_UPDATE;
+ | EventDistributor.UNREAD_ITEMS_UPDATE;
public static final String PREF_NAME = "MainActivityPrefs";
public static final String PREF_IS_FIRST_LAUNCH = "prefMainActivityIsFirstLaunch";
- public static final String PREF_LAST_FRAGMENT = "prefMainActivityLastFragment";
+ public static final String PREF_LAST_FRAGMENT_TAG = "prefMainActivityLastFragmentTag";
- public static final String EXTRA_NAV_INDEX = "nav_index";
public static final String EXTRA_NAV_TYPE = "nav_type";
+ public static final String EXTRA_NAV_INDEX = "nav_index";
+ public static final String EXTRA_FRAGMENT_TAG = "fragment_tag";
public static final String EXTRA_FRAGMENT_ARGS = "fragment_args";
public static final String SAVE_BACKSTACK_COUNT = "backstackCount";
- public static final String SAVE_SELECTED_NAV_INDEX = "selectedNavIndex";
public static final String SAVE_TITLE = "title";
-
- public static final int POS_QUEUE = 0,
- POS_NEW = 1,
- POS_ALL_EPISODES = 2,
- POS_DOWNLOADS = 3,
- POS_HISTORY = 4,
- POS_ADD = 5;
+ public static final String[] NAV_DRAWER_TAGS = {
+ QueueFragment.TAG,
+ NewEpisodesFragment.TAG,
+ AllEpisodesFragment.TAG,
+ DownloadsFragment.TAG,
+ PlaybackHistoryFragment.TAG,
+ AddFeedFragment.TAG
+ };
private Toolbar toolbar;
private ExternalPlayerFragment externalPlayerFragment;
@@ -88,7 +95,6 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
private CharSequence drawerTitle;
private CharSequence currentTitle;
-
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getNoTitleTheme());
@@ -106,30 +112,12 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
navList = (ListView) findViewById(R.id.nav_list);
navDrawer = findViewById(R.id.nav_layout);
- Log.i(TAG, "");
- drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close) {
- @Override
- public void onDrawerOpened(View drawerView) {
- super.onDrawerOpened(drawerView);
- currentTitle = getSupportActionBar().getTitle();
- getSupportActionBar().setTitle(drawerTitle);
- supportInvalidateOptionsMenu();
- }
-
- @Override
- public void onDrawerClosed(View drawerView) {
- super.onDrawerClosed(drawerView);
- getSupportActionBar().setTitle(currentTitle);
- supportInvalidateOptionsMenu();
-
- }
- };
+ drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close);
if (savedInstanceState != null) {
int backstackCount = savedInstanceState.getInt(SAVE_BACKSTACK_COUNT, 0);
drawerToggle.setDrawerIndicatorEnabled(backstackCount == 0);
}
-
drawerLayout.setDrawerListener(drawerToggle);
final FragmentManager fm = getSupportFragmentManager();
@@ -141,25 +129,20 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
});
- FragmentTransaction transaction = fm.beginTransaction();
-
- Fragment mainFragment = fm.findFragmentByTag("main");
- if (mainFragment != null) {
- transaction.replace(R.id.main_view, mainFragment);
- } else {
- loadFragment(NavListAdapter.VIEW_TYPE_NAV, getLastNavFragment(), null);
- }
-
- externalPlayerFragment = new ExternalPlayerFragment();
- transaction.replace(R.id.playerFragment, externalPlayerFragment);
- transaction.commit();
-
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
navAdapter = new NavListAdapter(itemAccess, this);
navList.setAdapter(navAdapter);
navList.setOnItemClickListener(navListClickListener);
+ navList.setOnItemLongClickListener(newListLongClickListener);
+
+ navAdapter.registerDataSetObserver(new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ selectedNavListIndex = getSelectedNavListIndex();
+ }
+ });
findViewById(R.id.nav_settings).setOnClickListener(new View.OnClickListener() {
@Override
@@ -169,19 +152,40 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
});
+ FragmentTransaction transaction = fm.beginTransaction();
+
+ Fragment mainFragment = fm.findFragmentByTag("main");
+ if (mainFragment != null) {
+ transaction.replace(R.id.main_view, mainFragment);
+ } else {
+ String lastFragment = getLastNavFragment();
+ if(ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) {
+ loadFragment(lastFragment, null);
+ }
+ // else: lastFragment contains feed id - drawer data is not loaded yet,
+ // so loading is postponed until then
+ }
+ externalPlayerFragment = new ExternalPlayerFragment();
+ transaction.replace(R.id.playerFragment, externalPlayerFragment);
+ transaction.commit();
+
checkFirstLaunch();
}
- private void saveLastNavFragment(int relPos) {
+ private void saveLastNavFragment(String tag) {
SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
SharedPreferences.Editor edit = prefs.edit();
- edit.putInt(PREF_LAST_FRAGMENT, relPos);
+ if(tag != null) {
+ edit.putString(PREF_LAST_FRAGMENT_TAG, tag);
+ } else {
+ edit.remove(PREF_LAST_FRAGMENT_TAG);
+ }
edit.commit();
}
- private int getLastNavFragment() {
+ private String getLastNavFragment() {
SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
- return prefs.getInt(PREF_LAST_FRAGMENT, POS_QUEUE);
+ return prefs.getString(PREF_LAST_FRAGMENT_TAG, QueueFragment.TAG);
}
private void checkFirstLaunch() {
@@ -200,6 +204,40 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
}
+ public void showDrawerPreferencesDialog() {
+ final List<String> hiddenDrawerItems = UserPreferences.getHiddenDrawerItems();
+ String[] navLabels = new String[NAV_DRAWER_TAGS.length];
+ final boolean[] checked = new boolean[NAV_DRAWER_TAGS.length];
+ for (int i = 0; i < NAV_DRAWER_TAGS.length; i++) {
+ String tag = NAV_DRAWER_TAGS[i];
+ navLabels[i] = navAdapter.getLabel(tag);
+ if (!hiddenDrawerItems.contains(tag)) {
+ checked[i] = true;
+ }
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
+ builder.setTitle(R.string.drawer_preferences);
+ builder.setMultiChoiceItems(navLabels, checked, new DialogInterface.OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ if (isChecked) {
+ hiddenDrawerItems.remove(NAV_DRAWER_TAGS[which]);
+ } else {
+ hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]);
+ }
+ }
+ });
+ builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ UserPreferences.setHiddenDrawerItems(MainActivity.this, hiddenDrawerItems);
+ }
+ });
+ builder.setNegativeButton(R.string.cancel_label, null);
+ builder.create().show();
+ }
+
public ActionBar getMainActivtyActionBar() {
return getSupportActionBar();
}
@@ -212,74 +250,91 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
return (navDrawerData != null) ? navDrawerData.feeds : null;
}
- private void loadFragment(int viewType, int relPos, Bundle args) {
- FragmentManager fragmentManager = getSupportFragmentManager();
- // clear back stack
- for (int i = 0; i < fragmentManager.getBackStackEntryCount(); i++) {
- fragmentManager.popBackStack();
+ public void loadFragment(int index, Bundle args) {
+ if (index < navAdapter.getSubscriptionOffset()) {
+ String tag = navAdapter.getTags().get(index);
+ loadFragment(tag, args);
+ } else {
+ int pos = index - navAdapter.getSubscriptionOffset();
+ loadFeedFragmentByPosition(pos, args);
}
+ }
- FragmentTransaction fT = fragmentManager.beginTransaction();
+ public void loadFragment(final String tag, Bundle args) {
+ Log.d(TAG, "loadFragment(\"" + tag + "\", " + args + ")");
Fragment fragment = null;
- if (viewType == NavListAdapter.VIEW_TYPE_NAV) {
- switch (relPos) {
- case POS_NEW:
- fragment = new NewEpisodesFragment();
- break;
- case POS_ALL_EPISODES:
- fragment = new AllEpisodesFragment();
- break;
- case POS_QUEUE:
- fragment = new QueueFragment();
- break;
- case POS_DOWNLOADS:
- fragment = new DownloadsFragment();
- break;
- case POS_HISTORY:
- fragment = new PlaybackHistoryFragment();
- break;
- case POS_ADD:
- fragment = new AddFeedFragment();
- break;
-
- }
- currentTitle = getString(NavListAdapter.NAV_TITLES[relPos]);
- selectedNavListIndex = relPos;
- saveLastNavFragment(relPos);
-
- } else if (viewType == NavListAdapter.VIEW_TYPE_SUBSCRIPTION) {
- Feed feed = itemAccess.getItem(relPos);
- currentTitle = "";
- fragment = ItemlistFragment.newInstance(feed.getId());
- selectedNavListIndex = NavListAdapter.SUBSCRIPTION_OFFSET + relPos;
-
- }
- if (fragment != null) {
- if (args != null) {
- fragment.setArguments(args);
- }
- fT.replace(R.id.main_view, fragment, "main");
- fragmentManager.popBackStack();
+ switch (tag) {
+ case QueueFragment.TAG:
+ fragment = new QueueFragment();
+ break;
+ case NewEpisodesFragment.TAG:
+ fragment = new NewEpisodesFragment();
+ break;
+ case AllEpisodesFragment.TAG:
+ fragment = new AllEpisodesFragment();
+ break;
+ case DownloadsFragment.TAG:
+ fragment = new DownloadsFragment();
+ break;
+ case PlaybackHistoryFragment.TAG:
+ fragment = new PlaybackHistoryFragment();
+ break;
+ case AddFeedFragment.TAG:
+ fragment = new AddFeedFragment();
+ break;
}
- fT.commit();
+ currentTitle = navAdapter.getLabel(tag);
getSupportActionBar().setTitle(currentTitle);
- if (navAdapter != null) {
- navAdapter.notifyDataSetChanged();
+ saveLastNavFragment(tag);
+ if (args != null) {
+ fragment.setArguments(args);
}
+ loadFragment(fragment);
}
- public void loadNavFragment(int position, Bundle args) {
- loadFragment(NavListAdapter.VIEW_TYPE_NAV, position, args);
+ private void loadFeedFragmentByPosition(int relPos, Bundle args) {
+ if(relPos < 0) {
+ return;
+ }
+ Feed feed = itemAccess.getItem(relPos);
+ long feedId = feed.getId();
+ Fragment fragment = ItemlistFragment.newInstance(feedId);
+ if(args != null) {
+ fragment.setArguments(args);
+ }
+ saveLastNavFragment(String.valueOf(feed.getId()));
+ currentTitle = "";
+ getSupportActionBar().setTitle(currentTitle);
+ loadFragment(fragment);
}
- public void loadFeedFragment(long feedID) {
+ public void loadFeedFragmentById(long feedId) {
if (navDrawerData != null) {
- for (int i = 0; i < navDrawerData.feeds.size(); i++) {
- if (navDrawerData.feeds.get(i).getId() == feedID) {
- loadFragment(NavListAdapter.VIEW_TYPE_SUBSCRIPTION, i, null);
- break;
+ int relPos = -1;
+ List<Feed> feeds = navDrawerData.feeds;
+ for (int i = 0; relPos < 0 && i < feeds.size(); i++) {
+ if (feeds.get(i).getId() == feedId) {
+ relPos = i;
}
}
+ if(relPos >= 0) {
+ loadFeedFragmentByPosition(relPos, null);
+ }
+ }
+ }
+
+ private void loadFragment(Fragment fragment) {
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ // clear back stack
+ for (int i = 0; i < fragmentManager.getBackStackEntryCount(); i++) {
+ fragmentManager.popBackStack();
+ }
+ FragmentTransaction t = fragmentManager.beginTransaction();
+ t.replace(R.id.main_view, fragment, "main");
+ fragmentManager.popBackStack();
+ t.commit();
+ if (navAdapter != null) {
+ navAdapter.notifyDataSetChanged();
}
}
@@ -300,20 +355,50 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
return toolbar;
}
+ private int getSelectedNavListIndex() {
+ String lastFragment = getLastNavFragment();
+ int tagIndex = navAdapter.getTags().indexOf(lastFragment);
+ if(tagIndex >= 0) {
+ return tagIndex;
+ } else if(ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) {
+ // the fragment was just hidden
+ return -1;
+ } else { // last fragment was not a list, but a feed
+ long feedId = Long.parseLong(lastFragment);
+ List<Feed> feeds = navDrawerData.feeds;
+ for (int i = 0; i < feeds.size(); i++) {
+ if (feeds.get(i).getId() == feedId) {
+ return i + navAdapter.getSubscriptionOffset();
+ }
+ }
+ return -1;
+ }
+ }
+
private AdapterView.OnItemClickListener navListClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int viewType = parent.getAdapter().getItemViewType(position);
if (viewType != NavListAdapter.VIEW_TYPE_SECTION_DIVIDER && position != selectedNavListIndex) {
- int relPos = (viewType == NavListAdapter.VIEW_TYPE_NAV) ? position : position - NavListAdapter.SUBSCRIPTION_OFFSET;
- loadFragment(viewType, relPos, null);
- selectedNavListIndex = position;
- navAdapter.notifyDataSetChanged();
+ loadFragment(position, null);
}
drawerLayout.closeDrawer(navDrawer);
}
};
+ private AdapterView.OnItemLongClickListener newListLongClickListener = new AdapterView.OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+ if(position < navAdapter.getTags().size()) {
+ showDrawerPreferencesDialog();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+
+
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
@@ -323,7 +408,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
if (!drawerLayout.isDrawerOpen(navDrawer)) {
getSupportActionBar().setTitle(currentTitle);
}
- selectedNavListIndex = savedInstanceState.getInt(SAVE_SELECTED_NAV_INDEX);
+ selectedNavListIndex = getSelectedNavListIndex();
}
}
@@ -337,9 +422,14 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(SAVE_TITLE, getSupportActionBar().getTitle().toString());
- outState.putInt(SAVE_SELECTED_NAV_INDEX, selectedNavListIndex);
outState.putInt(SAVE_BACKSTACK_COUNT, getSupportFragmentManager().getBackStackEntryCount());
+ }
+ @Override
+ public void onStart() {
+ super.onStart();
+ EventDistributor.getInstance().register(contentUpdate);
+ EventBus.getDefault().register(this);
}
@Override
@@ -351,10 +441,10 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
protected void onResume() {
super.onResume();
StorageUtils.checkStorageAvailability(this);
- EventDistributor.getInstance().register(contentUpdate);
Intent intent = getIntent();
- if (navDrawerData != null && intent.hasExtra(EXTRA_NAV_INDEX) && intent.hasExtra(EXTRA_NAV_TYPE)) {
+ if (navDrawerData != null && intent.hasExtra(EXTRA_NAV_TYPE) &&
+ (intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG))) {
handleNavIntent();
}
@@ -366,6 +456,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
super.onStop();
cancelLoadTask();
EventDistributor.getInstance().unregister(contentUpdate);
+ EventBus.getDefault().unregister(this);
}
@Override
@@ -382,7 +473,6 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
}
-
private DBReader.NavDrawerData navDrawerData;
private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask;
private int selectedNavListIndex = 0;
@@ -421,7 +511,6 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
return (navDrawerData != null) ? navDrawerData.numUnreadItems : 0;
}
-
};
private void loadData() {
@@ -440,6 +529,13 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
navDrawerData = result;
navAdapter.notifyDataSetChanged();
+ String lastFragment = getLastNavFragment();
+ if(!ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) {
+ long feedId = Long.valueOf(lastFragment);
+ loadFeedFragmentById(feedId);
+ saveLastNavFragment(null);
+ }
+
if (handleIntent) {
handleNavIntent();
}
@@ -454,25 +550,35 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
}
+ public void onEvent(QueueEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ loadData();
+ }
+
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((EVENTS & arg) != 0) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received contentUpdate Intent.");
+ Log.d(TAG, "Received contentUpdate Intent.");
loadData();
}
}
};
private void handleNavIntent() {
+ Log.d(TAG, "handleNavIntent()");
Intent intent = getIntent();
- if (intent.hasExtra(EXTRA_NAV_INDEX) && intent.hasExtra(EXTRA_NAV_TYPE)) {
- int index = intent.getIntExtra(EXTRA_NAV_INDEX, 0);
- int type = intent.getIntExtra(EXTRA_NAV_TYPE, NavListAdapter.VIEW_TYPE_NAV);
+ if (intent.hasExtra(EXTRA_NAV_TYPE) &&
+ intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)) {
+ int index = intent.getIntExtra(EXTRA_NAV_INDEX, -1);
+ String tag = intent.getStringExtra(EXTRA_FRAGMENT_TAG);
Bundle args = intent.getBundleExtra(EXTRA_FRAGMENT_ARGS);
- loadFragment(type, index, args);
+ if (index >= 0) {
+ loadFragment(index, args);
+ } else if (tag != null) {
+ loadFragment(tag, args);
+ }
}
setIntent(new Intent(MainActivity.this, MainActivity.class)); // to avoid handling the intent twice when the configuration changes
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
index 099e96be9..0cd388b9d 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -12,13 +12,13 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
-import android.view.Window;
+
+import android.view.View;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
@@ -48,7 +48,9 @@ public abstract class MediaplayerActivity extends ActionBarActivity
protected SeekBar sbPosition;
protected ImageButton butPlay;
protected ImageButton butRev;
+ protected TextView txtvRev;
protected ImageButton butFF;
+ protected TextView txtvFF;
private PlaybackController newPlaybackController() {
return new PlaybackController(this, false) {
@@ -167,8 +169,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
chooseTheme();
super.onCreate(savedInstanceState);
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Creating Activity");
+ Log.d(TAG, "onCreate()");
StorageUtils.checkStorageAvailability(this);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
@@ -224,8 +225,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
@Override
protected void onStop() {
super.onStop();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Activity stopped");
+ Log.d(TAG, "onStop()");
if (controller != null) {
controller.release();
}
@@ -234,8 +234,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
@Override
protected void onDestroy() {
super.onDestroy();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Activity destroyed");
+ Log.d(TAG, "onDestroy()");
}
@Override
@@ -358,8 +357,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
@Override
protected void onResume() {
super.onResume();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Resuming Activity");
+ Log.d(TAG, "onResume()");
StorageUtils.checkStorageAvailability(this);
controller.init();
}
@@ -378,6 +376,8 @@ public abstract class MediaplayerActivity extends ActionBarActivity
if (controller != null) {
int currentPosition = controller.getPosition();
int duration = controller.getDuration();
+ Log.d(TAG, "currentPosition " + Converter
+ .getDurationStringLong(currentPosition));
if (currentPosition != PlaybackService.INVALID_TIME
&& duration != PlaybackService.INVALID_TIME
&& controller.getMedia() != null) {
@@ -386,15 +386,13 @@ public abstract class MediaplayerActivity extends ActionBarActivity
txtvLength.setText(Converter.getDurationStringLong(duration));
updateProgressbarPosition(currentPosition, duration);
} else {
- Log.w(TAG,
- "Could not react to position observer update because of invalid time");
+ Log.w(TAG, "Could not react to position observer update because of invalid time");
}
}
}
private void updateProgressbarPosition(int position, int duration) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Updating progressbar info");
+ Log.d(TAG, "updateProgressbarPosition(" + position + ", " + duration +")");
float progress = ((float) position) / duration;
sbPosition.setProgress((int) (progress * sbPosition.getMax()));
}
@@ -406,8 +404,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
* FeedMedia object.
*/
protected boolean loadMediaInfo() {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Loading media info");
+ Log.d(TAG, "loadMediaInfo()");
Playable media = controller.getMedia();
if (media != null) {
txtvPosition.setText(Converter.getDurationStringLong((media
@@ -433,7 +430,15 @@ public abstract class MediaplayerActivity extends ActionBarActivity
txtvLength = (TextView) findViewById(R.id.txtvLength);
butPlay = (ImageButton) findViewById(R.id.butPlay);
butRev = (ImageButton) findViewById(R.id.butRev);
+ txtvRev = (TextView) findViewById(R.id.txtvRev);
+ if(txtvRev != null) {
+ txtvRev.setText(String.valueOf(UserPreferences.getRewindSecs()));
+ }
butFF = (ImageButton) findViewById(R.id.butFF);
+ txtvFF = (TextView) findViewById(R.id.txtvFF);
+ if(txtvFF != null) {
+ txtvFF.setText(String.valueOf(UserPreferences.getFastFowardSecs()));
+ }
// SEEKBAR SETUP
@@ -444,10 +449,100 @@ public abstract class MediaplayerActivity extends ActionBarActivity
butPlay.setOnClickListener(controller.newOnPlayButtonClickListener());
if (butFF != null) {
- butFF.setOnClickListener(controller.newOnFFButtonClickListener());
+ butFF.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int curr = controller.getPosition();
+ controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000);
+ }
+ });
+ butFF.setOnLongClickListener(new View.OnLongClickListener() {
+
+ int choice;
+
+ @Override
+ public boolean onLongClick(View v) {
+ int checked = 0;
+ int rewindSecs = UserPreferences.getFastFowardSecs();
+ final int[] values = getResources().getIntArray(R.array.seek_delta_values);
+ final String[] choices = new String[values.length];
+ for(int i=0; i < values.length; i++) {
+ if (rewindSecs == values[i]) {
+ checked = i;
+ }
+ choices[i] = String.valueOf(values[i]) + " "
+ + getString(R.string.time_unit_seconds);
+ }
+ choice = values[checked];
+ AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this);
+ builder.setTitle(R.string.pref_fast_forward);
+ builder.setSingleChoiceItems(choices, checked,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ choice = values[which];
+ }
+ });
+ builder.setNegativeButton(R.string.cancel_label, null);
+ builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ UserPreferences.setPrefFastForwardSecs(choice);
+ txtvFF.setText(String.valueOf(choice));
+ }
+ });
+ builder.create().show();
+ return true;
+ }
+ });
}
if (butRev != null) {
- butRev.setOnClickListener(controller.newOnRevButtonClickListener());
+ butRev.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int curr = controller.getPosition();
+ controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000);
+ }
+ });
+ butRev.setOnLongClickListener(new View.OnLongClickListener() {
+
+ int choice;
+
+ @Override
+ public boolean onLongClick(View v) {
+ int checked = 0;
+ int rewindSecs = UserPreferences.getRewindSecs();
+ final int[] values = getResources().getIntArray(R.array.seek_delta_values);
+ final String[] choices = new String[values.length];
+ for(int i=0; i < values.length; i++) {
+ if (rewindSecs == values[i]) {
+ checked = i;
+ }
+ choices[i] = String.valueOf(values[i]) + " "
+ + getString(R.string.time_unit_seconds);
+ }
+ choice = values[checked];
+ AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this);
+ builder.setTitle(R.string.pref_rewind);
+ builder.setSingleChoiceItems(choices, checked,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ choice = values[which];
+ }
+ });
+ builder.setNegativeButton(R.string.cancel_label, null);
+ builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ UserPreferences.setPrefRewindSecs(choice);
+ txtvRev.setText(String.valueOf(choice));
+ }
+ });
+ builder.create().show();
+ return true;
+ }
+ });
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
index 3b03ed2db..2b1b13ae6 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -26,7 +26,6 @@ import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedPreferences;
@@ -91,12 +90,10 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
getSupportActionBar().setTitle(R.string.add_new_feed_label);
} else {
- throw new IllegalArgumentException(
- "Activity must be started with feedurl argument!");
+ throw new IllegalArgumentException("Activity must be started with feedurl argument!");
}
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Activity was started with url " + feedUrl);
+ Log.d(TAG, "Activity was started with url " + feedUrl);
setLoadingLayout();
if (savedInstanceState == null) {
startFeedDownload(feedUrl, null, null);
@@ -147,7 +144,7 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
@Override
public void run() {
- if (BuildConfig.DEBUG) Log.d(TAG, "Download was completed");
+ Log.d(TAG, "Download was completed");
DownloadStatus status = downloader.getResult();
if (status != null) {
if (!status.isCancelled()) {
@@ -164,15 +161,13 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
OnlineFeedViewActivity.this);
if (errorMsg != null
&& status.getReasonDetailed() != null) {
- errorMsg += " ("
- + status.getReasonDetailed() + ")";
+ errorMsg += " (" + status.getReasonDetailed() + ")";
}
showErrorDialog(errorMsg);
}
}
} else {
- Log.wtf(TAG,
- "DownloadStatus returned by Downloader was null");
+ Log.wtf(TAG, "DownloadStatus returned by Downloader was null");
finish();
}
}
@@ -181,21 +176,18 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
}
private void startFeedDownload(String url, String username, String password) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Starting feed download");
+ Log.d(TAG, "Starting feed download");
url = URLChecker.prepareURL(url);
feed = new Feed(url, new Date(0));
if (username != null && password != null) {
feed.setPreferences(new FeedPreferences(0, false, username, password));
}
String fileUrl = new File(getExternalCacheDir(),
- FileNameGenerator.generateFileName(feed.getDownload_url()))
- .toString();
+ FileNameGenerator.generateFileName(feed.getDownload_url())).toString();
feed.setFile_url(fileUrl);
final DownloadRequest request = new DownloadRequest(feed.getFile_url(),
feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED, username, password, true, null);
- downloader = new HttpDownloader(
- request);
+ downloader = new HttpDownloader(request);
new Thread() {
@Override
public void run() {
@@ -233,8 +225,7 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
"feed must be non-null and downloaded when parseFeed is called");
}
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Parsing feed");
+ Log.d(TAG, "Parsing feed");
Thread thread = new Thread() {
@@ -258,7 +249,7 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
e.printStackTrace();
reasonDetailed = e.getMessage();
} catch (UnsupportedFeedtypeException e) {
- if (BuildConfig.DEBUG) Log.d(TAG, "Unsupported feed type detected");
+ Log.d(TAG, "Unsupported feed type detected");
if (StringUtils.equalsIgnoreCase("html", e.getRootElement())) {
if (showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url())) {
return;
@@ -269,8 +260,7 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
}
} finally {
boolean rc = new File(feed.getFile_url()).delete();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Deleted feed source file. Result: " + rc);
+ Log.d(TAG, "Deleted feed source file. Result: " + rc);
}
if (successful) {
@@ -386,7 +376,12 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
String selectedUrl = urls.get(which);
dialog.dismiss();
resetIntent(selectedUrl, titles.get(which));
- startFeedDownload(selectedUrl, null, null);
+ FeedPreferences prefs = feed.getPreferences();
+ if(prefs != null) {
+ startFeedDownload(selectedUrl, prefs.getUsername(), prefs.getPassword());
+ } else {
+ startFeedDownload(selectedUrl, null, null);
+ }
}
};
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
index 8d3e73429..8e347a819 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
@@ -10,7 +10,9 @@ import org.apache.commons.lang3.Validate;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.util.LongList;
/**
* Utility methods for the action button that is displayed on the right hand side
@@ -26,9 +28,21 @@ public class ActionButtonUtils {
Validate.notNull(context);
this.context = context;
- drawables = context.obtainStyledAttributes(new int[]{
- R.attr.av_play, R.attr.navigation_cancel, R.attr.av_download, R.attr.av_pause, R.attr.navigation_accept});
- labels = new int[]{R.string.play_label, R.string.cancel_download_label, R.string.download_label, R.string.mark_read_label};
+ drawables = context.obtainStyledAttributes(new int[] {
+ R.attr.av_play,
+ R.attr.navigation_cancel,
+ R.attr.av_download,
+ R.attr.av_pause,
+ R.attr.navigation_accept,
+ R.attr.content_new
+ });
+ labels = new int[] {
+ R.string.play_label,
+ R.string.cancel_download_label,
+ R.string.download_label,
+ R.string.mark_read_label,
+ R.string.add_to_queue_label
+ };
}
/**
@@ -50,18 +64,26 @@ public class ActionButtonUtils {
butSecondary.setContentDescription(context.getString(labels[1]));
} else {
// item is not downloaded and not being downloaded
- butSecondary.setVisibility(View.VISIBLE);
- butSecondary.setImageDrawable(drawables.getDrawable(2));
- butSecondary.setContentDescription(context.getString(labels[2]));
+ LongList queueIds = DBReader.getQueueIDList(context);
+ if(DefaultActionButtonCallback.userAllowedMobileDownloads() ||
+ !DefaultActionButtonCallback.userChoseAddToQueue() || queueIds.contains(item.getId())) {
+ butSecondary.setVisibility(View.VISIBLE);
+ butSecondary.setImageDrawable(drawables.getDrawable(2));
+ butSecondary.setContentDescription(context.getString(labels[2]));
+ } else {
+ // mobile download not allowed yet, item is not in queue and user chose add to queue
+ butSecondary.setVisibility(View.VISIBLE);
+ butSecondary.setImageDrawable(drawables.getDrawable(5));
+ butSecondary.setContentDescription(context.getString(labels[4]));
+ }
}
} else {
- // item is not being downloaded
+ // item is downloaded
butSecondary.setVisibility(View.VISIBLE);
if (media.isCurrentlyPlaying()) {
butSecondary.setImageDrawable(drawables.getDrawable(3));
} else {
- butSecondary
- .setImageDrawable(drawables.getDrawable(0));
+ butSecondary.setImageDrawable(drawables.getDrawable(0));
}
butSecondary.setContentDescription(context.getString(labels[0]));
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
index 14644dd68..3d233817b 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
@@ -1,6 +1,8 @@
package de.danoeh.antennapod.adapter;
+import android.app.AlertDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.widget.Toast;
@@ -10,43 +12,77 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
+
+import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
+import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
+import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
+import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.util.LongList;
+import de.danoeh.antennapod.core.util.NetworkUtils;
/**
* Default implementation of an ActionButtonCallback
*/
public class DefaultActionButtonCallback implements ActionButtonCallback {
+
private static final String TAG = "DefaultActionButtonCallback";
private final Context context;
+ private static final int TEN_MINUTES_IN_MILLIS = 60 * 1000 * 10;
+
+ // remember timestamp when user allowed downloading via mobile connection
+ private static long allowMobileDownloadsTimestamp;
+ private static long onlyAddToQueueTimeStamp;
+
public DefaultActionButtonCallback(Context context) {
Validate.notNull(context);
this.context = context;
}
+ public static boolean userAllowedMobileDownloads() {
+ return System.currentTimeMillis() - allowMobileDownloadsTimestamp < TEN_MINUTES_IN_MILLIS;
+ }
+
+ public static boolean userChoseAddToQueue() {
+ return System.currentTimeMillis() - onlyAddToQueueTimeStamp < TEN_MINUTES_IN_MILLIS;
+ }
+
@Override
public void onActionButtonPressed(final FeedItem item) {
-
if (item.hasMedia()) {
final FeedMedia media = item.getMedia();
boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
if (!isDownloading && !media.isDownloaded()) {
- try {
- DBTasks.downloadFeedItems(context, item);
- Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
- } catch (DownloadRequestException e) {
- e.printStackTrace();
- DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
+ LongList queueIds = DBReader.getQueueIDList(context);
+ if (NetworkUtils.isDownloadAllowed(context) || userAllowedMobileDownloads()) {
+ try {
+ DBTasks.downloadFeedItems(context, item);
+ Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
+ }
+ } else if(userChoseAddToQueue() && !queueIds.contains(item.getId())) {
+ DBWriter.addQueueItem(context, item.getId());
+ Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
+ } else {
+ confirmMobileDownload(context, item);
}
} else if (isDownloading) {
DownloadRequester.getInstance().cancelDownload(context, media);
- Toast.makeText(context, R.string.download_cancelled_msg, Toast.LENGTH_SHORT).show();
+ if(UserPreferences.isEnableAutodownload()) {
+ DBWriter.setFeedItemAutoDownload(context, media.getItem(), false);
+ Toast.makeText(context, R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_LONG).show();
+ } else {
+ Toast.makeText(context, R.string.download_canceled_msg, Toast.LENGTH_LONG).show();
+ }
} else { // media is downloaded
if (item.hasMedia() && item.getMedia().isCurrentlyPlaying()) {
context.sendBroadcast(new Intent(PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE));
@@ -61,7 +97,59 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
} else {
if (!item.isRead()) {
DBWriter.markItemRead(context, item, true, true);
+
+ if(GpodnetPreferences.loggedIn()) {
+ // gpodder: send played action
+ FeedMedia media = item.getMedia();
+ GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, GpodnetEpisodeAction.Action.PLAY)
+ .currentDeviceId()
+ .currentTimestamp()
+ .started(media.getDuration() / 1000)
+ .position(media.getDuration() / 1000)
+ .total(media.getDuration() / 1000)
+ .build();
+ GpodnetPreferences.enqueueEpisodeAction(action);
+ }
}
}
}
+
+ private void confirmMobileDownload(final Context context, final FeedItem item) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder
+ .setTitle(R.string.confirm_mobile_download_dialog_title)
+ .setMessage(context.getText(R.string.confirm_mobile_download_dialog_message))
+ .setPositiveButton(R.string.confirm_mobile_download_dialog_enable_temporarily,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ allowMobileDownloadsTimestamp = System.currentTimeMillis();
+ try {
+ DBTasks.downloadFeedItems(context, item);
+ Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
+ }
+ }
+ });
+ LongList queueIds = DBReader.getQueueIDList(context);
+ if(!queueIds.contains(item.getId())) {
+ builder.setNeutralButton(R.string.confirm_mobile_download_dialog_only_add_to_queue,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onlyAddToQueueTimeStamp = System.currentTimeMillis();
+ DBWriter.addQueueItem(context, item.getId());
+ Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
+ }
+ })
+ .setMessage(context.getText(R.string.confirm_mobile_download_dialog_message_not_in_queue));
+ } else {
+ builder.setMessage(context.getText(R.string.confirm_mobile_download_dialog_message));
+ }
+ builder.setNegativeButton(R.string.cancel_label, null)
+ .create()
+ .show();
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
index f982e86ce..f29cfdf2f 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
@@ -2,20 +2,34 @@ package de.danoeh.antennapod.adapter;
import android.content.Context;
import android.text.format.DateUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import android.widget.Button;
import android.widget.TextView;
+import android.widget.Toast;
+
+import com.joanzapata.android.iconify.Iconify;
+
+import java.util.Date;
+
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBTasks;
+import de.danoeh.antennapod.core.storage.DownloadRequestException;
/** Displays a list of DownloadStatus entries. */
public class DownloadLogAdapter extends BaseAdapter {
+ private final String TAG = "DownloadLogAdapter";
+
private Context context;
private ItemAccess itemAccess;
@@ -35,11 +49,11 @@ public class DownloadLogAdapter extends BaseAdapter {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.downloadlog_item, parent, false);
+ holder.icon = (TextView) convertView.findViewById(R.id.txtvIcon);
+ holder.retry = (Button) convertView.findViewById(R.id.btnRetry);
+ holder.date = (TextView) convertView.findViewById(R.id.txtvDate);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.type = (TextView) convertView.findViewById(R.id.txtvType);
- holder.date = (TextView) convertView.findViewById(R.id.txtvDate);
- holder.successful = (TextView) convertView
- .findViewById(R.id.txtvStatus);
holder.reason = (TextView) convertView
.findViewById(R.id.txtvReason);
convertView.setTag(holder);
@@ -62,33 +76,99 @@ public class DownloadLogAdapter extends BaseAdapter {
status.getCompletionDate().getTime(),
System.currentTimeMillis(), 0, 0));
if (status.isSuccessful()) {
- holder.successful.setTextColor(convertView.getResources().getColor(
+ holder.icon.setTextColor(convertView.getResources().getColor(
R.color.download_success_green));
- holder.successful.setText(R.string.download_successful);
+ holder.icon.setText("{fa-check-circle}");
+ Iconify.addIcons(holder.icon);
+ holder.retry.setVisibility(View.GONE);
holder.reason.setVisibility(View.GONE);
} else {
- holder.successful.setTextColor(convertView.getResources().getColor(
+ holder.icon.setTextColor(convertView.getResources().getColor(
R.color.download_failed_red));
- holder.successful.setText(R.string.download_failed);
+ holder.icon.setText("{fa-times-circle}");
+ Iconify.addIcons(holder.icon);
String reasonText = status.getReason().getErrorString(context);
if (status.getReasonDetailed() != null) {
reasonText += ": " + status.getReasonDetailed();
}
holder.reason.setText(reasonText);
holder.reason.setVisibility(View.VISIBLE);
+ if(status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE &&
+ !newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
+ holder.retry.setVisibility(View.VISIBLE);
+ holder.retry.setText("{fa-repeat}");
+ Iconify.addIcons(holder.retry);
+ holder.retry.setOnClickListener(clickListener);
+ ButtonHolder btnHolder;
+ if(holder.retry.getTag() != null) {
+ btnHolder = (ButtonHolder) holder.retry.getTag();
+ } else {
+ btnHolder = new ButtonHolder();
+ }
+ btnHolder.typeId = status.getFeedfileType();
+ btnHolder.id = status.getFeedfileId();
+ holder.retry.setTag(btnHolder);
+ } else {
+ holder.retry.setVisibility(View.GONE);
+ holder.retry.setOnClickListener(null);
+ holder.retry.setTag(null);
+ }
}
return convertView;
}
+ private final View.OnClickListener clickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ ButtonHolder holder = (ButtonHolder) v.getTag();
+ if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
+ Feed feed = DBReader.getFeed(context, holder.id);
+ feed.setLastUpdate(new Date(0)); // force refresh
+ try {
+ DBTasks.refreshFeed(context, feed);
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ }
+ } else if(holder.typeId == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
+ FeedMedia media = DBReader.getFeedMedia(context, holder.id);
+ try {
+ DBTasks.downloadFeedItems(context, media.getItem());
+ Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
+ }
+ } else {
+ Log.wtf(TAG, "Unexpected type id: " + holder.typeId);
+ }
+ v.setVisibility(View.GONE);
+ }
+ };
+
+ private boolean newerWasSuccessful(int position, int feedTypeId, long id) {
+ for (int i = 0; i < position; i++) {
+ DownloadStatus status = getItem(i);
+ if (status.getFeedfileType() == feedTypeId && status.getFeedfileId() == id &&
+ status.isSuccessful()) return true;
+ }
+ return false;
+ }
+
static class Holder {
+ TextView icon;
+ Button retry;
TextView title;
TextView type;
TextView date;
- TextView successful;
TextView reason;
}
+ static class ButtonHolder {
+ int typeId;
+ long id;
+ }
+
@Override
public int getCount() {
return itemAccess.getCount();
@@ -104,9 +184,9 @@ public class DownloadLogAdapter extends BaseAdapter {
return position;
}
- public static interface ItemAccess {
- public int getCount();
- public DownloadStatus getItem(int position);
+ public interface ItemAccess {
+ int getCount();
+ DownloadStatus getItem(int position);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
index d56bfc587..74fd4d9c0 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
@@ -7,9 +7,14 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.widget.*;
+import android.widget.Adapter;
+import android.widget.BaseAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
@@ -211,8 +216,8 @@ public class FeedItemlistAdapter extends BaseAdapter {
notifyDataSetChanged();
}
- public static interface ItemAccess {
- public boolean isInQueue(FeedItem item);
+ public interface ItemAccess {
+ boolean isInQueue(FeedItem item);
int getItemDownloadProgressPercent(FeedItem item);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
index 17cd71f86..907093ad6 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -1,9 +1,11 @@
package de.danoeh.antennapod.adapter;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
+import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -13,29 +15,36 @@ import android.widget.TextView;
import com.squareup.picasso.Picasso;
+import org.apache.commons.lang3.ArrayUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.fragment.AddFeedFragment;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
+import de.danoeh.antennapod.fragment.DownloadsFragment;
+import de.danoeh.antennapod.fragment.NewEpisodesFragment;
+import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
+import de.danoeh.antennapod.fragment.QueueFragment;
/**
* BaseAdapter for the navigation drawer
*/
-public class NavListAdapter extends BaseAdapter {
+public class NavListAdapter extends BaseAdapter
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final int VIEW_TYPE_COUNT = 3;
public static final int VIEW_TYPE_NAV = 0;
public static final int VIEW_TYPE_SECTION_DIVIDER = 1;
public static final int VIEW_TYPE_SUBSCRIPTION = 2;
- public static final int[] NAV_TITLES = {
- R.string.queue_label,
- R.string.new_episodes_label,
- R.string.all_episodes_label,
- R.string.downloads_label,
- R.string.playback_history_label,
- R.string.add_feed_label};
-
- private final Drawable[] drawables;
-
- public static final int SUBSCRIPTION_OFFSET = 1 + NAV_TITLES.length;
+ private static List<String> tags;
+ private static String[] titles;
private ItemAccess itemAccess;
private Context context;
@@ -44,28 +53,79 @@ public class NavListAdapter extends BaseAdapter {
this.itemAccess = itemAccess;
this.context = context;
- TypedArray ta = context.obtainStyledAttributes(new int[]{
- R.attr.stat_playlist,
- R.attr.ic_new,
- R.attr.feed,
- R.attr.av_download,
- R.attr.ic_history,
- R.attr.content_new});
- drawables = new Drawable[]{ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2),
- ta.getDrawable(3), ta.getDrawable(4), ta.getDrawable(5)};
+ titles = context.getResources().getStringArray(R.array.nav_drawer_titles);
+ loadItems();
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (key.equals(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS)) {
+ loadItems();
+ }
+ }
+
+ private void loadItems() {
+ List<String> newTags = new ArrayList<String>(Arrays.asList(MainActivity.NAV_DRAWER_TAGS));
+ List<String> hiddenFragments = UserPreferences.getHiddenDrawerItems();
+ for(String hidden : hiddenFragments) {
+ newTags.remove(hidden);
+ }
+ tags = newTags;
+ notifyDataSetChanged();
+ }
+
+ public String getLabel(String tag) {
+ int index = ArrayUtils.indexOf(MainActivity.NAV_DRAWER_TAGS, tag);
+ return titles[index];
+ }
+
+ private Drawable getDrawable(String tag) {
+ int icon;
+ switch (tag) {
+ case QueueFragment.TAG:
+ icon = R.attr.stat_playlist;
+ break;
+ case NewEpisodesFragment.TAG:
+ icon = R.attr.ic_new;
+ break;
+ case AllEpisodesFragment.TAG:
+ icon = R.attr.feed;
+ break;
+ case DownloadsFragment.TAG:
+ icon = R.attr.av_download;
+ break;
+ case PlaybackHistoryFragment.TAG:
+ icon = R.attr.ic_history;
+ break;
+ case AddFeedFragment.TAG:
+ icon = R.attr.content_new;
+ break;
+ default:
+ return null;
+ }
+ TypedArray ta = context.obtainStyledAttributes(new int[] { icon } );
+ Drawable result = ta.getDrawable(0);
ta.recycle();
+ return result;
}
+ public List<String> getTags() {
+ return Collections.unmodifiableList(tags);
+ }
+
+
@Override
public int getCount() {
- return NAV_TITLES.length + 1 + itemAccess.getCount();
+ return getSubscriptionOffset() + itemAccess.getCount();
}
@Override
public Object getItem(int position) {
int viewType = getItemViewType(position);
if (viewType == VIEW_TYPE_NAV) {
- return context.getString(NAV_TITLES[position]);
+ return getLabel(tags.get(position));
} else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
return "";
} else {
@@ -80,9 +140,9 @@ public class NavListAdapter extends BaseAdapter {
@Override
public int getItemViewType(int position) {
- if (0 <= position && position < NAV_TITLES.length) {
+ if (0 <= position && position < tags.size()) {
return VIEW_TYPE_NAV;
- } else if (position < NAV_TITLES.length + 1) {
+ } else if (position < getSubscriptionOffset()) {
return VIEW_TYPE_SECTION_DIVIDER;
} else {
return VIEW_TYPE_SUBSCRIPTION;
@@ -94,6 +154,11 @@ public class NavListAdapter extends BaseAdapter {
return VIEW_TYPE_COUNT;
}
+ public int getSubscriptionOffset() {
+ return tags.size() > 0 ? tags.size() + 1 : 0;
+ }
+
+
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int viewType = getItemViewType(position);
@@ -103,7 +168,7 @@ public class NavListAdapter extends BaseAdapter {
} else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
v = getSectionDividerView(convertView, parent);
} else {
- v = getFeedView(position - SUBSCRIPTION_OFFSET, convertView, parent);
+ v = getFeedView(position - getSubscriptionOffset(), convertView, parent);
}
if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) {
TextView txtvTitle = (TextView) v.findViewById(R.id.txtvTitle);
@@ -135,7 +200,7 @@ public class NavListAdapter extends BaseAdapter {
holder.title.setText(title);
- if (NAV_TITLES[position] == R.string.queue_label) {
+ if (tags.get(position).equals(QueueFragment.TAG)) {
int queueSize = itemAccess.getQueueSize();
if (queueSize > 0) {
holder.count.setVisibility(View.VISIBLE);
@@ -143,7 +208,7 @@ public class NavListAdapter extends BaseAdapter {
} else {
holder.count.setVisibility(View.GONE);
}
- } else if (NAV_TITLES[position] == R.string.new_episodes_label) {
+ } else if (tags.get(position).equals(NewEpisodesFragment.TAG)) {
int unreadItems = itemAccess.getNumberOfUnreadItems();
if (unreadItems > 0) {
holder.count.setVisibility(View.VISIBLE);
@@ -155,7 +220,7 @@ public class NavListAdapter extends BaseAdapter {
holder.count.setVisibility(View.GONE);
}
- holder.image.setImageDrawable(drawables[position]);
+ holder.image.setImageDrawable(getDrawable(tags.get(position)));
return convertView;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
index a256dc129..bba5a00a9 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
@@ -14,9 +14,9 @@ import android.widget.TextView;
import com.squareup.picasso.Picasso;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
@@ -31,6 +31,8 @@ public class QueueListAdapter extends BaseAdapter {
private final ActionButtonCallback actionButtonCallback;
private final ActionButtonUtils actionButtonUtils;
+ private boolean locked;
+
public QueueListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) {
super();
@@ -38,6 +40,12 @@ public class QueueListAdapter extends BaseAdapter {
this.itemAccess = itemAccess;
this.actionButtonUtils = new ActionButtonUtils(context);
this.actionButtonCallback = actionButtonCallback;
+ locked = UserPreferences.isQueueLocked();
+ }
+
+ public void setLocked(boolean locked) {
+ this.locked = locked;
+ notifyDataSetChanged();
}
@Override
@@ -67,6 +75,7 @@ public class QueueListAdapter extends BaseAdapter {
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.queue_listitem,
parent, false);
+ holder.dragHandle = (ImageView) convertView.findViewById(R.id.drag_handle);
holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate);
@@ -83,6 +92,12 @@ public class QueueListAdapter extends BaseAdapter {
holder = (Holder) convertView.getTag();
}
+ if(locked) {
+ holder.dragHandle.setVisibility(View.GONE);
+ } else {
+ holder.dragHandle.setVisibility(View.VISIBLE);
+ }
+
holder.title.setText(item.getTitle());
FeedMedia media = item.getMedia();
@@ -143,6 +158,7 @@ public class QueueListAdapter extends BaseAdapter {
static class Holder {
+ ImageView dragHandle;
ImageView imageView;
TextView title;
TextView pubDate;
diff --git a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
index 3a9e62435..998bfa6c9 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
@@ -20,7 +20,7 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
public PendingIntent getNotificationContentIntent(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_NAV_TYPE, NavListAdapter.VIEW_TYPE_NAV);
- intent.putExtra(MainActivity.EXTRA_NAV_INDEX, MainActivity.POS_DOWNLOADS);
+ intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, DownloadsFragment.TAG);
Bundle args = new Bundle();
args.putInt(DownloadsFragment.ARG_SELECTED_TAB, DownloadsFragment.POS_RUNNING);
intent.putExtra(MainActivity.EXTRA_FRAGMENT_ARGS, args);
@@ -41,7 +41,7 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
public PendingIntent getReportNotificationContentIntent(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_NAV_TYPE, NavListAdapter.VIEW_TYPE_NAV);
- intent.putExtra(MainActivity.EXTRA_NAV_INDEX, MainActivity.POS_DOWNLOADS);
+ intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, DownloadsFragment.TAG);
Bundle args = new Bundle();
args.putInt(DownloadsFragment.ARG_SELECTED_TAB, DownloadsFragment.POS_LOG);
intent.putExtra(MainActivity.EXTRA_FRAGMENT_ARGS, args);
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 10a3c1b32..2c5bc9cff 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java
@@ -13,7 +13,7 @@ public class StorageCallbacksImpl implements StorageCallbacks {
@Override
public int getDatabaseVersion() {
- return 14;
+ return 15;
}
@Override
@@ -124,5 +124,17 @@ public class StorageCallbacksImpl implements StorageCallbacks {
PodDBAdapter.KEY_LINK,
PodDBAdapter.KEY_CHAPTER_TYPE));
}
+ if(oldVersion <= 14) {
+ db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
+ + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " INTEGER");
+ db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
+ + " SET " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " = "
+ + "(SELECT " + PodDBAdapter.KEY_AUTO_DOWNLOAD
+ + " FROM " + PodDBAdapter.TABLE_NAME_FEEDS
+ + " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_ID
+ + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + ")");
+ db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
+ + " ADD COLUMN " + PodDBAdapter.KEY_HIDE + " TEXT");
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
index e4ae1683b..bbe6fab46 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
@@ -20,7 +20,8 @@ import de.danoeh.antennapod.fragment.gpodnet.GpodnetMainFragment;
* Provides actions for adding new podcast subscriptions
*/
public class AddFeedFragment extends Fragment {
- private static final String TAG = "AddFeedFragment";
+
+ public static final String TAG = "AddFeedFragment";
/**
* Preset value for url text field.
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 2eef7b635..6cd78da50 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -41,6 +41,7 @@ import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.QueueAccess;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
@@ -49,10 +50,11 @@ import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
* Shows unread or recently published episodes
*/
public class AllEpisodesFragment extends Fragment {
- private static final String TAG = "AllEpisodesFragment";
+
+ public static final String TAG = "AllEpisodesFragment";
+
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOAD_QUEUED |
- EventDistributor.QUEUE_UPDATE |
EventDistributor.UNREAD_ITEMS_UPDATE |
EventDistributor.PLAYER_STATUS_UPDATE;
@@ -69,7 +71,7 @@ public class AllEpisodesFragment extends Fragment {
private List<FeedItem> unreadItems;
private List<FeedItem> recentItems;
- private QueueAccess queueAccess;
+ private LongList queueAccess;
private List<Downloader> downloaderList;
private boolean itemsLoaded = false;
@@ -192,7 +194,7 @@ public class AllEpisodesFragment extends Fragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
inflater.inflate(R.menu.new_episodes, menu);
final SearchView sv = new SearchView(getActivity());
@@ -218,7 +220,7 @@ public class AllEpisodesFragment extends Fragment {
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
MenuItem menuItem = menu.findItem(R.id.mark_all_read_item);
if (menuItem != null) {
menuItem.setVisible(unreadItems != null && !unreadItems.isEmpty());
@@ -402,7 +404,7 @@ public class AllEpisodesFragment extends Fragment {
private ItemLoader itemLoader;
- private void startItemLoader() {
+ protected void startItemLoader() {
if (itemLoader != null) {
itemLoader.cancel(true);
}
@@ -432,9 +434,10 @@ public class AllEpisodesFragment extends Fragment {
protected Object[] doInBackground(Void... params) {
Context context = activity.get();
if (context != null) {
- return new Object[]{DBReader.getUnreadItemsList(context),
+ return new Object[]{
+ DBReader.getUnreadItemsList(context),
DBReader.getRecentlyPublishedEpisodes(context, RECENT_EPISODES_LIMIT),
- QueueAccess.IDListAccess(DBReader.getQueueIDList(context))};
+ DBReader.getQueueIDList(context)};
} else {
return null;
}
@@ -449,7 +452,7 @@ public class AllEpisodesFragment extends Fragment {
if (lists != null) {
unreadItems = (List<FeedItem>) lists[0];
recentItems = (List<FeedItem>) lists[1];
- queueAccess = (QueueAccess) lists[2];
+ queueAccess = (LongList) lists[2];
itemsLoaded = true;
if (viewsCreated && activity.get() != null) {
onFragmentLoaded();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
index d63d66966..3ca5b3c89 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
@@ -8,6 +8,7 @@ import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ListView;
+import java.util.Collections;
import java.util.List;
import de.danoeh.antennapod.R;
@@ -17,7 +18,6 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
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.QueueAccess;
/**
* Displays all running downloads and provides a button to delete them
@@ -26,11 +26,9 @@ public class CompletedDownloadsFragment extends ListFragment {
private static final int EVENTS =
EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOADLOG_UPDATE |
- EventDistributor.QUEUE_UPDATE |
EventDistributor.UNREAD_ITEMS_UPDATE;
private List<FeedItem> items;
- private QueueAccess queue;
private DownloadedEpisodesListAdapter listAdapter;
private boolean viewCreated = false;
@@ -155,7 +153,7 @@ public class CompletedDownloadsFragment extends ListFragment {
}
}
- private class ItemLoader extends AsyncTask<Void, Void, Object[]> {
+ private class ItemLoader extends AsyncTask<Void, Void, List<FeedItem>> {
@Override
protected void onPreExecute() {
@@ -166,11 +164,10 @@ public class CompletedDownloadsFragment extends ListFragment {
}
@Override
- protected void onPostExecute(Object[] results) {
+ protected void onPostExecute(List<FeedItem> results) {
super.onPostExecute(results);
if (results != null) {
- items = (List<FeedItem>) results[0];
- queue = (QueueAccess) results[1];
+ items = results;
itemsLoaded = true;
if (viewCreated && getActivity() != null) {
onFragmentLoaded();
@@ -179,13 +176,12 @@ public class CompletedDownloadsFragment extends ListFragment {
}
@Override
- protected Object[] doInBackground(Void... params) {
+ protected List<FeedItem> doInBackground(Void... params) {
Context context = getActivity();
if (context != null) {
- return new Object[]{DBReader.getDownloadedItems(context),
- QueueAccess.IDListAccess(DBReader.getQueueIDList(context))};
+ return DBReader.getDownloadedItems(context);
}
- return null;
+ return Collections.emptyList();
}
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
index 0f6f7d53c..074a87ea0 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
@@ -20,8 +20,6 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
/**
* Shows the download log
@@ -119,7 +117,7 @@ public class DownloadLogFragment extends ListFragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
MenuItem clearHistory = menu.add(Menu.NONE, R.id.clear_history_item, Menu.CATEGORY_CONTAINER, R.string.clear_history_label);
MenuItemCompat.setShowAsAction(clearHistory, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.content_discard});
@@ -131,8 +129,11 @@ public class DownloadLogFragment extends ListFragment {
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
- menu.findItem(R.id.clear_history_item).setVisible(downloadLog != null && !downloadLog.isEmpty());
+ if (itemsLoaded) {
+ MenuItem menuItem = menu.findItem(R.id.clear_history_item);
+ if(menuItem != null) {
+ menuItem.setVisible(downloadLog != null && !downloadLog.isEmpty());
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java
index 712db1421..1ce379cf8 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java
@@ -17,6 +17,8 @@ import de.danoeh.antennapod.R;
*/
public class DownloadsFragment extends Fragment {
+ public static final String TAG = "DownloadsFragment";
+
public static final String ARG_SELECTED_TAB = "selected_tab";
public static final int POS_RUNNING = 0;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
index a42658057..fdb128f03 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
@@ -13,7 +13,6 @@ import android.widget.TextView;
import com.squareup.picasso.Picasso;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.util.Converter;
@@ -54,8 +53,7 @@ public class ExternalPlayerFragment extends Fragment {
@Override
public void onClick(View v) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "layoutInfo was clicked");
+ Log.d(TAG, "layoutInfo was clicked");
if (controller.getMedia() != null) {
startActivity(PlaybackService.getPlayerActivityIntent(
@@ -90,14 +88,10 @@ public class ExternalPlayerFragment extends Fragment {
@Override
public void onBufferStart() {
- // TODO Auto-generated method stub
-
}
@Override
public void onBufferEnd() {
- // TODO Auto-generated method stub
-
}
@Override
@@ -153,7 +147,6 @@ public class ExternalPlayerFragment extends Fragment {
butPlay.setOnClickListener(controller
.newOnPlayButtonClickListener());
}
-
}
@Override
@@ -170,8 +163,6 @@ public class ExternalPlayerFragment extends Fragment {
@Override
public void onPlaybackSpeedChange() {
- // TODO Auto-generated method stub
-
}
};
}
@@ -185,8 +176,7 @@ public class ExternalPlayerFragment extends Fragment {
@Override
public void onDestroy() {
super.onDestroy();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Fragment is about to be destroyed");
+ Log.d(TAG, "Fragment is about to be destroyed");
if (controller != null) {
controller.release();
}
@@ -201,8 +191,7 @@ public class ExternalPlayerFragment extends Fragment {
}
private boolean loadMediaInfo() {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Loading media info");
+ Log.d(TAG, "Loading media info");
if (controller.serviceAvailable()) {
Playable media = controller.getMedia();
if (media != null) {
@@ -221,13 +210,11 @@ public class ExternalPlayerFragment extends Fragment {
}
return true;
} else {
- Log.w(TAG,
- "loadMediaInfo was called while the media object of playbackService was null!");
+ Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!");
return false;
}
} else {
- Log.w(TAG,
- "loadMediaInfo was called while playbackService was null!");
+ Log.w(TAG, "loadMediaInfo was called while playbackService was null!");
return false;
}
}
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 e80bf5f14..10409a421 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -17,6 +17,7 @@ import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.text.format.DateUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@@ -43,6 +44,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.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -51,18 +53,20 @@ import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
-import de.danoeh.antennapod.core.util.QueueAccess;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.playback.Timeline;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.greenrobot.event.EventBus;
/**
* Displays information about a FeedItem and actions.
*/
-public class ItemFragment extends Fragment implements LoaderManager.LoaderCallbacks<Pair<FeedItem, QueueAccess>> {
+public class ItemFragment extends Fragment implements LoaderManager.LoaderCallbacks<Pair<FeedItem, LongList>> {
+
+ private static final String TAG = "ItemFragment";
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOAD_QUEUED |
- EventDistributor.QUEUE_UPDATE |
EventDistributor.UNREAD_ITEMS_UPDATE;
private static final String ARG_FEEDITEM = "feeditem";
@@ -84,7 +88,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
private boolean itemsLoaded = false;
private long itemID;
private FeedItem item;
- private QueueAccess queue;
+ private LongList queue;
private String webviewData;
private DownloadObserver downloadObserver;
private List<Downloader> downloaderList;
@@ -124,6 +128,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
+ EventBus.getDefault().register(this);
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
downloadObserver.onResume();
@@ -138,6 +143,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
+ EventBus.getDefault().unregister(this);
}
private void resetViewState() {
@@ -387,25 +393,29 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
}
}
+ public void onEvent(QueueEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ getLoaderManager().restartLoader(0, null, ItemFragment.this);
+ }
@Override
- public Loader<Pair<FeedItem, QueueAccess>> onCreateLoader(int id, Bundle args) {
- return new DBTaskLoader<Pair<FeedItem, QueueAccess>>(getActivity()) {
+ public Loader<Pair<FeedItem,LongList>> onCreateLoader(int id, Bundle args) {
+ return new DBTaskLoader<Pair<FeedItem,LongList>>(getActivity()) {
@Override
- public Pair<FeedItem, QueueAccess> loadInBackground() {
+ public Pair<FeedItem,LongList> loadInBackground() {
FeedItem data1 = DBReader.getFeedItem(getContext(), itemID);
if (data1 != null) {
Timeline t = new Timeline(getActivity(), data1);
webviewData = t.processShownotes(false);
}
- QueueAccess data2 = QueueAccess.IDListAccess(DBReader.getQueueIDList(getContext()));
+ LongList data2 = DBReader.getQueueIDList(getContext());
return Pair.create(data1, data2);
}
};
}
@Override
- public void onLoadFinished(Loader<Pair<FeedItem, QueueAccess>> loader, Pair<FeedItem, QueueAccess> data) {
+ public void onLoadFinished(Loader<Pair<FeedItem,LongList>> loader, Pair<FeedItem,LongList> data) {
if (data != null) {
item = data.first;
@@ -420,8 +430,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
}
@Override
- public void onLoaderReset(Loader<Pair<FeedItem, QueueAccess>> loader) {
-
+ public void onLoaderReset(Loader<Pair<FeedItem,LongList>> loader) {
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
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 acb07626c..b16de1959 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -9,6 +9,7 @@ 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.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
@@ -23,13 +24,13 @@ import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
+import com.joanzapata.android.iconify.Iconify;
import com.squareup.picasso.Picasso;
import org.apache.commons.lang3.Validate;
import java.util.List;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.FeedInfoActivity;
import de.danoeh.antennapod.activity.MainActivity;
@@ -42,19 +43,22 @@ import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
+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.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
-import de.danoeh.antennapod.core.util.QueueAccess;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
+import de.greenrobot.event.EventBus;
/**
* Displays a list of FeedItems.
@@ -65,7 +69,6 @@ public class ItemlistFragment extends ListFragment {
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED
| EventDistributor.DOWNLOAD_QUEUED
- | EventDistributor.QUEUE_UPDATE
| EventDistributor.UNREAD_ITEMS_UPDATE
| EventDistributor.PLAYER_STATUS_UPDATE;
@@ -76,7 +79,7 @@ public class ItemlistFragment extends ListFragment {
private long feedID;
private Feed feed;
- protected QueueAccess queue;
+ private LongList queue;
private boolean itemsLoaded = false;
private boolean viewsCreated = false;
@@ -88,6 +91,8 @@ public class ItemlistFragment extends ListFragment {
private boolean isUpdatingFeed;
+ private TextView txtvInformation;
+
/**
* Creates new ItemlistFragment which shows the Feeditems of a specific
* feed. Sets 'showFeedtitle' to false
@@ -118,6 +123,7 @@ public class ItemlistFragment extends ListFragment {
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
+ EventBus.getDefault().register(this);
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
downloadObserver.onResume();
@@ -131,6 +137,7 @@ public class ItemlistFragment extends ListFragment {
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
+ EventBus.getDefault().unregister(this);
stopItemLoader();
}
@@ -177,7 +184,7 @@ public class ItemlistFragment extends ListFragment {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
FeedMenuHandler.onCreateOptionsMenu(inflater, menu);
final SearchView sv = new SearchView(getActivity());
@@ -204,7 +211,7 @@ public class ItemlistFragment extends ListFragment {
@Override
public void onPrepareOptionsMenu(Menu menu) {
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
FeedMenuHandler.onPrepareOptionsMenu(menu, feed);
}
}
@@ -221,7 +228,7 @@ public class ItemlistFragment extends ListFragment {
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
- ((MainActivity) getActivity()).loadNavFragment(MainActivity.POS_NEW, null);
+ ((MainActivity) getActivity()).loadFragment(NewEpisodesFragment.TAG, null);
}
};
ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
@@ -283,13 +290,24 @@ public class ItemlistFragment extends ListFragment {
}
}
+ public void onEvent(QueueEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ startItemLoader();
+ }
+
+ public void onEvent(FeedEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ if(event.feedId == feedID) {
+ startItemLoader();
+ }
+ }
+
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((EVENTS & arg) != 0) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received contentUpdate Intent.");
+ Log.d(TAG, "Received contentUpdate Intent.");
if ((EventDistributor.DOWNLOAD_QUEUED & arg) != 0) {
updateProgressBarVisibility();
} else {
@@ -323,6 +341,7 @@ public class ItemlistFragment extends ListFragment {
downloadObserver = new DownloadObserver(getActivity(), new Handler(), downloadObserverCallback);
downloadObserver.onResume();
}
+ refreshHeaderView();
setListShown(true);
adapter.notifyDataSetChanged();
@@ -336,6 +355,22 @@ public class ItemlistFragment extends ListFragment {
}
+ private void refreshHeaderView() {
+ if(feed.getItemFilter() != null) {
+ FeedItemFilter filter = feed.getItemFilter();
+ if(filter.getValues().length > 0) {
+ txtvInformation.setText("{fa-info-circle} " + this.getString(R.string.filtered_label));
+ Iconify.addIcons(txtvInformation);
+ txtvInformation.setVisibility(View.VISIBLE);
+ } else {
+ txtvInformation.setVisibility(View.GONE);
+ }
+ } else {
+ txtvInformation.setVisibility(View.GONE);
+ }
+ }
+
+
private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
@Override
public void onContentChanged() {
@@ -369,6 +404,7 @@ public class ItemlistFragment extends ListFragment {
ImageView imgvBackground = (ImageView) header.findViewById(R.id.imgvBackground);
ImageView imgvCover = (ImageView) header.findViewById(R.id.imgvCover);
ImageButton butShowInfo = (ImageButton) header.findViewById(R.id.butShowInfo);
+ txtvInformation = (TextView) header.findViewById(R.id.txtvInformation);
txtvTitle.setText(feed.getTitle());
txtvAuthor.setText(feed.getAuthor());
@@ -474,25 +510,30 @@ public class ItemlistFragment extends ListFragment {
}
}
- private class ItemLoader extends AsyncTask<Long, Void, Object[]> {
+ private class ItemLoader extends AsyncTask<Long, Void, Pair<Feed,LongList>> {
@Override
- protected Object[] doInBackground(Long... params) {
+ protected Pair<Feed,LongList> doInBackground(Long... params) {
long feedID = params[0];
Context context = getActivity();
if (context != null) {
- return new Object[]{DBReader.getFeed(context, feedID),
- QueueAccess.IDListAccess(DBReader.getQueueIDList(context))};
+ Feed feed = DBReader.getFeed(context, feedID);
+ if(feed.getItemFilter() != null) {
+ FeedItemFilter filter = feed.getItemFilter();
+ feed.setItems(filter.filter(context, feed.getItems()));
+ }
+ LongList queue = DBReader.getQueueIDList(context);
+ return Pair.create(feed, queue);
} else {
return null;
}
}
@Override
- protected void onPostExecute(Object[] res) {
+ protected void onPostExecute(Pair<Feed,LongList> res) {
super.onPostExecute(res);
if (res != null) {
- feed = (Feed) res[0];
- queue = (QueueAccess) res[1];
+ feed = res.first;
+ queue = res.second;
itemsLoaded = true;
if (viewsCreated) {
onFragmentLoaded();
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 c2bbae42d..4bce3c7ba 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
@@ -1,7 +1,7 @@
package de.danoeh.antennapod.fragment;
+import android.content.Context;
import android.os.Bundle;
-import android.os.Parcelable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -11,17 +11,25 @@ import com.mobeta.android.dslv.DragSortListView;
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.preferences.UserPreferences;
+import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
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 new episodes and
* supports swiping to mark as read.
*/
+
public class NewEpisodesFragment extends AllEpisodesFragment {
- private static final String TAG = "NewEpisodesFragment";
+ public static final String TAG = "NewEpisodesFragment";
+
private static final String PREF_NAME = "PrefNewEpisodesFragment";
private UndoBarController undoBarController;
@@ -30,6 +38,23 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
super(true, PREF_NAME);
}
+ public void onEvent(QueueEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ startItemLoader();
+ }
+
+ @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();
@@ -55,18 +80,30 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
}
});
- undoBarController = new UndoBarController(root.findViewById(R.id.undobar), new UndoBarController.UndoListener() {
+ undoBarController = new UndoBarController<FeedItemUndoToken>(root.findViewById(R.id.undobar), new UndoBarController.UndoListener<FeedItemUndoToken>() {
+
+ private final Context context = getActivity();
+
@Override
- public void onUndo(Parcelable token) {
- // Perform the undo
- FeedItemUndoToken undoToken = (FeedItemUndoToken) token;
+ public void onUndo(FeedItemUndoToken token) {
if (token != null) {
- long itemId = undoToken.getFeedItemId();
- int position = undoToken.getPosition();
- DBWriter.markItemRead(getActivity(), itemId, false);
+ long itemId = token.getFeedItemId();
+ DBWriter.markItemRead(context, itemId, false);
+ }
+ }
+ @Override
+ public void onHide(FeedItemUndoToken token) {
+ if (token != null && context != null) {
+ long itemId = token.getFeedItemId();
+ FeedItem item = DBReader.getFeedItem(context, itemId);
+ FeedMedia media = item.getMedia();
+ if(media != null && media.hasAlmostEnded() && UserPreferences.isAutoDelete()) {
+ DBWriter.deleteFeedMediaOfItem(context, media.getId());
+ }
}
}
});
return root;
}
+
}
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 9002227d6..440e38636 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -7,7 +7,9 @@ import android.os.AsyncTask;
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.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -25,20 +27,22 @@ 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.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.util.QueueAccess;
-import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
+import de.danoeh.antennapod.core.util.LongList;
+import de.greenrobot.event.EventBus;
public class PlaybackHistoryFragment extends ListFragment {
- private static final String TAG = "PlaybackHistoryFragment";
+
+ public static final String TAG = "PlaybackHistoryFragment";
+
private static final int EVENTS = EventDistributor.PLAYBACK_HISTORY_UPDATE |
EventDistributor.PLAYER_STATUS_UPDATE;
private List<FeedItem> playbackHistory;
- private QueueAccess queue;
+ private LongList queue;
private FeedItemlistAdapter adapter;
private boolean itemsLoaded = false;
@@ -66,12 +70,14 @@ public class PlaybackHistoryFragment extends ListFragment {
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
+ EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
+ EventBus.getDefault().unregister(this);
stopItemLoader();
}
@@ -133,7 +139,7 @@ public class PlaybackHistoryFragment extends ListFragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
MenuItem clearHistory = menu.add(Menu.NONE, R.id.clear_history_item, Menu.CATEGORY_CONTAINER, R.string.clear_history_label);
MenuItemCompat.setShowAsAction(clearHistory, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.content_discard});
@@ -145,7 +151,7 @@ public class PlaybackHistoryFragment extends ListFragment {
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
MenuItem menuItem = menu.findItem(R.id.clear_history_item);
if (menuItem != null) {
menuItem.setVisible(playbackHistory != null && !playbackHistory.isEmpty());
@@ -168,6 +174,11 @@ public class PlaybackHistoryFragment extends ListFragment {
}
}
+ public void onEvent(QueueEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ startItemLoader();
+ }
+
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
@@ -254,27 +265,27 @@ public class PlaybackHistoryFragment extends ListFragment {
}
}
- private class ItemLoader extends AsyncTask<Void, Void, Object[]> {
+ private class ItemLoader extends AsyncTask<Void, Void, Pair<List<FeedItem>,LongList>> {
@Override
- protected Object[] doInBackground(Void... params) {
+ protected Pair<List<FeedItem>,LongList> doInBackground(Void... params) {
Context context = activity.get();
if (context != null) {
- List<FeedItem> ph = DBReader.getPlaybackHistory(context);
- DBReader.loadFeedDataOfFeedItemlist(context, ph);
- return new Object[]{ph,
- QueueAccess.IDListAccess(DBReader.getQueueIDList(context))};
+ List<FeedItem> history = DBReader.getPlaybackHistory(context);
+ LongList queue = DBReader.getQueueIDList(context);
+ DBReader.loadFeedDataOfFeedItemlist(context, history);
+ return Pair.create(history, queue);
} else {
return null;
}
}
@Override
- protected void onPostExecute(Object[] res) {
+ protected void onPostExecute(Pair<List<FeedItem>,LongList> res) {
super.onPostExecute(res);
if (res != null) {
- playbackHistory = (List<FeedItem>) res[0];
- queue = (QueueAccess) res[1];
+ playbackHistory = res.first;
+ queue = res.second;
itemsLoaded = true;
if (viewsCreated) {
onFragmentLoaded();
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 70a231cad..4263fbfad 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -7,7 +7,6 @@ import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
-import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.SearchView;
import android.util.Log;
@@ -37,6 +36,8 @@ 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.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -47,16 +48,17 @@ import de.danoeh.antennapod.core.util.QueueSorter;
import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken;
import de.danoeh.antennapod.core.util.gui.UndoBarController;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
+import de.greenrobot.event.EventBus;
/**
* Shows all items in the queue
*/
public class QueueFragment extends Fragment {
- private static final String TAG = "QueueFragment";
+
+ public static final String TAG = "QueueFragment";
+
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
EventDistributor.DOWNLOAD_QUEUED |
- EventDistributor.QUEUE_UPDATE |
EventDistributor.PLAYER_STATUS_UPDATE;
private DragSortListView listView;
@@ -64,7 +66,9 @@ public class QueueFragment extends Fragment {
private TextView txtvEmpty;
private ProgressBar progLoading;
- private UndoBarController undoBarController;
+ private MenuItem queueLock;
+
+ private UndoBarController<FeedItemUndoToken> undoBarController;
private List<FeedItem> queue;
private List<Downloader> downloaderList;
@@ -104,6 +108,7 @@ public class QueueFragment extends Fragment {
public void onStart() {
super.onStart();
EventDistributor.getInstance().register(contentUpdate);
+ EventBus.getDefault().register(this);
this.activity.set((MainActivity) getActivity());
if (downloadObserver != null) {
downloadObserver.setActivity(getActivity());
@@ -124,7 +129,11 @@ public class QueueFragment extends Fragment {
public void onStop() {
super.onStop();
EventDistributor.getInstance().unregister(contentUpdate);
+ EventBus.getDefault().unregister(this);
stopItemLoader();
+ if(undoBarController.isShowing()) {
+ undoBarController.close();
+ }
}
@Override
@@ -133,6 +142,15 @@ public class QueueFragment extends Fragment {
this.activity.set((MainActivity) activity);
}
+ public void onEventMainThread(QueueEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ if(event.action == QueueEvent.Action.REMOVED) {
+ undoBarController.showUndoBar(false, getString(R.string.removed_from_queue),
+ new FeedItemUndoToken(event.item, event.position));
+ }
+ startItemLoader();
+ }
+
private void saveScrollPosition() {
SharedPreferences prefs = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
@@ -185,7 +203,7 @@ public class QueueFragment extends Fragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
inflater.inflate(R.menu.queue, menu);
final SearchView sv = new SearchView(getActivity());
@@ -204,6 +222,9 @@ public class QueueFragment extends Fragment {
return false;
}
});
+
+ MenuItemUtils.refreshLockItem(getActivity(), menu, queueLock);
+
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
}
}
@@ -212,6 +233,17 @@ public class QueueFragment extends Fragment {
public boolean onOptionsItemSelected(MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
switch (item.getItemId()) {
+ case R.id.queue_lock:
+ boolean locked = !UserPreferences.isQueueLocked();
+ if(locked) {
+ listView.setDragEnabled(false);
+ } else {
+ listView.setDragEnabled(true);
+ }
+ UserPreferences.setQueueLocked(locked);
+ getActivity().supportInvalidateOptionsMenu();
+ listAdapter.setLocked(locked);
+ return true;
case R.id.refresh_item:
List<Feed> feeds = ((MainActivity) getActivity()).getFeeds();
if (feeds != null) {
@@ -295,7 +327,7 @@ public class QueueFragment extends Fragment {
DBWriter.moveQueueItemToBottom(getActivity(), selectedItem.getId(), true);
return true;
case R.id.remove_from_queue_item:
- DBWriter.removeQueueItem(getActivity(), selectedItem.getId(), false);
+ DBWriter.removeQueueItem(getActivity(), selectedItem, false);
return true;
default:
return super.onContextItemSelected(item);
@@ -313,6 +345,12 @@ public class QueueFragment extends Fragment {
progLoading = (ProgressBar) root.findViewById(R.id.progLoading);
listView.setEmptyView(txtvEmpty);
+ if(UserPreferences.isQueueLocked()) {
+ listView.setDragEnabled(false);
+ } else {
+ listView.setDragEnabled(true);
+ }
+
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@@ -343,29 +381,42 @@ public class QueueFragment extends Fragment {
@Override
public void remove(int which) {
- Log.d(TAG, "remove("+which+")");
+ Log.d(TAG, "remove(" + which + ")");
stopItemLoader();
FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
- DBWriter.removeQueueItem(getActivity(), item.getId(), true);
- undoBarController.showUndoBar(false,
- getString(R.string.removed_from_queue), new FeedItemUndoToken(item,
- which)
- );
+ DBWriter.markItemRead(getActivity(), item.getId(), true);
+ DBWriter.removeQueueItem(getActivity(), item, true);
}
});
- undoBarController = new UndoBarController(root.findViewById(R.id.undobar), new UndoBarController.UndoListener() {
- @Override
- public void onUndo(Parcelable token) {
- // Perform the undo
- FeedItemUndoToken undoToken = (FeedItemUndoToken) token;
- if (token != null) {
- long itemId = undoToken.getFeedItemId();
- int position = undoToken.getPosition();
- DBWriter.addQueueItemAt(getActivity(), itemId, position, false);
- }
- }
- });
+ 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();
+ int position = token.getPosition();
+ DBWriter.markItemRead(context, itemId, false);
+ DBWriter.addQueueItemAt(context, itemId, position, false);
+ }
+ }
+
+ @Override
+ public void onHide(FeedItemUndoToken token) {
+ if (token != null && context != null) {
+ long itemId = token.getFeedItemId();
+ FeedItem item = DBReader.getFeedItem(context, itemId);
+ FeedMedia media = item.getMedia();
+ if(media != null && media.hasAlmostEnded() && UserPreferences.isAutoDelete()) {
+ DBWriter.deleteFeedMediaOfItem(context, media.getId());
+ }
+ }
+ }
+
+ });
registerForContextMenu(listView);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
index f578d4338..b1b61f74b 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
@@ -5,15 +5,21 @@ import android.os.Handler;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ListView;
+import android.widget.Toast;
+
+import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.DownloadlistAdapter;
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.service.download.DownloadRequest;
import de.danoeh.antennapod.core.service.download.Downloader;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
-import java.util.List;
-
/**
* Displays all running downloads and provides actions to cancel them
*/
@@ -73,7 +79,17 @@ public class RunningDownloadsFragment extends ListFragment {
@Override
public void onSecondaryActionClick(Downloader downloader) {
- DownloadRequester.getInstance().cancelDownload(getActivity(), downloader.getDownloadRequest().getSource());
+ DownloadRequest downloadRequest = downloader.getDownloadRequest();
+ DownloadRequester.getInstance().cancelDownload(getActivity(), downloadRequest.getSource());
+
+ if(downloadRequest.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA &&
+ UserPreferences.isEnableAutodownload()) {
+ FeedMedia media = DBReader.getFeedMedia(getActivity(), downloadRequest.getFeedfileId());
+ DBWriter.setFeedItemAutoDownload(getActivity(), media.getItem(), false);
+ Toast.makeText(getActivity(), R.string.download_canceled_autodownload_enabled_msg, Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(getActivity(), R.string.download_canceled_msg, Toast.LENGTH_SHORT).show();
+ }
}
};
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
index cf96bb094..fc6225409 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
@@ -13,6 +13,7 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
+import java.util.Collections;
import java.util.List;
import de.danoeh.antennapod.R;
@@ -23,11 +24,7 @@ import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
-import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.FeedSearcher;
-import de.danoeh.antennapod.core.util.QueueAccess;
-import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
/**
* Performs a search operation on all feeds or one specific feed and displays the search result.
@@ -44,8 +41,6 @@ public class SearchFragment extends ListFragment {
private boolean viewCreated = false;
private boolean itemsLoaded = false;
- private QueueAccess queue;
-
/**
* Create a new SearchFragment that searches all feeds.
*/
@@ -125,7 +120,7 @@ public class SearchFragment extends ListFragment {
SearchResult result = (SearchResult) l.getAdapter().getItem(position);
FeedComponent comp = result.getComponent();
if (comp.getClass() == Feed.class) {
- ((MainActivity) getActivity()).loadFeedFragment(comp.getId());
+ ((MainActivity) getActivity()).loadFeedFragmentById(comp.getId());
} else {
if (comp.getClass() == FeedItem.class) {
FeedItem item = (FeedItem) comp;
@@ -137,7 +132,7 @@ public class SearchFragment extends ListFragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
+ if (itemsLoaded) {
MenuItem item = menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
final SearchView sv = new SearchView(getActivity());
@@ -165,8 +160,7 @@ public class SearchFragment extends ListFragment {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
if ((arg & (EventDistributor.UNREAD_ITEMS_UPDATE
- | EventDistributor.DOWNLOAD_HANDLED
- | EventDistributor.QUEUE_UPDATE)) != 0) {
+ | EventDistributor.DOWNLOAD_HANDLED)) != 0) {
startSearchTask();
}
}
@@ -209,17 +203,16 @@ public class SearchFragment extends ListFragment {
}
}
- private class SearchTask extends AsyncTask<Bundle, Void, Object[]> {
+ private class SearchTask extends AsyncTask<Bundle, Void, List<SearchResult>> {
@Override
- protected Object[] doInBackground(Bundle... params) {
+ protected List<SearchResult> doInBackground(Bundle... params) {
String query = params[0].getString(ARG_QUERY);
long feed = params[0].getLong(ARG_FEED);
Context context = getActivity();
if (context != null) {
- return new Object[]{FeedSearcher.performSearch(context, query, feed),
- QueueAccess.IDListAccess(DBReader.getQueueIDList(context))};
+ return FeedSearcher.performSearch(context, query, feed);
} else {
- return null;
+ return Collections.emptyList();
}
}
@@ -232,12 +225,11 @@ public class SearchFragment extends ListFragment {
}
@Override
- protected void onPostExecute(Object[] results) {
+ protected void onPostExecute(List<SearchResult> results) {
super.onPostExecute(results);
if (results != null) {
itemsLoaded = true;
- searchResults = (List<SearchResult>) results[0];
- queue = (QueueAccess) results[1];
+ searchResults = results;
if (viewCreated) {
onFragmentLoaded();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
index 15a0b55b1..c87ed777c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
@@ -6,8 +6,18 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
-import android.view.*;
-import android.widget.*;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.GridView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import java.util.List;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
@@ -19,9 +29,6 @@ import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetPodcast;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
-
-import java.util.List;
/**
* Displays a list of GPodnetPodcast-Objects in a GridView
@@ -43,24 +50,22 @@ public abstract class PodcastListFragment extends Fragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (!MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
- final android.support.v7.widget.SearchView sv = new android.support.v7.widget.SearchView(getActivity());
- MenuItemUtils.addSearchItem(menu, sv);
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- sv.clearFocus();
- ((MainActivity) getActivity()).loadChildFragment(SearchListFragment.newInstance(s));
- return true;
- }
+ final android.support.v7.widget.SearchView sv = new android.support.v7.widget.SearchView(getActivity());
+ MenuItemUtils.addSearchItem(menu, sv);
+ sv.setQueryHint(getString(R.string.gpodnet_search_hint));
+ sv.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ sv.clearFocus();
+ ((MainActivity) getActivity()).loadChildFragment(SearchListFragment.newInstance(s));
+ return true;
+ }
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
+ @Override
+ public boolean onQueryTextChange(String s) {
+ return false;
+ }
+ });
}
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
index 635842196..2295ddf41 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
@@ -14,7 +14,6 @@ import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetPodcast;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
/**
* Performs a search on the gpodder.net directory and displays the results.
@@ -46,24 +45,22 @@ public class SearchListFragment extends PodcastListFragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final SearchView sv = new SearchView(getActivity());
- if (!MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
- MenuItemUtils.addSearchItem(menu, sv);
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setQuery(query, false);
- sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- sv.clearFocus();
- changeQuery(s);
- return true;
- }
+ MenuItemUtils.addSearchItem(menu, sv);
+ sv.setQueryHint(getString(R.string.gpodnet_search_hint));
+ sv.setQuery(query, false);
+ sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ sv.clearFocus();
+ changeQuery(s);
+ return true;
+ }
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
+ @Override
+ public boolean onQueryTextChange(String s) {
+ return false;
+ }
+ });
}
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
index cc87407b4..6dff496b2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
@@ -21,7 +21,6 @@ import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetTag;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
public class TagListFragment extends ListFragment {
private static final String TAG = "TagListFragment";
@@ -36,27 +35,25 @@ public class TagListFragment extends ListFragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (!MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
- final SearchView sv = new SearchView(getActivity());
- MenuItemUtils.addSearchItem(menu, sv);
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- Activity activity = getActivity();
- if (activity != null) {
- sv.clearFocus();
- ((MainActivity) activity).loadChildFragment(SearchListFragment.newInstance(s));
- }
- return true;
+ final SearchView sv = new SearchView(getActivity());
+ MenuItemUtils.addSearchItem(menu, sv);
+ sv.setQueryHint(getString(R.string.gpodnet_search_hint));
+ sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ Activity activity = getActivity();
+ if (activity != null) {
+ sv.clearFocus();
+ ((MainActivity) activity).loadChildFragment(SearchListFragment.newInstance(s));
}
+ return true;
+ }
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
+ @Override
+ public boolean onQueryTextChange(String s) {
+ return false;
+ }
+ });
}
@Override
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 8ccbdafc6..2b1770ee1 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -4,25 +4,29 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
+import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction.Action;
+import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
-import de.danoeh.antennapod.core.util.QueueAccess;
+import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.ShareUtils;
/**
* Handles interactions with the FeedItemMenu.
*/
public class FeedItemMenuHandler {
+
private static final String TAG = "FeedItemMenuHandler";
private FeedItemMenuHandler() {
-
}
/**
@@ -52,7 +56,7 @@ public class FeedItemMenuHandler {
* @return Returns true if selectedItem is not null.
*/
public static boolean onPrepareMenu(MenuInterface mi,
- FeedItem selectedItem, boolean showExtendedMenu, QueueAccess queueAccess) {
+ FeedItem selectedItem, boolean showExtendedMenu, LongList queueAccess) {
if (selectedItem == null) {
return false;
}
@@ -122,7 +126,7 @@ public class FeedItemMenuHandler {
* @return true if selectedItem is not null.
*/
public static boolean onPrepareMenu(MenuInterface mi,
- FeedItem selectedItem, boolean showExtendedMenu, QueueAccess queueAccess, int... excludeIds) {
+ FeedItem selectedItem, boolean showExtendedMenu, LongList queueAccess, int... excludeIds) {
boolean rc = onPrepareMenu(mi, selectedItem, showExtendedMenu, queueAccess);
if (rc && excludeIds != null) {
for (int id : excludeIds) {
@@ -156,15 +160,33 @@ public class FeedItemMenuHandler {
break;
case R.id.mark_read_item:
DBWriter.markItemRead(context, selectedItem, true, true);
+ if(GpodnetPreferences.loggedIn()) {
+ FeedMedia media = selectedItem.getMedia();
+ GpodnetEpisodeAction actionPlay = new GpodnetEpisodeAction.Builder(selectedItem, Action.PLAY)
+ .currentDeviceId()
+ .currentTimestamp()
+ .started(media.getDuration() / 1000)
+ .position(media.getDuration() / 1000)
+ .total(media.getDuration() / 1000)
+ .build();
+ GpodnetPreferences.enqueueEpisodeAction(actionPlay);
+ }
break;
case R.id.mark_unread_item:
DBWriter.markItemRead(context, selectedItem, false, true);
+ if(GpodnetPreferences.loggedIn()) {
+ GpodnetEpisodeAction actionNew = new GpodnetEpisodeAction.Builder(selectedItem, Action.NEW)
+ .currentDeviceId()
+ .currentTimestamp()
+ .build();
+ GpodnetPreferences.enqueueEpisodeAction(actionNew);
+ }
break;
case R.id.add_to_queue_item:
DBWriter.addQueueItem(context, selectedItem.getId());
break;
case R.id.remove_from_queue_item:
- DBWriter.removeQueueItem(context, selectedItem.getId(), true);
+ DBWriter.removeQueueItem(context, selectedItem, true);
break;
case R.id.stream_item:
DBTasks.playMedia(context, selectedItem.getMedia(), true, true,
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
index efb4adb01..6947c73c9 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.menuhandler;
+import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -9,6 +10,10 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
@@ -62,6 +67,9 @@ public class FeedMenuHandler {
case R.id.refresh_complete_item:
DBTasks.refreshCompleteFeed(context, selectedFeed);
break;
+ case R.id.hide_items:
+ showHideDialog(context, selectedFeed);
+ break;
case R.id.mark_all_read_item:
ConfirmationDialog conDialog = new ConfirmationDialog(context,
R.string.mark_all_read_label,
@@ -94,4 +102,43 @@ public class FeedMenuHandler {
}
return true;
}
+
+ private static void showHideDialog(final Context context, final Feed feed) {
+
+ final String[] items = context.getResources().getStringArray(R.array.episode_hide_options);
+ final String[] values = context.getResources().getStringArray(R.array.episode_hide_values);
+ final boolean[] checkedItems = new boolean[items.length];
+
+ final List<String> hidden = new ArrayList<String>(Arrays.asList(feed.getItemFilter().getValues()));
+ for(int i=0; i < values.length; i++) {
+ String value = values[i];
+ if(hidden.contains(value)) {
+ checkedItems[i] = true;
+ }
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.hide_episodes_title);
+ builder.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ if (isChecked) {
+ hidden.add(values[which]);
+ } else {
+ hidden.remove(values[which]);
+ }
+ }
+ });
+ builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ feed.setFeedItemsFilter(hidden.toArray(new String[hidden.size()]));
+ DBWriter.setFeedItemsFilter(context, feed.getId(), hidden);
+ }
+ });
+ builder.setNegativeButton(R.string.cancel_label, null);
+ builder.create().show();
+
+ }
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
index fc942ce20..edefb7d46 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java
@@ -1,11 +1,16 @@
package de.danoeh.antennapod.menuhandler;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Build;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuItem;
import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
/**
* Utilities for menu items
@@ -14,18 +19,32 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte
public static MenuItem addSearchItem(Menu menu, SearchView searchView) {
MenuItem item = menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label);
- MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
+ MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(item, searchView);
+
+ if(Build.VERSION.SDK_INT < 14) {
+ SearchView.SearchAutoComplete textField = (SearchView.SearchAutoComplete) searchView.findViewById(de.danoeh.antennapod.R.id.search_src_text);
+ if(UserPreferences.getTheme() == de.danoeh.antennapod.R.style.Theme_AntennaPod_Dark) {
+ textField.setTextColor(Resources.getSystem().getColor(android.R.color.white));
+ } else {
+ textField.setTextColor(Resources.getSystem().getColor(android.R.color.black));
+ }
+ }
+
return item;
}
- /**
- * Checks if the navigation drawer of the DrawerActivity is opened. This can be useful for Fragments
- * that hide their menu if the navigation drawer is open.
- *
- * @return True if the drawer is open, false otherwise (also if the parameter is null)
- */
- public static boolean isActivityDrawerOpen(NavDrawerActivity activity) {
- return activity != null && activity.isDrawerOpen();
+ public static void refreshLockItem(Context context, Menu menu, MenuItem queueLock) {
+ queueLock = menu.findItem(de.danoeh.antennapod.R.id.queue_lock);
+ int[] lockIcons = new int[] { de.danoeh.antennapod.R.attr.ic_lock_open, de.danoeh.antennapod.R.attr.ic_lock_closed };
+ TypedArray ta = context.obtainStyledAttributes(lockIcons);
+ if (UserPreferences.isQueueLocked()) {
+ queueLock.setTitle(de.danoeh.antennapod.R.string.unlock_queue);
+ queueLock.setIcon(ta.getDrawable(1));
+ } else {
+ queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue);
+ queueLock.setIcon(ta.getDrawable(0));
+ }
}
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
index 227ea8dfb..f387b7524 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
@@ -1,6 +1,7 @@
package de.danoeh.antennapod.preferences;
import android.app.Activity;
+import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -190,6 +191,15 @@ public class PreferenceController {
}
}
);
+ ui.findPreference(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS)
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ showDrawerPreferencesDialog();
+ return true;
+ }
+ });
+
ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL)
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
@@ -343,6 +353,7 @@ public class PreferenceController {
}
});
buildUpdateIntervalPreference();
+ buildSmartMarkAsPlayedPreference();
buildAutodownloadSelectedNetworsPreference();
setSelectedNetworksEnabled(UserPreferences
.isEnableAutodownloadWifiFilter());
@@ -403,6 +414,24 @@ public class PreferenceController {
}
+ private void buildSmartMarkAsPlayedPreference() {
+ final Resources res = ui.getActivity().getResources();
+
+ ListPreference pref = (ListPreference) ui.findPreference(UserPreferences.PREF_SMART_MARK_AS_PLAYED_SECS);
+ String[] values = res.getStringArray(
+ R.array.smart_mark_as_played_values);
+ String[] entries = new String[values.length];
+ for (int x = 0; x < values.length; x++) {
+ if(x == 0) {
+ entries[x] = res.getString(R.string.pref_smart_mark_as_played_disabled);
+ } else {
+ Integer v = Integer.parseInt(values[x]);
+ entries[x] = v + " " + res.getString(R.string.time_unit_seconds);
+ }
+ }
+ pref.setEntries(entries);
+ }
+
private void setSelectedNetworksEnabled(boolean b) {
if (selectedNetworks != null) {
for (Preference p : selectedNetworks) {
@@ -430,7 +459,6 @@ public class PreferenceController {
.setEnabled(UserPreferences.isEnableAutodownload());
}
-
private void setParallelDownloadsText(int downloads) {
final Resources res = ui.getActivity().getResources();
@@ -543,6 +571,43 @@ public class PreferenceController {
}
}
+ private void showDrawerPreferencesDialog() {
+ final Context context = ui.getActivity();
+ final List<String> hiddenDrawerItems = UserPreferences.getHiddenDrawerItems();
+ final String[] navTitles = context.getResources().getStringArray(R.array.nav_drawer_titles);
+ final String[] NAV_DRAWER_TAGS = MainActivity.NAV_DRAWER_TAGS;
+ boolean[] checked = new boolean[MainActivity.NAV_DRAWER_TAGS.length];
+ for(int i=0; i < NAV_DRAWER_TAGS.length; i++) {
+ String tag = NAV_DRAWER_TAGS[i];
+ if(!hiddenDrawerItems.contains(tag)) {
+ checked[i] = true;
+ }
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.drawer_preferences);
+ builder.setMultiChoiceItems(navTitles, checked, new DialogInterface.OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ if (isChecked) {
+ hiddenDrawerItems.remove(NAV_DRAWER_TAGS[which]);
+ } else {
+ hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]);
+ }
+ }
+ });
+ builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ UserPreferences.setHiddenDrawerItems(context, hiddenDrawerItems);
+ }
+ });
+ builder.setNegativeButton(R.string.cancel_label, null);
+ builder.create().show();
+ }
+
+
+
public static interface PreferenceUI {
diff --git a/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java b/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java
index 55dfdc20b..0d00823d3 100644
--- a/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java
+++ b/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java
@@ -12,14 +12,18 @@ import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.RemoteViews;
-import de.danoeh.antennapod.core.BuildConfig;
+
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
-import de.danoeh.antennapod.receiver.PlayerWidget;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
+import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.playback.Playable;
+import de.danoeh.antennapod.receiver.PlayerWidget;
/** Updates the state of the player widget */
public class PlayerWidgetService extends Service {
@@ -39,8 +43,7 @@ public class PlayerWidgetService extends Service {
@Override
public void onCreate() {
super.onCreate();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Service created");
+ Log.d(TAG, "Service created");
isUpdating = false;
psLock = new Object();
}
@@ -48,8 +51,25 @@ public class PlayerWidgetService extends Service {
@Override
public void onDestroy() {
super.onDestroy();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Service is about to be destroyed");
+ Log.d(TAG, "Service is about to be destroyed");
+ if (playbackService != null) {
+ Playable playable = playbackService.getPlayable();
+ if (playable != null && playable instanceof FeedMedia) {
+ FeedMedia media = (FeedMedia) playable;
+ if (media.hasAlmostEnded()) {
+ Log.d(TAG, "smart mark as read");
+ FeedItem item = media.getItem();
+ DBWriter.markItemRead(this, item, true, false);
+ DBWriter.removeQueueItem(this, item, false);
+ DBWriter.addItemToPlaybackHistory(this, media);
+ if (UserPreferences.isAutoDelete()) {
+ Log.d(TAG, "Delete " + media.toString());
+ DBWriter.deleteFeedMediaOfItem(this, media.getId());
+ }
+ }
+ }
+ }
+
try {
unbindService(mConnection);
} catch (IllegalArgumentException e) {
@@ -72,9 +92,7 @@ public class PlayerWidgetService extends Service {
startViewUpdaterIfNotRunning();
}
} else {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Service was called while updating. Ignoring update request");
+ Log.d(TAG, "Service was called while updating. Ignoring update request");
}
return Service.START_NOT_STICKY;
}
@@ -153,8 +171,7 @@ public class PlayerWidgetService extends Service {
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Connection to service established");
+ Log.d(TAG, "Connection to service established");
synchronized (psLock) {
playbackService = ((PlaybackService.LocalBinder) service)
.getService();
@@ -166,8 +183,7 @@ public class PlayerWidgetService extends Service {
public void onServiceDisconnected(ComponentName name) {
synchronized (psLock) {
playbackService = null;
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Disconnected from service");
+ Log.d(TAG, "Disconnected from service");
}
}
diff --git a/app/src/main/res/layout/audioplayer_activity.xml b/app/src/main/res/layout/audioplayer_activity.xml
index 644d8fe90..827e06e00 100644
--- a/app/src/main/res/layout/audioplayer_activity.xml
+++ b/app/src/main/res/layout/audioplayer_activity.xml
@@ -95,6 +95,18 @@
tools:src="@drawable/ic_fast_rewind_white_36dp"
tools:background="@android:color/holo_blue_dark" />
+ <TextView
+ android:id="@+id/txtvRev"
+ android:layout_width="wrap_content"
+ android:layout_height="32dp"
+ android:layout_alignTop="@id/butRev"
+ android:layout_alignLeft="@id/butRev"
+ android:layout_alignRight="@id/butRev"
+ android:gravity="center"
+ android:text="30"
+ android:textSize="8dp"
+ android:clickable="false"/>
+
<ImageButton
android:id="@+id/butFF"
android:layout_width="@dimen/audioplayer_playercontrols_length"
@@ -106,6 +118,18 @@
tools:src="@drawable/ic_fast_forward_white_36dp"
tools:background="@android:color/holo_blue_dark" />
+ <TextView
+ android:id="@+id/txtvFF"
+ android:layout_width="wrap_content"
+ android:layout_height="32dp"
+ android:layout_alignTop="@id/butFF"
+ android:layout_alignLeft="@id/butFF"
+ android:layout_alignRight="@id/butFF"
+ android:gravity="center"
+ android:text="30"
+ android:textSize="8dp"
+ android:clickable="false"/>
+
<Button
android:id="@+id/butPlaybackSpeed"
android:layout_width="@dimen/audioplayer_playercontrols_length"
diff --git a/app/src/main/res/layout/downloadlog_item.xml b/app/src/main/res/layout/downloadlog_item.xml
index df1501222..c6a34a517 100644
--- a/app/src/main/res/layout/downloadlog_item.xml
+++ b/app/src/main/res/layout/downloadlog_item.xml
@@ -1,78 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
+ android:paddingTop="8dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingBottom="8dp"
tools:background="@android:color/darker_gray">
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
- android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding"
- android:layout_marginTop="@dimen/listitem_threeline_verticalpadding">
-
- <TextView
- android:id="@+id/txtvType"
- style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding"
- tools:text="Media file"
- tools:background="@android:color/holo_green_dark" />
-
- <TextView
- android:id="@+id/txtvTitle"
- style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:layout_toLeftOf="@id/txtvType"
- tools:text="Download item title"
- tools:background="@android:color/holo_blue_light" />
- </RelativeLayout>
+ <TextView
+ android:id="@+id/txtvIcon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:textSize="48sp"
+ tools:text="[Icon]"
+ android:gravity="center" />
- <RelativeLayout
- android:layout_width="match_parent"
+ <Button
+ android:id="@+id/btnRetry"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
- android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
- android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding">
+ android:layout_below="@id/txtvIcon"
+ android:layout_alignLeft="@id/txtvIcon"
+ android:layout_alignRight="@id/txtvIcon"
+ android:layout_marginTop="8dp"
+ tools:text="↻" />
- <TextView
- android:id="@+id/txtvDate"
- style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_marginRight="8dp"
- tools:text="January 23"
- tools:background="@android:color/holo_green_dark" />
+ <TextView
+ android:id="@+id/txtvType"
+ style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:layout_marginLeft="8dp"
+ android:layout_marginBottom="8dp"
+ tools:text="Media file"
+ tools:background="@android:color/holo_green_dark" />
- <TextView
- android:id="@+id/txtvStatus"
- style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- tools:text="successful"
- tools:background="@android:color/holo_green_dark" />
+ <TextView
+ android:id="@+id/txtvTitle"
+ style="@style/AntennaPod.TextView.ListItemPrimaryTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@id/txtvIcon"
+ android:layout_toLeftOf="@id/txtvType"
+ android:layout_marginLeft="8dp"
+ android:layout_marginBottom="8dp"
+ android:minLines="1"
+ android:maxLines="2"
+ tools:text="Download item title"
+ tools:background="@android:color/holo_blue_light" />
- </RelativeLayout>
+ <TextView
+ android:id="@+id/txtvDate"
+ style="@style/AntennaPod.TextView.ListItemSecondaryTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/txtvIcon"
+ android:layout_below="@id/txtvTitle"
+ android:layout_marginLeft="8dp"
+ android:layout_marginBottom="8dp"
+ tools:text="January 23"
+ tools:background="@android:color/holo_green_dark" />
<TextView
android:id="@+id/txtvReason"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding"
- android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding"
- android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding"
+ android:layout_below="@id/txtvDate"
+ android:layout_toRightOf="@id/txtvIcon"
+ android:layout_marginLeft="8dp"
android:textColor="?android:attr/textColorTertiary"
android:textSize="@dimen/text_size_micro"
tools:text="@string/design_time_downloaded_log_failure_reason"
tools:background="@android:color/holo_green_dark" />
-</LinearLayout> \ No newline at end of file
+</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/feedinfo.xml b/app/src/main/res/layout/feedinfo.xml
index a52104afa..db897865c 100644
--- a/app/src/main/res/layout/feedinfo.xml
+++ b/app/src/main/res/layout/feedinfo.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -11,7 +12,10 @@
android:focusableInTouchMode="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="center_vertical">
+ android:gravity="center_vertical"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:layout_marginTop="8dp">
<ImageView
android:id="@+id/imgvCover"
@@ -20,26 +24,26 @@
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
- android:layout_margin="4dp"
tools:src="@drawable/ic_stat_antenna_default"
- tools:background="@android:color/holo_green_dark" />
+ tools:background="@android:color/holo_green_dark"/>
<TextView
android:id="@+id/txtvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
- android:layout_margin="4dp"
+ android:layout_marginLeft="8dp"
android:layout_toRightOf="@id/imgvCover"
style="@style/AntennaPod.TextView.Heading"
tools:text="Feed title"
- tools:background="@android:color/holo_green_dark" />
+ tools:background="@android:color/holo_green_dark"/>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/imgvCover"
+ android:layout_marginTop="8dp"
android:background="@color/bright_blue"/>
</RelativeLayout>
@@ -47,99 +51,120 @@
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_weight="1">
+ android:layout_weight="1"
+ android:scrollbarStyle="outsideInset"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingBottom="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
- <RelativeLayout
+ <android.support.v7.widget.GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="16dp">
-
- <View
- android:id="@+id/center_divider"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_centerHorizontal="true"/>
+ android:layout_marginTop="8dp"
+ app:columnCount="2"
+ app:rowCount="3">
<TextView
android:id="@+id/lblAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
- android:layout_margin="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginBottom="8dp"
+ app:layout_row="0"
+ app:layout_column="0"
+ android:lines="1"
android:text="@string/author_label"
android:textColor="?android:attr/textColorPrimary"
- tools:background="@android:color/holo_red_light" />
+ tools:background="@android:color/holo_red_light"/>
<TextView
android:id="@+id/txtvAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_margin="8dp"
- android:layout_toRightOf="@id/center_divider"
+ app:layout_row="0"
+ app:layout_column="1"
tools:text="Daniel Oeh"
- tools:background="@android:color/holo_green_dark" />
+ tools:background="@android:color/holo_green_dark"/>
<TextView
android:id="@+id/lblLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_below="@id/txtvAuthor"
- android:layout_margin="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginBottom="8dp"
+ app:layout_row="1"
+ app:layout_column="0"
+ android:lines="1"
android:text="@string/language_label"
android:textColor="?android:attr/textColorPrimary"
- tools:background="@android:color/holo_red_light" />
+ tools:background="@android:color/holo_red_light"/>
<TextView
android:id="@+id/txtvLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/txtvAuthor"
- android:layout_margin="8dp"
- android:layout_toRightOf="@id/center_divider"
+ app:layout_row="1"
+ app:layout_column="1"
tools:text="English"
- tools:background="@android:color/holo_green_dark" />
- </RelativeLayout>
+ tools:background="@android:color/holo_green_dark"/>
+
+ <TextView
+ android:id="@+id/lblUrl"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="8dp"
+ android:layout_marginBottom="8dp"
+ app:layout_row="2"
+ app:layout_column="0"
+ android:lines="1"
+ android:text="@string/url_label"
+ android:textColor="?android:attr/textColorPrimary"
+ tools:background="@android:color/holo_red_light"/>
+
+ <TextView
+ android:id="@+id/txtvUrl"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_row="2"
+ app:layout_column="1"
+ tools:text="http://www.example.com/feed"
+ tools:background="@android:color/holo_green_dark"/>
+
+ </android.support.v7.widget.GridLayout>
<TextView
android:id="@+id/txtvSettings"
style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_margin="8dp"
android:text="@string/podcast_settings_label"
- android:layout_marginLeft="8dp"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="24dp"/>
+ android:layout_marginTop="8dp"/>
<CheckBox
android:id="@+id/cbxAutoDownload"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_margin="8dp"
+ android:layout_marginTop="8dp"
android:text="@string/auto_download_label"
android:enabled="false"
android:textColor="?android:attr/textColorPrimary"
- tools:background="@android:color/holo_red_light" />
+ tools:background="@android:color/holo_red_light"
+ android:checked="false"/>
<TextView
android:id="@+id/txtvAuthentication"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_margin="8dp"
+ android:layout_marginTop="8dp"
android:text="@string/authentication_label"
android:textSize="@dimen/text_size_medium"
- android:textColor="?android:attr/textColorPrimary"
- android:layout_marginLeft="8dp"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="24dp"/>
+ android:textColor="?android:attr/textColorPrimary"/>
<TextView
android:id="@+id/txtvAuthenticationDescr"
@@ -148,71 +173,74 @@
android:textColor="?android:attr/textColorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_margin="8dp"/>
+ android:layout_marginTop="8dp"/>
- <LinearLayout
- android:layout_width="match_parent"
+ <android.support.v7.widget.GridLayout
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="8dp">
+ android:layout_marginTop="8dp"
+ app:columnCount="2"
+ app:rowCount="3"
+ android:layout_gravity="center_horizontal">
<TextView
android:id="@+id/txtvUsername"
- android:layout_width="0dp"
- android:layout_weight="1"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginBottom="8dp"
+ app:layout_row="0"
+ app:layout_column="0"
android:text="@string/username_label"
android:textColor="?android:attr/textColorPrimary"/>
<EditText
android:id="@+id/etxtUsername"
- android:layout_width="0dp"
- android:layout_weight="2"
+ android:layout_width="140sp"
android:layout_height="wrap_content"
+ app:layout_row="0"
+ app:layout_column="1"
android:hint="@string/username_label"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_margin="8dp">
<TextView
android:id="@+id/txtvPassword"
- android:layout_width="0dp"
- android:layout_weight="1"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginBottom="8dp"
+ app:layout_row="1"
+ app:layout_column="0"
android:text="@string/password_label"
android:textColor="?android:attr/textColorPrimary"/>
<EditText
android:id="@+id/etxtPassword"
- android:layout_width="0dp"
- android:layout_weight="2"
+ android:layout_width="140sp"
android:layout_height="wrap_content"
+ app:layout_row="1"
+ app:layout_column="1"
android:hint="@string/password_label"
android:inputType="textPassword"/>
- </LinearLayout>
+
+ </android.support.v7.widget.GridLayout>
<TextView
style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginLeft="8dp"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="24dp"
+ android:layout_marginTop="8dp"
android:text="@string/description_label"/>
<TextView
android:id="@+id/txtvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_margin="8dp"
+ android:layout_marginTop="8dp"
android:text="@string/design_time_lorem_ipsum"
- tools:background="@android:color/holo_green_dark" />
+ tools:background="@android:color/holo_green_dark"/>
</LinearLayout>
+
</ScrollView>
</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/feeditemlist_header.xml b/app/src/main/res/layout/feeditemlist_header.xml
index 4619580e3..943f4fc92 100644
--- a/app/src/main/res/layout/feeditemlist_header.xml
+++ b/app/src/main/res/layout/feeditemlist_header.xml
@@ -3,7 +3,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="@dimen/feeditemlist_header_height"
+ android:layout_height="wrap_content"
tools:context="de.danoeh.antennapod.activity.MainActivity"
tools:background="@android:color/darker_gray">
@@ -11,7 +11,7 @@
android:id="@+id/imgvBackground"
style="@style/BigBlurryBackground"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="@dimen/feeditemlist_header_height" />
<ImageView
android:id="@+id/imgvCover"
@@ -78,5 +78,16 @@
tools:text="Podcast author"
tools:background="@android:color/holo_green_dark" />
+ <TextView
+ android:id="@+id/txtvInformation"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/imgvBackground"
+ android:paddingTop="2dp"
+ android:paddingBottom="2dp"
+ android:gravity="center"
+ android:visibility="gone"
+ tools:text="(i) Information"
+ />
</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/nav_feedlistitem.xml b/app/src/main/res/layout/nav_feedlistitem.xml
index e942d1b08..38f4f21aa 100644
--- a/app/src/main/res/layout/nav_feedlistitem.xml
+++ b/app/src/main/res/layout/nav_feedlistitem.xml
@@ -18,8 +18,8 @@
android:adjustViewBounds="true"
android:cropToPadding="true"
android:scaleType="fitXY"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
+ android:layout_marginTop="4dp"
+ android:layout_marginBottom="4dp"
android:layout_marginLeft="@dimen/listitem_icon_leftpadding"
tools:src="@drawable/ic_stat_antenna_default"
tools:background="@android:color/holo_green_dark"/>
@@ -36,8 +36,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding"
- android:layout_marginTop="@dimen/listitem_iconwithtext_textverticalpadding"
- android:layout_marginBottom="@dimen/listitem_iconwithtext_textverticalpadding"
android:layout_marginRight="@dimen/listitem_icon_rightpadding"
android:layout_toRightOf="@id/imgvCover"
tools:text="Navigation feed item title"
diff --git a/app/src/main/res/layout/nav_list.xml b/app/src/main/res/layout/nav_list.xml
index 8c46e456d..9fcf9d9fc 100644
--- a/app/src/main/res/layout/nav_list.xml
+++ b/app/src/main/res/layout/nav_list.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_layout"
android:layout_width="@dimen/drawer_width"
@@ -9,32 +10,11 @@
android:background="?attr/nav_drawer_background"
android:orientation="vertical">
- <ListView
- android:id="@+id/nav_list"
- android:layout_width="@dimen/drawer_width"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:choiceMode="singleChoice"
- android:clipToPadding="false"
- android:divider="@android:color/transparent"
- android:dividerHeight="0dp"
- android:paddingBottom="@dimen/list_vertical_padding"
- android:paddingTop="@dimen/list_vertical_padding"
- android:scrollbarStyle="outsideOverlay"
- tools:listitem="@layout/nav_listitem"
- tools:background="@android:color/holo_purple" />
-
- <View
- android:layout_width="@dimen/drawer_width"
- android:layout_height="1dp"
- android:layout_centerVertical="true"
- android:background="?android:attr/listDivider"
- tools:background="@android:color/holo_red_dark" />
-
<LinearLayout
android:id="@+id/nav_settings"
android:layout_width="@dimen/drawer_width"
android:layout_height="@dimen/listitem_iconwithtext_height"
+ android:layout_alignParentBottom="true"
android:background="?attr/selectableItemBackground"
android:contentDescription="@string/settings_label"
android:orientation="horizontal">
@@ -45,9 +25,9 @@
android:layout_height="@dimen/thumbnail_length_navlist"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
- android:layout_marginBottom="8dp"
+ android:layout_marginBottom="4dp"
android:layout_marginLeft="@dimen/listitem_icon_leftpadding"
- android:layout_marginTop="8dp"
+ android:layout_marginTop="4dp"
android:adjustViewBounds="true"
android:contentDescription="@string/cover_label"
android:cropToPadding="true"
@@ -58,10 +38,10 @@
tools:background="@android:color/holo_orange_dark" />
<TextView
- android:layout_width="0dp"
- android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
- android:layout_margin="16dp"
+ android:layout_marginLeft="16dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="@string/settings_label"
@@ -71,4 +51,30 @@
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+ <View
+ android:id="@+id/divider"
+ android:layout_width="@dimen/drawer_width"
+ android:layout_height="1dp"
+ android:layout_centerVertical="true"
+ android:layout_above="@id/nav_settings"
+ android:background="?android:attr/listDivider"
+ tools:background="@android:color/holo_red_dark" />
+
+ <ListView
+ android:id="@+id/nav_list"
+ android:layout_width="@dimen/drawer_width"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_above="@id/divider"
+ android:layout_alignParentTop="true"
+ android:choiceMode="singleChoice"
+ android:clipToPadding="false"
+ android:divider="@android:color/transparent"
+ android:dividerHeight="0dp"
+ android:paddingBottom="@dimen/list_vertical_padding"
+ android:paddingTop="@dimen/list_vertical_padding"
+ android:scrollbarStyle="outsideOverlay"
+ tools:listitem="@layout/nav_listitem"
+ tools:background="@android:color/holo_purple" />
+
+</RelativeLayout>
diff --git a/app/src/main/res/layout/nav_listitem.xml b/app/src/main/res/layout/nav_listitem.xml
index bb5865ee6..d62672c34 100644
--- a/app/src/main/res/layout/nav_listitem.xml
+++ b/app/src/main/res/layout/nav_listitem.xml
@@ -16,11 +16,11 @@
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:cropToPadding="true"
- android:scaleType="centerCrop"
- android:padding="8dp"
+ android:scaleType="centerInside"
+ android:padding="4dp"
android:layout_marginLeft="@dimen/listitem_icon_leftpadding"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
+ android:layout_marginTop="4dp"
+ android:layout_marginBottom="4dp"
tools:src="@drawable/ic_new_releases_white_24dp"
tools:background="@android:color/holo_green_dark"/>
@@ -36,8 +36,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding"
- android:layout_marginTop="@dimen/listitem_iconwithtext_textverticalpadding"
- android:layout_marginBottom="@dimen/listitem_iconwithtext_textverticalpadding"
android:layout_marginRight="48dp"
android:layout_toRightOf="@id/imgvCover"
tools:text="Navigation item title"
@@ -52,8 +50,6 @@
android:textColor="?android:attr/textColorTertiary"
android:textSize="@dimen/text_size_navdrawer"
android:layout_marginLeft="12dp"
- android:layout_marginTop="14dp"
- android:layout_marginBottom="14dp"
android:layout_marginRight="@dimen/listitem_icon_rightpadding"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
diff --git a/app/src/main/res/layout/nav_section_item.xml b/app/src/main/res/layout/nav_section_item.xml
index 77b2ff253..fa1db865d 100644
--- a/app/src/main/res/layout/nav_section_item.xml
+++ b/app/src/main/res/layout/nav_section_item.xml
@@ -3,7 +3,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="24dp"
+ android:layout_height="16dp"
android:background="@android:color/transparent"
android:orientation="vertical">
diff --git a/app/src/main/res/layout/queue_listitem.xml b/app/src/main/res/layout/queue_listitem.xml
index bc5b951a2..39e9c72a5 100644
--- a/app/src/main/res/layout/queue_listitem.xml
+++ b/app/src/main/res/layout/queue_listitem.xml
@@ -1,17 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/listitem_threeline_height"
android:orientation="horizontal"
+ android:paddingLeft="16dp"
tools:background="@android:color/darker_gray" >
<ImageView
android:id="@+id/drag_handle"
android:layout_width="100dp"
android:layout_height="match_parent"
- android:layout_marginLeft="8dp"
+ android:layout_marginLeft="-8dp"
android:layout_marginRight="-64dp"
android:contentDescription="@string/drag_handle_content_description"
android:scaleType="fitXY"
diff --git a/app/src/main/res/menu/feedlist.xml b/app/src/main/res/menu/feedlist.xml
index b6512e828..00785a29b 100644
--- a/app/src/main/res/menu/feedlist.xml
+++ b/app/src/main/res/menu/feedlist.xml
@@ -3,6 +3,13 @@
xmlns:custom="http://schemas.android.com/apk/res-auto">
<item
+ android:id="@+id/hide_items"
+ android:icon="?attr/ic_filter"
+ android:menuCategory="container"
+ android:title="@string/hide_episodes_title"
+ custom:showAsAction="always">
+ </item>
+ <item
android:id="@+id/refresh_item"
android:icon="?attr/navigation_refresh"
android:menuCategory="container"
diff --git a/app/src/main/res/menu/queue.xml b/app/src/main/res/menu/queue.xml
index c7dd4d371..127a17f7d 100644
--- a/app/src/main/res/menu/queue.xml
+++ b/app/src/main/res/menu/queue.xml
@@ -4,6 +4,12 @@
xmlns:custom="http://schemas.android.com/apk/res-auto">
<item
+ android:id="@+id/queue_lock"
+ android:title=""
+ android:menuCategory="container"
+ custom:showAsAction="always" />
+
+ <item
android:id="@+id/refresh_item"
android:title="@string/refresh_label"
android:menuCategory="container"
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 6d14349d5..e848915cf 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -9,6 +9,10 @@
android:key="prefTheme"
android:summary="@string/pref_set_theme_sum"
android:defaultValue="0"/>
+ <Preference
+ android:key="prefHiddenDrawerItems"
+ android:summary="@string/pref_nav_drawer_items_sum"
+ android:title="@string/pref_nav_drawer_items_title" />
<CheckBoxPreference
android:defaultValue="false"
android:enabled="true"
@@ -59,6 +63,13 @@
android:key="prefAutoDelete"
android:summary="@string/pref_auto_delete_sum"
android:title="@string/pref_auto_delete_title"/>
+ <ListPreference
+ android:defaultValue="30"
+ android:entries="@array/smart_mark_as_played_values"
+ android:entryValues="@array/smart_mark_as_played_values"
+ android:key="prefSmartMarkAsPlayedSecs"
+ android:summary="@string/pref_smart_mark_as_played_sum"
+ android:title="@string/pref_smart_mark_as_played_title"/>
<Preference
android:key="prefPlaybackSpeedLauncher"
android:summary="@string/pref_playback_speed_sum"
@@ -70,14 +81,12 @@
android:key="prefPauseForFocusLoss"
android:summary="@string/pref_pausePlaybackForFocusLoss_sum"
android:title="@string/pref_pausePlaybackForFocusLoss_title" />
-
- <ListPreference
- android:defaultValue="30"
- android:entries="@array/seek_delta_values"
- android:entryValues="@array/seek_delta_values"
- android:key="prefSeekDeltaSecs"
- android:summary="@string/pref_seek_delta_sum"
- android:title="@string/pref_seek_delta_title" />
+ <CheckBoxPreference
+ android:defaultValue="true"
+ android:enabled="true"
+ android:key="prefResumeAfterCall"
+ android:summary="@string/pref_resumeAfterCall_sum"
+ android:title="@string/pref_resumeAfterCall_title"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/network_pref">
diff --git a/app/src/main/assets/about.html b/app/src/main/templates/about.html
index d9fcb80ca..3a48eeec1 100644
--- a/app/src/main/assets/about.html
+++ b/app/src/main/templates/about.html
@@ -41,9 +41,11 @@
<div id="header" align="center">
<img src="logo.png" alt="Logo" width="100px" height="100px"/>
- <p>AntennaPod, Version 1.1.2</p>
+ <p>AntennaPod, Version @versionname@, Build @versioncode@</p>
- <p>Copyright © 2014 Daniel Oeh</p>
+ <p>Created by Daniel Oeh</p>
+
+ <p>Copyright © 2015 AntennaPod Contributors <a href="https://github.com/AntennaPod/AntennaPod/blob/master/CONTRIBUTORS">(View)</a></p>
<p>Licensed under the MIT License <a href="LICENSE.html">(View)</a></p>
</div>
@@ -77,5 +79,11 @@ licensed under the Apache 2.0 license <a href="LICENSE_OKIO.txt">(View)</a>
<h2>Material Design Icons <a href="https://github.com/google/material-design-icons">(Link)</a></h2>
by Google, licensed under an Attribution-ShareAlike 4.0 International license <a href="LICENSE_MATERIAL_DESIGN_ICONS.txt">(View)</a>
+<h2>EventBus <a href="https://github.com/greenrobot/EventBus">(Link>)</a></h2>
+by greenrobot, licensed under the Apache 2.0 license <a href="LICENSE_EVENTBUS.txt">(View)</a>
+
+<h2>Iconify <a href="https://github.com/JoanZapata/android-iconify">(Link>)</a></h2>
+by Joan Zapata, licensed under the Apache 2.0 license <a href="LICENSE_ANDROID_ICONIFY.txt">(View)</a>
+
</body>
</html>