summaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'app/src')
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java32
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java36
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java29
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java51
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java40
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java3
-rw-r--r--app/src/main/res/layout/addfeed.xml14
16 files changed, 226 insertions, 28 deletions
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 595a9794f..84b8d0e09 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
@@ -68,7 +68,7 @@ public class DBTasksTest {
for (int i = 0; i < NUM_ITEMS; i++) {
feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed));
}
- Feed newFeed = DBTasks.updateFeed(context, feed)[0];
+ Feed newFeed = DBTasks.updateFeed(context, feed, false);
assertSame(feed, newFeed);
assertTrue(feed.getId() != 0);
@@ -88,8 +88,8 @@ public class DBTasksTest {
feed1.setItems(new ArrayList<>());
feed2.setItems(new ArrayList<>());
- Feed savedFeed1 = DBTasks.updateFeed(context, feed1)[0];
- Feed savedFeed2 = DBTasks.updateFeed(context, feed2)[0];
+ Feed savedFeed1 = DBTasks.updateFeed(context, feed1, false);
+ Feed savedFeed2 = DBTasks.updateFeed(context, feed2, false);
assertTrue(savedFeed1.getId() != savedFeed2.getId());
}
@@ -124,7 +124,7 @@ public class DBTasksTest {
feed.getItems().add(0, new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.UNPLAYED, feed));
}
- final Feed newFeed = DBTasks.updateFeed(context, feed)[0];
+ final Feed newFeed = DBTasks.updateFeed(context, feed, false);
assertNotSame(newFeed, feed);
updatedFeedTest(newFeed, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW);
@@ -156,7 +156,7 @@ public class DBTasksTest {
list.add(item);
feed.setItems(list);
- final Feed newFeed = DBTasks.updateFeed(context, feed)[0];
+ final Feed newFeed = DBTasks.updateFeed(context, feed, false);
assertNotSame(newFeed, feed);
final Feed feedFromDB = DBReader.getFeed(newFeed.getId());
@@ -164,6 +164,28 @@ public class DBTasksTest {
assertTrue("state: " + feedItemFromDB.getState(), feedItemFromDB.isNew());
}
+ @Test
+ public void testUpdateFeedRemoveUnlistedItems() {
+ final Feed feed = new Feed("url", null, "title");
+ feed.setItems(new ArrayList<>());
+ for (int i = 0; i < 10; i++) {
+ feed.getItems().add(
+ new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.PLAYED, feed));
+ }
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ // delete some items
+ feed.getItems().subList(0, 2).clear();
+ Feed newFeed = DBTasks.updateFeed(context, feed, true);
+ assertEquals(8, newFeed.getItems().size()); // 10 - 2 = 8 items
+
+ Feed feedFromDB = DBReader.getFeed(newFeed.getId());
+ assertEquals(8, feedFromDB.getItems().size()); // 10 - 2 = 8 items
+ }
+
private void updatedFeedTest(final Feed newFeed, long feedID, List<Long> itemIDs, final int NUM_ITEMS_OLD, final int NUM_ITEMS_NEW) {
assertEquals(feedID, newFeed.getId());
assertEquals(NUM_ITEMS_NEW + NUM_ITEMS_OLD, newFeed.getItems().size());
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 d300e23e7..652389d00 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -428,6 +428,42 @@ public class DBWriterTest {
adapter.close();
}
+ @Test
+ public void testDeleteFeedItems() throws Exception {
+ Feed feed = new Feed("url", null, "title");
+ feed.setItems(new ArrayList<>());
+ feed.setImageUrl("url");
+
+ // create items
+ for (int i = 0; i < 10; i++) {
+ FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed);
+ feed.getItems().add(item);
+ }
+
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ List<FeedItem> itemsToDelete = feed.getItems().subList(0, 2);
+ DBWriter.deleteFeedItems(InstrumentationRegistry.getInstrumentation()
+ .getTargetContext(), itemsToDelete).get(TIMEOUT, TimeUnit.SECONDS);
+
+ adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ for (int i = 0; i < feed.getItems().size(); i++) {
+ FeedItem feedItem = feed.getItems().get(i);
+ Cursor c = adapter.getFeedItemCursor(String.valueOf(feedItem.getId()));
+ if (i < 2) {
+ assertEquals(0, c.getCount());
+ } else {
+ assertEquals(1, c.getCount());
+ }
+ c.close();
+ }
+ adapter.close();
+ }
+
private FeedMedia playbackHistorySetup(Date playbackCompletionDate) {
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java b/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java
index 5acc25bee..d782d4ed5 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java
@@ -15,6 +15,8 @@ import com.bumptech.glide.request.target.CustomViewTarget;
import java.lang.ref.WeakReference;
import com.bumptech.glide.request.transition.Transition;
+
+import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
@@ -23,6 +25,7 @@ public class CoverLoader {
private String fallbackUri;
private TextView txtvPlaceholder;
private ImageView imgvCover;
+ private boolean textAndImageCombined;
private MainActivity activity;
public CoverLoader(MainActivity activity) {
@@ -49,6 +52,19 @@ public class CoverLoader {
return this;
}
+ /**
+ * Set cover text and if it should be shown even if there is a cover image.
+ *
+ * @param placeholderView Cover text.
+ * @param textAndImageCombined Show cover text even if there is a cover image?
+ */
+ @NonNull
+ public CoverLoader withPlaceholderView(@NonNull TextView placeholderView, boolean textAndImageCombined) {
+ this.txtvPlaceholder = placeholderView;
+ this.textAndImageCombined = textAndImageCombined;
+ return this;
+ }
+
public void load() {
RequestOptions options = new RequestOptions()
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
@@ -65,20 +81,22 @@ public class CoverLoader {
.apply(options));
}
- builder.into(new CoverTarget(txtvPlaceholder, imgvCover));
+ builder.into(new CoverTarget(txtvPlaceholder, imgvCover, textAndImageCombined));
}
static class CoverTarget extends CustomViewTarget<ImageView, Drawable> {
private final WeakReference<TextView> placeholder;
private final WeakReference<ImageView> cover;
+ private boolean textAndImageCombined;
- public CoverTarget(TextView txtvPlaceholder, ImageView imgvCover) {
+ public CoverTarget(TextView txtvPlaceholder, ImageView imgvCover, boolean textAndImageCombined) {
super(imgvCover);
if (txtvPlaceholder != null) {
txtvPlaceholder.setVisibility(View.VISIBLE);
}
placeholder = new WeakReference<>(txtvPlaceholder);
cover = new WeakReference<>(imgvCover);
+ this.textAndImageCombined = textAndImageCombined;
}
@Override
@@ -90,7 +108,12 @@ public class CoverLoader {
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
TextView txtvPlaceholder = placeholder.get();
if (txtvPlaceholder != null) {
- txtvPlaceholder.setVisibility(View.INVISIBLE);
+ if (textAndImageCombined) {
+ int bgColor = txtvPlaceholder.getContext().getResources().getColor(R.color.feed_text_bg);
+ txtvPlaceholder.setBackgroundColor(bgColor);
+ } else {
+ txtvPlaceholder.setVisibility(View.INVISIBLE);
+ }
}
ImageView ivCover = cover.get();
ivCover.setImageDrawable(resource);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
index fdda526ff..8c294a9c9 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
@@ -22,6 +22,7 @@ import java.util.Locale;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.feed.LocalFeedUpdater;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
import jp.shts.android.library.TriangleLabelView;
@@ -107,9 +108,11 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI
holder.count.setVisibility(View.GONE);
}
+ boolean textAndImageCombined = feed.isLocalFeed()
+ && LocalFeedUpdater.getDefaultIconUrl(convertView.getContext()).equals(feed.getImageUrl());
new CoverLoader(mainActivityRef.get())
.withUri(feed.getImageLocation())
- .withPlaceholderView(holder.feedTitle)
+ .withPlaceholderView(holder.feedTitle, textAndImageCombined)
.withCoverView(holder.imageView)
.load();
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java
index 3e210c822..0f7c2bdd0 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java
@@ -40,8 +40,7 @@ public class DownloadActionButton extends ItemActionButton {
@Override
public int getVisibility() {
- return (item.getMedia() != null && DownloadRequester.getInstance().isDownloadingFile(item.getMedia()))
- ? View.INVISIBLE : View.VISIBLE;
+ return item.getFeed().isLocalFeed() ? View.INVISIBLE : View.VISIBLE;
}
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java
index 527ac3ec1..5d95d3775 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java
@@ -42,6 +42,8 @@ public abstract class ItemActionButton {
final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media);
if (media.isCurrentlyPlaying()) {
return new PauseActionButton(item);
+ } else if (item.getFeed().isLocalFeed()) {
+ return new PlayLocalActionButton(item);
} else if (media.isDownloaded()) {
return new PlayActionButton(item);
} else if (isDownloadingMedia) {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java
new file mode 100644
index 000000000..31dfe15da
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java
@@ -0,0 +1,51 @@
+package de.danoeh.antennapod.adapter.actionbutton;
+
+import android.content.Context;
+import androidx.annotation.AttrRes;
+import androidx.annotation.StringRes;
+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.MediaType;
+import de.danoeh.antennapod.core.preferences.UsageStatistics;
+import de.danoeh.antennapod.core.service.playback.PlaybackService;
+import de.danoeh.antennapod.core.util.NetworkUtils;
+import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
+import de.danoeh.antennapod.dialog.StreamingConfirmationDialog;
+
+public class PlayLocalActionButton extends ItemActionButton {
+
+ public PlayLocalActionButton(FeedItem item) {
+ super(item);
+ }
+
+ @Override
+ @StringRes
+ public int getLabel() {
+ return R.string.play_label;
+ }
+
+ @Override
+ @AttrRes
+ public int getDrawable() {
+ return R.attr.av_play;
+ }
+
+ @Override
+ public void onClick(Context context) {
+ final FeedMedia media = item.getMedia();
+ if (media == null) {
+ return;
+ }
+
+ new PlaybackServiceStarter(context, media)
+ .callEvenIfRunning(true)
+ .startWhenPrepared(true)
+ .shouldStream(true)
+ .start();
+
+ if (media.getMediaType() == MediaType.VIDEO) {
+ context.startActivity(PlaybackService.getPlayerActivityIntent(context, media));
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
index c3177668a..f2524c40c 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -51,7 +51,7 @@ public class EpisodesApplyActionFragment extends Fragment {
private static final int ACTION_MARK_UNPLAYED = 8;
public static final int ACTION_DOWNLOAD = 16;
public static final int ACTION_DELETE = 32;
- private static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE
+ public static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE
| ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED | ACTION_DOWNLOAD | ACTION_DELETE;
private Toolbar toolbar;
@@ -103,10 +103,6 @@ public class EpisodesApplyActionFragment extends Fragment {
);
}
- public static EpisodesApplyActionFragment newInstance(List<FeedItem> items) {
- return newInstance(items, ACTION_ALL);
- }
-
public static EpisodesApplyActionFragment newInstance(List<FeedItem> items, int actions) {
EpisodesApplyActionFragment f = new EpisodesApplyActionFragment();
f.episodes.addAll(items);
@@ -449,7 +445,7 @@ public class EpisodesApplyActionFragment extends Fragment {
// download the check episodes in the same order as they are currently displayed
List<FeedItem> toDownload = new ArrayList<>(checkedIds.size());
for (FeedItem episode : episodes) {
- if (checkedIds.contains(episode.getId()) && episode.hasMedia()) {
+ if (checkedIds.contains(episode.getId()) && episode.hasMedia() && !episode.getFeed().isLocalFeed()) {
toDownload.add(episode);
}
}
@@ -473,10 +469,8 @@ public class EpisodesApplyActionFragment extends Fragment {
}
private void close(@PluralsRes int msgId, int numItems) {
- if (numItems > 0) {
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(
- getResources().getQuantityString(msgId, numItems, numItems), Snackbar.LENGTH_LONG);
- }
+ ((MainActivity) getActivity()).showSnackbarAbovePlayer(
+ getResources().getQuantityString(msgId, numItems, numItems), Snackbar.LENGTH_LONG);
getActivity().getSupportFragmentManager().popBackStack();
}
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 167daa08b..290bf1845 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
@@ -17,17 +17,24 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.Fragment;
+import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
import de.danoeh.antennapod.activity.OpmlImportActivity;
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.storage.DBTasks;
+import de.danoeh.antennapod.core.util.SortOrder;
import de.danoeh.antennapod.discovery.CombinedSearcher;
import de.danoeh.antennapod.discovery.FyydPodcastSearcher;
import de.danoeh.antennapod.discovery.ItunesPodcastSearcher;
import de.danoeh.antennapod.fragment.gpodnet.GpodnetMainFragment;
+import java.util.Collections;
+
/**
* Provides actions for adding new podcast subscriptions.
*/
@@ -35,6 +42,7 @@ public class AddFeedFragment extends Fragment {
public static final String TAG = "AddFeedFragment";
private static final int REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH = 1;
+ private static final int REQUEST_CODE_ADD_LOCAL_FOLDER = 2;
private EditText combinedFeedSearchBox;
private MainActivity activity;
@@ -64,8 +72,7 @@ public class AddFeedFragment extends Fragment {
root.findViewById(R.id.btn_add_via_url).setOnClickListener(v
-> showAddViaUrlDialog());
- View butOpmlImport = root.findViewById(R.id.btn_opml_import);
- butOpmlImport.setOnClickListener(v -> {
+ root.findViewById(R.id.btn_opml_import).setOnClickListener(v -> {
try {
Intent intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT);
intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE);
@@ -75,6 +82,15 @@ public class AddFeedFragment extends Fragment {
Log.e(TAG, "No activity found. Should never happen...");
}
});
+ root.findViewById(R.id.btn_add_local_folder).setOnClickListener(v -> {
+ try {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ startActivityForResult(intent, REQUEST_CODE_ADD_LOCAL_FOLDER);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "No activity found. Should never happen...");
+ }
+ });
root.findViewById(R.id.search_icon).setOnClickListener(view -> performSearch());
return root;
}
@@ -134,6 +150,26 @@ public class AddFeedFragment extends Fragment {
Intent intent = new Intent(getContext(), OpmlImportActivity.class);
intent.setData(uri);
startActivity(intent);
+ } else if (requestCode == REQUEST_CODE_ADD_LOCAL_FOLDER) {
+ try {
+ getActivity().getContentResolver()
+ .takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ DocumentFile documentFile = DocumentFile.fromTreeUri(getContext(), uri);
+ if (documentFile == null) {
+ throw new IllegalArgumentException("Unable to retrieve document tree");
+ }
+ Feed dirFeed = new Feed(Feed.PREFIX_LOCAL_FOLDER + uri.toString(), null, documentFile.getName());
+ dirFeed.setDescription(getString(R.string.local_feed_description));
+ dirFeed.setItems(Collections.emptyList());
+ dirFeed.setSortOrder(SortOrder.EPISODE_TITLE_A_Z);
+ DBTasks.forceRefreshFeed(getContext(), dirFeed, true);
+ ((MainActivity) getActivity())
+ .showSnackbarAbovePlayer(R.string.add_local_folder_success, Snackbar.LENGTH_SHORT);
+ } catch (Exception e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ ((MainActivity) getActivity())
+ .showSnackbarAbovePlayer(e.getLocalizedMessage(), Snackbar.LENGTH_LONG);
+ }
}
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
index 6911687dd..6f95d71da 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -122,7 +122,7 @@ public class ChaptersFragment extends Fragment {
disposable = Maybe.create(emitter -> {
Playable media = controller.getMedia();
if (media != null) {
- media.loadChapterMarks();
+ media.loadChapterMarks(getContext());
emitter.onSuccess(media);
} else {
emitter.onComplete();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
index 965cfdc86..7b66a189f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
@@ -271,8 +271,14 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
if (!FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed)) {
switch (item.getItemId()) {
case R.id.episode_actions:
+ int actions = EpisodesApplyActionFragment.ACTION_ALL;
+ if (feed.isLocalFeed()) {
+ // turn off download and delete actions for local feed
+ actions ^= EpisodesApplyActionFragment.ACTION_DOWNLOAD;
+ actions ^= EpisodesApplyActionFragment.ACTION_DELETE;
+ }
EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment
- .newInstance(feed.getItems());
+ .newInstance(feed.getItems(), actions);
((MainActivity)getActivity()).loadChildFragment(fragment);
return true;
case R.id.rename_item:
@@ -287,9 +293,11 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
}
};
+ int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
+ : R.string.feed_delete_confirmation_msg;
ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
R.string.remove_feed_label,
- getString(R.string.feed_delete_confirmation_msg, feed.getTitle())) {
+ getString(messageId, feed.getTitle())) {
@Override
public void onConfirmButtonPressed(
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 337c789fe..669dbdac2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -39,6 +39,7 @@ import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
import de.danoeh.antennapod.adapter.actionbutton.MarkAsPlayedActionButton;
import de.danoeh.antennapod.adapter.actionbutton.PauseActionButton;
import de.danoeh.antennapod.adapter.actionbutton.PlayActionButton;
+import de.danoeh.antennapod.adapter.actionbutton.PlayLocalActionButton;
import de.danoeh.antennapod.adapter.actionbutton.StreamActionButton;
import de.danoeh.antennapod.adapter.actionbutton.VisitWebsiteActionButton;
import de.danoeh.antennapod.core.event.DownloadEvent;
@@ -326,6 +327,8 @@ public class ItemFragment extends Fragment {
}
if (media.isCurrentlyPlaying()) {
actionButton1 = new PauseActionButton(item);
+ } else if (item.getFeed().isLocalFeed()) {
+ actionButton1 = new PlayLocalActionButton(item);
} else if (media.isDownloaded()) {
actionButton1 = new PlayActionButton(item);
} else {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
index 8b7d2b886..8746793be 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
@@ -200,9 +200,11 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
}
}
};
+ int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
+ : R.string.feed_delete_confirmation_msg;
ConfirmationDialog conDialog = new ConfirmationDialog(getContext(),
R.string.remove_feed_label,
- getString(R.string.feed_delete_confirmation_msg, feed.getTitle())) {
+ getString(messageId, feed.getTitle())) {
@Override
public void onConfirmButtonPressed(DialogInterface dialog) {
dialog.dismiss();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
index 3837c5025..26145c064 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -297,7 +297,9 @@ public class SubscriptionFragment extends Fragment {
}
};
- String message = getString(R.string.feed_delete_confirmation_msg, feed.getTitle());
+ int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
+ : R.string.feed_delete_confirmation_msg;
+ String message = getString(messageId, feed.getTitle());
ConfirmationDialog dialog = new ConfirmationDialog(getContext(), R.string.remove_feed_label, message) {
@Override
public void onConfirmButtonPressed(DialogInterface clickedDialog) {
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 bddafb75e..06b1c55bc 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -64,6 +64,9 @@ public class FeedItemMenuHandler {
if (!ShareUtils.hasLinkToShare(selectedItem)) {
setItemVisibility(menu, R.id.visit_website_item, false);
}
+ if (selectedItem.getFeed().isLocalFeed()) {
+ setItemVisibility(menu, R.id.visit_website_item, false);
+ }
boolean fileDownloaded = hasMedia && selectedItem.getMedia().fileExists();
diff --git a/app/src/main/res/layout/addfeed.xml b/app/src/main/res/layout/addfeed.xml
index ff0a54bc1..92569552a 100644
--- a/app/src/main/res/layout/addfeed.xml
+++ b/app/src/main/res/layout/addfeed.xml
@@ -101,6 +101,20 @@
android:text="@string/add_podcast_by_url"/>
<TextView
+ android:id="@+id/btn_add_local_folder"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:drawablePadding="8dp"
+ app:drawableStartCompat="?attr/ic_folder"
+ app:drawableLeftCompat="?attr/ic_folder"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:textColor="?android:attr/textColorPrimary"
+ android:clickable="true"
+ android:text="@string/add_local_folder"/>
+
+ <TextView
android:id="@+id/btn_search_itunes"
android:layout_width="match_parent"
android:layout_height="wrap_content"