diff options
Diffstat (limited to 'app/src')
10 files changed, 158 insertions, 87 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/handler/RssParserTest.java b/app/src/androidTest/java/de/test/antennapod/handler/RssParserTest.java index d137bb459..c2e319233 100644 --- a/app/src/androidTest/java/de/test/antennapod/handler/RssParserTest.java +++ b/app/src/androidTest/java/de/test/antennapod/handler/RssParserTest.java @@ -2,6 +2,8 @@ package de.test.antennapod.handler; import androidx.test.filters.SmallTest; import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.MediaType; +import de.danoeh.antennapod.core.syndication.namespace.NSMedia; import de.test.antennapod.util.syndication.feedgenerator.Rss2Generator; import org.junit.Test; import org.xmlpull.v1.XmlSerializer; @@ -39,4 +41,23 @@ public class RssParserTest extends FeedParserTestBase { }, "UTF-8", 0); assertEquals(image, f2.getImageUrl()); } + + @Test + public void testMediaContentMime() throws Exception { + Feed f1 = createTestFeed(0, false); + f1.setImageUrl(null); + Feed f2 = runFeedTest(f1, new Rss2Generator() { + @Override + protected void writeAdditionalAttributes(XmlSerializer xml) throws IOException { + xml.setPrefix(NSMedia.NSTAG, NSMedia.NSURI); + xml.startTag(null, "item"); + xml.startTag(NSMedia.NSURI, "content"); + xml.attribute(null, "url", "https://www.example.com/file.mp4"); + xml.attribute(null, "medium", "video"); + xml.endTag(NSMedia.NSURI, "content"); + xml.endTag(null, "item"); + } + }, "UTF-8", 0); + assertEquals(MediaType.VIDEO, f2.getItems().get(0).getMedia().getMediaType()); + } } diff --git a/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java b/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java index 4893d7d82..7f26ff612 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java @@ -57,6 +57,13 @@ public class URLCheckerTest { } @Test + public void testItpcProtocolWithScheme() { + final String in = "itpc://https://example.com"; + final String out = URLChecker.prepareURL(in); + assertEquals("https://example.com", out); + } + + @Test public void testWhiteSpaceUrlShouldNotAppend() { final String in = "\n http://example.com \t"; final String out = URLChecker.prepareURL(in); 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 a0644a4c4..f6623d5dc 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -265,16 +265,15 @@ public class OnlineFeedViewActivity extends AppCompatActivity { true, null, true); download = Observable.fromCallable(() -> { - feeds = DBReader.getFeedList(); - ClientConfig.installSslProvider(this); - downloader = new HttpDownloader(request); - downloader.call(); - return downloader.getResult(); - }) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(this::checkDownloadResult, - error -> Log.e(TAG, Log.getStackTraceString(error))); + feeds = DBReader.getFeedList(); + downloader = new HttpDownloader(request); + downloader.call(); + return downloader.getResult(); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(this::checkDownloadResult, + error -> Log.e(TAG, Log.getStackTraceString(error))); } private void checkDownloadResult(@NonNull DownloadStatus status) { @@ -561,13 +560,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.error_label); if (errorMsg != null) { - builder.setMessage(getString(R.string.error_msg_prefix) + errorMsg); + builder.setMessage(errorMsg); } else { - builder.setMessage(R.string.error_msg_prefix); + builder.setMessage(R.string.download_error_error_unknown); } - builder.setPositiveButton(android.R.string.ok, - (dialog, which) -> dialog.cancel() - ); + builder.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.cancel()); builder.setOnDismissListener(dialog -> { setResult(RESULT_ERROR); finish(); diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java index 81e86e217..46095604c 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java @@ -1,8 +1,6 @@ package de.danoeh.antennapod.dialog; import android.content.Context; -import android.view.View; -import android.widget.CheckBox; import androidx.appcompat.app.AlertDialog; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -19,25 +17,24 @@ public class StreamingConfirmationDialog { } public void show() { - View view = View.inflate(context, R.layout.checkbox_do_not_show_again, null); - CheckBox checkDoNotShowAgain = view.findViewById(R.id.checkbox_do_not_show_again); - new AlertDialog.Builder(context) .setTitle(R.string.stream_label) .setMessage(R.string.confirm_mobile_streaming_notification_message) - .setView(view) - .setPositiveButton(R.string.stream_label, (dialog, which) -> { - if (checkDoNotShowAgain.isChecked()) { - UserPreferences.setAllowMobileStreaming(true); - } - new PlaybackServiceStarter(context, playable) - .callEvenIfRunning(true) - .startWhenPrepared(true) - .shouldStream(true) - .shouldStreamThisTime(true) - .start(); + .setPositiveButton(R.string.stream_label, (dialog, which) -> stream()) + .setNegativeButton(R.string.confirm_mobile_streaming_button_always, (dialog, which) -> { + UserPreferences.setAllowMobileStreaming(true); + stream(); }) - .setNegativeButton(R.string.cancel_label, null) + .setNeutralButton(R.string.cancel_label, null) .show(); } + + private void stream() { + new PlaybackServiceStarter(context, playable) + .callEvenIfRunning(true) + .startWhenPrepared(true) + .shouldStream(true) + .shouldStreamThisTime(true) + .start(); + } } 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 2650d9d6b..6911687dd 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java @@ -92,17 +92,12 @@ public class ChaptersFragment extends Fragment { } @Override - public void onDestroyView() { - super.onDestroyView(); + public void onStop() { + super.onStop(); if (disposable != null) { disposable.dispose(); } - } - - @Override - public void onStop() { - super.onStop(); controller.release(); controller = null; EventBus.getDefault().unregister(this); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java index 7593188b7..79f378249 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java @@ -1,16 +1,23 @@ package de.danoeh.antennapod.fragment; +import android.content.Context; +import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.text.TextUtils; +import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; + import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; + import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.FitCenter; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; @@ -60,6 +67,11 @@ public class CoverFragment extends Fragment { return root; } + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + configureForOrientation(getResources().getConfiguration()); + } + private void loadMediaInfo() { if (disposable != null) { disposable.dispose(); @@ -71,13 +83,12 @@ public class CoverFragment extends Fragment { } else { emitter.onComplete(); } - }) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(media -> { - this.media = media; - displayMediaInfo(media); - }, error -> Log.e(TAG, Log.getStackTraceString(error))); + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(media -> { + this.media = media; + displayMediaInfo(media); + }, error -> Log.e(TAG, Log.getStackTraceString(error))); } private void displayMediaInfo(@NonNull Playable media) { @@ -117,6 +128,10 @@ public class CoverFragment extends Fragment { @Override public void onStop() { super.onStop(); + + if (disposable != null) { + disposable.dispose(); + } controller.release(); controller = null; EventBus.getDefault().unregister(this); @@ -160,11 +175,35 @@ public class CoverFragment extends Fragment { } @Override - public void onDestroyView() { - super.onDestroyView(); + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); - if (disposable != null) { - disposable.dispose(); + configureForOrientation(newConfig); + } + + public float convertDpToPixel(float dp) { + Context context = this.getActivity().getApplicationContext(); + return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT); + } + + private void configureForOrientation(Configuration newConfig) { + LinearLayout mainContainer = getView().findViewById(R.id.cover_fragment); + ViewGroup.LayoutParams params = imgvCover.getLayoutParams(); + + if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { + mainContainer.setOrientation(LinearLayout.VERTICAL); + if (newConfig.screenWidthDp > 0) { + params.width = (int) (convertDpToPixel(newConfig.screenWidthDp) * .80); + params.height = params.width; + imgvCover.setLayoutParams(params); + } + } else { + mainContainer.setOrientation(LinearLayout.HORIZONTAL); + if (newConfig.screenHeightDp > 0) { + params.height = (int) (convertDpToPixel(newConfig.screenHeightDp) * .40); + params.width = params.height; + imgvCover.setLayoutParams(params); + } } } 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 77be555f4..965cfdc86 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -372,7 +372,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem if (event.hasChangedFeedUpdateStatus(isUpdatingFeed)) { updateSyncProgressBarVisibility(); } - if (adapter != null && update.mediaIds.length > 0) { + if (adapter != null && update.mediaIds.length > 0 && feed != null) { for (long mediaId : update.mediaIds) { int pos = FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId); if (pos >= 0) { @@ -412,7 +412,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem @Subscribe(threadMode = ThreadMode.MAIN) public void onFeedListChanged(FeedListUpdateEvent event) { - if (event.contains(feed)) { + if (feed != null && event.contains(feed)) { updateUi(); } } @@ -439,7 +439,9 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem } recyclerView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); - adapter.updateItems(feed.getItems()); + if (feed != null) { + adapter.updateItems(feed.getItems()); + } getActivity().invalidateOptionsMenu(); updateSyncProgressBarVisibility(); @@ -586,4 +588,4 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem holder.coverHolder.setVisibility(View.GONE); } } -} +}
\ No newline at end of file diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java index ec64fbda1..ed8697adb 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java @@ -66,9 +66,6 @@ public class ItemDescriptionFragment extends Fragment { public void onDestroy() { super.onDestroy(); Log.d(TAG, "Fragment destroyed"); - if (webViewLoader != null) { - webViewLoader.dispose(); - } if (webvDescription != null) { webvDescription.removeAllViews(); webvDescription.destroy(); @@ -168,6 +165,10 @@ public class ItemDescriptionFragment extends Fragment { @Override public void onStop() { super.onStop(); + + if (webViewLoader != null) { + webViewLoader.dispose(); + } controller.release(); controller = null; } 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 04714f4aa..8b7d2b886 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java @@ -19,6 +19,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.PreferenceActivity; @@ -371,6 +372,7 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli String tag = navAdapter.getTags().get(position); if (getActivity() instanceof MainActivity) { ((MainActivity) getActivity()).loadFragment(tag, null); + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); } else { showMainActivity(tag); } @@ -379,6 +381,7 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli long feedId = navDrawerData.feeds.get(pos).getId(); if (getActivity() instanceof MainActivity) { ((MainActivity) getActivity()).loadFeedFragmentById(feedId, null); + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); } else { Intent intent = new Intent(getActivity(), MainActivity.class); intent.putExtra(MainActivity.EXTRA_FEED_ID, feedId); diff --git a/app/src/main/res/layout/cover_fragment.xml b/app/src/main/res/layout/cover_fragment.xml index 28321e760..443f19835 100644 --- a/app/src/main/res/layout/cover_fragment.xml +++ b/app/src/main/res/layout/cover_fragment.xml @@ -1,49 +1,58 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" xmlns:squareImageView="http://schemas.android.com/apk/de.danoeh.antennapod" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" + android:orientation="horizontal" + android:id="@+id/cover_fragment" android:padding="8dp" android:gravity="center"> <de.danoeh.antennapod.view.SquareImageView android:id="@+id/imgvCover" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" - android:scaleType="fitCenter" - android:layout_marginLeft="32dp" - android:layout_marginRight="32dp" - android:transitionName="coverTransition" - tools:src="@android:drawable/sym_def_app_icon" + android:layout_width="200dp" + android:layout_height="200dp" + android:layout_gravity="center" + android:layout_marginLeft="64dp" + android:layout_marginRight="64dp" + android:layout_weight="0" android:foreground="?attr/selectableItemBackgroundBorderless" android:importantForAccessibility="no" - squareImageView:direction="minimum" /> + android:scaleType="fitCenter" + squareImageView:direction="height" + tools:src="@android:drawable/sym_def_app_icon" /> - <TextView - android:id="@+id/txtvPodcastTitle" + <LinearLayout + android:id="@+id/cover_fragment_text_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:ellipsize="end" - android:gravity="center" - android:maxLines="2" + android:orientation="vertical" android:layout_marginTop="16dp" - android:textColor="?android:attr/textColorSecondary" - android:textIsSelectable="true" - tools:text="Podcast" /> + android:layout_marginBottom="8dp"> - <TextView - android:id="@+id/txtvEpisodeTitle" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:ellipsize="end" - android:gravity="center" - android:maxLines="2" - android:textColor="?android:attr/textColorPrimary" - android:textIsSelectable="true" - android:layout_marginBottom="8dp" - tools:text="Episode" /> + <TextView + android:id="@+id/txtvPodcastTitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="end" + android:gravity="center" + android:maxLines="2" + android:textColor="?android:attr/textColorSecondary" + android:textIsSelectable="true" + tools:text="Podcast" /> + + <TextView + android:id="@+id/txtvEpisodeTitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="end" + android:gravity="center" + android:maxLines="2" + android:textColor="?android:attr/textColorPrimary" + android:textIsSelectable="true" + tools:text="Episode" /> + </LinearLayout> </LinearLayout> |