summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/close-if-no-reply.yml10
-rw-r--r--CONTRIBUTING.md4
-rw-r--r--app/build.gradle4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java9
-rw-r--r--app/src/main/res/layout/audio_controls.xml25
-rw-r--r--common.gradle6
-rw-r--r--core/build.gradle4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java17
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/glide/GenerativePlaceholderImageModelLoader.java139
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java4
-rw-r--r--core/src/main/res/raw/local_feed_default_icon.pngbin1240 -> 0 bytes
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java28
-rw-r--r--event/build.gradle4
-rw-r--r--model/build.gradle4
-rw-r--r--model/src/main/java/de/danoeh/antennapod/model/feed/Feed.java1
-rw-r--r--net/ssl/build.gradle4
-rw-r--r--net/sync/gpoddernet/build.gradle4
-rw-r--r--net/sync/model/build.gradle4
-rw-r--r--parser/feed/build.gradle4
-rw-r--r--parser/feed/src/main/java/de/danoeh/antennapod/parser/feed/util/MimeTypeUtils.java2
-rw-r--r--parser/media/build.gradle4
-rw-r--r--playback/base/build.gradle4
-rw-r--r--playback/cast/build.gradle4
-rw-r--r--ui/app-start-intent/build.gradle4
-rw-r--r--ui/common/build.gradle4
-rw-r--r--ui/png-icons/build.gradle4
30 files changed, 225 insertions, 118 deletions
diff --git a/.github/workflows/close-if-no-reply.yml b/.github/workflows/close-if-no-reply.yml
index c0c32843a..78e4d340a 100644
--- a/.github/workflows/close-if-no-reply.yml
+++ b/.github/workflows/close-if-no-reply.yml
@@ -13,13 +13,15 @@ jobs:
steps:
- uses: actions/stale@v4
with:
- days-before-stale: 10
- days-before-close: 10
+ days-before-stale: 15
+ days-before-close: 15
only-labels: 'Awaiting reply'
stale-issue-label: 'Still awaiting reply'
stale-pr-label: 'Still awaiting reply'
+ stale-issue-message: "This issue will be closed when we don't get a reply within 15 days."
+ stale-pr-message: "This PR will be closed when we don't get a reply within 15 days."
labels-to-remove-when-unstale: 'Awaiting reply'
close-issue-label: "Close reason: no reply"
close-pr-label: "Close reason: no reply"
- close-issue-message: "This issue was closed because we didn't get a reply for 20 days."
- close-pr-message: "This pr was closed because we didn't get a reply for 20 days."
+ close-issue-message: "This issue was closed because we didn't get a reply for 30 days."
+ close-pr-message: "This PR was closed because we didn't get a reply for 30 days."
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e3bc7269d..0017c897d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,7 +8,7 @@ How to report a bug
- If possible, add instructions on how to reproduce the bug.
- If possible, add a logfile to your post. This is especially useful if the bug makes the application crash. AntennaPod has an `export logs` feature for this.
- Usually, you can take a screenshot of your smartphone by pressing *Power* + *Volume down* for a few seconds.
-- Please use the following **[template](.github/ISSUE_TEMPLATE/bug_report.md)**.
+- Please use the following **[template](https://github.com/AntennaPod/AntennaPod/issues/new?assignees=&labels=Type%3A+Possible+bug&template=bug_report.yml)**.
How to submit a feature request
@@ -18,7 +18,7 @@ How to submit a feature request
- To make it easier for us to keep track of requests, please only make one feature request per issue.
- Give a brief explanation about the problem that may currently exist and how your requested feature solves this problem.
- Try to be as specific as possible. Please not only explain what the feature does, but also how. If your request is about (or includes) changing or extending the UI, describe what the UI would look like and how the user would interact with it.
-- Please use the following **[template](.github/ISSUE_TEMPLATE/feature_request.md)**.
+- Please use the following **[template](https://github.com/AntennaPod/AntennaPod/issues/new?assignees=&labels=&template=feature_request.yml)**.
Translating AntennaPod
diff --git a/app/build.gradle b/app/build.gradle
index 520be2418..0257347fc 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -43,8 +43,8 @@ android {
signingConfigs {
releaseConfig {
- v1SigningEnabled true
- v2SigningEnabled true
+ enableV1Signing true
+ enableV2Signing true
if (project.hasProperty("releaseStoreFile")) {
storeFile file(releaseStoreFile)
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java
index 5ab354d05..8351d1fb5 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java
@@ -33,7 +33,6 @@ import java.util.Locale;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.core.feed.LocalFeedUpdater;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
@@ -255,7 +254,7 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter<Subscription
if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) {
Feed feed = ((NavDrawerData.FeedDrawerItem) drawerItem).feed;
boolean textAndImageCombind = feed.isLocalFeed()
- && LocalFeedUpdater.getDefaultIconUrl(itemView.getContext()).equals(feed.getImageUrl());
+ && feed.getImageUrl() != null && feed.getImageUrl().startsWith(Feed.PREFIX_GENERATIVE_COVER);
new CoverLoader(mainActivityRef.get())
.withUri(feed.getImageUrl())
.withPlaceholderView(feedTitle, textAndImageCombind)
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java
index 5cc1f99c6..841c121e9 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java
@@ -10,24 +10,14 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import android.widget.Button;
import android.widget.CheckBox;
-import android.widget.TextView;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.event.playback.SpeedChangedEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
-import de.danoeh.antennapod.view.PlaybackSpeedSeekBar;
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
-
import java.util.List;
-import java.util.Locale;
public class PlaybackControlsDialog extends DialogFragment {
private PlaybackController controller;
private AlertDialog dialog;
- private PlaybackSpeedSeekBar speedSeekBar;
- private TextView txtvPlaybackSpeed;
public static PlaybackControlsDialog newInstance() {
Bundle arguments = new Bundle();
@@ -48,12 +38,10 @@ public class PlaybackControlsDialog extends DialogFragment {
public void loadMediaInfo() {
setupUi();
setupAudioTracks();
- updateSpeed(new SpeedChangedEvent(getCurrentPlaybackSpeedMultiplier()));
}
};
controller.init();
setupUi();
- EventBus.getDefault().register(this);
}
@Override
@@ -61,7 +49,6 @@ public class PlaybackControlsDialog extends DialogFragment {
super.onStop();
controller.release();
controller = null;
- EventBus.getDefault().unregister(this);
}
@NonNull
@@ -75,15 +62,6 @@ public class PlaybackControlsDialog extends DialogFragment {
}
private void setupUi() {
- txtvPlaybackSpeed = dialog.findViewById(R.id.txtvPlaybackSpeed);
- speedSeekBar = dialog.findViewById(R.id.speed_seek_bar);
- speedSeekBar.setProgressChangedListener(speed -> {
- if (controller != null) {
- controller.setPlaybackSpeed(speed);
- }
- });
- updateSpeed(new SpeedChangedEvent(controller.getCurrentPlaybackSpeedMultiplier()));
-
final CheckBox stereoToMono = dialog.findViewById(R.id.stereo_to_mono);
stereoToMono.setChecked(UserPreferences.stereoToMono());
if (controller != null && !controller.canDownmix()) {
@@ -111,12 +89,6 @@ public class PlaybackControlsDialog extends DialogFragment {
});
}
- @Subscribe(threadMode = ThreadMode.MAIN)
- public void updateSpeed(SpeedChangedEvent event) {
- txtvPlaybackSpeed.setText(String.format(Locale.getDefault(), "%.2fx", event.getNewSpeed()));
- speedSeekBar.updateSpeed(event.getNewSpeed());
- }
-
private void setupAudioTracks() {
List<String> audioTracks = controller.getAudioTracks();
int selectedAudioTrack = controller.getSelectedAudioTrack();
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 120d1def8..ee56bb9f9 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
@@ -1,6 +1,7 @@
package de.danoeh.antennapod.fragment;
import android.content.ActivityNotFoundException;
+import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
@@ -140,9 +141,12 @@ public class AddFeedFragment extends Fragment {
alertViewBinding.urlEditText.setHint(R.string.add_podcast_by_url_hint);
ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
- String clipboardContent = clipboard.getText() != null ? clipboard.getText().toString() : "";
- if (clipboardContent.trim().startsWith("http")) {
- alertViewBinding.urlEditText.setText(clipboardContent.trim());
+ final ClipData clipData = clipboard.getPrimaryClip();
+ if (clipData != null && clipData.getItemCount() > 0 && clipData.getItemAt(0).getText() != null) {
+ final String clipboardContent = clipData.getItemAt(0).getText().toString();
+ if (clipboardContent.trim().startsWith("http")) {
+ alertViewBinding.urlEditText.setText(clipboardContent.trim());
+ }
}
builder.setView(alertViewBinding.getRoot());
builder.setPositiveButton(R.string.confirm_label,
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
index 8bfcfd1ed..f76b902cd 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
@@ -119,13 +119,12 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
String countryCode = prefs.getString(ItunesTopListLoader.PREF_KEY_COUNTRY_CODE,
Locale.getDefault().getCountry());
if (countryCode.equals(ItunesTopListLoader.DISCOVER_HIDE_FAKE_COUNTRY_CODE)) {
- errorTextView.setText(String.format(getResources().getString(R.string.discover_is_hidden),
- getResources().getString(R.string.discover_hide)));
+ errorTextView.setText(R.string.discover_is_hidden);
errorView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
- discoverGridLayout.setVisibility(View.INVISIBLE);
- errorRetry.setVisibility(View.INVISIBLE);
- poweredByTextView.setVisibility(View.INVISIBLE);
+ discoverGridLayout.setVisibility(View.GONE);
+ errorRetry.setVisibility(View.GONE);
+ poweredByTextView.setVisibility(View.GONE);
return;
}
diff --git a/app/src/main/res/layout/audio_controls.xml b/app/src/main/res/layout/audio_controls.xml
index 0bfa4f521..dc48006bb 100644
--- a/app/src/main/res/layout/audio_controls.xml
+++ b/app/src/main/res/layout/audio_controls.xml
@@ -19,31 +19,6 @@
android:visibility="gone"
android:layout_marginBottom="8dp" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="@string/playback_speed"
- style="@style/AntennaPod.TextView.ListItemPrimaryTitle" />
-
- <TextView
- android:id="@+id/txtvPlaybackSpeed"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="1.00x" />
-
- </LinearLayout>
-
- <de.danoeh.antennapod.view.PlaybackSpeedSeekBar
- android:id="@+id/speed_seek_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/common.gradle b/common.gradle
index 4f023212b..8284d2325 100644
--- a/common.gradle
+++ b/common.gradle
@@ -1,9 +1,9 @@
android {
- compileSdkVersion 31
+ compileSdk 31
defaultConfig {
- minSdkVersion 19
- targetSdkVersion 30
+ minSdk 19
+ targetSdk 30
multiDexEnabled false
vectorDrawables.useSupportLibrary true
diff --git a/core/build.gradle b/core/build.gradle
index 700487701..af0e2a7a7 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../common.gradle"
apply from: "../playFlavor.gradle"
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
index 7ddaa080a..e0e1bbaa5 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.core.feed;
-import android.content.ContentResolver;
import android.content.Context;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
@@ -104,7 +103,7 @@ public class LocalFeedUpdater {
}
}
- feed.setImageUrl(getImageUrl(context, documentFolder));
+ feed.setImageUrl(getImageUrl(documentFolder));
feed.getPreferences().setAutoDownload(false);
feed.getPreferences().setAutoDeleteAction(FeedPreferences.AutoDeleteAction.NO);
@@ -122,7 +121,7 @@ public class LocalFeedUpdater {
* Returns the image URL for the local feed.
*/
@NonNull
- static String getImageUrl(@NonNull Context context, @NonNull DocumentFile documentFolder) {
+ static String getImageUrl(@NonNull DocumentFile documentFolder) {
// look for special file names
for (String iconLocation : PREFERRED_FEED_IMAGE_FILENAMES) {
DocumentFile image = documentFolder.findFile(iconLocation);
@@ -140,17 +139,7 @@ public class LocalFeedUpdater {
}
// use default icon as fallback
- return getDefaultIconUrl(context);
- }
-
- /**
- * Returns the URL of the default icon for a local feed. The URL refers to an app resource file.
- */
- public static String getDefaultIconUrl(Context context) {
- String resourceEntryName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- return ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
- + context.getPackageName() + "/raw/"
- + resourceEntryName;
+ return Feed.PREFIX_GENERATIVE_COVER + documentFolder.getUri();
}
private static FeedItem feedContainsFile(Feed feed, String filename) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java
index 797addcc1..593b683f7 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ApGlideModule.java
@@ -42,6 +42,7 @@ public class ApGlideModule extends AppGlideModule {
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
registry.replace(String.class, InputStream.class, new MetadataRetrieverLoader.Factory(context));
+ registry.append(String.class, InputStream.class, new GenerativePlaceholderImageModelLoader.Factory());
registry.append(String.class, InputStream.class, new ApOkHttpUrlLoader.Factory());
registry.append(String.class, InputStream.class, new NoHttpStringLoader.StreamFactory());
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/GenerativePlaceholderImageModelLoader.java b/core/src/main/java/de/danoeh/antennapod/core/glide/GenerativePlaceholderImageModelLoader.java
new file mode 100644
index 000000000..a2263bc28
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/GenerativePlaceholderImageModelLoader.java
@@ -0,0 +1,139 @@
+package de.danoeh.antennapod.core.glide;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Shader;
+import androidx.annotation.NonNull;
+import com.bumptech.glide.Priority;
+import com.bumptech.glide.load.DataSource;
+import com.bumptech.glide.load.Options;
+import com.bumptech.glide.load.data.DataFetcher;
+import com.bumptech.glide.load.model.ModelLoader;
+import com.bumptech.glide.load.model.ModelLoaderFactory;
+import com.bumptech.glide.load.model.MultiModelLoaderFactory;
+import com.bumptech.glide.signature.ObjectKey;
+import de.danoeh.antennapod.model.feed.Feed;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Random;
+
+public final class GenerativePlaceholderImageModelLoader implements ModelLoader<String, InputStream> {
+
+ public static class Factory implements ModelLoaderFactory<String, InputStream> {
+ @NonNull
+ @Override
+ public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory unused) {
+ return new GenerativePlaceholderImageModelLoader();
+ }
+
+ @Override
+ public void teardown() {
+ // Do nothing.
+ }
+ }
+
+ @Override
+ public LoadData<InputStream> buildLoadData(@NonNull String model, int width, int height, @NonNull Options options) {
+ return new LoadData<>(new ObjectKey(model), new EmbeddedImageFetcher(model, width, height));
+ }
+
+ @Override
+ public boolean handles(@NonNull String model) {
+ return model.startsWith(Feed.PREFIX_GENERATIVE_COVER);
+ }
+
+ static class EmbeddedImageFetcher implements DataFetcher<InputStream> {
+ private static final int[] PALETTES = {0xff78909c, 0xffff6f00, 0xff388e3c,
+ 0xff00838f, 0xff7b1fa2, 0xffb71c1c, 0xff2196f3};
+ private final String model;
+ private final int width;
+ private final int height;
+
+ public EmbeddedImageFetcher(String model, int width, int height) {
+ this.model = model;
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
+ final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+ final Random generator = new Random(model.hashCode());
+ final int lineGridSteps = 4 + generator.nextInt(4);
+ final int slope = width / 4;
+ final float shadowWidth = width * 0.01f;
+ final float lineDistance = ((float) width / (lineGridSteps - 2));
+ final int baseColor = PALETTES[generator.nextInt(PALETTES.length)];
+
+ Paint paint = new Paint();
+ int color = randomShadeOfGrey(generator);
+ paint.setColor(color);
+ paint.setStrokeWidth(lineDistance);
+ paint.setColorFilter(new PorterDuffColorFilter(baseColor, PorterDuff.Mode.MULTIPLY));
+ Paint paintShadow = new Paint();
+ paintShadow.setColor(0xff000000);
+ paintShadow.setStrokeWidth(lineDistance);
+
+ int forcedColorChange = 1 + generator.nextInt(lineGridSteps - 2);
+ for (int i = lineGridSteps - 1; i >= 0; i--) {
+ float linePos = (i - 0.5f) * lineDistance;
+ boolean switchColor = generator.nextFloat() < 0.3f || i == forcedColorChange;
+ if (switchColor) {
+ int newColor = color;
+ while (newColor == color) {
+ newColor = randomShadeOfGrey(generator);
+ }
+ color = newColor;
+ paint.setColor(newColor);
+ canvas.drawLine(linePos + slope + shadowWidth, -slope,
+ linePos - slope + shadowWidth, height + slope, paintShadow);
+ }
+ canvas.drawLine(linePos + slope, -slope,
+ linePos - slope, height + slope, paint);
+ }
+
+ Paint gradientPaint = new Paint();
+ paint.setDither(true);
+ gradientPaint.setShader(new LinearGradient(0, 0, 0, height, 0x00000000, 0x55000000, Shader.TileMode.CLAMP));
+ canvas.drawRect(0, 0, width, height, gradientPaint);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
+ InputStream is = new ByteArrayInputStream(baos.toByteArray());
+ callback.onDataReady(is);
+ }
+
+ private static int randomShadeOfGrey(Random generator) {
+ return 0xff777777 + 0x222222 * generator.nextInt(5);
+ }
+
+ @Override
+ public void cleanup() {
+ // nothing to clean up
+ }
+
+ @Override
+ public void cancel() {
+ // cannot cancel
+ }
+
+ @NonNull
+ @Override
+ public Class<InputStream> getDataClass() {
+ return InputStream.class;
+ }
+
+ @NonNull
+ @Override
+ public DataSource getDataSource() {
+ return DataSource.LOCAL;
+ }
+ }
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java
index 21d3452d6..7e3b07880 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.core.service.download.handler;
+import android.text.TextUtils;
import android.util.Log;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedItem;
@@ -48,6 +49,9 @@ public class FeedParserTask implements Callable<FeedHandlerResult> {
result = feedHandler.parseFeed(feed);
Log.d(TAG, feed.getTitle() + " parsed");
checkFeedData(feed);
+ if (TextUtils.isEmpty(feed.getImageUrl())) {
+ feed.setImageUrl(Feed.PREFIX_GENERATIVE_COVER + feed.getDownload_url());
+ }
} catch (SAXException | IOException | ParserConfigurationException e) {
successful = false;
e.printStackTrace();
diff --git a/core/src/main/res/raw/local_feed_default_icon.png b/core/src/main/res/raw/local_feed_default_icon.png
deleted file mode 100644
index c1b24a729..000000000
--- a/core/src/main/res/raw/local_feed_default_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java b/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java
index eb56a1876..37d525670 100644
--- a/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java
@@ -31,7 +31,6 @@ import java.util.List;
import de.danoeh.antennapod.core.ApplicationCallbacks;
import de.danoeh.antennapod.core.ClientConfig;
-import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
@@ -41,6 +40,7 @@ import static org.hamcrest.CoreMatchers.endsWith;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
@@ -158,8 +158,7 @@ public class LocalFeedUpdaterTest {
callUpdateFeed(LOCAL_FEED_DIR1);
Feed feedAfter = verifySingleFeedInDatabase();
- String resourceEntryName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertThat(feedAfter.getImageUrl(), endsWith(resourceEntryName));
+ assertThat(feedAfter.getImageUrl(), startsWith(Feed.PREFIX_GENERATIVE_COVER));
}
/**
@@ -191,17 +190,15 @@ public class LocalFeedUpdaterTest {
@Test
public void testGetImageUrl_EmptyFolder() {
DocumentFile documentFolder = mockDocumentFolder();
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
- String defaultImageName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertThat(imageUrl, endsWith(defaultImageName));
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
+ assertThat(imageUrl, startsWith(Feed.PREFIX_GENERATIVE_COVER));
}
@Test
public void testGetImageUrl_NoImageButAudioFiles() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
- String defaultImageName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertThat(imageUrl, endsWith(defaultImageName));
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
+ assertThat(imageUrl, startsWith(Feed.PREFIX_GENERATIVE_COVER));
}
@Test
@@ -209,7 +206,7 @@ public class LocalFeedUpdaterTest {
for (String filename : LocalFeedUpdater.PREFERRED_FEED_IMAGE_FILENAMES) {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile(filename, "image/jpeg")); // image MIME type doesn't matter
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
assertThat(imageUrl, endsWith(filename));
}
}
@@ -218,7 +215,7 @@ public class LocalFeedUpdaterTest {
public void testGetImageUrl_OtherImageFilenameJpg() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile("my-image.jpg", "image/jpeg"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
assertThat(imageUrl, endsWith("my-image.jpg"));
}
@@ -226,7 +223,7 @@ public class LocalFeedUpdaterTest {
public void testGetImageUrl_OtherImageFilenameJpeg() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile("my-image.jpeg", "image/jpeg"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
assertThat(imageUrl, endsWith("my-image.jpeg"));
}
@@ -234,7 +231,7 @@ public class LocalFeedUpdaterTest {
public void testGetImageUrl_OtherImageFilenamePng() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile("my-image.png", "image/png"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
assertThat(imageUrl, endsWith("my-image.png"));
}
@@ -242,9 +239,8 @@ public class LocalFeedUpdaterTest {
public void testGetImageUrl_OtherImageFilenameUnsupportedMimeType() {
DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
mockDocumentFile("my-image.svg", "image/svg+xml"));
- String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
- String defaultImageName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertThat(imageUrl, endsWith(defaultImageName));
+ String imageUrl = LocalFeedUpdater.getImageUrl(documentFolder);
+ assertThat(imageUrl, startsWith(Feed.PREFIX_GENERATIVE_COVER));
}
/**
diff --git a/event/build.gradle b/event/build.gradle
index c852c0351..033fc5a3c 100644
--- a/event/build.gradle
+++ b/event/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../common.gradle"
dependencies {
diff --git a/model/build.gradle b/model/build.gradle
index 6f956a2d5..751a52ef6 100644
--- a/model/build.gradle
+++ b/model/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../common.gradle"
dependencies {
diff --git a/model/src/main/java/de/danoeh/antennapod/model/feed/Feed.java b/model/src/main/java/de/danoeh/antennapod/model/feed/Feed.java
index e570f9bce..006505eb1 100644
--- a/model/src/main/java/de/danoeh/antennapod/model/feed/Feed.java
+++ b/model/src/main/java/de/danoeh/antennapod/model/feed/Feed.java
@@ -19,6 +19,7 @@ public class Feed extends FeedFile {
public static final String TYPE_RSS2 = "rss";
public static final String TYPE_ATOM1 = "atom";
public static final String PREFIX_LOCAL_FOLDER = "antennapod_local:";
+ public static final String PREFIX_GENERATIVE_COVER = "antennapod_generative_cover:";
/**
* title as defined by the feed.
diff --git a/net/ssl/build.gradle b/net/ssl/build.gradle
index 2a47968d3..f76823e2a 100644
--- a/net/ssl/build.gradle
+++ b/net/ssl/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../common.gradle"
apply from: "../../playFlavor.gradle"
diff --git a/net/sync/gpoddernet/build.gradle b/net/sync/gpoddernet/build.gradle
index 13674b5c3..7a765e828 100644
--- a/net/sync/gpoddernet/build.gradle
+++ b/net/sync/gpoddernet/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../../common.gradle"
dependencies {
diff --git a/net/sync/model/build.gradle b/net/sync/model/build.gradle
index 72d962536..205a00fb0 100644
--- a/net/sync/model/build.gradle
+++ b/net/sync/model/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../../common.gradle"
dependencies {
diff --git a/parser/feed/build.gradle b/parser/feed/build.gradle
index 774e08a66..56b4ff740 100644
--- a/parser/feed/build.gradle
+++ b/parser/feed/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../common.gradle"
android {
diff --git a/parser/feed/src/main/java/de/danoeh/antennapod/parser/feed/util/MimeTypeUtils.java b/parser/feed/src/main/java/de/danoeh/antennapod/parser/feed/util/MimeTypeUtils.java
index be1048050..99faaa133 100644
--- a/parser/feed/src/main/java/de/danoeh/antennapod/parser/feed/util/MimeTypeUtils.java
+++ b/parser/feed/src/main/java/de/danoeh/antennapod/parser/feed/util/MimeTypeUtils.java
@@ -16,7 +16,7 @@ public class MimeTypeUtils {
// based on https://developer.android.com/guide/topics/media/media-formats
static final Set<String> AUDIO_FILE_EXTENSIONS = new HashSet<>(Arrays.asList(
- "3gp", "aac", "amr", "flac", "imy", "m4a", "mid", "mkv", "mp3", "mp4", "mxmf", "oga",
+ "3gp", "aac", "amr", "flac", "imy", "m4a", "m4b", "mid", "mkv", "mp3", "mp4", "mxmf", "oga",
"ogg", "ogx", "opus", "ota", "rtttl", "rtx", "wav", "xmf"
));
diff --git a/parser/media/build.gradle b/parser/media/build.gradle
index e463040b9..7dce7b86a 100644
--- a/parser/media/build.gradle
+++ b/parser/media/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../common.gradle"
dependencies {
diff --git a/playback/base/build.gradle b/playback/base/build.gradle
index a1d344492..df49b2fb6 100644
--- a/playback/base/build.gradle
+++ b/playback/base/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../common.gradle"
dependencies {
diff --git a/playback/cast/build.gradle b/playback/cast/build.gradle
index c51354838..64c16eb26 100644
--- a/playback/cast/build.gradle
+++ b/playback/cast/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../common.gradle"
apply from: "../../playFlavor.gradle"
diff --git a/ui/app-start-intent/build.gradle b/ui/app-start-intent/build.gradle
index 2f6d821b1..1f5161392 100644
--- a/ui/app-start-intent/build.gradle
+++ b/ui/app-start-intent/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../common.gradle"
dependencies {
diff --git a/ui/common/build.gradle b/ui/common/build.gradle
index 5390b85d8..bacb9f84c 100644
--- a/ui/common/build.gradle
+++ b/ui/common/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../common.gradle"
dependencies {
diff --git a/ui/png-icons/build.gradle b/ui/png-icons/build.gradle
index f0d9f7a57..ad0b9d0b0 100644
--- a/ui/png-icons/build.gradle
+++ b/ui/png-icons/build.gradle
@@ -1,4 +1,6 @@
-apply plugin: "com.android.library"
+plugins {
+ id("com.android.library")
+}
apply from: "../../common.gradle"
android {