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/DBReaderTest.java7
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java18
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java11
-rw-r--r--app/src/main/AndroidManifest.xml19
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java94
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java64
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java67
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java4
-rw-r--r--app/src/main/res/layout/all_episodes_fragment.xml34
-rw-r--r--app/src/main/res/layout/audio_controls.xml4
-rw-r--r--app/src/main/res/layout/search_fragment.xml20
-rw-r--r--app/src/main/res/xml/preferences.xml5
-rw-r--r--app/src/play/res/layout/media_router_controller.xml2
21 files changed, 232 insertions, 163 deletions
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 647ab911f..666cd845e 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
@@ -267,11 +267,11 @@ public class DBReaderTest {
for (int i = 0; i < newItems.size(); i++) {
unreadIds[i] = newItems.get(i).getId();
}
- List<FeedItem> newItemsSaved = DBReader.getNewItemsList();
+ List<FeedItem> newItemsSaved = DBReader.getNewItemsList(0, Integer.MAX_VALUE);
assertNotNull(newItemsSaved);
assertTrue(newItems.size() == newItemsSaved.size());
- for(int i=0; i < newItemsSaved.size(); i++) {
- long savedId = newItemsSaved.get(i).getId();
+ for (FeedItem feedItem : newItemsSaved) {
+ long savedId = feedItem.getId();
boolean found = false;
for (long id : unreadIds) {
if (id == savedId) {
@@ -368,7 +368,6 @@ public class DBReaderTest {
@Test
public void testGetFeedItemlistCheckChaptersFalse() throws Exception {
- Context context = InstrumentationRegistry.getTargetContext();
List<Feed> feeds = DBTestUtils.saveFeedlist(10, 10, false, false, 0);
for (Feed feed : feeds) {
for (FeedItem item : feed.getItems()) {
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
index a68afbc2e..7d3972378 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
@@ -164,7 +164,7 @@ public class PreferencesTest {
@Test
public void testHeadPhonesDisconnect() {
- onView(withText(R.string.playback_pref)).perform(click());
+ clickPreference(R.string.playback_pref);
final boolean pauseOnHeadsetDisconnect = UserPreferences.isPauseOnHeadsetDisconnect();
onView(withText(R.string.pref_pauseOnHeadsetDisconnect_title)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
@@ -176,7 +176,7 @@ public class PreferencesTest {
@Test
public void testHeadPhonesReconnect() {
- onView(withText(R.string.playback_pref)).perform(click());
+ clickPreference(R.string.playback_pref);
if (!UserPreferences.isPauseOnHeadsetDisconnect()) {
onView(withText(R.string.pref_pauseOnHeadsetDisconnect_title)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
@@ -193,7 +193,7 @@ public class PreferencesTest {
@Test
public void testBluetoothReconnect() {
- onView(withText(R.string.playback_pref)).perform(click());
+ clickPreference(R.string.playback_pref);
if (!UserPreferences.isPauseOnHeadsetDisconnect()) {
onView(withText(R.string.pref_pauseOnHeadsetDisconnect_title)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
@@ -222,7 +222,7 @@ public class PreferencesTest {
@Test
public void testAutoDelete() {
- onView(withText(R.string.storage_pref)).perform(click());
+ clickPreference(R.string.storage_pref);
final boolean autoDelete = UserPreferences.isAutoDelete();
onView(withText(R.string.pref_auto_delete_title)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
@@ -245,7 +245,7 @@ public class PreferencesTest {
@Test
public void testPauseForInterruptions() {
- onView(withText(R.string.playback_pref)).perform(click());
+ clickPreference(R.string.playback_pref);
final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss();
clickPreference(R.string.pref_pausePlaybackForFocusLoss_title);
Awaitility.await().atMost(1000, MILLISECONDS)
@@ -257,7 +257,7 @@ public class PreferencesTest {
@Test
public void testDisableUpdateInterval() {
- onView(withText(R.string.network_pref)).perform(click());
+ clickPreference(R.string.network_pref);
onView(withText(R.string.pref_autoUpdateIntervallOrTime_title)).perform(click());
onView(withText(R.string.pref_autoUpdateIntervallOrTime_Disable)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
@@ -385,7 +385,7 @@ public class PreferencesTest {
@Test
public void testEpisodeCleanupQueueOnly() {
- onView(withText(R.string.network_pref)).perform(click());
+ clickPreference(R.string.network_pref);
onView(withText(R.string.pref_automatic_download_title)).perform(click());
onView(withText(R.string.pref_episode_cleanup_title)).perform(click());
onView(isRoot()).perform(waitForView(withText(R.string.episode_cleanup_queue_removal), 1000));
@@ -396,7 +396,7 @@ public class PreferencesTest {
@Test
public void testEpisodeCleanupNeverAlg() {
- onView(withText(R.string.network_pref)).perform(click());
+ clickPreference(R.string.network_pref);
onView(withText(R.string.pref_automatic_download_title)).perform(click());
onView(withText(R.string.pref_episode_cleanup_title)).perform(click());
onView(withId(R.id.select_dialog_listview)).perform(swipeUp());
@@ -407,7 +407,7 @@ public class PreferencesTest {
@Test
public void testEpisodeCleanupClassic() {
- onView(withText(R.string.network_pref)).perform(click());
+ clickPreference(R.string.network_pref);
onView(withText(R.string.pref_automatic_download_title)).perform(click());
onView(withText(R.string.pref_episode_cleanup_title)).perform(click());
onView(isRoot()).perform(waitForView(withText(R.string.episode_cleanup_after_listening), 1000));
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 8e16d1a3b..4365fa0ae 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
@@ -98,15 +98,6 @@ public class UITestUtils {
return String.format("%s/files/%d", server.getBaseUrl(), id);
}
- private File newBitmapFile(String name) throws IOException {
- File imgFile = new File(destDir, name);
- Bitmap bitmap = Bitmap.createBitmap(128, 128, Bitmap.Config.ARGB_8888);
- FileOutputStream out = new FileOutputStream(imgFile);
- bitmap.compress(Bitmap.CompressFormat.PNG, 1, out);
- out.close();
- return imgFile;
- }
-
private File newMediaFile(String name) throws IOException {
File mediaFile = new File(hostedMediaDir, name);
if (mediaFile.exists()) {
@@ -201,7 +192,7 @@ public class UITestUtils {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
- adapter.setCompleteFeed(hostedFeeds.toArray(new Feed[hostedFeeds.size()]));
+ adapter.setCompleteFeed(hostedFeeds.toArray(new Feed[0]));
adapter.setQueue(queue);
adapter.close();
EventBus.getDefault().post(new FeedListUpdateEvent(hostedFeeds));
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 086206dcd..ad68fcfe3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -236,7 +236,6 @@
android:value="de.danoeh.antennapod.activity.MainActivity"/>
<!-- URLs ending with '.xml' or '.rss' -->
-
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
@@ -252,7 +251,6 @@
</intent-filter>
<!-- Feedburner URLs -->
-
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
@@ -268,7 +266,6 @@
</intent-filter>
<!-- Files with mimeType rss/xml/atom -->
-
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
@@ -284,7 +281,6 @@
</intent-filter>
<!-- Podcast protocols -->
-
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
@@ -297,6 +293,21 @@
<data android:scheme="antennapod-subscribe"/>
</intent-filter>
+ <!-- Support for subscribeonandroid.com URLS -->
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:pathPattern=".*\\..*/.*" />
+ <data android:host="subscribeonandroid.com" />
+ <data android:host="www.subscribeonandroid.com" />
+ <data android:host="*subscribeonandroid.com" />
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+ </intent-filter>
+
<intent-filter>
<action android:name="android.intent.action.SEND"/>
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 a0530fb95..50a8d0965 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -134,6 +134,10 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
} else {
Log.d(TAG, "Activity was started with url " + feedUrl);
setLoadingLayout();
+ // Remove subscribeonandroid.com from feed URL in order to subscribe to the actual feed URL
+ if (feedUrl.contains("subscribeonandroid.com")) {
+ feedUrl = feedUrl.replaceFirst("((www.)?(subscribeonandroid.com/))", "");
+ }
if (savedInstanceState == null) {
startFeedDownload(feedUrl, null, null);
} else {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java
index 45cb4af87..ad23478d6 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java
@@ -93,10 +93,7 @@ public class SearchlistAdapter extends BaseAdapter {
} else if (component.getClass() == FeedItem.class) {
final FeedItem item = (FeedItem) component;
holder.title.setText(item.getTitle());
- if (result.getSubtitle() != null) {
- holder.subtitle.setVisibility(View.VISIBLE);
- holder.subtitle.setText(result.getSubtitle());
- }
+ holder.subtitle.setText(result.getLocation().getDescription());
convertView.setAlpha(item.isPlayed() ? 0.5f : 1.0f);
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 96f350569..34b102ca8 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -492,7 +492,7 @@ public class EpisodesApplyActionFragment extends Fragment {
}
}
try {
- DownloadRequester.getInstance().downloadMedia(getActivity(), toDownload.toArray(new FeedItem[toDownload.size()]));
+ DownloadRequester.getInstance().downloadMedia(getActivity(), toDownload.toArray(new FeedItem[0]));
} catch (DownloadRequestException e) {
e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage());
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 fdb74fa64..e4276b3b9 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -3,26 +3,18 @@ package de.danoeh.antennapod.fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import android.util.Log;
-import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.joanzapata.iconify.Iconify;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedItemFilter;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.dialog.FilterDialog;
-import io.reactivex.Observable;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.schedulers.Schedulers;
-import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
@@ -33,16 +25,18 @@ import java.util.Set;
* supports swiping to mark as read.
*/
public class AllEpisodesFragment extends EpisodesListFragment {
-
public static final String TAG = "AllEpisodesFragment";
private static final String PREF_NAME = "PrefAllEpisodesFragment";
private static final String PREF_FILTER = "filter";
- private static final int EPISODES_PER_PAGE = 150;
- private static final int VISIBLE_EPISODES_SCROLL_THRESHOLD = 5;
- private static int page = 1;
+ private static FeedItemFilter feedItemFilter = new FeedItemFilter("");
- private FeedItemFilter feedItemFilter = new FeedItemFilter("");
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+ feedItemFilter = new FeedItemFilter(prefs.getString(PREF_FILTER, ""));
+ }
@Override
protected boolean showOnlyNewEpisodes() {
@@ -69,53 +63,6 @@ public class AllEpisodesFragment extends EpisodesListFragment {
}
}
- @NonNull
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View root = super.onCreateView(inflater, container, savedInstanceState);
-
- SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
- feedItemFilter = new FeedItemFilter(prefs.getString(PREF_FILTER, ""));
-
- recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
-
- /* Total number of episodes after last load */
- private int previousTotalEpisodes = 0;
-
- /* True if loading more episodes is still in progress */
- private boolean isLoadingMore = true;
-
- @Override
- public void onScrolled(RecyclerView recyclerView, int deltaX, int deltaY) {
- super.onScrolled(recyclerView, deltaX, deltaY);
-
- int visibleEpisodeCount = recyclerView.getChildCount();
- int totalEpisodeCount = recyclerView.getLayoutManager().getItemCount();
- int firstVisibleEpisode = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
-
- /* Determine if loading more episodes has finished */
- if (isLoadingMore) {
- if (totalEpisodeCount > previousTotalEpisodes) {
- isLoadingMore = false;
- previousTotalEpisodes = totalEpisodeCount;
- }
- }
-
- /* Determine if the user scrolled to the bottom and loading more episodes is not already in progress */
- if (!isLoadingMore && (totalEpisodeCount - visibleEpisodeCount)
- <= (firstVisibleEpisode + VISIBLE_EPISODES_SCROLL_THRESHOLD)) {
-
- /* The end of the list has been reached. Load more data. */
- page++;
- loadMoreItems();
- isLoadingMore = true;
- }
- }
- });
-
- return root;
- }
-
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
@@ -136,20 +83,6 @@ public class AllEpisodesFragment extends EpisodesListFragment {
}
}
- private void loadMoreItems() {
- if (disposable != null) {
- disposable.dispose();
- }
- disposable = Observable.fromCallable(this::loadMoreData)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(data -> {
- progLoading.setVisibility(View.GONE);
- episodes.addAll(data);
- onFragmentLoaded(episodes);
- }, error -> Log.e(TAG, Log.getStackTraceString(error)));
- }
-
private void showFilterDialog() {
FilterDialog filterDialog = new FilterDialog(getContext(), feedItemFilter) {
@Override
@@ -167,10 +100,13 @@ public class AllEpisodesFragment extends EpisodesListFragment {
@NonNull
@Override
protected List<FeedItem> loadData() {
- return feedItemFilter.filter( DBReader.getRecentlyPublishedEpisodes(0, page * EPISODES_PER_PAGE));
+ return feedItemFilter.filter(DBReader.getRecentlyPublishedEpisodes(0, page * EPISODES_PER_PAGE));
}
- List<FeedItem> loadMoreData() {
- return feedItemFilter.filter( DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE));
+ @NonNull
+ @Override
+ protected List<FeedItem> loadMoreData() {
+ return feedItemFilter.filter(DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE,
+ EPISODES_PER_PAGE));
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
index 5dbb703b7..b6d6dd9bb 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
@@ -70,9 +70,14 @@ public abstract class EpisodesListFragment extends Fragment {
private static final String PREF_SCROLL_POSITION = "scroll_position";
private static final String PREF_SCROLL_OFFSET = "scroll_offset";
+ protected static final int EPISODES_PER_PAGE = 150;
+ private static final int VISIBLE_EPISODES_SCROLL_THRESHOLD = 5;
+ protected int page = 1;
+
RecyclerView recyclerView;
AllEpisodesRecycleAdapter listAdapter;
ProgressBar progLoading;
+ View loadingMore;
EmptyViewHandler emptyView;
@NonNull
@@ -264,6 +269,7 @@ public abstract class EpisodesListFragment extends Fragment {
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build());
recyclerView.setVisibility(View.GONE);
+ setupLoadMoreScrollListener();
RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator();
if (animator instanceof SimpleItemAnimator) {
@@ -272,6 +278,7 @@ public abstract class EpisodesListFragment extends Fragment {
progLoading = root.findViewById(R.id.progLoading);
progLoading.setVisibility(View.VISIBLE);
+ loadingMore = root.findViewById(R.id.loadingMore);
emptyView = new EmptyViewHandler(getContext());
emptyView.attachToRecyclerView(recyclerView);
@@ -285,6 +292,60 @@ public abstract class EpisodesListFragment extends Fragment {
return root;
}
+ private void setupLoadMoreScrollListener() {
+ recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+
+ /* Total number of episodes after last load */
+ private int previousTotalEpisodes = 0;
+
+ /* True if loading more episodes is still in progress */
+ private boolean isLoadingMore = true;
+
+ @Override
+ public void onScrolled(@NonNull RecyclerView recyclerView, int deltaX, int deltaY) {
+ super.onScrolled(recyclerView, deltaX, deltaY);
+
+ int visibleEpisodeCount = recyclerView.getChildCount();
+ int totalEpisodeCount = recyclerView.getLayoutManager().getItemCount();
+ int firstVisibleEpisode = layoutManager.findFirstVisibleItemPosition();
+
+ /* Determine if loading more episodes has finished */
+ if (isLoadingMore) {
+ if (totalEpisodeCount > previousTotalEpisodes) {
+ isLoadingMore = false;
+ previousTotalEpisodes = totalEpisodeCount;
+ }
+ }
+
+ /* Determine if the user scrolled to the bottom and loading more episodes is not already in progress */
+ if (!isLoadingMore && (totalEpisodeCount - visibleEpisodeCount)
+ <= (firstVisibleEpisode + VISIBLE_EPISODES_SCROLL_THRESHOLD)) {
+
+ /* The end of the list has been reached. Load more data. */
+ page++;
+ loadMoreItems();
+ isLoadingMore = true;
+ }
+ }
+ });
+ }
+
+ private void loadMoreItems() {
+ if (disposable != null) {
+ disposable.dispose();
+ }
+ loadingMore.setVisibility(View.VISIBLE);
+ disposable = Observable.fromCallable(this::loadMoreData)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(data -> {
+ loadingMore.setVisibility(View.GONE);
+ progLoading.setVisibility(View.GONE);
+ episodes.addAll(data);
+ onFragmentLoaded(episodes);
+ }, error -> Log.e(TAG, Log.getStackTraceString(error)));
+ }
+
protected void onFragmentLoaded(List<FeedItem> episodes) {
listAdapter.notifyDataSetChanged();
@@ -453,4 +514,7 @@ public abstract class EpisodesListFragment extends Fragment {
@NonNull
protected abstract List<FeedItem> loadData();
+
+ @NonNull
+ protected abstract List<FeedItem> loadMoreData();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
index f73735658..87a555cfd 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
@@ -88,6 +88,12 @@ public class FavoriteEpisodesFragment extends EpisodesListFragment {
@NonNull
@Override
protected List<FeedItem> loadData() {
- return DBReader.getFavoriteItemsList();
+ return DBReader.getFavoriteItemsList(0, page * EPISODES_PER_PAGE);
+ }
+
+ @NonNull
+ @Override
+ protected List<FeedItem> loadMoreData() {
+ return DBReader.getFavoriteItemsList((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE);
}
}
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 2bfdd040b..bd3fd06b0 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
@@ -104,6 +104,12 @@ public class NewEpisodesFragment extends EpisodesListFragment {
@NonNull
@Override
protected List<FeedItem> loadData() {
- return DBReader.getNewItemsList();
+ return DBReader.getNewItemsList(0, page * EPISODES_PER_PAGE);
+ }
+
+ @NonNull
+ @Override
+ protected List<FeedItem> loadMoreData() {
+ return DBReader.getNewItemsList((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE);
}
}
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 1214edf2c..6befa7e18 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
@@ -2,21 +2,22 @@ package de.danoeh.antennapod.fragment;
import android.content.Context;
import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.fragment.app.ListFragment;
-import androidx.core.view.MenuItemCompat;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.SearchView;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
import android.widget.ListView;
-
-import java.util.ArrayList;
-import java.util.List;
-
+import android.widget.ProgressBar;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.SearchView;
+import androidx.core.view.MenuItemCompat;
+import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.SearchlistAdapter;
@@ -26,17 +27,20 @@ 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.FeedSearcher;
+import de.danoeh.antennapod.view.EmptyViewHandler;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
+import java.util.ArrayList;
+import java.util.List;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
/**
* Performs a search operation on all feeds or one specific feed and displays the search result.
*/
-public class SearchFragment extends ListFragment {
+public class SearchFragment extends Fragment implements AdapterView.OnItemClickListener {
private static final String TAG = "SearchFragment";
private static final String ARG_QUERY = "query";
@@ -45,6 +49,9 @@ public class SearchFragment extends ListFragment {
private SearchlistAdapter searchAdapter;
private List<SearchResult> searchResults = new ArrayList<>();
private Disposable disposable;
+ private ListView listView;
+ private ProgressBar progressBar;
+ private EmptyViewHandler emptyViewHandler;
/**
* Create a new SearchFragment that searches all feeds.
@@ -84,26 +91,30 @@ public class SearchFragment extends ListFragment {
@Override
public void onStop() {
super.onStop();
- if(disposable != null) {
+ if (disposable != null) {
disposable.dispose();
}
}
+ @Nullable
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- // add padding
- final ListView lv = getListView();
- lv.setClipToPadding(false);
- final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding);
- lv.setPadding(0, vertPadding, 0, vertPadding);
-
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(R.string.search_label);
+ View layout = inflater.inflate(R.layout.search_fragment, container, false);
+ listView = layout.findViewById(R.id.listview);
+ progressBar = layout.findViewById(R.id.progressBar);
searchAdapter = new SearchlistAdapter(getActivity(), itemAccess);
- setListAdapter(searchAdapter);
+ listView.setAdapter(searchAdapter);
+ listView.setOnItemClickListener(this);
+
+ emptyViewHandler = new EmptyViewHandler(getContext());
+ emptyViewHandler.attachToListView(listView);
+ emptyViewHandler.setIcon(R.attr.action_search);
+ emptyViewHandler.setTitle(R.string.search_status_no_results);
EventBus.getDefault().register(this);
+ return layout;
}
@Override
@@ -113,9 +124,8 @@ public class SearchFragment extends ListFragment {
}
@Override
- public void onListItemClick(ListView l, View v, int position, long id) {
- super.onListItemClick(l, v, position, id);
- SearchResult result = (SearchResult) l.getAdapter().getItem(position);
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ SearchResult result = (SearchResult) listView.getAdapter().getItem(position);
FeedComponent comp = result.getComponent();
if (comp.getClass() == Feed.class) {
((MainActivity) getActivity()).loadFeedFragmentById(comp.getId(), null);
@@ -128,7 +138,7 @@ public class SearchFragment extends ListFragment {
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
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);
@@ -158,10 +168,11 @@ public class SearchFragment extends ListFragment {
}
private void onSearchResults(List<SearchResult> results) {
+ progressBar.setVisibility(View.GONE);
searchResults = results;
searchAdapter.notifyDataSetChanged();
String query = getArguments().getString(ARG_QUERY);
- setEmptyText(getString(R.string.no_results_for_query, query));
+ emptyViewHandler.setMessage(getString(R.string.no_results_for_query, query));
}
private final SearchlistAdapter.ItemAccess itemAccess = new SearchlistAdapter.ItemAccess() {
@@ -181,9 +192,11 @@ public class SearchFragment extends ListFragment {
};
private void search() {
- if(disposable != null) {
+ if (disposable != null) {
disposable.dispose();
}
+ progressBar.setVisibility(View.VISIBLE);
+ emptyViewHandler.hide();
disposable = Observable.fromCallable(this::performSearch)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java
index fa17fed0a..469697e23 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/AutoDownloadPreferencesFragment.java
@@ -131,9 +131,7 @@ public class AutoDownloadPreferencesFragment extends PreferenceFragmentCompat {
prefValuesList.add(key);
}
- UserPreferences.setAutodownloadSelectedNetworks(
- prefValuesList.toArray(new String[prefValuesList.size()])
- );
+ UserPreferences.setAutodownloadSelectedNetworks(prefValuesList.toArray(new String[0]));
return true;
} else {
return false;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java
index 191999cf7..0acfe60bf 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java
@@ -33,19 +33,6 @@ public class UserInterfacePreferencesFragment extends PreferenceFragmentCompat {
}
private void setupInterfaceScreen() {
-
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
- // disable expanded notification option on unsupported android versions
- findPreference(PREF_EXPANDED_NOTIFICATION).setEnabled(false);
- findPreference(PREF_EXPANDED_NOTIFICATION).setOnPreferenceClickListener(
- preference -> {
- Toast toast = Toast.makeText(getActivity(),
- R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT);
- toast.show();
- return true;
- }
- );
- }
findPreference(UserPreferences.PREF_THEME)
.setOnPreferenceChangeListener(
(preference, newValue) -> {
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 e32deba27..44b6453e5 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
@@ -108,7 +108,7 @@ public class FeedMenuHandler {
FilterDialog filterDialog = new FilterDialog(context, selectedFeed.getItemFilter()) {
@Override
protected void updateFilter(Set<String> filterValues) {
- selectedFeed.setItemFilter(filterValues.toArray(new String[filterValues.size()]));
+ selectedFeed.setItemFilter(filterValues.toArray(new String[0]));
DBWriter.setFeedItemsFilter(selectedFeed.getId(), filterValues);
}
};
diff --git a/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java b/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java
index a2d8ec091..9471db0a1 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java
@@ -45,6 +45,10 @@ public class EmptyViewHandler {
tvMessage.setText(message);
}
+ public void setMessage(String message) {
+ tvMessage.setText(message);
+ }
+
public void setIcon(@AttrRes int iconAttr) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(iconAttr, typedValue, true);
diff --git a/app/src/main/res/layout/all_episodes_fragment.xml b/app/src/main/res/layout/all_episodes_fragment.xml
index 9160998ac..784e7a1c8 100644
--- a/app/src/main/res/layout/all_episodes_fragment.xml
+++ b/app/src/main/res/layout/all_episodes_fragment.xml
@@ -27,6 +27,7 @@
android:clipToPadding="false"
android:paddingTop="@dimen/list_vertical_padding"
android:paddingBottom="@dimen/list_vertical_padding"
+ android:layout_above="@id/loadingMore"
app:fastScrollEnabled="true"
app:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
app:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
@@ -43,9 +44,36 @@
android:indeterminateOnly="true"
android:visibility="gone"
android:layout_centerInParent="true"
- tools:visibility="gone"
- tools:layout_width="match_parent"
- tools:layout_height="64dp"
tools:background="@android:color/holo_red_light"/>
+ <LinearLayout
+ android:id="@+id/loadingMore"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:orientation="horizontal"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
+ android:visibility="gone"
+ android:gravity="center">
+
+ <ProgressBar
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:gravity="center_horizontal"
+ android:indeterminateOnly="true"
+ android:layout_centerInParent="true"
+ tools:background="@android:color/holo_red_light" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="4dp"
+ android:layout_marginStart="4dp"
+ android:text="@string/loading_more" />
+
+ </LinearLayout>
+
</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/audio_controls.xml b/app/src/main/res/layout/audio_controls.xml
index 5049db215..25e914c55 100644
--- a/app/src/main/res/layout/audio_controls.xml
+++ b/app/src/main/res/layout/audio_controls.xml
@@ -43,7 +43,7 @@
android:textStyle="bold"
android:textColor="@color/status_progress"
android:textSize="24sp"
- android:background="@drawable/borderless_button_dark"/>
+ android:background="?android:attr/selectableItemBackground"/>
<Button
android:id="@+id/butIncSpeed"
@@ -57,7 +57,7 @@
android:textStyle="bold"
android:textColor="@color/status_progress"
android:textSize="24sp"
- android:background="@drawable/borderless_button_dark"/>
+ android:background="?android:attr/selectableItemBackground"/>
<SeekBar
android:id="@+id/playback_speed"
diff --git a/app/src/main/res/layout/search_fragment.xml b/app/src/main/res/layout/search_fragment.xml
new file mode 100644
index 000000000..6f455a056
--- /dev/null
+++ b/app/src/main/res/layout/search_fragment.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <ProgressBar
+ android:id="@+id/progressBar"
+ style="?android:attr/progressBarStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+
+ <ListView
+ android:id="@+id/listview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ android:paddingLeft="@dimen/list_vertical_padding"
+ android:paddingRight="@dimen/list_vertical_padding" />
+</FrameLayout> \ No newline at end of file
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 37707ead6..6e734f789 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -12,26 +12,31 @@
<Preference
android:key="prefScreenInterface"
android:title="@string/user_interface_label"
+ android:summary="@string/user_interface_sum"
android:icon="?attr/ic_cellphone_text" />
<Preference
android:key="prefScreenPlayback"
android:title="@string/playback_pref"
+ android:summary="@string/playback_pref_sum"
android:icon="?attr/av_play" />
<Preference
android:key="prefScreenNetwork"
android:title="@string/network_pref"
+ android:summary="@string/network_pref_sum"
android:icon="?attr/ic_swap" />
<Preference
android:key="prefScreenIntegrations"
android:title="@string/integrations_label"
+ android:summary="@string/integrations_sum"
android:icon="?attr/ic_unfav" />
<Preference
android:key="prefScreenStorage"
android:title="@string/storage_pref"
+ android:summary="@string/storage_sum"
android:icon="?attr/storage" />
<Preference
diff --git a/app/src/play/res/layout/media_router_controller.xml b/app/src/play/res/layout/media_router_controller.xml
index 9489173a3..bdb1b1cc2 100644
--- a/app/src/play/res/layout/media_router_controller.xml
+++ b/app/src/play/res/layout/media_router_controller.xml
@@ -17,7 +17,7 @@
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:contentDescription="@string/mr_controller_play"
- android:background="?attr/selectableItemBackgroundBorderless"/>
+ android:background="?android:attr/selectableItemBackground"/>
<LinearLayout android:id="@+id/mrc_control_title_container"
android:orientation="vertical"