summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS185
-rw-r--r--CONTRIBUTORS.md53
-rw-r--r--LICENSE681
-rw-r--r--README.md2
-rw-r--r--app/build.gradle4
-rw-r--r--app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java37
-rw-r--r--app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java43
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java24
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java1
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java51
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java3
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java3
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java1
-rw-r--r--app/src/main/AndroidManifest.xml22
-rw-r--r--app/src/main/assets/developers.csv41
-rw-r--r--app/src/main/assets/licenses.xml2
-rw-r--r--app/src/main/assets/special_thanks.csv1
-rw-r--r--app/src/main/assets/translators.csv34
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java88
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java86
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java57
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java19
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java49
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java395
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java22
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java59
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java52
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java22
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java11
-rw-r--r--app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java61
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java42
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java46
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java40
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java47
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java37
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java80
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java41
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderAuthenticationFragment.java302
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java29
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java64
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/PagerIndicatorView.java124
-rw-r--r--app/src/main/play/listings/ca/full-description.txt31
-rw-r--r--app/src/main/play/listings/ca/short-description.txt1
-rw-r--r--app/src/main/play/listings/ca/title.txt1
-rw-r--r--app/src/main/play/listings/cs-CZ/full-description.txt31
-rw-r--r--app/src/main/play/listings/cs-CZ/short-description.txt1
-rw-r--r--app/src/main/play/listings/cs-CZ/title.txt1
-rw-r--r--app/src/main/play/listings/de-DE/graphics/large-tablet-screenshots/tablet.pngbin0 -> 604491 bytes
-rw-r--r--app/src/main/play/listings/en-US/graphics/large-tablet-screenshots/tablet.pngbin0 -> 605931 bytes
-rw-r--r--app/src/main/play/listings/es-ES/full-description.txt4
-rw-r--r--app/src/main/play/release-notes/en-US/default.txt14
-rw-r--r--app/src/main/res/layout/activity_widget_config.xml29
-rw-r--r--app/src/main/res/layout/addfeed.xml18
-rw-r--r--app/src/main/res/layout/audioplayer_fragment.xml18
-rw-r--r--app/src/main/res/layout/bug_report.xml6
-rw-r--r--app/src/main/res/layout/edit_text_dialog.xml2
-rw-r--r--app/src/main/res/layout/feeditem_fragment.xml9
-rw-r--r--app/src/main/res/layout/filter_dialog.xml24
-rw-r--r--app/src/main/res/layout/filter_dialog_row.xml6
-rw-r--r--app/src/main/res/layout/gpodnet_podcast_list.xml11
-rw-r--r--app/src/main/res/layout/gpodnetauth_activity.xml10
-rw-r--r--app/src/main/res/layout/gpodnetauth_credentials.xml169
-rw-r--r--app/src/main/res/layout/gpodnetauth_device.xml125
-rw-r--r--app/src/main/res/layout/gpodnetauth_device_row.xml13
-rw-r--r--app/src/main/res/layout/gpodnetauth_dialog.xml20
-rw-r--r--app/src/main/res/layout/gpodnetauth_finish.xml32
-rw-r--r--app/src/main/res/layout/gpodnetauth_host.xml50
-rw-r--r--app/src/main/res/layout/quick_feed_discovery.xml3
-rw-r--r--app/src/main/res/layout/time_dialog.xml47
-rw-r--r--app/src/main/res/menu/bug_report_options.xml7
-rw-r--r--app/src/main/res/menu/feedinfo.xml26
-rw-r--r--app/src/main/res/menu/gpodder_podcasts.xml13
-rw-r--r--app/src/main/res/xml/player_widget_info.xml3
-rw-r--r--app/src/main/res/xml/preferences.xml4
-rw-r--r--app/src/main/res/xml/preferences_about.xml2
-rw-r--r--app/src/main/res/xml/preferences_gpodder.xml14
-rw-r--r--app/src/main/res/xml/preferences_notifications.xml41
-rw-r--r--app/src/main/res/xml/preferences_playback.xml5
-rw-r--r--app/src/main/res/xml/preferences_user_interface.xml6
-rw-r--r--app/src/play/java/de/danoeh/antennapod/dialog/RatingDialog.java1
-rw-r--r--config/checkstyle/checkstyle-new-code.xml1
-rw-r--r--config/checkstyle/checkstyle.xml1
-rw-r--r--core/src/androidTest/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java49
-rw-r--r--core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java3
-rw-r--r--core/src/main/assets/html-export-template.html23
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/DBTasksCallbacks.java20
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/DownloadServiceCallbacks.java10
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/PlaybackServiceCallbacks.java7
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java61
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java10
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java16
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java128
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/util/PlaybackSpeedUtils.java6
-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/ChapterImageModelLoader.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java30
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java6
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java35
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java26
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java5
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FailedDownloadHandler.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java20
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java12
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java55
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/ssl/BackportCaCerts.java32
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/ssl/BackportTrustManager.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java14
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java41
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java132
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java22
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/DownloadError.java8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/LangUtils.java124
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java123
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/comparator/FeedItemPubdateComparator.java6
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java81
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java9
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java7
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java6
-rw-r--r--core/src/main/res/drawable-v21/ic_filter_close.xml55
-rw-r--r--core/src/main/res/drawable/ic_av_replay_black_48dp.xml9
-rw-r--r--core/src/main/res/drawable/ic_av_replay_white_48dp.xml9
-rw-r--r--core/src/main/res/drawable/ic_filter_close.xml8
-rw-r--r--core/src/main/res/drawable/ic_share_black.xml7
-rw-r--r--core/src/main/res/drawable/ic_share_white.xml7
-rw-r--r--core/src/main/res/layout/player_widget.xml61
-rw-r--r--core/src/main/res/values-br/strings.xml54
-rw-r--r--core/src/main/res/values-ca/strings.xml51
-rw-r--r--core/src/main/res/values-cs/strings.xml138
-rw-r--r--core/src/main/res/values-da/strings.xml158
-rw-r--r--core/src/main/res/values-de/strings.xml120
-rw-r--r--core/src/main/res/values-es/strings.xml119
-rw-r--r--core/src/main/res/values-et/strings.xml120
-rw-r--r--core/src/main/res/values-eu/strings.xml128
-rw-r--r--core/src/main/res/values-fa/strings.xml376
-rw-r--r--core/src/main/res/values-fi/strings.xml48
-rw-r--r--core/src/main/res/values-fr/strings.xml128
-rw-r--r--core/src/main/res/values-gl/strings.xml120
-rw-r--r--core/src/main/res/values-hu/strings.xml82
-rw-r--r--core/src/main/res/values-it/strings.xml120
-rw-r--r--core/src/main/res/values-iw/strings.xml124
-rw-r--r--core/src/main/res/values-ja/strings.xml49
-rw-r--r--core/src/main/res/values-ko/strings.xml50
-rw-r--r--core/src/main/res/values-lt/strings.xml55
-rw-r--r--core/src/main/res/values-nb/strings.xml117
-rw-r--r--core/src/main/res/values-nl/strings.xml134
-rw-r--r--core/src/main/res/values-pl/strings.xml141
-rw-r--r--core/src/main/res/values-pt-rBR/strings.xml146
-rw-r--r--core/src/main/res/values-pt/strings.xml126
-rw-r--r--core/src/main/res/values-ru/strings.xml128
-rw-r--r--core/src/main/res/values-sv/strings.xml120
-rw-r--r--core/src/main/res/values-tr/strings.xml403
-rw-r--r--core/src/main/res/values-uk/strings.xml47
-rw-r--r--core/src/main/res/values-zh-rCN/strings.xml124
-rw-r--r--core/src/main/res/values-zh-rTW/strings.xml156
-rw-r--r--core/src/main/res/values/arrays.xml2
-rw-r--r--core/src/main/res/values/attrs.xml4
-rw-r--r--core/src/main/res/values/colors.xml1
-rw-r--r--core/src/main/res/values/strings.xml75
-rw-r--r--core/src/main/res/values/styles.xml13
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java3
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/feed/FeedFilterTest.java (renamed from app/src/androidTest/java/de/test/antennapod/feed/FeedFilterTest.java)18
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java45
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java96
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/service/download/DownloadRequestTest.java (renamed from core/src/androidTest/java/de/danoeh/antennapod/core/service/download/DownloadRequestTest.java)6
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/storage/DbNullCleanupAlgorithmTest.java (renamed from app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java)60
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/storage/DbTasksTest.java (renamed from app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java)75
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/storage/DbWriterTest.java (renamed from app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java)282
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java35
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/util/DateUtilsTest.java (renamed from core/src/androidTest/java/de/danoeh/antennapod/core/util/DateUtilsTest.java)48
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/util/FilenameGeneratorTest.java (renamed from app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java)28
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/util/URLCheckerTest.java (renamed from app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java)22
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/util/playback/ExternalMediaTest.java (renamed from app/src/androidTest/java/de/test/antennapod/entities/ExternalMediaTest.java)20
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/util/playback/TimelineTest.java (renamed from app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java)44
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/util/syndication/FeedDiscovererTest.java (renamed from app/src/androidTest/java/de/test/antennapod/util/syndication/FeedDiscovererTest.java)24
-rw-r--r--createContributors.py73
-rw-r--r--createDevelopersList.py30
-rw-r--r--createTranslatorsList.py39
237 files changed, 5993 insertions, 4083 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
deleted file mode 100644
index bd4a20cc4..000000000
--- a/CONTRIBUTORS
+++ /dev/null
@@ -1,185 +0,0 @@
-ByteHamster
-danieloeh
-mfietz
-TomHennen
-orionlee
-domingos86
-andersonvom
-TacoTheDank
-shortspider
-ebraminio
-spacecowboy
-patheticpat
-tonytamsf
-brad
-Cj-Malone
-maxbechtold
-asdoi
-gaul
-qkolj
-pachecosf
-gerardolgvr
-bws9000
-ahangarha
-damoasda
-hannesa2
-keunes
-rharriso
-xgouchet
-sevenmaster
-TheRealFalcon
-jas14
-johnjohndoe
-udif
-malockin
-dirkmueller
-jatinkumarg
-peschmae0
-orelogo
-txtd
-ydinath
-CedricCabessa
-mchelen
-dethstar
-drabux
-saqura
-bibz
-hzulla
-deandreamatias
-MeirAtIMDDE
-egsavage
-ligi
-dreiss
-liesen
-nereocystis
-rezanejati
-twiceyuan
-JessieVela
-HaBaLeS
-volhol
-michaelmwhite
-CameronBanga
-HrBDev
-HolgerJeromin
-xisberto
-jmue
-katrinleinweber
-LatinSuD
-24hours
-SosoTughushi
-fabolhak
-archibishop
-alifeflow
-toggles
-matdb
-kingargyle
-dsmith47
-hannesaa2
-jhunnius
-ShadowIce
-raghulj
-raghulrm
-mamehacker
-skitt
-wseemann
-mr-intj
-tuxayo
-schlch
-alimemonzx
-olivoto
-alanorth
-alexte
-andrey-krutov
-arantius
-chrissicool
-cszucko
-CWftw
-danielm5
-ariedov
-brettle
-edwinhere
-eirikv
-eerden
-jklippel
-jannic
-Foso
-Kaligule
-kvithayathil
-luiscruz
-mlasson
-M-arcel
-msoose
-mo
-mdeveloper20
-Slinger
-mschuetz
-MolarAmbiguity
-mounirlamouri
-ortylp
-PtilopsisLeucotis
-ramzan
-SamWhited
-selivan
-sonnayasomnambula
-sethoscope
-shantanahardy
-danners
-corecode
-vimsick
-edent
-atrus6
-waylife
-amhokies
-andrewc1
-axq
-fossterer
-jmdouglas
-lightonflux
-minusf
-
-
-Arabic: abuzar3.khalid, keunes, nabilMaghura, rex07
-Asturian (ast_ES): enolp
-Basque: gaztainalde, keunes, Osoitz, pospolos
-Breton: Belvar, keunes
-Bulgarian: keunes, solusitor
-Catalan: carles.llacer, dvd1985, exort12, javiercoll, keunes, Kintu, lambdani, marcmetallextrem, xc70
-Chinese (zh_CN): brnme, cyril3, Felix2yu, gaohongyuan, Guaidaodl, Huck0, iconteral, jhxie, jxj2zzz79pfp9bpo, keunes, kyleehee, molisiye, owen8877, RainSlide, Sak94664, spice2wolf, tupunco, wongsyrone, yangyang, yiqiok
-Chinese (zh_TW): bobchao, ijliao, keunes, mapobi, pggdt, ymhuang0808
-Czech (cs_CZ): anotheranonymoususer, elich, Hanzmeister, svetlemodry, Thomaash
-Danish: jhertel, keunes, SebastianKiwiDk, twikedk
-Dutch: e2jk, keunes, rwv, Vistaus
-Estonian: Eraser, keunes, mahfiaz
-Finnish: Ban3, keunes, Sahtor
-French: ChaoticMind, clombion, Cornegidouille, e2jk, keunes, lacouture, LouFex, Matth78, Poussinou, sterylmreep
-Galician: antiparvos, pikamoku, Raichely
-German: ByteHamster, ceving, dadosch, DerSilly, elkangaroo, enz, f_grubm, finsterwalder, HolgerJeromin, kalei, keunes, mfietz, Quiss42, repat, ypid
-Modern Greek (1453-): AnimaRain, antonist, keunes, pavlosv
-Hebrew (he_IL): amir.dafnyman, E1i9, mongoose4004, pinkasey, rellieberman, Yaron
-Hindi (hi_IN): keunes, purple.coder, siddhusengar
-Hungarian: hurrikan, keunes, lna91, marthynw, meskobalazs, naren93
-Icelandic: keunes, marthjod
-Indonesian: dbrw, keunes, levirs565
-Italian (it_IT): aalex70, allin, Bonnee, dontknowcris, giuseppep, Guybrush88, ilmanzo, keunes, m.chinni, marco_pag, neonsoftware, niccord, theloca95
-Japanese: keunes, KotaKato, Naofumi, sh3llc4t, TranslatorG
-Kannada (kn_IN): chiraag.nataraj, keunes, thejeshgn
-Korean: changwoo, keunes, libliboom
-Lithuanian: keunes, naglis
-Macedonian: krisfremen
-Malayalam: joice, keunes, rashivkp
-Norwegian Bokmål (nb_NO): abstrakct, bablecopherye, corkie, heraldo, jakobkg, keunes, kongk, sevenmaster, timbast
-Persian: ahangarha, danialbehzadi, ebraminio, F7D, hamidrezabayat76, keunes, sinamoghaddas
-Polish (pl_PL): hiro2020, Iwangelion, keunes, lomapur, mandlus, maniexx, Mephistofeles, shark103, tyle
-Portuguese: emansije, keunes, smarquespt
-Portuguese (pt_BR): alexupits, alysonborges, andersonvom, arua, caioau, carlo_valente, castrors, edman, keunes, lipefire, mbaltar, olivoto, rogervezaro, RubeensVinicius, SamWilliam
-Romanian (ro_RO): corneliu.e, fuzzmz, keunes, ralienpp
-Russian (ru_RU): btimofeev, Duke_Raven, gammja, homocomputeris, IgorPolyakov, keunes, mercutiy, null, overmind88, Platun0v, PtilopsisLeucotis, s.chebotar, un_logic, Vladryyu, whereisthetea
-Slovak: ati3, keunes, tiborepcek
-Slovenian (sl_SI): keunes, panter23
-Spanish: AleksSyntek, andersonvom, andrespelaezp, deandreamatias, dvd1985, Fitoschido, frandavid100, hard_ware, javiercoll, keunes, LatinSuD, leogrignafini, tres.14159, vfmatzkin, wakutiteo
-Swahili (macrolanguage): keunes, kmtra
-Swedish (sv_SE): bpnilsson, keunes, nilso, TwoD
-Telugu: keunes, veeven
-Turkish: brsata, Erdy, keunes, overbite, Slsdem
-Ukrainian (uk_UA): IndibidAbulya, keunes, older, paul_sm, sergiyr, zhenya97
-Vietnamese: abnvolk, keunes, ppanhh
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
new file mode 100644
index 000000000..a2a44e10e
--- /dev/null
+++ b/CONTRIBUTORS.md
@@ -0,0 +1,53 @@
+# Developers
+
+[ByteHamster](https://github.com/ByteHamster), [danieloeh](https://github.com/danieloeh), [mfietz](https://github.com/mfietz), [TomHennen](https://github.com/TomHennen), [orionlee](https://github.com/orionlee), [domingos86](https://github.com/domingos86), [tonytamsf](https://github.com/tonytamsf), [andersonvom](https://github.com/andersonvom), [damoasda](https://github.com/damoasda), [TacoTheDank](https://github.com/TacoTheDank), [shortspider](https://github.com/shortspider), [ebraminio](https://github.com/ebraminio), [asdoi](https://github.com/asdoi), [spacecowboy](https://github.com/spacecowboy), [patheticpat](https://github.com/patheticpat), [brad](https://github.com/brad), [Cj-Malone](https://github.com/Cj-Malone), [maxbechtold](https://github.com/maxbechtold), [gaul](https://github.com/gaul), [qkolj](https://github.com/qkolj), [keunes](https://github.com/keunes), [pachecosf](https://github.com/pachecosf), [gerardolgvr](https://github.com/gerardolgvr), [bws9000](https://github.com/bws9000), [ahangarha](https://github.com/ahangarha), [hannesa2](https://github.com/hannesa2), [rharriso](https://github.com/rharriso), [xgouchet](https://github.com/xgouchet), [sevenmaster](https://github.com/sevenmaster), [TheRealFalcon](https://github.com/TheRealFalcon), [Slinger](https://github.com/Slinger), [johnjohndoe](https://github.com/johnjohndoe), [jas14](https://github.com/jas14), [udif](https://github.com/udif), [malockin](https://github.com/malockin), [dirkmueller](https://github.com/dirkmueller), [jatinkumarg](https://github.com/jatinkumarg), [peschmae0](https://github.com/peschmae0), [orelogo](https://github.com/orelogo), [txtd](https://github.com/txtd), [ydinath](https://github.com/ydinath), [CedricCabessa](https://github.com/CedricCabessa), [mchelen](https://github.com/mchelen), [dethstar](https://github.com/dethstar), [drabux](https://github.com/drabux), [saqura](https://github.com/saqura), [bibz](https://github.com/bibz), [hzulla](https://github.com/hzulla), [deandreamatias](https://github.com/deandreamatias), [MeirAtIMDDE](https://github.com/MeirAtIMDDE), [egsavage](https://github.com/egsavage), [ligi](https://github.com/ligi), [Xeitor](https://github.com/Xeitor), [dreiss](https://github.com/dreiss), [liesen](https://github.com/liesen), [nereocystis](https://github.com/nereocystis), [rezanejati](https://github.com/rezanejati), [twiceyuan](https://github.com/twiceyuan), [JessieVela](https://github.com/JessieVela), [HaBaLeS](https://github.com/HaBaLeS), [volhol](https://github.com/volhol), [michaelmwhite](https://github.com/michaelmwhite), [CameronBanga](https://github.com/CameronBanga), [HrBDev](https://github.com/HrBDev), [HolgerJeromin](https://github.com/HolgerJeromin), [xisberto](https://github.com/xisberto), [jmue](https://github.com/jmue), [katrinleinweber](https://github.com/katrinleinweber), [LatinSuD](https://github.com/LatinSuD), [24hours](https://github.com/24hours), [SosoTughushi](https://github.com/SosoTughushi), [fabolhak](https://github.com/fabolhak), [archibishop](https://github.com/archibishop), [alifeflow](https://github.com/alifeflow), [avirajrsingh](https://github.com/avirajrsingh), [toggles](https://github.com/toggles), [matdb](https://github.com/matdb), [damlayildiz](https://github.com/damlayildiz), [kingargyle](https://github.com/kingargyle), [dsmith47](https://github.com/dsmith47), [hannesaa2](https://github.com/hannesaa2), [jhunnius](https://github.com/jhunnius), [ShadowIce](https://github.com/ShadowIce), [Niffler](https://github.com/Niffler), [raghulj](https://github.com/raghulj), [raghulrm](https://github.com/raghulrm), [mamehacker](https://github.com/mamehacker), [skitt](https://github.com/skitt), [wseemann](https://github.com/wseemann), [markamaze](https://github.com/markamaze), [mohitshah3111999](https://github.com/mohitshah3111999), [moralesg](https://github.com/moralesg), [mr-intj](https://github.com/mr-intj), [tuxayo](https://github.com/tuxayo), [schlch](https://github.com/schlch), [alimemonzx](https://github.com/alimemonzx), [dev-darrell](https://github.com/dev-darrell), [jmdouglas](https://github.com/jmdouglas), [olivoto](https://github.com/olivoto), [PtilopsisLeucotis](https://github.com/PtilopsisLeucotis), [abhinavg1997](https://github.com/abhinavg1997), [alanorth](https://github.com/alanorth), [alexte](https://github.com/alexte), [andrey-krutov](https://github.com/andrey-krutov), [arantius](https://github.com/arantius), [BoJacobs](https://github.com/BoJacobs), [chetan882777](https://github.com/chetan882777), [chrissicool](https://github.com/chrissicool), [cszucko](https://github.com/cszucko), [CWftw](https://github.com/CWftw), [connectety](https://github.com/connectety), [danielm5](https://github.com/danielm5), [ariedov](https://github.com/ariedov), [brettle](https://github.com/brettle), [edwinhere](https://github.com/edwinhere), [eirikv](https://github.com/eirikv), [eerden](https://github.com/eerden), [jklippel](https://github.com/jklippel), [jannic](https://github.com/jannic), [Foso](https://github.com/Foso), [Kaligule](https://github.com/Kaligule), [kvithayathil](https://github.com/kvithayathil), [luiscruz](https://github.com/luiscruz), [mlasson](https://github.com/mlasson), [schwedenmut](https://github.com/schwedenmut), [M-arcel](https://github.com/M-arcel), [msoose](https://github.com/msoose), [mo](https://github.com/mo), [mdeveloper20](https://github.com/mdeveloper20), [mschuetz](https://github.com/mschuetz), [max-wittig](https://github.com/max-wittig), [MolarAmbiguity](https://github.com/MolarAmbiguity), [mounirlamouri](https://github.com/mounirlamouri), [nikhil097](https://github.com/nikhil097), [panoreak](https://github.com/panoreak), [patrickjkennedy](https://github.com/patrickjkennedy), [ortylp](https://github.com/ortylp), [ramzan](https://github.com/ramzan), [iamrichR](https://github.com/iamrichR), [SamWhited](https://github.com/SamWhited), [selivan](https://github.com/selivan), [sonnayasomnambula](https://github.com/sonnayasomnambula), [sethoscope](https://github.com/sethoscope), [shantanahardy](https://github.com/shantanahardy), [danners](https://github.com/danners), [corecode](https://github.com/corecode), [vimsick](https://github.com/vimsick), [lyallemma](https://github.com/lyallemma), [edent](https://github.com/edent), [atrus6](https://github.com/atrus6), [heyyviv](https://github.com/heyyviv), [waylife](https://github.com/waylife), [amhokies](https://github.com/amhokies), [andrewc1](https://github.com/andrewc1), [axq](https://github.com/axq), [binarytoto](https://github.com/binarytoto), [chrk2205](https://github.com/chrk2205), [fossterer](https://github.com/fossterer), [lightonflux](https://github.com/lightonflux), [minusf](https://github.com/minusf), [zawad2221](https://github.com/zawad2221)
+
+# Translators
+
+| Language | Translators |
+| :-- | :-- |
+| Arabic | abuzar3.khalid, badarotti, keunes, nabilMaghura, rex07, shubbar |
+| Asturian (ast_ES) | enolp |
+| Basque | gaztainalde, keunes, Osoitz, pospolos |
+| Breton | Belvar, keunes |
+| Bulgarian | keunes, solusitor |
+| Catalan | carles.llacer, dvd1985, exort12, IvanAmarante, javiercoll, keunes, Kintu, lambdani, marcmetallextrem, xc70 |
+| Chinese (zh_CN) | brnme, cyril3, Felix2yu, gaohongyuan, Guaidaodl, Huck0, iconteral, jhxie, jxj2zzz79pfp9bpo, keunes, kyleehee, molisiye, owen8877, RainSlide, RangerNJU, Sak94664, spice2wolf, tupunco, wongsyrone, yangyang, yiqiok |
+| Chinese (zh_TW) | bobchao, ijliao, keunes, mapobi, pggdt, ymhuang0808 |
+| Czech (cs_CZ) | anotheranonymoususer, elich, Hanzmeister, svetlemodry, Thomaash |
+| Danish | JFreak, jhertel, keunes, SebastianKiwiDk, twikedk |
+| Dutch | e2jk, keunes, rwv, Vistaus |
+| Estonian | Eraser, keunes, mahfiaz |
+| Finnish | Ban3, keunes, Sahtor |
+| French | ChaoticMind, clombion, Cornegidouille, e2jk, keunes, lacouture, LouFex, Matth78, Poussinou, sterylmreep |
+| Galician | antiparvos, pikamoku, Raichely |
+| German | _Er, ByteHamster, ceving, dadosch, DerSilly, elkangaroo, enz, f_grubm, finsterwalder, hbilke, HolgerJeromin, JoeMcFly, kalei, keunes, mfietz, pudeeh, Quiss42, repat, tomte, tweimer, Willhelm, ypid |
+| Modern Greek (1453-) | AnimaRain, antonist, keunes, pavlosv |
+| Hebrew (he_IL) | amir.dafnyman, E1i9, mongoose4004, pinkasey, rellieberman, Yaron |
+| Hindi (hi_IN) | keunes, purple.coder, siddhusengar, thelazyoxymoron |
+| Hu | hurrikan, keunes, lna91, marthynw, meskobalazs, naren93 |
+| Icelandic | keunes, marthjod |
+| Indonesian | dbrw, keunes, levirs565 |
+| Italian (it_IT) | aalex70, allin, alvami, Bonnee, dontknowcris, giuseppep, Guybrush88, ilmanzo, keunes, m.chinni, marco_pag, neonsoftware, niccord, salorock, theloca95 |
+| Japanese | keunes, KotaKato, Naofumi, sh3llc4t, TranslatorG |
+| Kannada (kn_IN) | chiraag.nataraj, keunes, thejeshgn |
+| Ko | changwoo, keunes, libliboom |
+| Lithuanian | keunes, naglis |
+| Macedonian | krisfremen |
+| Malayalam | joice, keunes, rashivkp |
+| Norwegian Bokmål (nb_NO) | abstrakct, ahysing, bablecopherye, corkie, forteller, heraldo, jakobkg, keunes, kongk, sevenmaster, timbast |
+| Persian | ahangarha, danialbehzadi, ebadi, ebraminio, F7D, hamidrezabayat76, keunes, sinamoghaddas |
+| Polish (pl_PL) | befeleme, hiro2020, Iwangelion, keunes, lomapur, mandlus, maniexx, Mephistofeles, shark103, tyle |
+| Portuguese | emansije, keunes, smarquespt |
+| Portuguese (pt_BR) | alexupits, alysonborges, andersonvom, arua, caioau, carlo_valente, castrors, edman, keunes, lipefire, mbaltar, olivoto, rogervezaro, RubeensVinicius, SamWilliam |
+| Romanian (ro_RO) | corneliu.e, fuzzmz, keunes, ralienpp |
+| Russian (ru_RU) | ashed, btimofeev, Duke_Raven, gammja, homocomputeris, IgorPolyakov, keunes, mercutiy, null, overmind88, Platun0v, PtilopsisLeucotis, s.chebotar, un_logic, Vladryyu, whereisthetea |
+| Slovak | ati3, keunes, marulinko, tiborepcek |
+| Slovenian (sl_SI) | keunes, panter23 |
+| Spanish | AleksSyntek, andersonvom, andrespelaezp, deandreamatias, dvd1985, elojodepajaro, Fitoschido, frandavid100, hard_ware, javiercoll, keunes, LatinSuD, leogrignafini, rafael.osuna, tres.14159, vfmatzkin, wakutiteo |
+| Swahili (macrolanguage) | keunes, kmtra |
+| Swedish (sv_SE) | bpnilsson, keunes, nilso, TwoD |
+| Telugu | keunes, veeven |
+| Turkish | AhmedDuran, brsata, Erdy, keunes, overbite, Slsdem |
+| Ukrainian (uk_UA) | keunes, older, paul_sm, sergiyr, zhenya97 |
+| Vietnamese | abnvolk, keunes, ppanhh |
diff --git a/LICENSE b/LICENSE
index 041569700..0c780f71e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,685 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
+
+-------------------------------------------------------------------------------
+Parts of AntennaPod use the MIT license.
+-------------------------------------------------------------------------------
+
The MIT License (MIT)
-Copyright (c) 2012-2015 AntennaPod contributors
+Copyright (c) 2012-2020 AntennaPod contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 3a59b7974..c5dd33d7d 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ AntennaPod has many users and we don't want them to run into trouble when we add
## License
-AntennaPod is licensed under the MIT License. You can find the license text in the LICENSE file.
+AntennaPod is licensed under the GNU General Public License (GPL-3.0). You can find the license text in the LICENSE file.
## Translating AntennaPod
If you want to translate AntennaPod into another language, you can visit the [Transifex project page](https://www.transifex.com/antennapod/antennapod/).
diff --git a/app/build.gradle b/app/build.gradle
index 2880f980f..ef8e850b3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -22,8 +22,8 @@ android {
// "1.2.3-SNAPSHOT" -> 1020300
// "1.2.3-RC4" -> 1020304
// "1.2.3" -> 1020395
- versionCode 2000395
- versionName "2.0.3"
+ versionCode 2010295
+ versionName "2.1.2"
multiDexEnabled false
vectorDrawables.useSupportLibrary true
diff --git a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
index 3c8c5d7f0..21498effd 100644
--- a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
@@ -3,8 +3,10 @@ package de.test.antennapod;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.IdRes;
+import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.preference.PreferenceManager;
+import androidx.test.espresso.NoMatchingViewException;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.espresso.PerformException;
import androidx.test.espresso.UiController;
@@ -15,6 +17,9 @@ import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.util.HumanReadables;
import androidx.test.espresso.util.TreeIterables;
import android.view.View;
+
+import junit.framework.AssertionFailedError;
+
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.preferences.UserPreferences;
@@ -33,6 +38,7 @@ import java.util.concurrent.TimeoutException;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
@@ -57,7 +63,7 @@ public class EspressoTestUtils {
@Override
public String getDescription() {
- return "wait for a specific view for" + millis + " millis.";
+ return "wait for a specific view for " + millis + " millis.";
}
@Override
@@ -88,6 +94,33 @@ public class EspressoTestUtils {
}
/**
+ * Wait until a certain view becomes visible, but at the longest until the timeout.
+ * Unlike {@link #waitForView(Matcher, long)} it doesn't stick to the initial root view.
+ *
+ * @param viewMatcher The view to wait for.
+ * @param timeoutMillis Maximum waiting period in milliseconds.
+ * @throws Exception Throws an Exception in case of a timeout.
+ */
+ public static void waitForViewGlobally(@NonNull Matcher<View> viewMatcher, long timeoutMillis) throws Exception {
+ long startTime = System.currentTimeMillis();
+ long endTime = startTime + timeoutMillis;
+
+ do {
+ try {
+ onView(viewMatcher).check(matches(isDisplayed()));
+ // no Exception thrown -> check successful
+ return;
+ } catch (NoMatchingViewException | AssertionFailedError ignore) {
+ // check was not successful "not found" -> continue waiting
+ }
+ //noinspection BusyWait
+ Thread.sleep(50);
+ } while (System.currentTimeMillis() < endTime);
+
+ throw new Exception("Timeout after " + timeoutMillis + " ms");
+ }
+
+ /**
* Perform action of waiting for a specific view id.
* https://stackoverflow.com/a/30338665/
* @param id The id of the child to click.
@@ -113,7 +146,7 @@ public class EspressoTestUtils {
}
/**
- * Clear all app databases
+ * Clear all app databases.
*/
public static void clearPreferences() {
File root = InstrumentationRegistry.getInstrumentation().getTargetContext().getFilesDir().getParentFile();
diff --git a/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java b/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java
deleted file mode 100644
index 0b9a67d0a..000000000
--- a/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.test.antennapod.feed;
-
-import androidx.test.filters.SmallTest;
-import de.danoeh.antennapod.core.feed.FeedItem;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-@SmallTest
-public class FeedItemTest {
- private static final String TEXT_LONG = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
- private static final String TEXT_SHORT = "Lorem ipsum";
-
- /**
- * If one of `description` or `content:encoded` is null, use the other one.
- */
- @Test
- public void testShownotesNullValues() throws Exception {
- testShownotes(null, TEXT_LONG);
- testShownotes(TEXT_LONG, null);
- }
-
- /**
- * If `description` is reasonably longer than `content:encoded`, use `description`.
- */
- @Test
- public void testShownotesLength() throws Exception {
- testShownotes(TEXT_SHORT, TEXT_LONG);
- testShownotes(TEXT_LONG, TEXT_SHORT);
- }
-
- /**
- * Checks if the shownotes equal TEXT_LONG, using the given `description` and `content:encoded`
- * @param description Description of the feed item
- * @param contentEncoded `content:encoded` of the feed item
- */
- private void testShownotes(String description, String contentEncoded) throws Exception {
- FeedItem item = new FeedItem();
- item.setDescription(description);
- item.setContentEncoded(contentEncoded);
- assertEquals(TEXT_LONG, item.loadShownotes().call());
- }
-}
diff --git a/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java b/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java
index fd395f7c1..70cf4166b 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java
@@ -17,10 +17,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.feed.Feed;
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java
index 5396b218d..1d2e3d9e8 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java
@@ -4,14 +4,12 @@ import android.content.Context;
import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider;
import de.danoeh.antennapod.core.ClientConfig;
-import de.danoeh.antennapod.core.DBTasksCallbacks;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm;
import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
import de.test.antennapod.EspressoTestUtils;
import de.test.antennapod.ui.UITestUtils;
@@ -32,7 +30,7 @@ public class AutoDownloadTest {
private Context context;
private UITestUtils stubFeedsServer;
- private DBTasksCallbacks dbTasksCallbacksOrig;
+ private AutomaticDownloadAlgorithm automaticDownloadAlgorithmOrig;
@Before
public void setUp() throws Exception {
@@ -41,7 +39,7 @@ public class AutoDownloadTest {
stubFeedsServer = new UITestUtils(context);
stubFeedsServer.setup();
- dbTasksCallbacksOrig = ClientConfig.dbTasksCallbacks;
+ automaticDownloadAlgorithmOrig = ClientConfig.automaticDownloadAlgorithm;
EspressoTestUtils.clearPreferences();
EspressoTestUtils.clearDatabase();
@@ -50,7 +48,7 @@ public class AutoDownloadTest {
@After
public void tearDown() throws Exception {
- ClientConfig.dbTasksCallbacks = dbTasksCallbacksOrig;
+ ClientConfig.automaticDownloadAlgorithm = automaticDownloadAlgorithmOrig;
EspressoTestUtils.tryKillPlaybackService();
stubFeedsServer.tearDown();
}
@@ -79,7 +77,7 @@ public class AutoDownloadTest {
// Setup: enable automatic download
// it is not needed, as the actual automatic download is stubbed.
StubDownloadAlgorithm stubDownloadAlgorithm = new StubDownloadAlgorithm();
- useDownloadAlgorithm(stubDownloadAlgorithm);
+ ClientConfig.automaticDownloadAlgorithm = stubDownloadAlgorithm;
// Actual test
// Play the first one in the queue
@@ -113,20 +111,6 @@ public class AutoDownloadTest {
.until(() -> item.getMedia().getId() == PlaybackPreferences.getCurrentlyPlayingFeedMediaId());
}
- private void useDownloadAlgorithm(final AutomaticDownloadAlgorithm downloadAlgorithm) {
- ClientConfig.dbTasksCallbacks = new DBTasksCallbacks() {
- @Override
- public AutomaticDownloadAlgorithm getAutomaticDownloadAlgorithm() {
- return downloadAlgorithm;
- }
-
- @Override
- public EpisodeCleanupAlgorithm getEpisodeCacheCleanupAlgorithm() {
- return dbTasksCallbacksOrig.getEpisodeCacheCleanupAlgorithm();
- }
- };
- }
-
private static class StubDownloadAlgorithm implements AutomaticDownloadAlgorithm {
private long currentlyPlaying = -1;
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java b/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
index 6c36da13e..339d3cea9 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
@@ -11,7 +11,6 @@ import java.util.Date;
import java.util.List;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
import androidx.test.filters.SmallTest;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
index be1ed6cc2..417a78f02 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
@@ -2,16 +2,14 @@ package de.test.antennapod.ui;
import android.app.Activity;
import android.content.Intent;
-import androidx.test.platform.app.InstrumentationRegistry;
+
import androidx.test.espresso.Espresso;
import androidx.test.espresso.intent.rule.IntentsTestRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
import com.robotium.solo.Solo;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
-import de.test.antennapod.EspressoTestUtils;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -20,6 +18,12 @@ import org.junit.runner.RunWith;
import java.io.IOException;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.test.antennapod.EspressoTestUtils;
+
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.replaceText;
@@ -28,18 +32,17 @@ import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.contrib.ActivityResultMatchers.hasResultCode;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static de.test.antennapod.EspressoTestUtils.clickPreference;
import static de.test.antennapod.EspressoTestUtils.openNavDrawer;
-import static de.test.antennapod.EspressoTestUtils.waitForView;
-import static junit.framework.TestCase.assertTrue;
+import static de.test.antennapod.EspressoTestUtils.waitForViewGlobally;
import static org.hamcrest.Matchers.allOf;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
/**
- * User interface tests for MainActivity
+ * User interface tests for MainActivity.
*/
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
@@ -48,19 +51,19 @@ public class MainActivityTest {
private UITestUtils uiTestUtils;
@Rule
- public IntentsTestRule<MainActivity> mActivityRule = new IntentsTestRule<>(MainActivity.class, false, false);
+ public IntentsTestRule<MainActivity> activityRule = new IntentsTestRule<>(MainActivity.class, false, false);
@Before
public void setUp() throws IOException {
EspressoTestUtils.clearPreferences();
EspressoTestUtils.clearDatabase();
- mActivityRule.launchActivity(new Intent());
+ activityRule.launchActivity(new Intent());
uiTestUtils = new UITestUtils(InstrumentationRegistry.getInstrumentation().getTargetContext());
uiTestUtils.setup();
- solo = new Solo(InstrumentationRegistry.getInstrumentation(), mActivityRule.getActivity());
+ solo = new Solo(InstrumentationRegistry.getInstrumentation(), activityRule.getActivity());
}
@After
@@ -71,16 +74,22 @@ public class MainActivityTest {
@Test
public void testAddFeed() throws Exception {
+ // connect to podcast feed
uiTestUtils.addHostedFeedData();
final Feed feed = uiTestUtils.hostedFeeds.get(0);
openNavDrawer();
onView(withText(R.string.add_feed_label)).perform(click());
- onView(withId(R.id.btn_add_via_url)).perform(scrollTo(), click());
- onView(withId(R.id.text)).perform(replaceText(feed.getDownload_url()));
+ onView(withId(R.id.addViaUrlButton)).perform(scrollTo(), click());
+ onView(withId(R.id.urlEditText)).perform(replaceText(feed.getDownload_url()));
onView(withText(R.string.confirm_label)).perform(scrollTo(), click());
+
+ // subscribe podcast
Espresso.closeSoftKeyboard();
+ waitForViewGlobally(withText(R.string.subscribe_label), 15000);
onView(withText(R.string.subscribe_label)).perform(click());
- onView(isRoot()).perform(waitForView(withId(R.id.butShowSettings), 5000));
+
+ // wait for podcast feed item list
+ waitForViewGlobally(withId(R.id.butShowSettings), 15000);
}
@Test
@@ -100,7 +109,7 @@ public class MainActivityTest {
onView(allOf(withId(R.id.toolbar), isDisplayed())).check(
matches(hasDescendant(withText(R.string.subscriptions_label))));
solo.goBack();
- assertThat(mActivityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
+ assertThat(activityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
}
@Test
@@ -113,7 +122,7 @@ public class MainActivityTest {
solo.goBackToActivity(MainActivity.class.getSimpleName());
solo.goBack();
solo.goBack();
- assertTrue(((MainActivity)solo.getCurrentActivity()).isDrawerOpen());
+ assertTrue(((MainActivity) solo.getCurrentActivity()).isDrawerOpen());
}
@Test
@@ -127,7 +136,7 @@ public class MainActivityTest {
solo.goBack();
solo.goBack();
solo.goBack();
- assertThat(mActivityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
+ assertThat(activityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
}
@Test
@@ -142,7 +151,7 @@ public class MainActivityTest {
solo.goBack();
onView(withText(R.string.yes)).perform(click());
Thread.sleep(100);
- assertThat(mActivityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
+ assertThat(activityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
}
@Test
@@ -155,6 +164,6 @@ public class MainActivityTest {
solo.goBackToActivity(MainActivity.class.getSimpleName());
solo.goBack();
solo.goBack();
- assertThat(mActivityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
+ assertThat(activityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
}
}
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java b/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java
index ade5ea298..53396372a 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java
@@ -42,9 +42,9 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static de.test.antennapod.EspressoTestUtils.onDrawerItem;
import static de.test.antennapod.EspressoTestUtils.waitForView;
import static de.test.antennapod.NthMatcher.first;
-import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.Matchers.allOf;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
* User interface tests for MainActivity drawer.
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 9bf89980c..3cdb09605 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
@@ -43,9 +43,9 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static de.test.antennapod.EspressoTestUtils.clickPreference;
import static de.test.antennapod.EspressoTestUtils.waitForView;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertTrue;
@LargeTest
public class PreferencesTest {
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java b/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java
index 634904f71..5b291752d 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java
@@ -1,15 +1,12 @@
package de.test.antennapod.ui;
import android.content.Intent;
-import android.view.View;
-import androidx.test.espresso.Espresso;
import androidx.test.espresso.intent.rule.IntentsTestRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.test.antennapod.EspressoTestUtils;
-import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java
index 5f79e935c..904e17ebf 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java
@@ -14,7 +14,6 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
-import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.test.antennapod.EspressoTestUtils;
import de.test.antennapod.IgnoreOnCi;
@@ -37,8 +36,6 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static de.test.antennapod.EspressoTestUtils.waitForView;
-import static de.test.antennapod.NthMatcher.first;
-import static org.hamcrest.Matchers.allOf;
/**
* User interface tests for changing the playback speed.
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java
index 60516454f..54592df0b 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java
@@ -6,7 +6,6 @@ import java.net.URL;
import java.util.List;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
import androidx.test.filters.MediumTest;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fb205b1c3..b4a2c52a3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -189,15 +189,6 @@
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="de.danoeh.antennapod.activity.MainActivity"/>
- <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:scheme="file"/>
- <data android:mimeType="video/*"/>
- </intent-filter>
</activity>
<activity
@@ -292,19 +283,6 @@
</activity>
- <activity
- android:name=".activity.gpoddernet.GpodnetAuthenticationActivity"
- android:configChanges="orientation"
- android:label="@string/gpodnet_auth_label">
- <intent-filter>
- <action android:name=".activity.gpoddernet.GpodnetAuthenticationActivity"/>
- <category android:name="android.intent.category.DEFAULT"/>
- </intent-filter>
- <meta-data
- android:name="android.support.PARENT_ACTIVITY"
- android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
- </activity>
-
<receiver android:name=".receiver.ConnectivityActionReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
diff --git a/app/src/main/assets/developers.csv b/app/src/main/assets/developers.csv
index cff15ee38..a2c54723d 100644
--- a/app/src/main/assets/developers.csv
+++ b/app/src/main/assets/developers.csv
@@ -1,35 +1,36 @@
ByteHamster;5811634;Maintainer
danieloeh;968613;Original creator of AntennaPod (retired)
-mfietz;6860662;Maintainer
+mfietz;6860662;Maintainer (retired)
TomHennen;5216560;Maintainer (retired)
orionlee;250644;Contributor
domingos86;9538859;Contributor
+tonytamsf;149837;Contributor
andersonvom;69922;Contributor
+damoasda;46045854;Contributor
TacoTheDank;32376686;Contributor
shortspider;5712543;Contributor
ebraminio;833473;Contributor
+asdoi;36813904;Contributor
spacecowboy;223655;Contributor
patheticpat;16046;Contributor
-tonytamsf;149837;Contributor
brad;1614;Contributor
Cj-Malone;10121513;Contributor
maxbechtold;9162198;Contributor
-asdoi;36813904;Contributor
gaul;848247;Contributor
qkolj;6667105;Contributor
+keunes;11229646;Maintainer
pachecosf;46357909;Contributor
gerardolgvr;20119298;Contributor
bws9000;262625;Contributor
ahangarha;11241315;Contributor
-damoasda;46045854;Contributor
hannesa2;3314607;Contributor
-keunes;11229646;Contributor
rharriso;570910;Contributor
xgouchet;818706;Contributor
sevenmaster;12869538;Contributor
TheRealFalcon;153674;Contributor
-jas14;569991;Contributor
+Slinger;75751;Contributor
johnjohndoe;144518;Contributor
+jas14;569991;Contributor
udif;809640;Contributor
malockin;12814657;Contributor
dirkmueller;1029152;Contributor
@@ -49,6 +50,7 @@ deandreamatias;21011641;Contributor
MeirAtIMDDE;4421079;Contributor
egsavage;126165;Contributor
ligi;111600;Contributor
+Xeitor;8825715;Contributor
dreiss;4121;Contributor
liesen;26872;Contributor
nereocystis;2257107;Contributor
@@ -70,30 +72,43 @@ SosoTughushi;19908097;Contributor
fabolhak;20029691;Contributor
archibishop;36948493;Contributor
alifeflow;24603829;Contributor
+avirajrsingh;69088913;Contributor
toggles;14695;Contributor
matdb;48329535;Contributor
+damlayildiz;56313500;Contributor
kingargyle;177042;Contributor
dsmith47;14109426;Contributor
hannesaa2;18496079;Contributor
jhunnius;9149031;Contributor
ShadowIce;59123;Contributor
+Niffler;8172446;Contributor
raghulj;57007;Contributor
raghulrm;5362986;Contributor
mamehacker;16738348;Contributor
skitt;2128935;Contributor
wseemann;2296196;Contributor
+markamaze;17114678;Contributor
+mohitshah3111999;42018918;Contributor
+moralesg;14352147;Contributor
mr-intj;6268767;Contributor
tuxayo;2678215;Contributor
schlch;56929215;Contributor
alimemonzx;44647595;Contributor
+dev-darrell;52300159;Contributor
+jmdouglas;10855634;Contributor
olivoto;15932680;Contributor
+PtilopsisLeucotis;54054883;Contributor
+abhinavg1997;60095795;Contributor
alanorth;191754;Contributor
alexte;7724992;Contributor
andrey-krutov;1488973;Contributor
arantius;84729;Contributor
+BoJacobs;25435640;Contributor
+chetan882777;36985543;Contributor
chrissicool;232590;Contributor
cszucko;1810383;Contributor
CWftw;1498303;Contributor
+connectety;26038710;Contributor
danielm5;66779;Contributor
ariedov;958646;Contributor
brettle;118192;Contributor
@@ -107,17 +122,21 @@ Kaligule;3586246;Contributor
kvithayathil;1056073;Contributor
luiscruz;1080714;Contributor
mlasson;5814258;Contributor
+schwedenmut;9077622;Contributor
M-arcel;56698158;Contributor
msoose;30473690;Contributor
mo;7117;Contributor
mdeveloper20;2319126;Contributor
-Slinger;75751;Contributor
mschuetz;108637;Contributor
+max-wittig;6639323;Contributor
MolarAmbiguity;10541979;Contributor
mounirlamouri;573590;Contributor
+nikhil097;35090769;Contributor
+panoreak;25068506;Contributor
+patrickjkennedy;8617261;Contributor
ortylp;470439;Contributor
-PtilopsisLeucotis;54054883;Contributor
ramzan;55637406;Contributor
+iamrichR;44210678;Contributor
SamWhited;512573;Contributor
selivan;1208989;Contributor
sonnayasomnambula;7716779;Contributor
@@ -126,13 +145,17 @@ shantanahardy;26757164;Contributor
danners;116551;Contributor
corecode;177979;Contributor
vimsick;20211590;Contributor
+lyallemma;25173082;Contributor
edent;837136;Contributor
atrus6;357881;Contributor
+heyyviv;56256802;Contributor
waylife;3348620;Contributor
amhokies;3124968;Contributor
andrewc1;19559401;Contributor
axq;5077221;Contributor
+binarytoto;75904760;Contributor
+chrk2205;44704035;Contributor
fossterer;4236021;Contributor
-jmdouglas;10855634;Contributor
lightonflux;1377943;Contributor
minusf;3632883;Contributor
+zawad2221;32180355;Contributor
diff --git a/app/src/main/assets/licenses.xml b/app/src/main/assets/licenses.xml
index 4f0255182..b6e12cf54 100644
--- a/app/src/main/assets/licenses.xml
+++ b/app/src/main/assets/licenses.xml
@@ -4,7 +4,7 @@
name="AntennaPod"
author="The AntennaPod team"
website="https://github.com/AntennaPod/AntennaPod/"
- license="MIT"
+ license="GPL-3.0"
licenseText="LICENSE.txt" />
<library
name="AntennaPod-AudioPlayer"
diff --git a/app/src/main/assets/special_thanks.csv b/app/src/main/assets/special_thanks.csv
index 348e3208e..ab44bd7f4 100644
--- a/app/src/main/assets/special_thanks.csv
+++ b/app/src/main/assets/special_thanks.csv
@@ -1,3 +1,4 @@
221 Pixels;Logo design;https://avatars2.githubusercontent.com/u/58243143?s=60&v=4
+Anxhelo Lushka;Website design;https://avatars2.githubusercontent.com/u/25004151?s=60&v=4
ByteHamster;Forum admin;https://avatars2.githubusercontent.com/u/5811634?s=60&v=4
Keunes;Communications;https://avatars2.githubusercontent.com/u/11229646?s=60&v=4
diff --git a/app/src/main/assets/translators.csv b/app/src/main/assets/translators.csv
index a7d289963..fddad789b 100644
--- a/app/src/main/assets/translators.csv
+++ b/app/src/main/assets/translators.csv
@@ -1,45 +1,45 @@
-Arabic;abuzar3.khalid, keunes, nabilMaghura, rex07
+Arabic;abuzar3.khalid, badarotti, keunes, nabilMaghura, rex07, shubbar
Asturian (ast_ES);enolp
Basque;gaztainalde, keunes, Osoitz, pospolos
Breton;Belvar, keunes
Bulgarian;keunes, solusitor
-Catalan;carles.llacer, dvd1985, exort12, javiercoll, keunes, Kintu, lambdani, marcmetallextrem, xc70
-Chinese (zh_CN);brnme, cyril3, Felix2yu, gaohongyuan, Guaidaodl, Huck0, iconteral, jhxie, jxj2zzz79pfp9bpo, keunes, kyleehee, molisiye, owen8877, RainSlide, Sak94664, spice2wolf, tupunco, wongsyrone, yangyang, yiqiok
+Catalan;carles.llacer, dvd1985, exort12, IvanAmarante, javiercoll, keunes, Kintu, lambdani, marcmetallextrem, xc70
+Chinese (zh_CN);brnme, cyril3, Felix2yu, gaohongyuan, Guaidaodl, Huck0, iconteral, jhxie, jxj2zzz79pfp9bpo, keunes, kyleehee, molisiye, owen8877, RainSlide, RangerNJU, Sak94664, spice2wolf, tupunco, wongsyrone, yangyang, yiqiok
Chinese (zh_TW);bobchao, ijliao, keunes, mapobi, pggdt, ymhuang0808
Czech (cs_CZ);anotheranonymoususer, elich, Hanzmeister, svetlemodry, Thomaash
-Danish;jhertel, keunes, SebastianKiwiDk, twikedk
+Danish;JFreak, jhertel, keunes, SebastianKiwiDk, twikedk
Dutch;e2jk, keunes, rwv, Vistaus
Estonian;Eraser, keunes, mahfiaz
Finnish;Ban3, keunes, Sahtor
French;ChaoticMind, clombion, Cornegidouille, e2jk, keunes, lacouture, LouFex, Matth78, Poussinou, sterylmreep
Galician;antiparvos, pikamoku, Raichely
-German;ByteHamster, ceving, dadosch, DerSilly, elkangaroo, enz, f_grubm, finsterwalder, HolgerJeromin, kalei, keunes, mfietz, Quiss42, repat, ypid
+German;_Er, ByteHamster, ceving, dadosch, DerSilly, elkangaroo, enz, f_grubm, finsterwalder, hbilke, HolgerJeromin, JoeMcFly, kalei, keunes, mfietz, pudeeh, Quiss42, repat, tomte, tweimer, Willhelm, ypid
Modern Greek (1453-);AnimaRain, antonist, keunes, pavlosv
Hebrew (he_IL);amir.dafnyman, E1i9, mongoose4004, pinkasey, rellieberman, Yaron
-Hindi (hi_IN);keunes, purple.coder, siddhusengar
-Hungarian;hurrikan, keunes, lna91, marthynw, meskobalazs, naren93
+Hindi (hi_IN);keunes, purple.coder, siddhusengar, thelazyoxymoron
+Hu;hurrikan, keunes, lna91, marthynw, meskobalazs, naren93
Icelandic;keunes, marthjod
Indonesian;dbrw, keunes, levirs565
-Italian (it_IT);aalex70, allin, Bonnee, dontknowcris, giuseppep, Guybrush88, ilmanzo, keunes, m.chinni, marco_pag, neonsoftware, niccord, theloca95
+Italian (it_IT);aalex70, allin, alvami, Bonnee, dontknowcris, giuseppep, Guybrush88, ilmanzo, keunes, m.chinni, marco_pag, neonsoftware, niccord, salorock, theloca95
Japanese;keunes, KotaKato, Naofumi, sh3llc4t, TranslatorG
Kannada (kn_IN);chiraag.nataraj, keunes, thejeshgn
-Korean;changwoo, keunes, libliboom
+Ko;changwoo, keunes, libliboom
Lithuanian;keunes, naglis
Macedonian;krisfremen
Malayalam;joice, keunes, rashivkp
-Norwegian Bokmål (nb_NO);abstrakct, bablecopherye, corkie, heraldo, jakobkg, keunes, kongk, sevenmaster, timbast
-Persian;ahangarha, danialbehzadi, ebraminio, F7D, hamidrezabayat76, keunes, sinamoghaddas
-Polish (pl_PL);hiro2020, Iwangelion, keunes, lomapur, mandlus, maniexx, Mephistofeles, shark103, tyle
+Norwegian Bokmål (nb_NO);abstrakct, ahysing, bablecopherye, corkie, forteller, heraldo, jakobkg, keunes, kongk, sevenmaster, timbast
+Persian;ahangarha, danialbehzadi, ebadi, ebraminio, F7D, hamidrezabayat76, keunes, sinamoghaddas
+Polish (pl_PL);befeleme, hiro2020, Iwangelion, keunes, lomapur, mandlus, maniexx, Mephistofeles, shark103, tyle
Portuguese;emansije, keunes, smarquespt
Portuguese (pt_BR);alexupits, alysonborges, andersonvom, arua, caioau, carlo_valente, castrors, edman, keunes, lipefire, mbaltar, olivoto, rogervezaro, RubeensVinicius, SamWilliam
Romanian (ro_RO);corneliu.e, fuzzmz, keunes, ralienpp
-Russian (ru_RU);btimofeev, Duke_Raven, gammja, homocomputeris, IgorPolyakov, keunes, mercutiy, null, overmind88, Platun0v, PtilopsisLeucotis, s.chebotar, un_logic, Vladryyu, whereisthetea
-Slovak;ati3, keunes, tiborepcek
+Russian (ru_RU);ashed, btimofeev, Duke_Raven, gammja, homocomputeris, IgorPolyakov, keunes, mercutiy, null, overmind88, Platun0v, PtilopsisLeucotis, s.chebotar, un_logic, Vladryyu, whereisthetea
+Slovak;ati3, keunes, marulinko, tiborepcek
Slovenian (sl_SI);keunes, panter23
-Spanish;AleksSyntek, andersonvom, andrespelaezp, deandreamatias, dvd1985, Fitoschido, frandavid100, hard_ware, javiercoll, keunes, LatinSuD, leogrignafini, tres.14159, vfmatzkin, wakutiteo
+Spanish;AleksSyntek, andersonvom, andrespelaezp, deandreamatias, dvd1985, elojodepajaro, Fitoschido, frandavid100, hard_ware, javiercoll, keunes, LatinSuD, leogrignafini, rafael.osuna, tres.14159, vfmatzkin, wakutiteo
Swahili (macrolanguage);keunes, kmtra
Swedish (sv_SE);bpnilsson, keunes, nilso, TwoD
Telugu;keunes, veeven
-Turkish;brsata, Erdy, keunes, overbite, Slsdem
-Ukrainian (uk_UA);IndibidAbulya, keunes, older, paul_sm, sergiyr, zhenya97
+Turkish;AhmedDuran, brsata, Erdy, keunes, overbite, Slsdem
+Ukrainian (uk_UA);keunes, older, paul_sm, sergiyr, zhenya97
Vietnamese;abnvolk, keunes, ppanhh
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
index bff11fa5e..721291597 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
@@ -11,10 +11,15 @@ import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import com.google.android.material.snackbar.Snackbar;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
+import android.view.Menu;
+import android.view.MenuItem;
import android.widget.TextView;
@@ -67,42 +72,65 @@ public class BugReportActivity extends AppCompatActivity {
clipboard.setPrimaryClip(clip);
Snackbar.make(findViewById(android.R.id.content), R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT).show();
});
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.bug_report_options, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
- findViewById(R.id.btn_export_logcat).setOnClickListener(v -> {
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ if (item.getItemId() == R.id.export_logcat) {
+ AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
+ alertBuilder.setMessage(R.string.confirm_export_log_dialog_message);
+ alertBuilder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
+ exportLog();
+ dialog.dismiss();
+ });
+ alertBuilder.setNegativeButton(R.string.cancel_label, null);
+ alertBuilder.show();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void exportLog() {
+ try {
+ File filename = new File(UserPreferences.getDataFolder(null), "full-logs.txt");
+ filename.createNewFile();
+ String cmd = "logcat -d -f " + filename.getAbsolutePath();
+ Runtime.getRuntime().exec(cmd);
+ //share file
try {
- File filename = new File(UserPreferences.getDataFolder(null), "full-logs.txt");
- filename.createNewFile();
- String cmd = "logcat -d -f " + filename.getAbsolutePath();
- Runtime.getRuntime().exec(cmd);
- //share file
- try {
- Intent i = new Intent(Intent.ACTION_SEND);
- i.setType("text/*");
- String authString = getString(de.danoeh.antennapod.core.R.string.provider_authority);
- Uri fileUri = FileProvider.getUriForFile(this, authString, filename);
- i.putExtra(Intent.EXTRA_STREAM, fileUri);
- i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
- PackageManager pm = getPackageManager();
- List<ResolveInfo> resInfos = pm.queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
- for (ResolveInfo resolveInfo : resInfos) {
- String packageName = resolveInfo.activityInfo.packageName;
- grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
- }
+ Intent i = new Intent(Intent.ACTION_SEND);
+ i.setType("text/*");
+ String authString = getString(de.danoeh.antennapod.core.R.string.provider_authority);
+ Uri fileUri = FileProvider.getUriForFile(this, authString, filename);
+ i.putExtra(Intent.EXTRA_STREAM, fileUri);
+ i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
+ PackageManager pm = getPackageManager();
+ List<ResolveInfo> resInfos = pm.queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
+ for (ResolveInfo resolveInfo : resInfos) {
+ String packageName = resolveInfo.activityInfo.packageName;
+ grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
- String chooserTitle = getString(de.danoeh.antennapod.core.R.string.share_file_label);
- startActivity(Intent.createChooser(i, chooserTitle));
- } catch (Exception e) {
- e.printStackTrace();
- int strResId = R.string.log_file_share_exception;
- Snackbar.make(findViewById(android.R.id.content), strResId, Snackbar.LENGTH_LONG)
- .show();
}
- } catch (IOException e) {
+ String chooserTitle = getString(de.danoeh.antennapod.core.R.string.share_file_label);
+ startActivity(Intent.createChooser(i, chooserTitle));
+ } catch (Exception e) {
e.printStackTrace();
- Snackbar.make(findViewById(android.R.id.content), e.getMessage(), Snackbar.LENGTH_LONG).show();
+ int strResId = R.string.log_file_share_exception;
+ Snackbar.make(findViewById(android.R.id.content), strResId, Snackbar.LENGTH_LONG)
+ .show();
}
- });
+ } catch (IOException e) {
+ e.printStackTrace();
+ Snackbar.make(findViewById(android.R.id.content), e.getMessage(), Snackbar.LENGTH_LONG).show();
+ }
}
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
index 1d3d9bf11..4900f0e27 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
@@ -1,62 +1,54 @@
package de.danoeh.antennapod.activity;
import android.app.Activity;
-import android.content.Intent;
import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AppCompatActivity;
-import android.widget.Button;
+import android.text.TextUtils;
import android.widget.EditText;
import android.widget.TextView;
-
-import org.apache.commons.lang3.Validate;
-
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.feed.FeedPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadRequest;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
+import io.reactivex.Completable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+import org.apache.commons.lang3.Validate;
+
/**
* Shows a username and a password text field.
* The activity MUST be started with the ARG_DOWNlOAD_REQUEST argument set to a non-null value.
- * Other arguments are optional.
- * The activity's result will be the same DownloadRequest with the entered username and password.
*/
public class DownloadAuthenticationActivity extends AppCompatActivity {
/**
- * The download request object that contains information about the resource that requires a username and a password
+ * The download request object that contains information about the resource that requires a username and a password.
*/
public static final String ARG_DOWNLOAD_REQUEST = "request";
- /**
- * True if the request should be sent to the DownloadRequester when this activity is finished, false otherwise.
- * The default value is false.
- */
- public static final String ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL = "send_to_downloadrequester";
-
- private static final String RESULT_REQUEST = "request";
private EditText etxtUsername;
private EditText etxtPassword;
+ private DownloadRequest request;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getNoTitleTheme());
super.onCreate(savedInstanceState);
-
setContentView(R.layout.download_authentication_activity);
- TextView txtvDescription = findViewById(R.id.txtvDescription);
+
etxtUsername = findViewById(R.id.etxtUsername);
etxtPassword = findViewById(R.id.etxtPassword);
- Button butConfirm = findViewById(R.id.butConfirm);
- Button butCancel = findViewById(R.id.butCancel);
Validate.isTrue(getIntent().hasExtra(ARG_DOWNLOAD_REQUEST), "Download request missing");
- DownloadRequest request = getIntent().getParcelableExtra(ARG_DOWNLOAD_REQUEST);
- boolean sendToDownloadRequester = getIntent().getBooleanExtra(ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL, false);
+ request = getIntent().getParcelableExtra(ARG_DOWNLOAD_REQUEST);
+ TextView txtvDescription = findViewById(R.id.txtvDescription);
String newDescription = txtvDescription.getText() + ":\n\n" + request.getTitle();
txtvDescription.setText(newDescription);
@@ -65,28 +57,42 @@ public class DownloadAuthenticationActivity extends AppCompatActivity {
etxtPassword.setText(savedInstanceState.getString("password"));
}
- butConfirm.setOnClickListener(v -> {
- String username = etxtUsername.getText().toString();
- String password = etxtPassword.getText().toString();
- request.setUsername(username);
- request.setPassword(password);
- Intent result = new Intent();
- result.putExtra(RESULT_REQUEST, request);
- setResult(Activity.RESULT_OK, result);
-
- if (sendToDownloadRequester) {
- DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request);
- }
- finish();
- });
+ findViewById(R.id.butConfirm).setOnClickListener(v ->
+ Completable.fromAction(this::updatePassword)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(() -> {
+ DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request);
+ finish();
+ }));
- butCancel.setOnClickListener(v -> {
+ findViewById(R.id.butCancel).setOnClickListener(v -> {
setResult(Activity.RESULT_CANCELED);
finish();
});
}
+ private void updatePassword() {
+ String username = etxtUsername.getText().toString();
+ String password = etxtPassword.getText().toString();
+ request.setUsername(username);
+ request.setPassword(password);
+
+ if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
+ long mediaId = request.getFeedfileId();
+ FeedMedia media = DBReader.getFeedMedia(mediaId);
+ if (media != null) {
+ FeedPreferences preferences = media.getItem().getFeed().getPreferences();
+ if (TextUtils.isEmpty(preferences.getPassword()) || TextUtils.isEmpty(preferences.getUsername())) {
+ preferences.setUsername(username);
+ preferences.setPassword(password);
+ DBWriter.setFeedPreferences(preferences);
+ }
+ }
+ }
+ }
+
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
index d39edb9b2..d1716e009 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -16,6 +16,7 @@ import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -542,6 +543,11 @@ public class MainActivity extends CastEnabledActivity {
//Hardware keyboard support
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
+ View currentFocus = getCurrentFocus();
+ if (currentFocus instanceof EditText) {
+ return super.onKeyUp(keyCode, event);
+ }
+
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
Integer customKeyCode = null;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
index b03d1e5cd..c1d921f8c 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -1,10 +1,9 @@
package de.danoeh.antennapod.activity;
-import android.Manifest;
+
import android.annotation.TargetApi;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
@@ -17,7 +16,6 @@ import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
-import android.widget.Toast;
import com.bumptech.glide.Glide;
@@ -28,18 +26,13 @@ import org.greenrobot.eventbus.ThreadMode;
import java.text.NumberFormat;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
-import androidx.core.content.ContextCompat;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
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.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -51,11 +44,9 @@ import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.core.util.TimeSpeedConverter;
import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
-import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.MediaPlayerError;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
-import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
import de.danoeh.antennapod.dialog.PlaybackControlsDialog;
import de.danoeh.antennapod.dialog.ShareDialog;
import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
@@ -74,8 +65,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
private static final String TAG = "MediaplayerActivity";
private static final String PREFS = "MediaPlayerActivityPreferences";
private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft";
- private static final int REQUEST_CODE_STORAGE_PLAY_VIDEO = 42;
- private static final int REQUEST_CODE_STORAGE_PLAY_AUDIO = 43;
PlaybackController controller;
@@ -664,50 +653,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
- void playExternalMedia(Intent intent, MediaType type) {
- if (intent == null || intent.getData() == null) {
- return;
- }
- if (Build.VERSION.SDK_INT >= 23
- && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
- != PackageManager.PERMISSION_GRANTED) {
-
- if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
- Toast.makeText(this, R.string.needs_storage_permission, Toast.LENGTH_LONG).show();
- }
-
- int code = REQUEST_CODE_STORAGE_PLAY_AUDIO;
- if (type == MediaType.VIDEO) {
- code = REQUEST_CODE_STORAGE_PLAY_VIDEO;
- }
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, code);
- return;
- }
-
- Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath());
- ExternalMedia media = new ExternalMedia(intent.getData().getPath(), type);
-
- new PlaybackServiceStarter(this, media)
- .callEvenIfRunning(true)
- .startWhenPrepared(true)
- .shouldStream(false)
- .prepareImmediately(true)
- .start();
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- if (requestCode == REQUEST_CODE_STORAGE_PLAY_AUDIO) {
- playExternalMedia(getIntent(), MediaType.AUDIO);
- } else if (requestCode == REQUEST_CODE_STORAGE_PLAY_VIDEO) {
- playExternalMedia(getIntent(), MediaType.VIDEO);
- }
- } else {
- Toast.makeText(this, R.string.needs_storage_permission, Toast.LENGTH_LONG).show();
- }
- }
-
@Nullable
private static FeedItem getFeedItem(@Nullable Playable playable) {
if (playable instanceof FeedMedia) {
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 2fd537159..f53c629b9 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -4,6 +4,7 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.graphics.LightingColorFilter;
import android.os.Build;
import android.os.Bundle;
@@ -13,7 +14,6 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
-import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
@@ -88,6 +88,9 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
// Optional argument: specify a title for the actionbar.
private static final int RESULT_ERROR = 2;
private static final String TAG = "OnlineFeedViewActivity";
+ private static final String PREFS = "OnlineFeedViewActivityPreferences";
+ private static final String PREF_LAST_AUTO_DOWNLOAD = "lastAutoDownload";
+
private volatile List<Feed> feeds;
private Feed feed;
private String selectedDownloadUrl;
@@ -446,6 +449,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
IntentUtils.sendLocalBroadcast(this, PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE);
});
+ if (UserPreferences.isEnableAutodownload()) {
+ SharedPreferences preferences = getSharedPreferences(PREFS, MODE_PRIVATE);
+ viewBinding.autoDownloadCheckBox.setChecked(preferences.getBoolean(PREF_LAST_AUTO_DOWNLOAD, true));
+ }
+
final int MAX_LINES_COLLAPSED = 10;
description.setMaxLines(MAX_LINES_COLLAPSED);
description.setOnClickListener(v -> {
@@ -512,10 +520,17 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
if (didPressSubscribe) {
didPressSubscribe = false;
if (UserPreferences.isEnableAutodownload()) {
+ boolean autoDownload = viewBinding.autoDownloadCheckBox.isChecked();
+
Feed feed1 = DBReader.getFeed(getFeedId(feed));
FeedPreferences feedPreferences = feed1.getPreferences();
- feedPreferences.setAutoDownload(viewBinding.autoDownloadCheckBox.isChecked());
+ feedPreferences.setAutoDownload(autoDownload);
feed1.savePreferences();
+
+ SharedPreferences preferences = getSharedPreferences(PREFS, MODE_PRIVATE);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putBoolean(PREF_LAST_AUTO_DOWNLOAD, autoDownload);
+ editor.apply();
}
openFeed();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
index 10292b892..d4e9ee5d9 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
@@ -17,9 +17,8 @@ import de.danoeh.antennapod.asynctask.OpmlFeedQueuer;
import de.danoeh.antennapod.asynctask.OpmlImportWorker;
import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.util.LangUtils;
+
import org.apache.commons.io.ByteOrderMark;
-import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.lang3.ArrayUtils;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
index d85235cf9..f0c76d545 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
@@ -13,9 +13,9 @@ import android.widget.ProgressBar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.error.CrashReportWriter;
import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
@@ -44,13 +44,15 @@ public class SplashActivity extends AppCompatActivity {
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(() -> {
- Intent intent = new Intent(SplashActivity.this, MainActivity.class);
- startActivity(intent);
- overridePendingTransition(0, 0);
- finish();
- }, error -> {
+ .subscribe(
+ () -> {
+ Intent intent = new Intent(SplashActivity.this, MainActivity.class);
+ startActivity(intent);
+ overridePendingTransition(0, 0);
+ finish();
+ }, error -> {
error.printStackTrace();
+ CrashReportWriter.write(error);
Toast.makeText(this, error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
finish();
});
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
index 2d4510e8f..75198c016 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -12,12 +12,11 @@ import android.view.KeyEvent;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
+import android.widget.EditText;
import android.widget.ImageView;
-import androidx.appcompat.view.menu.ActionMenuItem;
import androidx.core.view.WindowCompat;
import androidx.appcompat.app.ActionBar;
-import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.Menu;
@@ -37,7 +36,6 @@ import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicBoolean;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
@@ -88,9 +86,7 @@ public class VideoplayerActivity extends MediaplayerActivity {
@Override
protected void onResume() {
super.onResume();
- if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
- playExternalMedia(getIntent(), MediaType.VIDEO);
- } else if (PlaybackService.isCasting()) {
+ if (PlaybackService.isCasting()) {
Intent intent = PlaybackService.getPlayerActivityIntent(this);
if (!intent.getComponent().getClassName().equals(VideoplayerActivity.class.getName())) {
destroyingDueToReload = true;
@@ -489,6 +485,11 @@ public class VideoplayerActivity extends MediaplayerActivity {
//Hardware keyboard support
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
+ View currentFocus = getCurrentFocus();
+ if (currentFocus instanceof EditText) {
+ return super.onKeyUp(keyCode, event);
+ }
+
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
switch (keyCode) {
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java
index 474b96c38..1b4e8b81e 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java
@@ -2,22 +2,19 @@ package de.danoeh.antennapod.activity;
import android.Manifest;
import android.app.WallpaperManager;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.widget.ImageView;
-import android.widget.RemoteViews;
-import androidx.appcompat.app.AppCompatActivity;
-
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.Bundle;
import android.view.View;
-import android.widget.RelativeLayout;
+import android.widget.CheckBox;
+import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
-
+import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
@@ -29,7 +26,10 @@ public class WidgetConfigActivity extends AppCompatActivity {
private SeekBar opacitySeekBar;
private TextView opacityTextView;
- private RelativeLayout widgetPreview;
+ private View widgetPreview;
+ private CheckBox ckRewind;
+ private CheckBox ckFastForward;
+ private CheckBox ckSkip;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -74,6 +74,32 @@ public class WidgetConfigActivity extends AppCompatActivity {
}
});
+
+ widgetPreview.findViewById(R.id.txtNoPlaying).setVisibility(View.GONE);
+ TextView title = widgetPreview.findViewById(R.id.txtvTitle);
+ title.setVisibility(View.VISIBLE);
+ title.setText(R.string.app_name);
+ TextView progress = widgetPreview.findViewById(R.id.txtvProgress);
+ progress.setVisibility(View.VISIBLE);
+ progress.setText(R.string.position_default_label);
+
+ ckRewind = findViewById(R.id.ckRewind);
+ ckRewind.setOnClickListener(v -> displayPreviewPanel());
+ ckFastForward = findViewById(R.id.ckFastForward);
+ ckFastForward.setOnClickListener(v -> displayPreviewPanel());
+ ckSkip = findViewById(R.id.ckSkip);
+ ckSkip.setOnClickListener(v -> displayPreviewPanel());
+ }
+
+ private void displayPreviewPanel() {
+ boolean showExtendedPreview = ckRewind.isChecked() || ckFastForward.isChecked() || ckSkip.isChecked();
+ widgetPreview.findViewById(R.id.extendedButtonsContainer)
+ .setVisibility(showExtendedPreview ? View.VISIBLE : View.GONE);
+ widgetPreview.findViewById(R.id.butPlay).setVisibility(showExtendedPreview ? View.GONE : View.VISIBLE);
+ widgetPreview.findViewById(R.id.butFastForward)
+ .setVisibility(ckFastForward.isChecked() ? View.VISIBLE : View.GONE);
+ widgetPreview.findViewById(R.id.butSkip).setVisibility(ckSkip.isChecked() ? View.VISIBLE : View.GONE);
+ widgetPreview.findViewById(R.id.butRew).setVisibility(ckRewind.isChecked() ? View.VISIBLE : View.GONE);
}
private void displayDeviceBackground() {
@@ -92,6 +118,9 @@ public class WidgetConfigActivity extends AppCompatActivity {
SharedPreferences prefs = getSharedPreferences(PlayerWidget.PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(PlayerWidget.KEY_WIDGET_COLOR + appWidgetId, backgroundColor);
+ editor.putBoolean(PlayerWidget.KEY_WIDGET_SKIP + appWidgetId, ckSkip.isChecked());
+ editor.putBoolean(PlayerWidget.KEY_WIDGET_REWIND + appWidgetId, ckRewind.isChecked());
+ editor.putBoolean(PlayerWidget.KEY_WIDGET_FAST_FORWARD + appWidgetId, ckFastForward.isChecked());
editor.apply();
Intent resultValue = new Intent();
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
deleted file mode 100644
index cfd6ec702..000000000
--- a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
+++ /dev/null
@@ -1,395 +0,0 @@
-package de.danoeh.antennapod.activity.gpoddernet;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import androidx.appcompat.app.AppCompatActivity;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ProgressBar;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.ViewFlipper;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import de.danoeh.antennapod.BuildConfig;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
-import de.danoeh.antennapod.core.sync.SyncService;
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetService;
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetServiceException;
-import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetDevice;
-
-/**
- * Guides the user through the authentication process
- * Step 1: Request username and password from user
- * Step 2: Choose device from a list of available devices or create a new one
- * Step 3: Choose from a list of actions
- */
-public class GpodnetAuthenticationActivity extends AppCompatActivity {
- private static final String TAG = "GpodnetAuthActivity";
-
- private ViewFlipper viewFlipper;
-
- private static final int STEP_DEFAULT = -1;
- private static final int STEP_LOGIN = 0;
- private static final int STEP_DEVICE = 1;
- private static final int STEP_FINISH = 2;
-
- private int currentStep = -1;
-
- private GpodnetService service;
- private volatile String username;
- private volatile String password;
- private volatile GpodnetDevice selectedDevice;
-
- private View[] views;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setTheme(UserPreferences.getTheme());
- super.onCreate(savedInstanceState);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
- setContentView(R.layout.gpodnetauth_activity);
- service = new GpodnetService(AntennapodHttpClient.getHttpClient(), GpodnetPreferences.getHostname());
-
- viewFlipper = findViewById(R.id.viewflipper);
- LayoutInflater inflater = (LayoutInflater)
- getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- views = new View[]{
- inflater.inflate(R.layout.gpodnetauth_credentials, viewFlipper, false),
- inflater.inflate(R.layout.gpodnetauth_device, viewFlipper, false),
- inflater.inflate(R.layout.gpodnetauth_finish, viewFlipper, false)
- };
- for (View view : views) {
- viewFlipper.addView(view);
- }
- advance();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == android.R.id.home) {
- finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void setupLoginView(View view) {
- final EditText username = view.findViewById(R.id.etxtUsername);
- final EditText password = view.findViewById(R.id.etxtPassword);
- final Button login = view.findViewById(R.id.butLogin);
- final TextView txtvError = view.findViewById(R.id.txtvError);
- final ProgressBar progressBar = view.findViewById(R.id.progBarLogin);
-
- password.setOnEditorActionListener((v, actionID, event) ->
- actionID == EditorInfo.IME_ACTION_GO && login.performClick());
-
- login.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
-
- final String usernameStr = username.getText().toString();
- final String passwordStr = password.getText().toString();
-
- if (usernameHasUnwantedChars(usernameStr)) {
- txtvError.setText(R.string.gpodnetsync_username_characters_error);
- txtvError.setVisibility(View.VISIBLE);
- return;
- }
- if (BuildConfig.DEBUG) Log.d(TAG, "Checking login credentials");
- AsyncTask<GpodnetService, Void, Void> authTask = new AsyncTask<GpodnetService, Void, Void>() {
-
- volatile Exception exception;
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- login.setEnabled(false);
- progressBar.setVisibility(View.VISIBLE);
- txtvError.setVisibility(View.GONE);
- // hide the keyboard
- InputMethodManager inputManager = (InputMethodManager)
- getSystemService(Context.INPUT_METHOD_SERVICE);
- inputManager.hideSoftInputFromWindow(login.getWindowToken(),
- InputMethodManager.HIDE_NOT_ALWAYS);
-
- }
-
- @Override
- protected void onPostExecute(Void aVoid) {
- super.onPostExecute(aVoid);
- login.setEnabled(true);
- progressBar.setVisibility(View.GONE);
-
- if (exception == null) {
- advance();
- } else {
- txtvError.setText(exception.getCause().getMessage());
- txtvError.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- protected Void doInBackground(GpodnetService... params) {
- try {
- params[0].authenticate(usernameStr, passwordStr);
- GpodnetAuthenticationActivity.this.username = usernameStr;
- GpodnetAuthenticationActivity.this.password = passwordStr;
- } catch (GpodnetServiceException e) {
- e.printStackTrace();
- exception = e;
- }
- return null;
- }
- };
- authTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, service);
- }
- });
- }
-
- private void setupDeviceView(View view) {
- final EditText deviceID = view.findViewById(R.id.etxtDeviceID);
- final EditText caption = view.findViewById(R.id.etxtCaption);
- final Button createNewDevice = view.findViewById(R.id.butCreateNewDevice);
- final Button chooseDevice = view.findViewById(R.id.butChooseExistingDevice);
- final TextView txtvError = view.findViewById(R.id.txtvError);
- final ProgressBar progBarCreateDevice = view.findViewById(R.id.progbarCreateDevice);
- final Spinner spinnerDevices = view.findViewById(R.id.spinnerChooseDevice);
-
-
- // load device list
- final AtomicReference<List<GpodnetDevice>> devices = new AtomicReference<>();
- new AsyncTask<GpodnetService, Void, List<GpodnetDevice>>() {
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- chooseDevice.setEnabled(false);
- spinnerDevices.setEnabled(false);
- createNewDevice.setEnabled(false);
- }
-
- @Override
- protected void onPostExecute(List<GpodnetDevice> gpodnetDevices) {
- super.onPostExecute(gpodnetDevices);
- if (gpodnetDevices != null) {
- List<String> deviceNames = new ArrayList<>();
- for (GpodnetDevice device : gpodnetDevices) {
- deviceNames.add(device.getCaption());
- }
- spinnerDevices.setAdapter(new ArrayAdapter<>(GpodnetAuthenticationActivity.this,
- android.R.layout.simple_spinner_dropdown_item, deviceNames));
- spinnerDevices.setEnabled(true);
- if (!deviceNames.isEmpty()) {
- chooseDevice.setEnabled(true);
- }
- devices.set(gpodnetDevices);
- deviceID.setText(generateDeviceID(gpodnetDevices));
- createNewDevice.setEnabled(true);
- }
- }
-
- @Override
- protected List<GpodnetDevice> doInBackground(GpodnetService... params) {
- try {
- return params[0].getDevices();
- } catch (GpodnetServiceException e) {
- e.printStackTrace();
- return null;
- }
- }
- }.execute(service);
-
-
- createNewDevice.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (checkDeviceIDText(deviceID, caption, txtvError, devices.get())) {
- final String deviceStr = deviceID.getText().toString();
- final String captionStr = caption.getText().toString();
-
- new AsyncTask<GpodnetService, Void, GpodnetDevice>() {
-
- private volatile Exception exception;
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- createNewDevice.setEnabled(false);
- chooseDevice.setEnabled(false);
- progBarCreateDevice.setVisibility(View.VISIBLE);
- txtvError.setVisibility(View.GONE);
- }
-
- @Override
- protected void onPostExecute(GpodnetDevice result) {
- super.onPostExecute(result);
- createNewDevice.setEnabled(true);
- chooseDevice.setEnabled(true);
- progBarCreateDevice.setVisibility(View.GONE);
- if (exception == null) {
- selectedDevice = result;
- advance();
- } else {
- txtvError.setText(exception.getMessage());
- txtvError.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- protected GpodnetDevice doInBackground(GpodnetService... params) {
- try {
- params[0].configureDevice(deviceStr, captionStr, GpodnetDevice.DeviceType.MOBILE);
- return new GpodnetDevice(deviceStr, captionStr, GpodnetDevice.DeviceType.MOBILE.toString(), 0);
- } catch (GpodnetServiceException e) {
- e.printStackTrace();
- exception = e;
- }
- return null;
- }
- }.execute(service);
- }
- }
- });
-
- chooseDevice.setOnClickListener(v -> {
- final int position = spinnerDevices.getSelectedItemPosition();
- if (position != AdapterView.INVALID_POSITION) {
- selectedDevice = devices.get().get(position);
- advance();
- }
- });
- }
-
-
- private String generateDeviceID(List<GpodnetDevice> gpodnetDevices) {
- // devices names must be of a certain form:
- // https://gpoddernet.readthedocs.org/en/latest/api/reference/general.html#devices
- // This is more restrictive than needed, but I think it makes for more readable names.
- String baseId = Build.MODEL.replaceAll("\\W", "");
- String id = baseId;
- int num = 0;
-
- while (isDeviceWithIdInList(id, gpodnetDevices)) {
- id = baseId + "_" + num;
- num++;
- }
-
- return id;
- }
-
- private boolean isDeviceWithIdInList(String id, List<GpodnetDevice> gpodnetDevices) {
- if (gpodnetDevices == null) {
- return false;
- }
- for (GpodnetDevice device : gpodnetDevices) {
- if (device.getId().equals(id)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean checkDeviceIDText(EditText deviceID, EditText caption, TextView txtvError, List<GpodnetDevice> devices) {
- String text = deviceID.getText().toString();
- if (text.length() == 0) {
- txtvError.setText(R.string.gpodnetauth_device_errorEmpty);
- txtvError.setVisibility(View.VISIBLE);
- return false;
- } else if (caption.length() == 0) {
- txtvError.setText(R.string.gpodnetauth_device_caption_errorEmpty);
- txtvError.setVisibility(View.VISIBLE);
- return false;
- } else {
- if (devices != null) {
- if (isDeviceWithIdInList(text, devices)) {
- txtvError.setText(R.string.gpodnetauth_device_errorAlreadyUsed);
- txtvError.setVisibility(View.VISIBLE);
- return false;
- }
- txtvError.setVisibility(View.GONE);
- return true;
- }
- return true;
- }
-
- }
-
- private void setupFinishView(View view) {
- final Button sync = view.findViewById(R.id.butSyncNow);
- final Button back = view.findViewById(R.id.butGoMainscreen);
-
- sync.setOnClickListener(v -> {
- finish();
- SyncService.sync(getApplicationContext());
- });
- back.setOnClickListener(v -> {
- Intent intent = new Intent(GpodnetAuthenticationActivity.this, MainActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- });
- }
-
- private void writeLoginCredentials() {
- if (BuildConfig.DEBUG) Log.d(TAG, "Writing login credentials");
- GpodnetPreferences.setUsername(username);
- GpodnetPreferences.setPassword(password);
- GpodnetPreferences.setDeviceID(selectedDevice.getId());
- }
-
- private void advance() {
- if (currentStep < STEP_FINISH) {
-
- View view = views[currentStep + 1];
- if (currentStep == STEP_DEFAULT) {
- setupLoginView(view);
- } else if (currentStep == STEP_LOGIN) {
- if (username == null || password == null) {
- throw new IllegalStateException("Username and password must not be null here");
- } else {
- setupDeviceView(view);
- }
- } else if (currentStep == STEP_DEVICE) {
- if (selectedDevice == null) {
- throw new IllegalStateException("Device must not be null here");
- } else {
- writeLoginCredentials();
- setupFinishView(view);
- }
- }
- if (currentStep != STEP_DEFAULT) {
- viewFlipper.showNext();
- }
- currentStep++;
- } else {
- finish();
- }
- }
-
- private boolean usernameHasUnwantedChars(String username) {
- Pattern special = Pattern.compile("[!@#$%&*()+=|<>?{}\\[\\]~]");
- Matcher containsUnwantedChars = special.matcher(username);
- return containsUnwantedChars.find();
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
index 002147071..4fa8acc43 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
@@ -22,12 +22,14 @@ import de.danoeh.antennapod.core.util.EmbeddedChapterImage;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.playback.Playable;
+import de.danoeh.antennapod.view.CircularProgressBar;
public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapter.ChapterHolder> {
private Playable media;
private final Callback callback;
private final Context context;
private int currentChapterIndex = -1;
+ private long currentChapterPosition = -1;
private boolean hasImages = false;
public ChaptersListAdapter(Context context, Callback callback) {
@@ -48,7 +50,6 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
notifyDataSetChanged();
}
-
@Override
public void onBindViewHolder(@NonNull ChapterHolder holder, int position) {
Chapter sc = getItem(position);
@@ -65,7 +66,7 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
holder.duration.setText(context.getString(R.string.chapter_duration,
Converter.getDurationStringLocalized(context, (int) duration)));
- if (sc.getLink() == null) {
+ if (TextUtils.isEmpty(sc.getLink())) {
holder.link.setVisibility(View.GONE);
} else {
holder.link.setVisibility(View.VISIBLE);
@@ -73,6 +74,7 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
holder.link.setOnClickListener(v -> IntentUtils.openInBrowser(context, sc.getLink()));
}
holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.av_play));
+ holder.secondaryActionButton.setContentDescription(context.getString(R.string.play_chapter));
holder.secondaryActionButton.setOnClickListener(v -> {
if (callback != null) {
callback.onPlayChapterButtonClicked(position);
@@ -82,8 +84,14 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
if (position == currentChapterIndex) {
int playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background);
holder.itemView.setBackgroundColor(playingBackGroundColor);
+ float progress = ((float) (currentChapterPosition - sc.getStart())) / duration;
+ progress = Math.max(progress, CircularProgressBar.MINIMUM_PERCENTAGE);
+ progress = Math.min(progress, CircularProgressBar.MAXIMUM_PERCENTAGE);
+ holder.progressBar.setPercentage(progress, position);
+ holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.av_replay));
} else {
holder.itemView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent));
+ holder.progressBar.setPercentage(0, null);
}
if (hasImages) {
@@ -135,6 +143,7 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
final ImageView image;
final View secondaryActionButton;
final ImageView secondaryActionIcon;
+ final CircularProgressBar progressBar;
public ChapterHolder(@NonNull View itemView) {
super(itemView);
@@ -145,14 +154,23 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
duration = itemView.findViewById(R.id.txtvDuration);
secondaryActionButton = itemView.findViewById(R.id.secondaryActionButton);
secondaryActionIcon = itemView.findViewById(R.id.secondaryActionIcon);
+ progressBar = itemView.findViewById(R.id.secondaryActionProgress);
}
}
public void notifyChapterChanged(int newChapterIndex) {
currentChapterIndex = newChapterIndex;
+ currentChapterPosition = getItem(newChapterIndex).getStart();
notifyDataSetChanged();
}
+ public void notifyTimeChanged(long timeMs) {
+ currentChapterPosition = timeMs;
+ // Passing an argument prevents flickering.
+ // See EpisodeItemListAdapter.notifyItemChangedCompat.
+ notifyItemChanged(currentChapterIndex, "foo");
+ }
+
private boolean ignoreChapter(Chapter c) {
return media.getDuration() > 0 && media.getDuration() < c.getStart();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
index 7d195a9ad..0c4aaf6ed 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
@@ -1,23 +1,15 @@
package de.danoeh.antennapod.adapter;
import android.app.Activity;
-import android.content.Context;
-import android.os.Build;
-import android.text.Layout;
import android.text.format.DateUtils;
import android.util.Log;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
-import android.widget.TextView;
import android.widget.Toast;
import androidx.core.content.ContextCompat;
-import com.joanzapata.iconify.widget.IconButton;
-import com.joanzapata.iconify.widget.IconTextView;
-
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java
index 540cd054c..268a21409 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java
@@ -65,6 +65,7 @@ public class DownloadlistAdapter extends BaseAdapter {
holder.title.setText(request.getTitle());
holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.navigation_cancel));
+ holder.secondaryActionButton.setContentDescription(context.getString(R.string.cancel_download_label));
holder.secondaryActionButton.setTag(downloader);
holder.secondaryActionButton.setOnClickListener(butSecondaryListener);
holder.secondaryActionProgress.setPercentage(0, request);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
index 6bfd34d5c..8cb0fd30a 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
@@ -13,8 +13,6 @@ import androidx.annotation.Nullable;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.MediaType;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
-import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.playback.RemoteMedia;
import de.danoeh.antennapod.core.feed.FeedItem;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
index 92ed7b052..f8507ba74 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -75,7 +75,7 @@ public class NavListAdapter extends BaseAdapter
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS)) {
+ if (UserPreferences.PREF_HIDDEN_DRAWER_ITEMS.equals(key)) {
loadItems();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
index 7ce086694..01712ea29 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
@@ -6,7 +6,6 @@ import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.View;
-import androidx.core.view.MotionEventCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
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 8c294a9c9..919a4e217 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
@@ -13,8 +13,6 @@ import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
-import com.bumptech.glide.Glide;
-
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
import java.util.Locale;
@@ -23,7 +21,6 @@ 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;
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
index 31dfe15da..78ea3b93f 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java
@@ -7,11 +7,8 @@ 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 {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java
index 7b8659968..e45280eed 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java
@@ -1,8 +1,6 @@
package de.danoeh.antennapod.adapter.actionbutton;
import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
import android.view.View;
import androidx.annotation.AttrRes;
import androidx.annotation.StringRes;
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java
index 3ac05e842..906d50c61 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java
@@ -9,10 +9,10 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
import de.danoeh.antennapod.core.export.ExportWriter;
import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.util.LangUtils;
import io.reactivex.Observable;
/**
@@ -44,7 +44,7 @@ public class DocumentFileExportWorker {
if (outputStream == null) {
throw new IOException();
}
- writer = new OutputStreamWriter(outputStream, LangUtils.UTF_8);
+ writer = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
exportWriter.writeDocument(DBReader.getFeedList(), writer, context);
subscriber.onNext(output);
} catch (IOException e) {
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
index f81a52402..0930b59eb 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
@@ -8,11 +8,11 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
import de.danoeh.antennapod.core.export.ExportWriter;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.util.LangUtils;
import io.reactivex.Observable;
/**
@@ -47,7 +47,7 @@ public class ExportWorker {
return Observable.create(subscriber -> {
OutputStreamWriter writer = null;
try {
- writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8);
+ writer = new OutputStreamWriter(new FileOutputStream(output), Charset.forName("UTF-8"));
exportWriter.writeDocument(DBReader.getFeedList(), writer, context);
subscriber.onNext(output);
} catch (IOException e) {
diff --git a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
index 6e584d34f..7a5cf431f 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.config;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.core.ClientConfig;
+import de.danoeh.antennapod.core.storage.APDownloadAlgorithm;
/**
* Configures the ClientConfig class of the core package.
@@ -15,7 +16,7 @@ class ClientConfigurator {
ClientConfig.applicationCallbacks = new ApplicationCallbacksImpl();
ClientConfig.downloadServiceCallbacks = new DownloadServiceCallbacksImpl();
ClientConfig.playbackServiceCallbacks = new PlaybackServiceCallbacksImpl();
- ClientConfig.dbTasksCallbacks = new DBTasksCallbacksImpl();
+ ClientConfig.automaticDownloadAlgorithm = new APDownloadAlgorithm();
ClientConfig.castCallbacks = new CastCallbackImpl();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java
deleted file mode 100644
index c3f7ae9c8..000000000
--- a/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.danoeh.antennapod.config;
-
-import de.danoeh.antennapod.core.DBTasksCallbacks;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.APDownloadAlgorithm;
-import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm;
-import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
-
-public class DBTasksCallbacksImpl implements DBTasksCallbacks {
-
- @Override
- public AutomaticDownloadAlgorithm getAutomaticDownloadAlgorithm() {
- return new APDownloadAlgorithm();
- }
-
- @Override
- public EpisodeCleanupAlgorithm getEpisodeCacheCleanupAlgorithm() {
- return UserPreferences.getEpisodeCleanupAlgorithm();
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
index 71442f50b..f509f6dd4 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
@@ -31,7 +31,6 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
public PendingIntent getAuthentificationNotificationContentIntent(Context context, DownloadRequest request) {
final Intent activityIntent = new Intent(context.getApplicationContext(), DownloadAuthenticationActivity.class);
activityIntent.putExtra(DownloadAuthenticationActivity.ARG_DOWNLOAD_REQUEST, request);
- activityIntent.putExtra(DownloadAuthenticationActivity.ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL, true);
return PendingIntent.getActivity(context.getApplicationContext(),
R.id.pending_intent_download_service_auth, activityIntent, PendingIntent.FLAG_ONE_SHOT);
}
@@ -54,9 +53,4 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
return PendingIntent.getActivity(context, R.id.pending_intent_download_service_autodownload_report,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
-
- @Override
- public boolean shouldCreateReport() {
- return true;
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
index 44f18e9da..f70cb26ff 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
@@ -3,7 +3,6 @@ package de.danoeh.antennapod.config;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
-import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.VideoplayerActivity;
import de.danoeh.antennapod.core.PlaybackServiceCallbacks;
@@ -22,10 +21,4 @@ public class PlaybackServiceCallbacksImpl implements PlaybackServiceCallbacks {
return i;
}
}
-
- @Override
- public boolean useQueue() {
- return true;
- }
-
}
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 5aee3f2be..efaff1da3 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -436,13 +436,18 @@ public class EpisodesApplyActionFragment extends Fragment implements Toolbar.OnM
}
private void deleteChecked() {
+ int countHasMedia = 0;
+ int countNoMedia = 0;
for (long id : checkedIds.toArray()) {
FeedItem episode = idMap.get(id);
- if (episode.hasMedia()) {
+ if (episode.hasMedia() && episode.getMedia().isDownloaded()) {
+ countHasMedia++;
DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
+ } else {
+ countNoMedia++;
}
}
- close(R.plurals.deleted_episode_batch_label, checkedIds.size());
+ closeMore(R.plurals.deleted_multi_episode_batch_label, countNoMedia, countHasMedia);
}
private void close(@PluralsRes int msgId, int numItems) {
@@ -451,4 +456,12 @@ public class EpisodesApplyActionFragment extends Fragment implements Toolbar.OnM
getActivity().getSupportFragmentManager().popBackStack();
}
+ private void closeMore(@PluralsRes int msgId, int countNoMedia, int countHasMedia) {
+ ((MainActivity) getActivity()).showSnackbarAbovePlayer(
+ getResources().getQuantityString(msgId,
+ (countHasMedia + countNoMedia),
+ (countHasMedia + countNoMedia), countHasMedia),
+ Snackbar.LENGTH_LONG);
+ getActivity().getSupportFragmentManager().popBackStack();
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
index 82010637f..80df87891 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.dialog;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
+import android.view.View;
import android.widget.LinearLayout;
import android.widget.RadioButton;
@@ -34,18 +35,19 @@ public abstract class FilterDialog {
builder.setTitle(R.string.filter);
LayoutInflater inflater = LayoutInflater.from(this.context);
- LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.filter_dialog, null, false);
+ View layout = inflater.inflate(R.layout.filter_dialog, null, false);
+ LinearLayout rows = layout.findViewById(R.id.filter_rows);
builder.setView(layout);
for (FeedItemFilterGroup item : FeedItemFilterGroup.values()) {
- RecursiveRadioGroup row = (RecursiveRadioGroup) inflater.inflate(R.layout.filter_dialog_row, null);
+ RecursiveRadioGroup row = (RecursiveRadioGroup) inflater.inflate(R.layout.filter_dialog_row, null, false);
RadioButton filter1 = row.findViewById(R.id.filter_dialog_radioButton1);
RadioButton filter2 = row.findViewById(R.id.filter_dialog_radioButton2);
filter1.setText(item.values[0].displayName);
filter1.setTag(item.values[0].filterId);
filter2.setText(item.values[1].displayName);
filter2.setTag(item.values[1].filterId);
- layout.addView(row);
+ rows.addView(row);
}
for (String filterId : filterValues) {
@@ -56,11 +58,11 @@ public abstract class FilterDialog {
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
filterValues.clear();
- for (int i = 0; i < layout.getChildCount(); i++) {
- if (!(layout.getChildAt(i) instanceof RecursiveRadioGroup)) {
+ for (int i = 0; i < rows.getChildCount(); i++) {
+ if (!(rows.getChildAt(i) instanceof RecursiveRadioGroup)) {
continue;
}
- RecursiveRadioGroup group = (RecursiveRadioGroup) layout.getChildAt(i);
+ RecursiveRadioGroup group = (RecursiveRadioGroup) rows.getChildAt(i);
if (group.getCheckedButton() != null) {
String tag = (String) group.getCheckedButton().getTag();
if (tag != null) { // Clear buttons use no tag
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java
deleted file mode 100644
index 8119dffcb..000000000
--- a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package de.danoeh.antennapod.dialog;
-
-import android.content.Context;
-import androidx.appcompat.app.AlertDialog;
-import android.text.Editable;
-import android.text.InputType;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetService;
-
-/**
- * Creates a dialog that lets the user change the hostname for the gpodder.net service.
- */
-public class GpodnetSetHostnameDialog {
-
- private GpodnetSetHostnameDialog(){}
-
- private static final String TAG = "GpodnetSetHostnameDialog";
-
- public static AlertDialog createDialog(final Context context) {
- AlertDialog.Builder dialog = new AlertDialog.Builder(context);
- final EditText et = new EditText(context);
- et.setText(GpodnetPreferences.getHostname());
- et.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
- dialog.setTitle(R.string.pref_gpodnet_sethostname_title)
- .setView(setupContentView(context, et))
- .setPositiveButton(R.string.confirm_label, (dialog1, which) -> {
- final Editable e = et.getText();
- if (e != null) {
- GpodnetPreferences.setHostname(e.toString());
- }
- dialog1.dismiss();
- })
- .setNegativeButton(R.string.cancel_label, (dialog1, which) -> dialog1.cancel())
- .setNeutralButton(R.string.pref_gpodnet_sethostname_use_default_host, (dialog1, which) -> {
- GpodnetPreferences.setHostname(GpodnetService.DEFAULT_BASE_HOST);
- dialog1.dismiss();
- })
- .setCancelable(true);
- return dialog.show();
- }
-
- private static View setupContentView(Context context, EditText et) {
- LinearLayout ll = new LinearLayout(context);
- ll.addView(et);
- LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) et.getLayoutParams();
- if (params != null) {
- params.setMargins(8, 8, 8, 8);
- params.width = ViewGroup.LayoutParams.MATCH_PARENT;
- params.height = ViewGroup.LayoutParams.MATCH_PARENT;
- }
- return ll;
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java
new file mode 100644
index 000000000..156c1dba8
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java
@@ -0,0 +1,52 @@
+package de.danoeh.antennapod.dialog;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.util.Log;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import io.reactivex.Completable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+public class RemoveFeedDialog {
+ private static final String TAG = "RemoveFeedDialog";
+
+ public static void show(Context context, Feed feed, Runnable onSuccess) {
+ int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
+ : R.string.feed_delete_confirmation_msg;
+ String message = context.getString(messageId, feed.getTitle());
+
+ ConfirmationDialog dialog = new ConfirmationDialog(context, R.string.remove_feed_label, message) {
+ @Override
+ public void onConfirmButtonPressed(DialogInterface clickedDialog) {
+ clickedDialog.dismiss();
+
+ ProgressDialog progressDialog = new ProgressDialog(context);
+ progressDialog.setMessage(context.getString(R.string.feed_remover_msg));
+ progressDialog.setIndeterminate(true);
+ progressDialog.setCancelable(false);
+ progressDialog.show();
+
+ Completable.fromCallable(() -> DBWriter.deleteFeed(context, feed.getId()).get())
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ () -> {
+ Log.d(TAG, "Feed was deleted");
+ if (onSuccess != null) {
+ onSuccess.run();
+ }
+ progressDialog.dismiss();
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ progressDialog.dismiss();
+ });
+ }
+ };
+ dialog.createNewDialog().show();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
index 699c6f492..a4e49ff96 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
@@ -1,16 +1,15 @@
package de.danoeh.antennapod.dialog;
import android.app.Activity;
-import android.text.InputType;
import java.lang.ref.WeakReference;
import android.view.View;
-import android.widget.EditText;
import androidx.appcompat.app.AlertDialog;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.databinding.EditTextDialogBinding;
public class RenameFeedDialog {
@@ -29,13 +28,14 @@ public class RenameFeedDialog {
}
View content = View.inflate(activity, R.layout.edit_text_dialog, null);
- EditText editText = content.findViewById(R.id.text);
- editText.setText(feed.getTitle());
+ EditTextDialogBinding alertViewBinding = EditTextDialogBinding.bind(content);
+
+ alertViewBinding.urlEditText.setText(feed.getTitle());
AlertDialog dialog = new AlertDialog.Builder(activity)
.setView(content)
.setTitle(de.danoeh.antennapod.core.R.string.rename_feed_label)
.setPositiveButton(android.R.string.ok, (d, input) -> {
- feed.setCustomTitle(editText.getText().toString());
+ feed.setCustomTitle(alertViewBinding.urlEditText.getText().toString());
DBWriter.setFeedCustomTitle(feed);
})
.setNeutralButton(de.danoeh.antennapod.core.R.string.reset, null)
@@ -44,7 +44,7 @@ public class RenameFeedDialog {
// To prevent cancelling the dialog on button click
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(
- (view) -> editText.setText(feed.getFeedTitle()));
+ (view) -> alertViewBinding.urlEditText.setText(feed.getFeedTitle()));
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
index 274c3b7bd..f1a41d753 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
@@ -3,7 +3,6 @@ package de.danoeh.antennapod.dialog;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
-import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
@@ -88,6 +87,27 @@ public class SleepTimerDialog extends DialogFragment {
timeSetup = content.findViewById(R.id.timeSetup);
timeDisplay = content.findViewById(R.id.timeDisplay);
time = content.findViewById(R.id.time);
+ Button extendSleepFiveMinutesButton = content.findViewById(R.id.extendSleepFiveMinutesButton);
+ extendSleepFiveMinutesButton.setText(getString(R.string.extend_sleep_timer_label, 5));
+ Button extendSleepTenMinutesButton = content.findViewById(R.id.extendSleepTenMinutesButton);
+ extendSleepTenMinutesButton.setText(getString(R.string.extend_sleep_timer_label, 10));
+ Button extendSleepTwentyMinutesButton = content.findViewById(R.id.extendSleepTwentyMinutesButton);
+ extendSleepTwentyMinutesButton.setText(getString(R.string.extend_sleep_timer_label, 20));
+ extendSleepFiveMinutesButton.setOnClickListener(v -> {
+ if (controller != null) {
+ controller.extendSleepTimer(5 * 1000 * 60);
+ }
+ });
+ extendSleepTenMinutesButton.setOnClickListener(v -> {
+ if (controller != null) {
+ controller.extendSleepTimer(10 * 1000 * 60);
+ }
+ });
+ extendSleepTwentyMinutesButton.setOnClickListener(v -> {
+ if (controller != null) {
+ controller.extendSleepTimer(20 * 1000 * 60);
+ }
+ });
etxtTime.setText(SleepTimerPreferences.lastTimerValue());
etxtTime.postDelayed(() -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java
index a8915480c..8a87fef25 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java
@@ -30,7 +30,8 @@ public class SubscriptionsFilterDialog {
builder.setTitle(context.getString(R.string.pref_filter_feed_title));
LayoutInflater inflater = LayoutInflater.from(context);
- LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.filter_dialog, null, false);
+ View layout = inflater.inflate(R.layout.filter_dialog, null, false);
+ LinearLayout rows = layout.findViewById(R.id.filter_rows);
builder.setView(layout);
for (SubscriptionsFilterGroup item : SubscriptionsFilterGroup.values()) {
@@ -45,7 +46,7 @@ public class SubscriptionsFilterDialog {
} else {
filter2.setVisibility(View.GONE);
}
- layout.addView(row);
+ rows.addView(row);
}
for (String filterId : filterValues) {
@@ -56,11 +57,11 @@ public class SubscriptionsFilterDialog {
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
filterValues.clear();
- for (int i = 0; i < layout.getChildCount(); i++) {
- if (!(layout.getChildAt(i) instanceof RecursiveRadioGroup)) {
+ for (int i = 0; i < rows.getChildCount(); i++) {
+ if (!(rows.getChildAt(i) instanceof RecursiveRadioGroup)) {
continue;
}
- RecursiveRadioGroup group = (RecursiveRadioGroup) layout.getChildAt(i);
+ RecursiveRadioGroup group = (RecursiveRadioGroup) rows.getChildAt(i);
if (group.getCheckedButton() != null) {
String tag = (String) group.getCheckedButton().getTag();
if (tag != null) { // Clear buttons use no tag
diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java
index 796ec556f..6e894176f 100644
--- a/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java
+++ b/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java
@@ -1,7 +1,5 @@
package de.danoeh.antennapod.discovery;
-import android.content.Context;
-import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java
index eeebd2ebf..8fbc8c76b 100644
--- a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java
+++ b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java
@@ -1,8 +1,6 @@
package de.danoeh.antennapod.discovery;
import io.reactivex.Single;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.functions.Consumer;
import java.util.List;
public interface PodcastSearcher {
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 caf489569..06a974dfd 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
@@ -12,7 +12,6 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -30,6 +29,8 @@ import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.util.SortOrder;
+import de.danoeh.antennapod.databinding.AddfeedBinding;
+import de.danoeh.antennapod.databinding.EditTextDialogBinding;
import de.danoeh.antennapod.discovery.CombinedSearcher;
import de.danoeh.antennapod.discovery.FyydPodcastSearcher;
import de.danoeh.antennapod.discovery.ItunesPodcastSearcher;
@@ -50,7 +51,7 @@ public class AddFeedFragment extends Fragment {
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 AddfeedBinding viewBinding;
private MainActivity activity;
@Override
@@ -59,39 +60,43 @@ public class AddFeedFragment extends Fragment {
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
- View root = inflater.inflate(R.layout.addfeed, container, false);
+ viewBinding = AddfeedBinding.inflate(getLayoutInflater());
activity = (MainActivity) getActivity();
- Toolbar toolbar = root.findViewById(R.id.toolbar);
+
+ Toolbar toolbar = viewBinding.toolbar;
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
- root.findViewById(R.id.btn_search_itunes).setOnClickListener(v
+ viewBinding.searchItunesButton.setOnClickListener(v
-> activity.loadChildFragment(OnlineSearchFragment.newInstance(ItunesPodcastSearcher.class)));
- root.findViewById(R.id.btn_search_fyyd).setOnClickListener(v
+ viewBinding.searchFyydButton.setOnClickListener(v
-> activity.loadChildFragment(OnlineSearchFragment.newInstance(FyydPodcastSearcher.class)));
- root.findViewById(R.id.btn_search_gpodder).setOnClickListener(v
+ viewBinding.searchGPodderButton.setOnClickListener(v
-> activity.loadChildFragment(new GpodnetMainFragment()));
- root.findViewById(R.id.btn_search_podcastindex).setOnClickListener(v
+ viewBinding.searchPodcastIndexButton.setOnClickListener(v
-> activity.loadChildFragment(OnlineSearchFragment.newInstance(PodcastIndexPodcastSearcher.class)));
- combinedFeedSearchBox = root.findViewById(R.id.combinedFeedSearchBox);
- combinedFeedSearchBox.setOnEditorActionListener((v, actionId, event) -> {
+ viewBinding.combinedFeedSearchEditText.setOnEditorActionListener((v, actionId, event) -> {
performSearch();
return true;
});
- root.findViewById(R.id.btn_add_via_url).setOnClickListener(v
+
+ viewBinding.addViaUrlButton.setOnClickListener(v
-> showAddViaUrlDialog());
- root.findViewById(R.id.btn_opml_import).setOnClickListener(v -> {
+ viewBinding.opmlImportButton.setOnClickListener(v -> {
try {
Intent intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT);
intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE);
intentGetContentAction.setType("*/*");
startActivityForResult(intentGetContentAction, REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH);
} catch (ActivityNotFoundException e) {
- Log.e(TAG, "No activity found. Should never happen...");
+ e.printStackTrace();
+ ((MainActivity) getActivity())
+ .showSnackbarAbovePlayer(R.string.unable_to_start_system_file_manager, Snackbar.LENGTH_LONG);
}
});
- root.findViewById(R.id.btn_add_local_folder).setOnClickListener(v -> {
+
+ viewBinding.addLocalFolderButton.setOnClickListener(v -> {
if (Build.VERSION.SDK_INT < 21) {
return;
}
@@ -100,29 +105,35 @@ public class AddFeedFragment extends Fragment {
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...");
+ e.printStackTrace();
+ ((MainActivity) getActivity())
+ .showSnackbarAbovePlayer(R.string.unable_to_start_system_file_manager, Snackbar.LENGTH_LONG);
}
});
if (Build.VERSION.SDK_INT < 21) {
- root.findViewById(R.id.btn_add_local_folder).setVisibility(View.GONE);
+ viewBinding.addLocalFolderButton.setVisibility(View.GONE);
}
- root.findViewById(R.id.search_icon).setOnClickListener(view -> performSearch());
- return root;
+
+ viewBinding.searchButton.setOnClickListener(view -> performSearch());
+
+ return viewBinding.getRoot();
}
private void showAddViaUrlDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.add_podcast_by_url);
View content = View.inflate(getContext(), R.layout.edit_text_dialog, null);
- EditText editText = content.findViewById(R.id.text);
- editText.setHint(R.string.add_podcast_by_url_hint);
+ EditTextDialogBinding alertViewBinding = EditTextDialogBinding.bind(content);
+ 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")) {
- editText.setText(clipboardContent.trim());
+ alertViewBinding.urlEditText.setText(clipboardContent.trim());
}
- builder.setView(content);
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> addUrl(editText.getText().toString()));
+ builder.setView(alertViewBinding.getRoot());
+ builder.setPositiveButton(R.string.confirm_label,
+ (dialog, which) -> addUrl(alertViewBinding.urlEditText.getText().toString()));
builder.setNegativeButton(R.string.cancel_label, null);
builder.show();
}
@@ -134,8 +145,7 @@ public class AddFeedFragment extends Fragment {
}
private void performSearch() {
- String query = combinedFeedSearchBox.getText().toString();
-
+ String query = viewBinding.combinedFeedSearchEditText.getText().toString();
if (query.matches("http[s]?://.*")) {
addUrl(query);
return;
@@ -187,7 +197,6 @@ public class AddFeedFragment extends Fragment {
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);
Feed fromDatabase = DBTasks.updateFeed(getContext(), dirFeed, false);
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 08da1f8d9..77b272da7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import androidx.annotation.NonNull;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
index 5a65f956c..82e2b3a6a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
@@ -22,6 +22,8 @@ import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.tabs.TabLayout;
+import com.google.android.material.tabs.TabLayoutMediator;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.CastEnabledActivity;
import de.danoeh.antennapod.activity.MainActivity;
@@ -43,7 +45,6 @@ import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
import de.danoeh.antennapod.dialog.SleepTimerDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
-import de.danoeh.antennapod.view.PagerIndicatorView;
import de.danoeh.antennapod.view.PlaybackSpeedIndicatorView;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -74,7 +75,6 @@ public class AudioPlayerFragment extends Fragment implements
PlaybackSpeedIndicatorView butPlaybackSpeed;
TextView txtvPlaybackSpeed;
private ViewPager2 pager;
- private PagerIndicatorView pageIndicator;
private TextView txtvPosition;
private TextView txtvLength;
private SeekBar sbPosition;
@@ -90,6 +90,8 @@ public class AudioPlayerFragment extends Fragment implements
private PlaybackController controller;
private Disposable disposable;
private boolean showTimeLeft;
+ private boolean hasChapters = false;
+ private TabLayoutMediator tabLayoutMediator;
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@@ -141,13 +143,37 @@ public class AudioPlayerFragment extends Fragment implements
});
}
});
- pageIndicator = root.findViewById(R.id.page_indicator);
- pageIndicator.setViewPager(pager);
- pageIndicator.setOnClickListener(v ->
- pager.setCurrentItem((pager.getCurrentItem() + 1) % NUM_CONTENT_FRAGMENTS));
+
+ TabLayout tabLayout = root.findViewById(R.id.sliding_tabs);
+ tabLayoutMediator = new TabLayoutMediator(tabLayout, pager, (tab, position) -> {
+ tab.view.setAlpha(1.0f);
+ switch (position) {
+ case POS_COVER:
+ tab.setText(R.string.cover_label);
+ break;
+ case POS_DESCR:
+ tab.setText(R.string.description_label);
+ break;
+ case POS_CHAPTERS:
+ tab.setText(R.string.chapters_label);
+ if (!hasChapters) {
+ tab.view.setAlpha(0.5f);
+ }
+ break;
+ default:
+ break;
+ }
+ });
+ tabLayoutMediator.attach();
return root;
}
+ public void setHasChapters(boolean hasChapters) {
+ this.hasChapters = hasChapters;
+ tabLayoutMediator.detach();
+ tabLayoutMediator.attach();
+ }
+
public View getExternalPlayerHolder() {
return getView().findViewById(R.id.playerFragment);
}
@@ -362,10 +388,6 @@ public class AudioPlayerFragment extends Fragment implements
setupOptionsMenu(media);
}
- public void setHasChapters(boolean hasChapters) {
- pageIndicator.setDisabledPage(hasChapters ? -1 : 2);
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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 6f95d71da..d781d0774 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -106,6 +106,7 @@ public class ChaptersFragment extends Fragment {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(PlaybackPositionEvent event) {
updateChapterSelection(getCurrentChapter(media));
+ adapter.notifyTimeChanged(event.getPosition());
}
private int getCurrentChapter(Playable media) {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
index 59b2cd234..3519a34b4 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
@@ -4,7 +4,6 @@ import android.os.Bundle;
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;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
index 98d6a946b..2e11ea4ec 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
@@ -4,7 +4,6 @@ import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
-import android.content.res.TypedArray;
import android.os.Bundle;
import androidx.annotation.NonNull;
@@ -13,7 +12,6 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.ListFragment;
import android.util.Log;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
@@ -176,7 +174,7 @@ public class DownloadLogFragment extends ListFragment {
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
switch (item.getItemId()) {
- case R.id.clear_history_item:
+ case R.id.clear_logs_item:
DBWriter.clearDownloadLog();
return true;
case R.id.refresh_item:
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
index 4ca08cbdd..ddfcd06ad 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
@@ -130,6 +130,8 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
protected void doTint(Context themedContext) {
toolbar.getMenu().findItem(R.id.visit_website_item)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.location_web_site));
+ toolbar.getMenu().findItem(R.id.share_parent)
+ .setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.ic_share));
}
};
iconTintManager.updateTint();
@@ -284,8 +286,13 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
}
private void refreshToolbarState() {
+ boolean shareLinkVisible = feed != null && feed.getLink() != null;
+ boolean downloadUrlVisible = feed != null && !feed.isLocalFeed();
+
toolbar.getMenu().findItem(R.id.reconnect_local_folder).setVisible(feed != null && feed.isLocalFeed());
- toolbar.getMenu().findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
+ toolbar.getMenu().findItem(R.id.share_download_url_item).setVisible(downloadUrlVisible);
+ toolbar.getMenu().findItem(R.id.share_link_item).setVisible(shareLinkVisible);
+ toolbar.getMenu().findItem(R.id.share_parent).setVisible(downloadUrlVisible || shareLinkVisible);
toolbar.getMenu().findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null
&& IntentUtils.isCallable(getContext(), new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
}
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 681d3a88e..8e14214d2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
@@ -1,7 +1,6 @@
package de.danoeh.antennapod.fragment;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.res.Configuration;
import android.content.Intent;
import android.graphics.LightingColorFilter;
@@ -36,8 +35,6 @@ import com.joanzapata.iconify.widget.IconTextView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.core.asynctask.FeedRemover;
-import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloaderUpdate;
@@ -65,6 +62,7 @@ import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
import de.danoeh.antennapod.dialog.FilterDialog;
+import de.danoeh.antennapod.dialog.RemoveFeedDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
@@ -298,28 +296,8 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
new RenameFeedDialog(getActivity(), feed).show();
return true;
case R.id.remove_item:
- final FeedRemover remover = new FeedRemover(
- getActivity(), feed) {
- @Override
- protected void onPostExecute(Void result) {
- super.onPostExecute(result);
- ((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(messageId, feed.getTitle())) {
-
- @Override
- public void onConfirmButtonPressed(
- DialogInterface dialog) {
- dialog.dismiss();
- remover.executeAsync();
- }
- };
- conDialog.createNewDialog().show();
+ RemoveFeedDialog.show(getContext(), feed, () ->
+ ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null));
return true;
default:
return false;
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 fc3052e20..18a61f1e6 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -8,10 +8,8 @@ import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
import de.danoeh.antennapod.core.util.playback.Timeline;
import de.danoeh.antennapod.view.ShownotesWebView;
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 669dbdac2..07f59bb42 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -17,7 +17,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
import androidx.core.text.TextUtilsCompat;
import androidx.core.util.ObjectsCompat;
import androidx.core.view.ViewCompat;
@@ -71,7 +70,6 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
-import java.util.Date;
import java.util.List;
import java.util.Locale;
@@ -120,6 +118,7 @@ public class ItemFragment extends Fragment {
private View butAction2;
private ItemActionButton actionButton1;
private ItemActionButton actionButton2;
+ private View noMediaLabel;
private Disposable disposable;
private PlaybackController controller;
@@ -169,6 +168,7 @@ public class ItemFragment extends Fragment {
butAction2Icon = layout.findViewById(R.id.butAction2Icon);
butAction1Text = layout.findViewById(R.id.butAction1Text);
butAction2Text = layout.findViewById(R.id.butAction2Text);
+ noMediaLabel = layout.findViewById(R.id.noMediaLabel);
butAction1.setOnClickListener(v -> {
if (actionButton1 instanceof StreamActionButton && !UserPreferences.isStreamOverDownload()
@@ -319,7 +319,9 @@ public class ItemFragment extends Fragment {
if (media == null) {
actionButton1 = new MarkAsPlayedActionButton(item);
actionButton2 = new VisitWebsiteActionButton(item);
+ noMediaLabel.setVisibility(View.VISIBLE);
} else {
+ noMediaLabel.setVisibility(View.GONE);
if (media.getDuration() > 0) {
txtvDuration.setText(Converter.getDurationStringLong(media.getDuration()));
txtvDuration.setContentDescription(
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 4f99e8130..c69d46265 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
@@ -26,19 +26,15 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.NavListAdapter;
-import de.danoeh.antennapod.core.asynctask.FeedRemover;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.core.util.IntentUtils;
+import de.danoeh.antennapod.dialog.RemoveFeedDialog;
import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
import io.reactivex.Observable;
@@ -192,41 +188,15 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
new RenameFeedDialog(getActivity(), feed).show();
return true;
case R.id.remove_item:
- final FeedRemover remover = new FeedRemover(getContext(), feed) {
- @Override
- protected void onPostExecute(Void result) {
- super.onPostExecute(result);
- if (selectedNavListIndex == position) {
- if (getActivity() instanceof MainActivity) {
- ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
- } else {
- showMainActivity(EpisodesFragment.TAG);
- }
- }
- }
- };
- 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(messageId, feed.getTitle())) {
- @Override
- public void onConfirmButtonPressed(DialogInterface dialog) {
- dialog.dismiss();
- long mediaId = PlaybackPreferences.getCurrentlyPlayingFeedMediaId();
- if (mediaId > 0 && FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId) >= 0) {
- Log.d(TAG, "Currently playing episode is about to be deleted, skipping");
- remover.skipOnCompletion = true;
- int playerStatus = PlaybackPreferences.getCurrentPlayerStatus();
- if (playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) {
- IntentUtils.sendLocalBroadcast(getContext(),
- PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
- }
+ RemoveFeedDialog.show(getContext(), feed, () -> {
+ if (selectedNavListIndex == position) {
+ if (getActivity() instanceof MainActivity) {
+ ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
+ } else {
+ showMainActivity(EpisodesFragment.TAG);
}
- remover.executeAsync();
}
- };
- conDialog.createNewDialog().show();
+ });
return true;
default:
return super.onContextItemSelected(item);
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 d748d14c9..1aa66dcbb 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
@@ -1,7 +1,6 @@
package de.danoeh.antennapod.fragment;
import android.os.Bundle;
-import android.view.MenuInflater;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.ItemTouchHelper;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
index ba817650b..992b6930c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
@@ -90,7 +90,6 @@ public class OnlineSearchFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_itunes_search, container, false);
- setupToolbar(root.findViewById(R.id.toolbar));
root.findViewById(R.id.spinner_country).setVisibility(INVISIBLE);
gridView = root.findViewById(R.id.gridView);
adapter = new ItunesAdapter(getActivity(), new ArrayList<>());
@@ -110,6 +109,7 @@ public class OnlineSearchFragment extends Fragment {
txtvEmpty = root.findViewById(android.R.id.empty);
TextView txtvPoweredBy = root.findViewById(R.id.search_powered_by);
txtvPoweredBy.setText(getString(R.string.search_powered_by, searchProvider.getName()));
+ setupToolbar(root.findViewById(R.id.toolbar));
return root;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
index 4549e2a09..973fcb978 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -20,6 +20,7 @@ import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.PlaybackHistoryEvent;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
+import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
@@ -180,6 +181,12 @@ public class PlaybackHistoryFragment extends Fragment implements Toolbar.OnMenuI
refreshToolbarState();
}
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onUnreadItemsChanged(UnreadItemsUpdateEvent event) {
+ loadItems();
+ refreshToolbarState();
+ }
+
private void onFragmentLoaded() {
adapter.notifyDataSetChanged();
refreshToolbarState();
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 c994b4d8b..14f355b52 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
@@ -46,6 +46,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
private FeedDiscoverAdapter adapter;
private GridView discoverGridLayout;
private TextView errorTextView;
+ private TextView poweredByTextView;
private LinearLayout errorView;
private Button errorRetry;
@@ -63,6 +64,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
errorTextView = root.findViewById(R.id.discover_error_txtV);
errorRetry = root.findViewById(R.id.discover_error_retry_btn);
errorRetry.setOnClickListener((listener) -> loadToplist());
+ poweredByTextView = root.findViewById(R.id.discover_powered_by_itunes);
adapter = new FeedDiscoverAdapter((MainActivity) getActivity());
discoverGridLayout.setAdapter(adapter);
@@ -110,6 +112,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
discoverGridLayout.setVisibility(View.INVISIBLE);
errorView.setVisibility(View.GONE);
errorRetry.setVisibility(View.INVISIBLE);
+ poweredByTextView.setVisibility(View.VISIBLE);
ItunesTopListLoader loader = new ItunesTopListLoader(getContext());
SharedPreferences prefs = getActivity().getSharedPreferences(ItunesTopListLoader.PREFS, MODE_PRIVATE);
@@ -122,6 +125,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
progressBar.setVisibility(View.GONE);
discoverGridLayout.setVisibility(View.INVISIBLE);
errorRetry.setVisibility(View.INVISIBLE);
+ poweredByTextView.setVisibility(View.INVISIBLE);
return;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
index 087abc327..fc500a223 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
@@ -6,7 +6,6 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.ListFragment;
import android.util.Log;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
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 3b4246e3a..4735cab42 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -33,22 +33,18 @@ import java.util.concurrent.Callable;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.SubscriptionsAdapter;
-import de.danoeh.antennapod.core.asynctask.FeedRemover;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadService;
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
-import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
+import de.danoeh.antennapod.dialog.RemoveFeedDialog;
import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
import de.danoeh.antennapod.dialog.FeedSortDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
@@ -299,45 +295,13 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
new RenameFeedDialog(getActivity(), feed).show();
return true;
case R.id.remove_item:
- displayRemoveFeedDialog(feed);
+ RemoveFeedDialog.show(getContext(), feed, null);
return true;
default:
return super.onContextItemSelected(item);
}
}
- private void displayRemoveFeedDialog(Feed feed) {
- final FeedRemover remover = new FeedRemover(getContext(), feed) {
- @Override
- protected void onPostExecute(Void result) {
- super.onPostExecute(result);
- loadSubscriptions();
- }
- };
-
- 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) {
- clickedDialog.dismiss();
- long mediaId = PlaybackPreferences.getCurrentlyPlayingFeedMediaId();
- if (mediaId > 0 && FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId) >= 0) {
- Log.d(TAG, "Currently playing episode is about to be deleted, skipping");
- remover.skipOnCompletion = true;
- int playerStatus = PlaybackPreferences.getCurrentPlayerStatus();
- if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) {
- IntentUtils.sendLocalBroadcast(getContext(), PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
-
- }
- }
- remover.executeAsync();
- }
- };
- dialog.createNewDialog().show();
- }
-
private <T> void displayConfirmationDialog(@StringRes int title, @StringRes int message, Callable<? extends T> task) {
ConfirmationDialog dialog = new ConfirmationDialog(getActivity(), title, message) {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
index 641e82b5a..ad815c3c9 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
@@ -1,11 +1,14 @@
package de.danoeh.antennapod.fragment.gpodnet;
+import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
+import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
@@ -15,6 +18,9 @@ import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.discovery.GpodnetPodcastSearcher;
+import de.danoeh.antennapod.fragment.OnlineSearchFragment;
/**
* Main navigation hub for gpodder.net podcast directory
@@ -30,9 +36,7 @@ public class GpodnetMainFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.pager_fragment, container, false);
- Toolbar toolbar = root.findViewById(R.id.toolbar);
- toolbar.setTitle(R.string.gpodnet_main_label);
- toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
+ setupToolbar(root.findViewById(R.id.toolbar));
ViewPager2 viewPager = root.findViewById(R.id.viewpager);
GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(this);
@@ -59,6 +63,33 @@ public class GpodnetMainFragment extends Fragment {
return root;
}
+ private void setupToolbar(Toolbar toolbar) {
+ toolbar.setTitle(R.string.gpodnet_main_label);
+ toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
+
+ toolbar.inflateMenu(R.menu.search);
+ MenuItem searchItem = toolbar.getMenu().findItem(R.id.action_search);
+ final SearchView sv = (SearchView) searchItem.getActionView();
+ sv.setQueryHint(getString(R.string.gpodnet_search_hint));
+ sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ Activity activity = getActivity();
+ if (activity != null) {
+ searchItem.collapseActionView();
+ ((MainActivity) activity).loadChildFragment(
+ OnlineSearchFragment.newInstance(GpodnetPodcastSearcher.class, query));
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String s) {
+ return false;
+ }
+ });
+ }
+
public static class GpodnetPagerAdapter extends FragmentStateAdapter {
GpodnetPagerAdapter(@NonNull Fragment fragment) {
@@ -68,20 +99,14 @@ public class GpodnetMainFragment extends Fragment {
@NonNull
@Override
public Fragment createFragment(int position) {
- Bundle arguments = new Bundle();
- arguments.putBoolean(PodcastListFragment.ARGUMENT_HIDE_TOOLBAR, true);
switch (position) {
case POS_TAGS:
return new TagListFragment();
case POS_TOPLIST:
- PodcastListFragment topListFragment = new PodcastTopListFragment();
- topListFragment.setArguments(arguments);
- return topListFragment;
+ return new PodcastTopListFragment();
default:
case POS_SUGGESTIONS:
- PodcastListFragment suggestionsFragment = new SuggestionListFragment();
- suggestionsFragment.setArguments(arguments);
- return suggestionsFragment;
+ return new SuggestionListFragment();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
index b3f56941b..1f5434688 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
@@ -4,12 +4,9 @@ import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
-import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
-import androidx.appcompat.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
@@ -33,7 +30,6 @@ import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetPodcast;
* Displays a list of GPodnetPodcast-Objects in a GridView
*/
public abstract class PodcastListFragment extends Fragment {
- public static final String ARGUMENT_HIDE_TOOLBAR = "hideToolbar";
private static final String TAG = "PodcastListFragment";
private GridView gridView;
@@ -44,8 +40,6 @@ public abstract class PodcastListFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.gpodnet_podcast_list, container, false);
- setupToolbar(root.findViewById(R.id.toolbar));
-
gridView = root.findViewById(R.id.gridView);
progressBar = root.findViewById(R.id.progressBar);
txtvError = root.findViewById(R.id.txtvError);
@@ -59,37 +53,6 @@ public abstract class PodcastListFragment extends Fragment {
return root;
}
- private void setupToolbar(Toolbar toolbar) {
- if (getArguments() != null && getArguments().getBoolean(ARGUMENT_HIDE_TOOLBAR, false)) {
- toolbar.setVisibility(View.GONE);
- return;
- }
-
- toolbar.setTitle(R.string.gpodnet_main_label);
- toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
- toolbar.inflateMenu(R.menu.gpodder_podcasts);
-
- MenuItem searchItem = toolbar.getMenu().findItem(R.id.action_search);
- final SearchView sv = (SearchView) searchItem.getActionView();
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- sv.clearFocus();
- MainActivity activity = (MainActivity)getActivity();
- if (activity != null) {
- activity.loadChildFragment(SearchListFragment.newInstance(s));
- }
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
-
private void onPodcastSelected(GpodnetPodcast selection) {
Log.d(TAG, "Selected podcast: " + selection.toString());
Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
deleted file mode 100644
index 72a752bf1..000000000
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package de.danoeh.antennapod.fragment.gpodnet;
-
-import android.os.Bundle;
-import androidx.core.view.MenuItemCompat;
-import androidx.appcompat.widget.SearchView;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetService;
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetServiceException;
-import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetPodcast;
-import org.apache.commons.lang3.Validate;
-
-import de.danoeh.antennapod.R;
-
-import java.util.List;
-
-/**
- * Performs a search on the gpodder.net directory and displays the results.
- */
-public class SearchListFragment extends PodcastListFragment {
- private static final String ARG_QUERY = "query";
-
- private String query;
-
- public static SearchListFragment newInstance(String query) {
- SearchListFragment fragment = new SearchListFragment();
- Bundle args = new Bundle();
- args.putString(ARG_QUERY, query);
- fragment.setArguments(args);
- return fragment;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (getArguments() != null && getArguments().containsKey(ARG_QUERY)) {
- this.query = getArguments().getString(ARG_QUERY);
- } else {
- this.query = "";
- }
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- // parent already inflated menu
- MenuItem searchItem = menu.findItem(R.id.action_search);
- final SearchView sv = (SearchView) searchItem.getActionView();
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setQuery(query, false);
- sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- sv.clearFocus();
- changeQuery(s);
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
-
- @Override
- protected List<GpodnetPodcast> loadPodcastData(GpodnetService service) throws GpodnetServiceException {
- return service.searchPodcasts(query, 0);
- }
-
- private void changeQuery(String query) {
- Validate.notNull(query);
-
- this.query = query;
- loadData();
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
index 53a31b68d..2c41ee070 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
@@ -1,19 +1,11 @@
package de.danoeh.antennapod.fragment.gpodnet;
-import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
-import androidx.fragment.app.ListFragment;
-import androidx.core.view.MenuItemCompat;
-import androidx.appcompat.widget.SearchView;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
-
-import de.danoeh.antennapod.R;
+import androidx.fragment.app.ListFragment;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.gpodnet.TagListAdapter;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
@@ -28,37 +20,6 @@ public class TagListFragment extends ListFragment {
private static final int COUNT = 50;
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.gpodder_podcasts, menu);
- MenuItem searchItem = menu.findItem(R.id.action_search);
- final SearchView sv = (SearchView) searchItem.getActionView();
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- Activity activity = getActivity();
- if (activity != null) {
- sv.clearFocus();
- ((MainActivity) activity).loadChildFragment(SearchListFragment.newInstance(s));
- }
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
-
- @Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderAuthenticationFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderAuthenticationFragment.java
new file mode 100644
index 000000000..187e8480b
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderAuthenticationFragment.java
@@ -0,0 +1,302 @@
+package de.danoeh.antennapod.fragment.preferences;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Paint;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+import android.widget.ViewFlipper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
+import com.google.android.material.button.MaterialButton;
+import com.google.android.material.textfield.TextInputLayout;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
+import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
+import de.danoeh.antennapod.core.sync.SyncService;
+import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetService;
+import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetDevice;
+import de.danoeh.antennapod.core.util.FileNameGenerator;
+import de.danoeh.antennapod.core.util.IntentUtils;
+import io.reactivex.Completable;
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Guides the user through the authentication process.
+ */
+public class GpodderAuthenticationFragment extends DialogFragment {
+ public static final String TAG = "GpodnetAuthActivity";
+
+ private ViewFlipper viewFlipper;
+
+ private static final int STEP_DEFAULT = -1;
+ private static final int STEP_HOSTNAME = 0;
+ private static final int STEP_LOGIN = 1;
+ private static final int STEP_DEVICE = 2;
+ private static final int STEP_FINISH = 3;
+
+ private int currentStep = -1;
+
+ private GpodnetService service;
+ private volatile String username;
+ private volatile String password;
+ private volatile GpodnetDevice selectedDevice;
+ private List<GpodnetDevice> devices;
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
+ dialog.setTitle(GpodnetService.DEFAULT_BASE_HOST);
+ dialog.setNegativeButton(R.string.cancel_label, null);
+ dialog.setCancelable(false);
+ this.setCancelable(false);
+
+ View root = View.inflate(getContext(), R.layout.gpodnetauth_dialog, null);
+ viewFlipper = root.findViewById(R.id.viewflipper);
+ advance();
+ dialog.setView(root);
+
+ return dialog.create();
+ }
+
+ private void setupHostView(View view) {
+ final Button selectHost = view.findViewById(R.id.chooseHostButton);
+ final RadioGroup serverRadioGroup = view.findViewById(R.id.serverRadioGroup);
+ final EditText serverUrlText = view.findViewById(R.id.serverUrlText);
+ if (!GpodnetService.DEFAULT_BASE_HOST.equals(GpodnetPreferences.getHostname())) {
+ serverUrlText.setText(GpodnetPreferences.getHostname());
+ }
+ final TextInputLayout serverUrlTextInput = view.findViewById(R.id.serverUrlTextInput);
+ serverRadioGroup.setOnCheckedChangeListener((group, checkedId) -> {
+ serverUrlTextInput.setVisibility(checkedId == R.id.customServerRadio ? View.VISIBLE : View.GONE);
+ });
+ selectHost.setOnClickListener(v -> {
+ if (serverRadioGroup.getCheckedRadioButtonId() == R.id.customServerRadio) {
+ GpodnetPreferences.setHostname(serverUrlText.getText().toString());
+ } else {
+ GpodnetPreferences.setHostname(GpodnetService.DEFAULT_BASE_HOST);
+ }
+ service = new GpodnetService(AntennapodHttpClient.getHttpClient(), GpodnetPreferences.getHostname());
+ getDialog().setTitle(GpodnetPreferences.getHostname());
+ advance();
+ });
+ }
+
+ private void setupLoginView(View view) {
+ final EditText username = view.findViewById(R.id.etxtUsername);
+ final EditText password = view.findViewById(R.id.etxtPassword);
+ final Button login = view.findViewById(R.id.butLogin);
+ final TextView txtvError = view.findViewById(R.id.credentialsError);
+ final ProgressBar progressBar = view.findViewById(R.id.progBarLogin);
+ final TextView createAccount = view.findViewById(R.id.createAccountButton);
+
+ createAccount.setPaintFlags(createAccount.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
+ createAccount.setOnClickListener(v -> IntentUtils.openInBrowser(getContext(), "https://gpodder.net/register/"));
+
+ password.setOnEditorActionListener((v, actionID, event) ->
+ actionID == EditorInfo.IME_ACTION_GO && login.performClick());
+
+ login.setOnClickListener(v -> {
+ final String usernameStr = username.getText().toString();
+ final String passwordStr = password.getText().toString();
+
+ if (usernameHasUnwantedChars(usernameStr)) {
+ txtvError.setText(R.string.gpodnetsync_username_characters_error);
+ txtvError.setVisibility(View.VISIBLE);
+ return;
+ }
+
+ login.setEnabled(false);
+ progressBar.setVisibility(View.VISIBLE);
+ txtvError.setVisibility(View.GONE);
+ InputMethodManager inputManager = (InputMethodManager) getContext()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+ inputManager.hideSoftInputFromWindow(login.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+
+ Completable.fromAction(() -> {
+ service.authenticate(usernameStr, passwordStr);
+ devices = service.getDevices();
+ GpodderAuthenticationFragment.this.username = usernameStr;
+ GpodderAuthenticationFragment.this.password = passwordStr;
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(() -> {
+ login.setEnabled(true);
+ progressBar.setVisibility(View.GONE);
+ advance();
+ }, error -> {
+ login.setEnabled(true);
+ progressBar.setVisibility(View.GONE);
+ txtvError.setText(error.getCause().getMessage());
+ txtvError.setVisibility(View.VISIBLE);
+ });
+
+ });
+ }
+
+ private void setupDeviceView(View view) {
+ final EditText deviceName = view.findViewById(R.id.deviceName);
+ final LinearLayout devicesContainer = view.findViewById(R.id.devicesContainer);
+ deviceName.setText(generateDeviceName());
+
+ MaterialButton createDeviceButton = view.findViewById(R.id.createDeviceButton);
+ createDeviceButton.setOnClickListener(v -> createDevice(view));
+
+ for (GpodnetDevice device : devices) {
+ View row = View.inflate(getContext(), R.layout.gpodnetauth_device_row, null);
+ Button selectDeviceButton = row.findViewById(R.id.selectDeviceButton);
+ selectDeviceButton.setOnClickListener(v -> {
+ selectedDevice = device;
+ advance();
+ });
+ selectDeviceButton.setText(device.getCaption());
+ devicesContainer.addView(row);
+ }
+ }
+
+ private void createDevice(View view) {
+ final EditText deviceName = view.findViewById(R.id.deviceName);
+ final TextView txtvError = view.findViewById(R.id.deviceSelectError);
+ final ProgressBar progBarCreateDevice = view.findViewById(R.id.progbarCreateDevice);
+
+ String deviceNameStr = deviceName.getText().toString();
+ if (isDeviceInList(deviceNameStr)) {
+ return;
+ }
+ progBarCreateDevice.setVisibility(View.VISIBLE);
+ txtvError.setVisibility(View.GONE);
+ deviceName.setEnabled(false);
+
+ Observable.fromCallable(() -> {
+ String deviceId = generateDeviceId(deviceNameStr);
+ service.configureDevice(deviceId, deviceNameStr, GpodnetDevice.DeviceType.MOBILE);
+ return new GpodnetDevice(deviceId, deviceNameStr, GpodnetDevice.DeviceType.MOBILE.toString(), 0);
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(device -> {
+ progBarCreateDevice.setVisibility(View.GONE);
+ selectedDevice = device;
+ advance();
+ }, error -> {
+ deviceName.setEnabled(true);
+ progBarCreateDevice.setVisibility(View.GONE);
+ txtvError.setText(error.getMessage());
+ txtvError.setVisibility(View.VISIBLE);
+ });
+ }
+
+ private String generateDeviceName() {
+ String baseName = getString(R.string.gpodnetauth_device_name_default, Build.MODEL);
+ String name = baseName;
+ int num = 1;
+ while (isDeviceInList(name)) {
+ name = baseName + " (" + num + ")";
+ num++;
+ }
+ return name;
+ }
+
+ private String generateDeviceId(String name) {
+ // devices names must be of a certain form:
+ // https://gpoddernet.readthedocs.org/en/latest/api/reference/general.html#devices
+ return FileNameGenerator.generateFileName(name).replaceAll("\\W", "_").toLowerCase(Locale.US);
+ }
+
+ private boolean isDeviceInList(String name) {
+ if (devices == null) {
+ return false;
+ }
+ String id = generateDeviceId(name);
+ for (GpodnetDevice device : devices) {
+ if (device.getId().equals(id) || device.getCaption().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private GpodnetDevice findDevice(String id) {
+ if (devices == null) {
+ return null;
+ }
+ for (GpodnetDevice device : devices) {
+ if (device.getId().equals(id)) {
+ return device;
+ }
+ }
+ return null;
+ }
+
+ private void setupFinishView(View view) {
+ final Button sync = view.findViewById(R.id.butSyncNow);
+
+ sync.setOnClickListener(v -> {
+ dismiss();
+ SyncService.sync(getContext());
+ });
+ }
+
+ private void writeLoginCredentials() {
+ GpodnetPreferences.setUsername(username);
+ GpodnetPreferences.setPassword(password);
+ GpodnetPreferences.setDeviceID(selectedDevice.getId());
+ }
+
+ private void advance() {
+ if (currentStep < STEP_FINISH) {
+
+ View view = viewFlipper.getChildAt(currentStep + 1);
+ if (currentStep == STEP_DEFAULT) {
+ setupHostView(view);
+ } else if (currentStep == STEP_HOSTNAME) {
+ setupLoginView(view);
+ } else if (currentStep == STEP_LOGIN) {
+ if (username == null || password == null) {
+ throw new IllegalStateException("Username and password must not be null here");
+ } else {
+ setupDeviceView(view);
+ }
+ } else if (currentStep == STEP_DEVICE) {
+ if (selectedDevice == null) {
+ throw new IllegalStateException("Device must not be null here");
+ } else {
+ writeLoginCredentials();
+ setupFinishView(view);
+ }
+ }
+ if (currentStep != STEP_DEFAULT) {
+ viewFlipper.showNext();
+ }
+ currentStep++;
+ } else {
+ dismiss();
+ }
+ }
+
+ private boolean usernameHasUnwantedChars(String username) {
+ Pattern special = Pattern.compile("[!@#$%&*()+=|<>?{}\\[\\]~]");
+ Matcher containsUnwantedChars = special.matcher(username);
+ return containsUnwantedChars.find();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
index bec73894c..4fb734e17 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
@@ -1,15 +1,12 @@
package de.danoeh.antennapod.fragment.preferences;
import android.app.Activity;
-import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.core.text.HtmlCompat;
-import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import android.text.Spanned;
import android.text.format.DateUtils;
-import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.PreferenceActivity;
@@ -17,19 +14,16 @@ import de.danoeh.antennapod.core.event.SyncServiceEvent;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.sync.SyncService;
import de.danoeh.antennapod.dialog.AuthenticationDialog;
-import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
-
public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
private static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate";
private static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information";
private static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync";
private static final String PREF_GPODNET_FORCE_FULL_SYNC = "pref_gpodnet_force_full_sync";
private static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
- private static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname";
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
@@ -54,6 +48,7 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void syncStatusChanged(SyncServiceEvent event) {
+ updateGpodnetPreferenceScreen();
if (!GpodnetPreferences.loggedIn()) {
return;
}
@@ -69,6 +64,10 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
private void setupGpodderScreen() {
final Activity activity = getActivity();
+ findPreference(PREF_GPODNET_LOGIN).setOnPreferenceClickListener(preference -> {
+ new GpodderAuthenticationFragment().show(getChildFragmentManager(), GpodderAuthenticationFragment.TAG);
+ return true;
+ });
findPreference(PREF_GPODNET_SETLOGIN_INFORMATION)
.setOnPreferenceClickListener(preference -> {
AuthenticationDialog dialog = new AuthenticationDialog(activity,
@@ -97,11 +96,6 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
updateGpodnetPreferenceScreen();
return true;
});
- findPreference(PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener(preference -> {
- GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(
- dialog -> updateGpodnetPreferenceScreen());
- return true;
- });
}
private void updateGpodnetPreferenceScreen() {
@@ -122,7 +116,6 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
} else {
findPreference(PREF_GPODNET_LOGOUT).setSummary(null);
}
- findPreference(PREF_GPODNET_HOSTNAME).setSummary(GpodnetPreferences.getHostname());
}
private void updateLastGpodnetSyncReport(boolean successful, long lastTime) {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java
index 99fd12021..7bf602e35 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java
@@ -1,8 +1,11 @@
package de.danoeh.antennapod.fragment.preferences;
import android.content.Intent;
+import android.os.Build;
import android.os.Bundle;
+import android.provider.Settings;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import com.bytehamster.lib.preferencesearch.SearchConfiguration;
import com.bytehamster.lib.preferencesearch.SearchPreference;
@@ -20,7 +23,7 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
private static final String PREF_SCREEN_NETWORK = "prefScreenNetwork";
private static final String PREF_SCREEN_GPODDER = "prefScreenGpodder";
private static final String PREF_SCREEN_STORAGE = "prefScreenStorage";
- private static final String PREF_FAQ = "prefFaq";
+ private static final String PREF_DOCUMENTATION = "prefDocumentation";
private static final String PREF_VIEW_FORUM = "prefViewForum";
private static final String PREF_SEND_BUG_REPORT = "prefSendBugReport";
private static final String PREF_CATEGORY_PROJECT = "project";
@@ -35,10 +38,18 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
setupSearch();
// If you are writing a spin-off, please update the details on screens like "About" and "Report bug"
- // and afterwards remove the following lines.
+ // and afterwards remove the following lines. Please keep in mind that AntennaPod is licensed under the GPL.
+ // This means that your application needs to be open-source under the GPL, too.
+ // It must also include a prominent copyright notice.
String packageName = getContext().getPackageName();
if (!"de.danoeh.antennapod".equals(packageName) && !"de.danoeh.antennapod.debug".equals(packageName)) {
findPreference(PREF_CATEGORY_PROJECT).setVisible(false);
+ Preference copyrightNotice = new Preference(getContext());
+ copyrightNotice.setSummary("This application is based on AntennaPod."
+ + " The AntennaPod team does NOT provide support for this unofficial version."
+ + " If you can read this message, the developers of this modification"
+ + " violate the GNU General Public License (GPL).");
+ findPreference(PREF_CATEGORY_PROJECT).getParent().addPreference(copyrightNotice);
}
}
@@ -70,10 +81,16 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
return true;
});
findPreference(PREF_NOTIFICATION).setOnPreferenceClickListener(preference -> {
- ((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_notifications);
+ if (Build.VERSION.SDK_INT >= 26) {
+ Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
+ intent.putExtra(Settings.EXTRA_APP_PACKAGE, getActivity().getPackageName());
+ startActivity(intent);
+ } else {
+ ((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_notifications);
+ }
return true;
});
-
findPreference(PREF_ABOUT).setOnPreferenceClickListener(
preference -> {
getParentFragmentManager().beginTransaction().replace(R.id.content, new AboutFragment())
@@ -88,8 +105,8 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
return true;
}
);
- findPreference(PREF_FAQ).setOnPreferenceClickListener(preference -> {
- IntentUtils.openInBrowser(getContext(), "https://antennapod.org/faq.html");
+ findPreference(PREF_DOCUMENTATION).setOnPreferenceClickListener(preference -> {
+ IntentUtils.openInBrowser(getContext(), "https://antennapod.org/documentation/");
return true;
});
findPreference(PREF_VIEW_FORUM).setOnPreferenceClickListener(preference -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
index fcc37f644..77f8063f2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
@@ -15,7 +15,6 @@ import org.apache.commons.lang3.ArrayUtils;
import java.util.Calendar;
import java.util.GregorianCalendar;
-import java.util.Locale;
import java.util.concurrent.TimeUnit;
public class NetworkPreferencesFragment extends PreferenceFragmentCompat {
@@ -97,8 +96,7 @@ public class NetworkPreferencesFragment extends PreferenceFragmentCompat {
private void setParallelDownloadsText(int downloads) {
final Resources res = getActivity().getResources();
- String s = String.format(Locale.getDefault(), "%d%s",
- downloads, res.getString(R.string.parallel_downloads_suffix));
+ String s = res.getString(R.string.parallel_downloads, downloads);
findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS).setSummary(s);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java
index b440d053b..0a64bbe71 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java
@@ -33,7 +33,7 @@ public class AboutFragment extends PreferenceFragmentCompat {
return true;
});
findPreference("about_privacy_policy").setOnPreferenceClickListener((preference) -> {
- IntentUtils.openInBrowser(getContext(), "https://antennapod.org/privacy.html");
+ IntentUtils.openInBrowser(getContext(), "https://antennapod.org/privacy/");
return true;
});
findPreference("about_licenses").setOnPreferenceClickListener((preference) -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java
index 60d9f95dd..b844234b7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java
@@ -6,8 +6,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.ListFragment;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.SimpleIconListAdapter;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java
index 6db1389ea..d759a5ff2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java
@@ -6,8 +6,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.ListFragment;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.SimpleIconListAdapter;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java
index e8d8e113b..b77c74de6 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java
@@ -6,8 +6,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.ListFragment;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.SimpleIconListAdapter;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
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 3d8f3fe09..1eecccb4c 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -48,65 +48,43 @@ public class FeedItemMenuHandler {
if (menu == null || selectedItem == null) {
return false;
}
- boolean hasMedia = selectedItem.getMedia() != null;
- boolean isPlaying = hasMedia && selectedItem.getState() == FeedItem.State.PLAYING;
-
- if (!isPlaying) {
- setItemVisibility(menu, R.id.skip_episode_item, false);
- }
- boolean isInQueue = selectedItem.isTagged(FeedItem.TAG_QUEUE);
- if (!isInQueue) {
- setItemVisibility(menu, R.id.remove_from_queue_item, false);
- }
- if (!(!isInQueue && selectedItem.getMedia() != null)) {
- setItemVisibility(menu, R.id.add_to_queue_item, false);
- }
- if (!ShareUtils.hasLinkToShare(selectedItem)) {
- setItemVisibility(menu, R.id.visit_website_item, false);
- }
-
- boolean fileDownloaded = hasMedia && selectedItem.getMedia().fileExists();
+ final boolean hasMedia = selectedItem.getMedia() != null;
+ final boolean isPlaying = hasMedia && selectedItem.getState() == FeedItem.State.PLAYING;
+ final boolean isInQueue = selectedItem.isTagged(FeedItem.TAG_QUEUE);
+ final boolean fileDownloaded = hasMedia && selectedItem.getMedia().fileExists();
+ final boolean isFavorite = selectedItem.isTagged(FeedItem.TAG_FAVORITE);
+ setItemVisibility(menu, R.id.skip_episode_item, isPlaying);
+ setItemVisibility(menu, R.id.remove_from_queue_item, isInQueue);
+ setItemVisibility(menu, R.id.add_to_queue_item, !isInQueue && selectedItem.getMedia() != null);
+ setItemVisibility(menu, R.id.visit_website_item, !selectedItem.getFeed().isLocalFeed()
+ && ShareUtils.hasLinkToShare(selectedItem));
+ setItemVisibility(menu, R.id.share_item, !selectedItem.getFeed().isLocalFeed());
setItemVisibility(menu, R.id.remove_new_flag_item, selectedItem.isNew());
- if (selectedItem.isPlayed()) {
- setItemVisibility(menu, R.id.mark_read_item, false);
- } else {
- setItemVisibility(menu, R.id.mark_unread_item, false);
- }
-
- if (selectedItem.getMedia() == null || selectedItem.getMedia().getPosition() == 0) {
- setItemVisibility(menu, R.id.reset_position, false);
- }
+ setItemVisibility(menu, R.id.mark_read_item, !selectedItem.isPlayed());
+ setItemVisibility(menu, R.id.mark_unread_item, selectedItem.isPlayed());
+ setItemVisibility(menu, R.id.reset_position, hasMedia && selectedItem.getMedia().getPosition() != 0);
if (!UserPreferences.isEnableAutodownload() || fileDownloaded || selectedItem.getFeed().isLocalFeed()) {
setItemVisibility(menu, R.id.activate_auto_download, false);
setItemVisibility(menu, R.id.deactivate_auto_download, false);
- } else if (selectedItem.getAutoDownload()) {
- setItemVisibility(menu, R.id.activate_auto_download, false);
} else {
- setItemVisibility(menu, R.id.deactivate_auto_download, false);
+ setItemVisibility(menu, R.id.activate_auto_download, !selectedItem.getAutoDownload());
+ setItemVisibility(menu, R.id.deactivate_auto_download, selectedItem.getAutoDownload());
}
// Display proper strings when item has no media
- if (!hasMedia && !selectedItem.isPlayed()) {
+ if (hasMedia) {
+ setItemTitle(menu, R.id.mark_read_item, R.string.mark_read_label);
+ setItemTitle(menu, R.id.mark_unread_item, R.string.mark_unread_label);
+ } else {
setItemTitle(menu, R.id.mark_read_item, R.string.mark_read_no_media_label);
- }
-
- if (!hasMedia && selectedItem.isPlayed()) {
setItemTitle(menu, R.id.mark_unread_item, R.string.mark_unread_label_no_media);
}
- boolean isFavorite = selectedItem.isTagged(FeedItem.TAG_FAVORITE);
setItemVisibility(menu, R.id.add_to_favorites_item, !isFavorite);
setItemVisibility(menu, R.id.remove_from_favorites_item, isFavorite);
-
setItemVisibility(menu, R.id.remove_item, fileDownloaded);
-
- if (selectedItem.getFeed().isLocalFeed()) {
- setItemVisibility(menu, R.id.visit_website_item, false);
- setItemVisibility(menu, R.id.share_item, false);
- }
-
return true;
}
@@ -134,7 +112,7 @@ public class FeedItemMenuHandler {
* @param id The id of the string that is going to be replaced.
* @param noMedia The id of the new String that is going to be used.
* */
- public static void setItemTitle(Menu menu, int id, int noMedia){
+ public static void setItemTitle(Menu menu, int id, int noMedia) {
MenuItem item = menu.findItem(id);
if (item != null) {
item.setTitle(noMedia);
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 9ceed9369..0086a75ab 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.annotation.NonNull;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java b/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
index f755a4c84..2fd570ece 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
@@ -11,7 +11,8 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.util.ThemeUtils;
public class CircularProgressBar extends View {
- private static final float EPSILON = 0.005f;
+ public static final float MINIMUM_PERCENTAGE = 0.005f;
+ public static final float MAXIMUM_PERCENTAGE = 1 - MINIMUM_PERCENTAGE;
private final Paint paintBackground = new Paint();
private final Paint paintProgress = new Paint();
@@ -74,11 +75,11 @@ public class CircularProgressBar extends View {
bounds.set(padding, padding, getWidth() - padding, getHeight() - padding);
canvas.drawArc(bounds, 0, 360, false, paintBackground);
- if (percentage > EPSILON && 1 - percentage > EPSILON) {
+ if (MINIMUM_PERCENTAGE <= percentage && percentage <= MAXIMUM_PERCENTAGE) {
canvas.drawArc(bounds, -90, percentage * 360, false, paintProgress);
}
- if (Math.abs(percentage - targetPercentage) > EPSILON) {
+ if (Math.abs(percentage - targetPercentage) > MINIMUM_PERCENTAGE) {
float speed = 0.02f;
if (Math.abs(targetPercentage - percentage) < 0.1 && targetPercentage > percentage) {
speed = 0.006f;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/PagerIndicatorView.java b/app/src/main/java/de/danoeh/antennapod/view/PagerIndicatorView.java
deleted file mode 100644
index 10ed98769..000000000
--- a/app/src/main/java/de/danoeh/antennapod/view/PagerIndicatorView.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package de.danoeh.antennapod.view;
-
-import android.animation.ArgbEvaluator;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.core.text.TextUtilsCompat;
-import androidx.core.view.ViewCompat;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.viewpager2.widget.ViewPager2;
-
-import java.util.Locale;
-
-public class PagerIndicatorView extends View {
- private final Paint paint = new Paint();
- private float position = 0;
- private int numPages = 0;
- private int disabledPage = -1;
- private int circleColor = 0;
- private int circleColorHighlight = -1;
- private boolean isLocaleRtl = false;
-
- public PagerIndicatorView(Context context) {
- super(context);
- setup();
- }
-
- public PagerIndicatorView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- setup();
- }
-
- public PagerIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- setup();
- }
-
- private void setup() {
- isLocaleRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault())
- == ViewCompat.LAYOUT_DIRECTION_RTL;
-
- paint.setAntiAlias(true);
- paint.setStyle(Paint.Style.FILL);
-
- int[] colorAttrs = new int[]{android.R.attr.textColorSecondary};
- TypedArray a = getContext().obtainStyledAttributes(colorAttrs);
- circleColorHighlight = a.getColor(0, 0xffffffff);
- circleColor = (Integer) new ArgbEvaluator().evaluate(0.8f, 0x00ffffff, circleColorHighlight);
- a.recycle();
- }
-
- /**
- * Visual and logical position distinction only happens in RTL locales (e.g. Persian)
- * where pages positions are flipped thus it does nothing in LTR locales (e.g. English)
- */
- private float logicalPositionToVisual(float position) {
- return isLocaleRtl ? numPages - 1 - position : position;
- }
-
- public void setViewPager(ViewPager2 pager) {
- numPages = pager.getAdapter().getItemCount();
- pager.getAdapter().registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
- @Override
- public void onChanged() {
- numPages = pager.getAdapter().getItemCount();
- invalidate();
- }
- });
- pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- PagerIndicatorView.this.position = logicalPositionToVisual(
- position + positionOffset);
- invalidate();
- }
- });
- }
-
- public void setDisabledPage(int disabledPage) {
- this.disabledPage = (int) logicalPositionToVisual(disabledPage);
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- for (int i = 0; i < numPages; i++) {
- if ((int) Math.floor(position) == i) {
- // This is the current dot
- drawCircle(canvas, i, (float) (1 - (position - Math.floor(position))));
- } else if ((int) Math.ceil(position) == i) {
- // This is the next dot
- drawCircle(canvas, i, (float) (position - Math.floor(position)));
- } else {
- drawCircle(canvas, i, 0);
- }
- }
- }
-
- private void drawCircle(Canvas canvas, int position, float frac) {
- float availableHeight = canvas.getHeight() - getPaddingTop() - getPaddingBottom();
- float circleRadiusSmall = availableHeight * 0.26f;
- float circleRadiusBig = availableHeight * 0.35f;
- float circleRadiusDelta = (circleRadiusBig - circleRadiusSmall);
- float start = 0.5f * (canvas.getWidth() - numPages * 1.5f * availableHeight);
- paint.setStrokeWidth(availableHeight * 0.3f);
-
- if (position == disabledPage) {
- paint.setStyle(Paint.Style.STROKE);
- } else {
- paint.setStyle(Paint.Style.FILL_AND_STROKE);
- }
-
- paint.setColor((Integer) new ArgbEvaluator().evaluate(frac, circleColor, circleColorHighlight));
- canvas.drawCircle(start + (position * 1.5f + 0.75f) * availableHeight, 0.5f * availableHeight + getPaddingTop(),
- circleRadiusSmall + frac * circleRadiusDelta, paint);
- }
-} \ No newline at end of file
diff --git a/app/src/main/play/listings/ca/full-description.txt b/app/src/main/play/listings/ca/full-description.txt
new file mode 100644
index 000000000..90227a4c0
--- /dev/null
+++ b/app/src/main/play/listings/ca/full-description.txt
@@ -0,0 +1,31 @@
+AntennaPod és un reproductor i organitzador de podcasts que et dona accés instantani a milions de podcasts tant de pagament com gratuïts, des de podcasters independents fins a grans publicacions com la BBC, NPR i CNN. Afegeix, importa i exporta els seus feeds sense problemes usant la base de dates de podcasts de iTunes, arxius OPML o simples URLs RSS.
+Descarrega, transmet o posa en cola episodis i disfruta'ls com tu vulgues amb velocitats de reproducció ajustables, suport per a capítols i un temporitzador per a dormir.
+Estalvia esforç, bateria i us de dades mòbils amb controls d'automatització per a descarregar (hores específiques, intervals i xarxes Wi-Fi) i esborrar episodis (basant-se en els teus favorits i els ajustos de retard).
+
+Fet per entusiastes dels podcasts, AntennaPod es lliure en tots els sentits de la paraula: codi obert, sense cost, sense anuncis.
+
+<b>Importa, organitza i reprodueix</b>
+• Organitza la reproducció desde qualsevol lloc: widget a la pantalla principal, notificacions de sistema i controls d'auricular amb fil o bluetooth.
+• Afegeix i importa feeds via iTunes, gPodder.net, fitxers OPML o enllaços RSS o Atom.
+• Disfruta escoltant a la teua manera amb velocitat de reproducció ajustable, suport per a capitols, memòria de posició de reproducció i un avançat temporitzador per a dormir (que pots resetetjar agitant el mòbil)
+• Accedix a feeds i episodis protegits amb contrasenya
+
+<b>Organitza, comparteix i aprecia</b>
+• Recorda als millors dels millors marcant episodis com a favorits.
+• Troba un episodi usant el historial de reproducció o buscant títols i notes.
+• Comparteix episodis i feeds a través d'opcions avançades de medis socials i email, els serveis de gPodder.net i via l'exportació OPML.
+
+<b>Controla el sistema</b>
+• Pren control de les descarregues automàtiques: tria feeds, exclou xarxes mòbils, selecciona xarxes WiFi específiques, requereix que el telèfon estiga carregant i selecciona hores o intervals.
+• Gestioneu l'emmagatzematge ajustant la quantitat d'episodis en emmagatzematge temporal, l'esborrat intel·ligent i triant la vostra ubicació preferida.
+• Adapteu-vos al vostre entorn fent servir el tema clar o el fosc.
+• Feu còpies de seguretat de les vostres subscripcions amb la integració amb gPodder.net i l'exportació a OPML.
+
+<b>Uniu-vos a la comunitat d'AntennaPod!</b>
+L'AntennaPod el desenvolupen voluntaris. Podeu col·laborar, amb codi o comentaris.
+
+Els amigables membres del nostre fòrum estaran contents d'ajudar-vos amb qualsevol pregunta. Esteu convidats a parlar de les features i de podcasting en general, a més.
+https://forum.antennapod.org/
+
+Transifex és el lloc on podeu ajudar amb les traduccions.
+https://www.transifex.com/antennapod/antennapod \ No newline at end of file
diff --git a/app/src/main/play/listings/ca/short-description.txt b/app/src/main/play/listings/ca/short-description.txt
new file mode 100644
index 000000000..25b884d1b
--- /dev/null
+++ b/app/src/main/play/listings/ca/short-description.txt
@@ -0,0 +1 @@
+Reproductor i organitzador de podcasts, fàcil d'usar, flexible i de codi obert. \ No newline at end of file
diff --git a/app/src/main/play/listings/ca/title.txt b/app/src/main/play/listings/ca/title.txt
new file mode 100644
index 000000000..31552f353
--- /dev/null
+++ b/app/src/main/play/listings/ca/title.txt
@@ -0,0 +1 @@
+AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/listings/cs-CZ/full-description.txt b/app/src/main/play/listings/cs-CZ/full-description.txt
new file mode 100644
index 000000000..8411a2e7f
--- /dev/null
+++ b/app/src/main/play/listings/cs-CZ/full-description.txt
@@ -0,0 +1,31 @@
+AntennaPod je správce a přehrávač podcastů, co vám umožňuje okamžitý přístup k milionům podcastů (placené i zdarma) od nezávislých autorů, přes velké zahraniční korporace jako BBC, NPR a CNN, až po české DVTV nebo Český rozhlas. Své podcasty můžete jednoduše přidávat, importovat i exportovat pomocí iTunes, OPML souborů nebo RSS.
+Stahujte, streamujte nebo si vytvořte frontu epizod a užijte si poslech tak, jak ho máte rádi s nastavitelnou rychlostí přehrávání, podporou kapitol a s časovačem vypnutí.
+Ušetři si námahu, baterku i mobilní data s pomocí robustní automatické kontroly nad stahováním epizod (urči časy, intervaly a WIFI sítě) a mazáním epizod (na základě oblíbenosti a nastavení zpoždění).
+
+Vytvořeno nadšenci do podcastů, AntennaPod je otevřený software (OSS), zdarma a bez reklam.
+
+<b>Importujte, zorganizujte a přehrávejte</b>
+• Ovládejte přehrávání odkudkoli: z widgetu na domovské obrazovce, z oznámení nebo pomocí tlačítek na sluchátkách včetně Bluetooth
+• Přidejte a importujte podcasty přes iTunes anebo gPodder.net, OPML soubory a RSS anebo Atom odkazy
+• Užijte si poslech s nastavitelnou rychlostí přehrávání, podporou kapitol, zapamatování poslední pozice přehrávání a pokročilým časovačem vypnutí (restart zatřesením, snížení hlasitosti)
+• Přistupujte k zaheslovaným podcastům a epizodám
+
+<b>Udržovat přehled, sdílet & ocenit</b>
+• Udržujte si seznam toho nejlepšího z nejlepšího přidáním epizod do oblíbených
+• Vyhledej tu správnou epizodu ve své historii přehrávání nebo prohledáním jmen a popisů epizod
+• Sdílej epizody a kanály pomocí pokročilých nastavení pro sociální média a email, gPodder.net službu nebo OPML export
+
+<b>Ovládat systém</b>
+• Převezmi kontrolu nad automatickým stahováním: vybírej kanály, vyluč mobilní sítě, vyber specifické WIFI sítě, vyžaduj stav nabíjení telefonu a nastav časy nebo intervaly
+• Spravujte využití úložiště nastavením množství uložených epizod, chytrého mazání a výběrem místa uložení
+• Přizpůsobte si aplikaci svému prostředí pomocí světlého nebo tmavého motivu
+• Zálohujte své sbírky pomocí služby gPodder.net nebo exportem OPML souborů
+
+<b>Přidejte se do komunity AntennaPodu!</b>
+AntennaPod je aktivně vyvíjen dobrovolníky. Můžete přispět také svým kódem nebo komentáři!
+
+Naše přátelská členská základna vám ráda zodpoví jakékoli dotazy. Zveme vás k diskuzi o AntennaPodu nebo i podcastech obecně.
+https://forum.antennapod.org/
+
+Na Transifexu můžete pomoct s překladem:
+https://www.transifex.com/antennapod/antennapod \ No newline at end of file
diff --git a/app/src/main/play/listings/cs-CZ/short-description.txt b/app/src/main/play/listings/cs-CZ/short-description.txt
new file mode 100644
index 000000000..e0df116ee
--- /dev/null
+++ b/app/src/main/play/listings/cs-CZ/short-description.txt
@@ -0,0 +1 @@
+Jednoduchý a flexibilní open-source program pro správu a poslech podcastů \ No newline at end of file
diff --git a/app/src/main/play/listings/cs-CZ/title.txt b/app/src/main/play/listings/cs-CZ/title.txt
new file mode 100644
index 000000000..31552f353
--- /dev/null
+++ b/app/src/main/play/listings/cs-CZ/title.txt
@@ -0,0 +1 @@
+AntennaPod \ No newline at end of file
diff --git a/app/src/main/play/listings/de-DE/graphics/large-tablet-screenshots/tablet.png b/app/src/main/play/listings/de-DE/graphics/large-tablet-screenshots/tablet.png
new file mode 100644
index 000000000..5ff81f1e0
--- /dev/null
+++ b/app/src/main/play/listings/de-DE/graphics/large-tablet-screenshots/tablet.png
Binary files differ
diff --git a/app/src/main/play/listings/en-US/graphics/large-tablet-screenshots/tablet.png b/app/src/main/play/listings/en-US/graphics/large-tablet-screenshots/tablet.png
new file mode 100644
index 000000000..2defb5ce9
--- /dev/null
+++ b/app/src/main/play/listings/en-US/graphics/large-tablet-screenshots/tablet.png
Binary files differ
diff --git a/app/src/main/play/listings/es-ES/full-description.txt b/app/src/main/play/listings/es-ES/full-description.txt
index b15dd1762..52897ce9c 100644
--- a/app/src/main/play/listings/es-ES/full-description.txt
+++ b/app/src/main/play/listings/es-ES/full-description.txt
@@ -24,8 +24,8 @@ Creado por entusiastas del pódcast, AntennaPod es libre en todos los sentidos:
<b>¡Únete a la comunidad AntennaPod!</b>
AntennaPod es desarrollado por voluntarios. ¡Tú también puedes contribuir, con tu código o con tus comentarios!
-Visita GitHub para solicitar características nuevas, reportar fallos y contribuir con código:
-https://www.github.com/AntennaPod/AntennaPod
+Nuestros amables miembros del foro te ayudarán con cualquier duda que tengas. Estás invitado a discutir sobre las características y el podcasting en general.
+https://forum.antennapod.org/
Ayuda con las traducciones en Transifex:
https://www.transifex.com/antennapod/antennapod \ No newline at end of file
diff --git a/app/src/main/play/release-notes/en-US/default.txt b/app/src/main/play/release-notes/en-US/default.txt
index a27f2d0c0..c911a4f1f 100644
--- a/app/src/main/play/release-notes/en-US/default.txt
+++ b/app/src/main/play/release-notes/en-US/default.txt
@@ -1,7 +1,7 @@
-We are proud to release version 2.0 with a new logo and refreshed user interface.
-Thank you to 6420 users who participated in the vote for the new logo!
-
-- Support for chapter images (only new episodes, by @ByteHamster)
-- Skip intro and ending per feed (by @tonytamsf)
-- Option to show notifications after episodes have been auto-downloaded (by @shortspider)
-- Bug fixes and improvements (by @ebraminio, @tonytamsf, @JessieVela, @ByteHamster and more)
+- A long-standing wish of many: playing local files! In the 'Add podcast' screen simply tap 'Add local folder' and select a location on your phone! (@ByteHamster, @igoralmeida & @damoasda)
+- Pick a country for the 'Discover' screen (@tonytamsf)
+- Keyboard shortcuts (@asdoi)
+- Search the PodcastIndex.org database (@edwinhere)
+- Pull to refresh (@asdoi)
+- Playback speed & filter dialogs (@ByteHamster & @bws9000)
+- Smooth sleep timer volume (@olivoto)
diff --git a/app/src/main/res/layout/activity_widget_config.xml b/app/src/main/res/layout/activity_widget_config.xml
index ca8aba52d..6e31aec0d 100644
--- a/app/src/main/res/layout/activity_widget_config.xml
+++ b/app/src/main/res/layout/activity_widget_config.xml
@@ -22,7 +22,7 @@
android:id="@+id/widget_config_preview"
layout="@layout/player_widget"
android:layout_width="match_parent"
- android:layout_height="80dp"
+ android:layout_height="96dp"
android:layout_gravity="center"
android:layout_margin="16dp" />
</FrameLayout>
@@ -68,13 +68,38 @@
android:max="100"
android:progress="100" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <CheckBox
+ android:id="@+id/ckRewind"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Rewind" />
+
+ <CheckBox
+ android:id="@+id/ckFastForward"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Forward" />
+
+ <CheckBox
+ android:id="@+id/ckSkip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Skip" />
+ </LinearLayout>
<Button
android:id="@+id/butConfirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/widget_create_button" />
-
</LinearLayout>
</LinearLayout>
diff --git a/app/src/main/res/layout/addfeed.xml b/app/src/main/res/layout/addfeed.xml
index ee57fdbed..d6ebd58d7 100644
--- a/app/src/main/res/layout/addfeed.xml
+++ b/app/src/main/res/layout/addfeed.xml
@@ -35,11 +35,11 @@
android:layout_marginRight="8dp"
android:contentDescription="@string/search_podcast_hint"
app:srcCompat="?attr/action_search"
- android:id="@+id/search_icon"
+ android:id="@+id/searchButton"
android:scaleType="center"/>
<EditText
- android:id="@+id/combinedFeedSearchBox"
+ android:id="@+id/combinedFeedSearchEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@@ -87,7 +87,7 @@
android:textColor="?android:attr/textColorPrimary"/>
<TextView
- android:id="@+id/btn_add_via_url"
+ android:id="@+id/addViaUrlButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawableStartCompat="?attr/feed"
@@ -96,7 +96,7 @@
android:text="@string/add_podcast_by_url"/>
<TextView
- android:id="@+id/btn_add_local_folder"
+ android:id="@+id/addLocalFolderButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawableStartCompat="?attr/ic_folder"
@@ -105,7 +105,7 @@
android:text="@string/add_local_folder"/>
<TextView
- android:id="@+id/btn_search_itunes"
+ android:id="@+id/searchItunesButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawableStartCompat="?attr/action_search"
@@ -114,7 +114,7 @@
android:text="@string/search_itunes_label"/>
<TextView
- android:id="@+id/btn_search_fyyd"
+ android:id="@+id/searchFyydButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawableStartCompat="?attr/action_search"
@@ -123,7 +123,7 @@
android:text="@string/search_fyyd_label"/>
<TextView
- android:id="@+id/btn_search_gpodder"
+ android:id="@+id/searchGPodderButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawableStartCompat="?attr/action_search"
@@ -132,7 +132,7 @@
android:text="@string/browse_gpoddernet_label"/>
<TextView
- android:id="@+id/btn_search_podcastindex"
+ android:id="@+id/searchPodcastIndexButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawableStartCompat="?attr/action_search"
@@ -141,7 +141,7 @@
android:text="@string/search_podcastindex_label"/>
<TextView
- android:id="@+id/btn_opml_import"
+ android:id="@+id/opmlImportButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:drawableStartCompat="?attr/av_download"
diff --git a/app/src/main/res/layout/audioplayer_fragment.xml b/app/src/main/res/layout/audioplayer_fragment.xml
index 225fdd98c..3b065cefc 100644
--- a/app/src/main/res/layout/audioplayer_fragment.xml
+++ b/app/src/main/res/layout/audioplayer_fragment.xml
@@ -15,15 +15,15 @@
app:navigationIcon="?homeAsUpIndicator"
android:id="@+id/toolbar"/>
- <de.danoeh.antennapod.view.PagerIndicatorView
- android:id="@+id/page_indicator"
- android:layout_height="16dp"
- android:layout_width="40dp"
- android:layout_marginTop="-12dp"
- android:padding="4dp"
+ <com.google.android.material.tabs.TabLayout
+ android:id="@+id/sliding_tabs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
- android:contentDescription="@string/switch_pages"
- android:layout_centerHorizontal="true"/>
+ android:background="?android:attr/windowBackground"
+ app:tabBackground="?attr/selectableItemBackground"
+ app:tabMode="fixed"
+ app:tabGravity="fill"/>
<FrameLayout
android:id="@+id/playerFragment"
@@ -39,7 +39,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="@id/playtime_layout"
- android:layout_below="@id/toolbar"
+ android:layout_below="@id/sliding_tabs"
android:foreground="?android:windowContentOverlay"
android:layout_marginBottom="12dp"/>
diff --git a/app/src/main/res/layout/bug_report.xml b/app/src/main/res/layout/bug_report.xml
index 1cc9bc9d8..e97e85265 100644
--- a/app/src/main/res/layout/bug_report.xml
+++ b/app/src/main/res/layout/bug_report.xml
@@ -16,12 +16,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
- <Button
- android:id="@+id/btn_export_logcat"
- android:text="@string/export_logs"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
<TextView
android:layout_marginTop="8dp"
android:id="@+id/crash_report_logs"
diff --git a/app/src/main/res/layout/edit_text_dialog.xml b/app/src/main/res/layout/edit_text_dialog.xml
index 6bf0bc6cb..b442b92ce 100644
--- a/app/src/main/res/layout/edit_text_dialog.xml
+++ b/app/src/main/res/layout/edit_text_dialog.xml
@@ -10,6 +10,6 @@
android:layout_height="wrap_content"
android:inputType="text"
android:ems="10"
- android:id="@+id/text" />
+ android:id="@+id/urlEditText" />
</LinearLayout>
diff --git a/app/src/main/res/layout/feeditem_fragment.xml b/app/src/main/res/layout/feeditem_fragment.xml
index 72effc585..049182803 100644
--- a/app/src/main/res/layout/feeditem_fragment.xml
+++ b/app/src/main/res/layout/feeditem_fragment.xml
@@ -166,6 +166,15 @@
</LinearLayout>
</LinearLayout>
+ <TextView
+ android:id="@+id/noMediaLabel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:textAlignment="center"
+ android:background="?android:attr/dividerVertical"
+ android:text="@string/no_media_label"/>
+
<View
android:layout_width="match_parent"
android:layout_height="1dp"
diff --git a/app/src/main/res/layout/filter_dialog.xml b/app/src/main/res/layout/filter_dialog.xml
index 39e9258d9..d700f0365 100644
--- a/app/src/main/res/layout/filter_dialog.xml
+++ b/app/src/main/res/layout/filter_dialog.xml
@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:paddingLeft="24dp"
- android:paddingTop="24dp"
- android:paddingRight="24dp"
- android:paddingBottom="8dp">
-
-</LinearLayout> \ No newline at end of file
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:id="@+id/filter_rows"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="24dp"
+ android:paddingTop="24dp"
+ android:paddingRight="24dp"
+ android:paddingBottom="8dp">
+ </LinearLayout>
+</ScrollView>
diff --git a/app/src/main/res/layout/filter_dialog_row.xml b/app/src/main/res/layout/filter_dialog_row.xml
index 0863997b3..5011812d9 100644
--- a/app/src/main/res/layout/filter_dialog_row.xml
+++ b/app/src/main/res/layout/filter_dialog_row.xml
@@ -28,7 +28,7 @@
android:layout_marginRight="2dp"
android:layout_weight="1"
android:background="?attr/filter_dialog_button_background"
- android:button="@android:color/transparent"
+ style="@style/NoButtonRadio"
android:foreground="?android:attr/selectableItemBackground"
android:checked="false"
android:gravity="center"
@@ -40,7 +40,7 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?attr/filter_dialog_button_background"
- android:button="@android:color/transparent"
+ style="@style/NoButtonRadio"
android:foreground="?android:attr/selectableItemBackground"
android:checked="false"
android:gravity="center"
@@ -53,7 +53,7 @@
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/ic_filter_close"
- android:button="@android:color/transparent"
+ style="@style/NoButtonRadio"
android:foreground="?android:attr/selectableItemBackground"
android:layout_gravity="center_vertical"
android:checked="true" />
diff --git a/app/src/main/res/layout/gpodnet_podcast_list.xml b/app/src/main/res/layout/gpodnet_podcast_list.xml
index ae0a400f1..a6918f8d4 100644
--- a/app/src/main/res/layout/gpodnet_podcast_list.xml
+++ b/app/src/main/res/layout/gpodnet_podcast_list.xml
@@ -2,18 +2,9 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <androidx.appcompat.widget.Toolbar
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?attr/actionBarSize"
- android:theme="?attr/actionBarTheme"
- app:navigationIcon="?homeAsUpIndicator"
- android:id="@+id/toolbar"/>
-
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
@@ -27,7 +18,7 @@
android:paddingTop="@dimen/list_vertical_padding"
android:stretchMode="columnWidth"
android:verticalSpacing="8dp"
- android:layout_below="@id/toolbar"
+ android:layout_alignParentTop="true"
tools:listitem="@layout/gpodnet_podcast_listitem" />
<ProgressBar
diff --git a/app/src/main/res/layout/gpodnetauth_activity.xml b/app/src/main/res/layout/gpodnetauth_activity.xml
deleted file mode 100644
index c096c20cf..000000000
--- a/app/src/main/res/layout/gpodnetauth_activity.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-<ViewFlipper
- android:id="@+id/viewflipper"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-</ScrollView> \ No newline at end of file
diff --git a/app/src/main/res/layout/gpodnetauth_credentials.xml b/app/src/main/res/layout/gpodnetauth_credentials.xml
index 895b0999c..291b98da3 100644
--- a/app/src/main/res/layout/gpodnetauth_credentials.xml
+++ b/app/src/main/res/layout/gpodnetauth_credentials.xml
@@ -1,96 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="16dp">
-
- <ImageView
- android:id="@id/icon"
- android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/gpodder_icon" />
+ android:orientation="vertical">
- <TextView
- android:id="@id/txtvDescription"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/gpodnetauth_login_descr"
- android:layout_below="@id/icon"
- android:textSize="@dimen/text_size_medium"
- android:textColor="?android:attr/textColorPrimary"/>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginBottom="8dp">
- <EditText
- android:id="@+id/etxtUsername"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/username_label"
- android:layout_below="@id/txtvDescription"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:cursorVisible="true"
- android:maxLines="1"
- android:inputType="text"
- android:imeOptions="actionNext|flagNoFullscreen"
- android:nextFocusForward="@id/etxtPassword"/>
+ <ImageView
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:src="@drawable/gpodder_icon"/>
- <EditText
- android:id="@+id/etxtPassword"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/password_label"
- android:layout_below="@id/etxtUsername"
- android:inputType="textPassword"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:cursorVisible="true"
- android:imeOptions="actionGo|flagNoFullscreen"
- android:imeActionLabel="@string/gpodnetauth_login_butLabel"/>
+ <TextView
+ android:id="@+id/createAccountButton"
+ android:layout_width="0dp"
+ android:textAlignment="textEnd"
+ android:layout_height="wrap_content"
+ android:background="?attr/selectableItemBackground"
+ android:textColor="?colorAccent"
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical|end"
+ android:text="@string/create_account"/>
+ </LinearLayout>
- <Button
- android:id="@+id/butLogin"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/etxtPassword"
- android:layout_alignParentRight="true"
- android:layout_alignParentEnd="true"
- android:text="@string/gpodnetauth_login_butLabel"/>
+ <com.google.android.material.textfield.TextInputLayout
+ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
- <TextView
- android:id="@+id/txtvError"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_below="@id/etxtPassword"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:layout_toLeftOf="@id/butLogin"
- android:layout_toStartOf="@id/butLogin"
- android:textColor="@color/download_failed_red"
- android:textSize="@dimen/text_size_small"
- android:maxLines="2"
- android:ellipsize="end"
- android:gravity="center"
- android:layout_margin="16dp"
- tools:text="Error message"
- tools:background="@android:color/holo_green_dark" />
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/etxtUsername"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/username_label"
+ android:lines="1"
+ android:imeOptions="actionNext|flagNoFullscreen"/>
- <ProgressBar
- android:id="@+id/progBarLogin"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:layout_alignTop="@+id/butLogin"
- android:layout_toLeftOf="@+id/butLogin"
- android:layout_toStartOf="@+id/butLogin"/>
+ </com.google.android.material.textfield.TextInputLayout>
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="@dimen/text_size_medium"
- android:textColor="?android:attr/textColorPrimary"
- android:layout_marginTop="16dp"
- android:text="@string/gpodnetauth_login_register"
- android:autoLink="web"
- android:layout_below="@id/butLogin"/>
-</RelativeLayout> \ No newline at end of file
+ <com.google.android.material.textfield.TextInputLayout
+ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/etxtPassword"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/password_label"
+ android:inputType="textPassword"
+ android:lines="1"
+ android:imeOptions="actionNext|flagNoFullscreen"
+ android:imeActionLabel="@string/gpodnetauth_login_butLabel"/>
+
+ </com.google.android.material.textfield.TextInputLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="end|center_vertical">
+
+ <TextView
+ android:id="@+id/credentialsError"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:textColor="@color/download_failed_red"
+ android:textSize="@dimen/text_size_small"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:gravity="center"
+ tools:text="Error message"
+ tools:background="@android:color/holo_green_dark"/>
+
+ <ProgressBar
+ android:id="@+id/progBarLogin"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:layout_gravity="right"/>
+
+ <Button
+ android:id="@+id/butLogin"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/gpodnetauth_login_butLabel"/>
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/gpodnetauth_device.xml b/app/src/main/res/layout/gpodnetauth_device.xml
index 7837121e1..656ba0889 100644
--- a/app/src/main/res/layout/gpodnetauth_device.xml
+++ b/app/src/main/res/layout/gpodnetauth_device.xml
@@ -1,114 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="16dp">
-
- <TextView
- android:id="@+id/txtvTitle"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/gpodnetauth_device_title"
- android:layout_alignParentTop="true"
- android:layout_marginBottom="16dp"
- style="@style/AntennaPod.TextView.Heading"/>
+ android:orientation="vertical">
- <TextView
- android:id="@+id/txtvDescription"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/gpodnetauth_device_descr"
- android:layout_below="@id/txtvTitle"
- android:textSize="@dimen/text_size_medium"
- android:textColor="?android:attr/textColorPrimary"/>
-
- <EditText
- android:id="@+id/etxtCaption"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/gpodnetauth_device_caption"
- android:layout_below="@id/txtvDescription"
- android:imeOptions="flagNoFullscreen"/>
+ <com.google.android.material.textfield.TextInputLayout
+ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
- <TextView
- android:id="@+id/txtvDeviceID"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/gpodnetauth_device_deviceID"
- android:textSize="@dimen/text_size_medium"
- android:layout_below="@id/etxtCaption"/>
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/deviceName"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/gpodnetauth_device_name"
+ android:lines="1"
+ android:imeOptions="actionNext|flagNoFullscreen"/>
- <EditText
- android:id="@+id/etxtDeviceID"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/txtvDeviceID"
- android:layout_alignParentRight="true"
- android:layout_alignParentEnd="true"
- android:imeOptions="flagNoFullscreen"/>
+ </com.google.android.material.textfield.TextInputLayout>
<Button
- android:id="@+id/butCreateNewDevice"
- android:layout_width="wrap_content"
+ android:id="@+id/createDeviceButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right|end"
+ android:text="@string/gpodnetauth_create_device"/>
+
+ <TextView
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignParentEnd="true"
- android:layout_below="@id/etxtDeviceID"
- android:text="@string/gpodnetauth_device_butCreateNewDevice"/>
+ style="@style/AntennaPod.TextView.Heading"
+ android:layout_marginTop="16dp"
+ android:text="@string/gpodnetauth_existing_devices"/>
<TextView
- android:id="@+id/txtvError"
- android:layout_width="0dp"
+ android:id="@+id/deviceSelectError"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:layout_below="@id/etxtDeviceID"
- android:layout_toLeftOf="@id/butCreateNewDevice"
- android:layout_toStartOf="@id/butCreateNewDevice"
android:textColor="@color/download_failed_red"
android:textSize="@dimen/text_size_small"
+ android:visibility="gone"
tools:text="Error message"
tools:background="@android:color/holo_green_dark" />
- <ProgressBar
- android:id="@+id/progbarCreateDevice"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignTop="@id/butCreateNewDevice"
- android:layout_toLeftOf="@id/butCreateNewDevice"
- android:layout_toStartOf="@id/butCreateNewDevice"
- android:textColor="@color/download_failed_red"
- android:textSize="@dimen/text_size_medium"
- android:visibility="gone"
- />
-
- <TextView
- android:id="@+id/txtvChooseExistingDevice"
+ <LinearLayout
+ android:id="@+id/devicesContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/gpodnetauth_device_chooseExistingDevice"
- android:layout_below="@id/butCreateNewDevice"
- android:textColor="?android:attr/textColorPrimary"
- android:textSize="@dimen/text_size_medium"
- android:layout_marginTop="32dp"/>
+ android:orientation="vertical" />
- <Button
- android:id="@+id/butChooseExistingDevice"
+ <ProgressBar
+ android:id="@+id/progbarCreateDevice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/gpodnetauth_device_butChoose"
- android:layout_below="@+id/spinnerChooseDevice"
- android:layout_alignParentRight="true"
- android:layout_alignParentEnd="true"/>
-
- <Spinner
- android:id="@+id/spinnerChooseDevice"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/txtvChooseExistingDevice"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"/>
+ android:textColor="@color/download_failed_red"
+ android:visibility="gone" />
-</RelativeLayout> \ No newline at end of file
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/gpodnetauth_device_row.xml b/app/src/main/res/layout/gpodnetauth_device_row.xml
new file mode 100644
index 000000000..d39c00571
--- /dev/null
+++ b/app/src/main/res/layout/gpodnetauth_device_row.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp">
+
+ <Button
+ android:id="@+id/selectDeviceButton"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?attr/materialButtonOutlinedStyle" />
+</FrameLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/gpodnetauth_dialog.xml b/app/src/main/res/layout/gpodnetauth_dialog.xml
new file mode 100644
index 000000000..a70b76a49
--- /dev/null
+++ b/app/src/main/res/layout/gpodnetauth_dialog.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ android:clipToPadding="false">
+ <ViewFlipper
+ android:id="@+id/viewflipper"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inAnimation="@anim/slide_right_in"
+ android:outAnimation="@anim/slide_left_out">
+
+ <include layout="@layout/gpodnetauth_host" />
+ <include layout="@layout/gpodnetauth_credentials" />
+ <include layout="@layout/gpodnetauth_device" />
+ <include layout="@layout/gpodnetauth_finish" />
+
+ </ViewFlipper>
+</ScrollView> \ No newline at end of file
diff --git a/app/src/main/res/layout/gpodnetauth_finish.xml b/app/src/main/res/layout/gpodnetauth_finish.xml
index fdaa0d5d0..f0bcfd4dc 100644
--- a/app/src/main/res/layout/gpodnetauth_finish.xml
+++ b/app/src/main/res/layout/gpodnetauth_finish.xml
@@ -1,46 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="16dp">
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
<ImageView
android:id="@id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
android:src="@drawable/gpodder_icon" />
<TextView
- android:id="@+id/txtvTitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/icon"
- android:text="@string/gpodnetauth_finish_title"
- style="@style/AntennaPod.TextView.Heading"/>
-
- <TextView
android:id="@+id/txtvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gpodnetauth_finish_descr"
- android:layout_below="@id/txtvTitle"
- android:textSize="@dimen/text_size_medium"
android:textColor="?android:attr/textColorPrimary" />
<Button
android:id="@+id/butSyncNow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/txtvDescription"
- android:layout_marginTop="16dp"
+ android:layout_marginTop="8dp"
android:text="@string/gpodnetauth_finish_butsyncnow"/>
- <Button
- android:id="@+id/butGoMainscreen"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/butSyncNow"
- android:text="@string/gpodnetauth_finish_butgomainscreen"/>
-
-</RelativeLayout> \ No newline at end of file
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/gpodnetauth_host.xml b/app/src/main/res/layout/gpodnetauth_host.xml
new file mode 100644
index 000000000..52c5fdb5d
--- /dev/null
+++ b/app/src/main/res/layout/gpodnetauth_host.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <RadioGroup
+ android:id="@+id/serverRadioGroup"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <RadioButton
+ android:id="@+id/officialServerRadio"
+ android:text="@string/gpodnetauth_server_official"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:checked="true"/>
+ <RadioButton
+ android:id="@+id/customServerRadio"
+ android:text="@string/gpodnetauth_server_custom"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </RadioGroup>
+
+ <com.google.android.material.textfield.TextInputLayout
+ android:id="@+id/serverUrlTextInput"
+ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/serverUrlText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/gpodnetauth_host"
+ android:inputType="textNoSuggestions"
+ android:lines="1"
+ android:imeOptions="actionNext|flagNoFullscreen" />
+
+ </com.google.android.material.textfield.TextInputLayout>
+
+ <Button
+ android:id="@+id/chooseHostButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right|end"
+ android:text="@string/gpodnetauth_select_server"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/quick_feed_discovery.xml b/app/src/main/res/layout/quick_feed_discovery.xml
index 0c55311e3..dd720afed 100644
--- a/app/src/main/res/layout/quick_feed_discovery.xml
+++ b/app/src/main/res/layout/quick_feed_discovery.xml
@@ -23,7 +23,7 @@
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:minHeight="0dp"
+ android:minHeight="48dp"
android:minWidth="0dp"
android:text="@string/discover_more"
style="@style/Widget.MaterialComponents.Button.TextButton"
@@ -85,6 +85,7 @@
</RelativeLayout>
<TextView
+ android:id="@+id/discover_powered_by_itunes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorTertiary"
diff --git a/app/src/main/res/layout/time_dialog.xml b/app/src/main/res/layout/time_dialog.xml
index 6523bb1be..6b6ab3195 100644
--- a/app/src/main/res/layout/time_dialog.xml
+++ b/app/src/main/res/layout/time_dialog.xml
@@ -2,6 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
@@ -52,10 +53,11 @@
<TextView
android:text="00:00:00"
android:layout_gravity="center"
+ android:gravity="center"
android:textSize="32sp"
android:textColor="?android:attr/textColorPrimary"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:id="@+id/time"/>
<Button
@@ -64,6 +66,45 @@
android:layout_height="wrap_content"
android:id="@+id/disableSleeptimerButton"/>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/extendSleepFiveMinutesButton"
+ style="?attr/materialButtonOutlinedStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="4dp"
+ android:layout_marginRight="4dp"
+ android:layout_weight="1"
+ android:padding="5dp"
+ tools:text="+5 min" />
+
+ <Button
+ android:id="@+id/extendSleepTenMinutesButton"
+ style="?attr/materialButtonOutlinedStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:layout_weight="1"
+ tools:text="+10 min" />
+
+ <Button
+ android:id="@+id/extendSleepTwentyMinutesButton"
+ style="?attr/materialButtonOutlinedStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:layout_marginRight="4dp"
+ android:layout_marginLeft="4dp"
+ android:layout_weight="1"
+ tools:text="+20 min" />
+
+ </LinearLayout>
+
</LinearLayout>
@@ -93,4 +134,4 @@
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/app/src/main/res/menu/bug_report_options.xml b/app/src/main/res/menu/bug_report_options.xml
new file mode 100644
index 000000000..62963210c
--- /dev/null
+++ b/app/src/main/res/menu/bug_report_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:id="@+id/export_logcat"
+ android:title="@string/export_logs_menu_title" />
+
+</menu> \ No newline at end of file
diff --git a/app/src/main/res/menu/feedinfo.xml b/app/src/main/res/menu/feedinfo.xml
index b1daf1f36..a5fbe0c20 100644
--- a/app/src/main/res/menu/feedinfo.xml
+++ b/app/src/main/res/menu/feedinfo.xml
@@ -8,17 +8,25 @@
android:title="@string/visit_website_label"
android:visible="true"/>
<item
- android:id="@+id/share_link_item"
- custom:showAsAction="collapseActionView"
- android:title="@string/share_website_url_label"/>
- <item
- android:id="@+id/share_download_url_item"
- custom:showAsAction="collapseActionView"
- android:title="@string/share_feed_url_label"/>
+ android:id="@+id/share_parent"
+ custom:showAsAction="ifRoom"
+ android:title="@string/share_label_with_ellipses"
+ android:icon="?attr/ic_share"
+ android:visible="true">
+ <menu android:id="@+id/share_submenu">
+ <item
+ android:id="@+id/share_link_item"
+ custom:showAsAction="collapseActionView"
+ android:title="@string/share_website_url_label"/>
+ <item
+ android:id="@+id/share_download_url_item"
+ custom:showAsAction="collapseActionView"
+ android:title="@string/share_feed_url_label"/>
+ </menu>
+ </item>
<item
android:id="@+id/reconnect_local_folder"
custom:showAsAction="collapseActionView"
android:title="@string/reconnect_local_folder"
android:visible="false" />
-
-</menu>
+</menu> \ No newline at end of file
diff --git a/app/src/main/res/menu/gpodder_podcasts.xml b/app/src/main/res/menu/gpodder_podcasts.xml
deleted file mode 100644
index 93d93157a..000000000
--- a/app/src/main/res/menu/gpodder_podcasts.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:custom="http://schemas.android.com/apk/res-auto">
-
- <item
- android:id="@+id/action_search"
- android:icon="?attr/action_search"
- custom:showAsAction="collapseActionView|ifRoom"
- custom:actionViewClass="androidx.appcompat.widget.SearchView"
- android:title="@string/search_label"/>
-
-</menu>
diff --git a/app/src/main/res/xml/player_widget_info.xml b/app/src/main/res/xml/player_widget_info.xml
index 79cdd4a69..803cc89ed 100644
--- a/app/src/main/res/xml/player_widget_info.xml
+++ b/app/src/main/res/xml/player_widget_info.xml
@@ -8,5 +8,4 @@
android:minWidth="250dp"
android:minResizeWidth="40dp"
android:configure="de.danoeh.antennapod.activity.WidgetConfigActivity">
-
-</appwidget-provider> \ No newline at end of file
+</appwidget-provider>
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 1630dc2f9..805dff47d 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -53,8 +53,8 @@
android:key="project"
android:title="@string/project_pref">
<Preference
- android:key="prefFaq"
- android:title="@string/pref_faq"
+ android:key="prefDocumentation"
+ android:title="@string/documentation_support"
android:icon="?attr/ic_questionmark" />
<Preference
android:key="prefViewForum"
diff --git a/app/src/main/res/xml/preferences_about.xml b/app/src/main/res/xml/preferences_about.xml
index 475a1152f..f56b7f2ac 100644
--- a/app/src/main/res/xml/preferences_about.xml
+++ b/app/src/main/res/xml/preferences_about.xml
@@ -17,7 +17,7 @@
<Preference
android:key="about_privacy_policy"
android:icon="?attr/ic_questionmark"
- android:summary="https://antennapod.org/privacy.html"
+ android:summary="www.antennapod.org/privacy"
android:title="@string/privacy_policy"/>
<Preference
android:key="about_licenses"
diff --git a/app/src/main/res/xml/preferences_gpodder.xml b/app/src/main/res/xml/preferences_gpodder.xml
index 7bddbf245..a210b8e11 100644
--- a/app/src/main/res/xml/preferences_gpodder.xml
+++ b/app/src/main/res/xml/preferences_gpodder.xml
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
-
- <PreferenceScreen
+ <Preference
+ android:key="pref_gpodnet_description"
+ android:icon="@drawable/gpodder_icon"
+ android:summary="@string/gpodnet_description"/>
+ <Preference
android:key="pref_gpodnet_authenticate"
android:title="@string/pref_gpodnet_authenticate_title"
- android:summary="@string/pref_gpodnet_authenticate_sum">
- <intent android:action=".activity.gpoddernet.GpodnetAuthenticationActivity"/>
- </PreferenceScreen>
+ android:summary="@string/pref_gpodnet_authenticate_sum"/>
<Preference
android:key="pref_gpodnet_setlogin_information"
android:title="@string/pref_gpodnet_setlogin_information_title"
@@ -23,8 +24,5 @@
<Preference
android:key="pref_gpodnet_logout"
android:title="@string/pref_gpodnet_logout_title"/>
- <Preference
- android:key="pref_gpodnet_hostname"
- android:title="@string/pref_gpodnet_sethostname_title"/>
</PreferenceScreen>
diff --git a/app/src/main/res/xml/preferences_notifications.xml b/app/src/main/res/xml/preferences_notifications.xml
index 3aa907ca8..237ea5c99 100644
--- a/app/src/main/res/xml/preferences_notifications.xml
+++ b/app/src/main/res/xml/preferences_notifications.xml
@@ -2,21 +2,28 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
- <SwitchPreferenceCompat
- android:defaultValue="true"
- android:enabled="true"
- android:key="prefShowDownloadReport"
- android:summary="@string/pref_showDownloadReport_sum"
- android:title="@string/pref_showDownloadReport_title" />
- <SwitchPreferenceCompat
- android:defaultValue="false"
- android:enabled="true"
- android:key="prefShowAutoDownloadReport"
- android:summary="@string/pref_showAutoDownloadReport_sum"
- android:title="@string/pref_showAutoDownloadReport_title" />
- <SwitchPreferenceCompat
- android:defaultValue="true"
- android:key="pref_gpodnet_notifications"
- android:summary="@string/pref_gpodnet_notifications_sum"
- android:title="@string/pref_gpodnet_notifications_title" />
+ <PreferenceCategory
+ android:title="@string/notification_group_news">
+ <SwitchPreferenceCompat
+ android:defaultValue="false"
+ android:enabled="true"
+ android:key="prefShowAutoDownloadReport"
+ android:summary="@string/notification_channel_episode_auto_download"
+ android:title="@string/notification_channel_auto_download" />
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/notification_group_errors">
+ <SwitchPreferenceCompat
+ android:defaultValue="true"
+ android:enabled="true"
+ android:key="prefShowDownloadReport"
+ android:summary="@string/notification_channel_download_error_description"
+ android:title="@string/notification_channel_download_error" />
+ <SwitchPreferenceCompat
+ android:defaultValue="true"
+ android:key="pref_gpodnet_notifications"
+ android:summary="@string/notification_channel_sync_error_description"
+ android:title="@string/notification_channel_sync_error" />
+ </PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/app/src/main/res/xml/preferences_playback.xml b/app/src/main/res/xml/preferences_playback.xml
index 161332d2f..d2999c59d 100644
--- a/app/src/main/res/xml/preferences_playback.xml
+++ b/app/src/main/res/xml/preferences_playback.xml
@@ -114,7 +114,7 @@
android:title="@string/pref_skip_keeps_episodes_title"/>
</PreferenceCategory>
- <PreferenceCategory android:title="@string/media_player">
+ <PreferenceCategory android:title="@string/experimental_pref">
<ListPreference
android:defaultValue="exoplayer"
android:entries="@array/media_player_options"
@@ -122,9 +122,6 @@
android:title="@string/media_player"
android:summary="@string/pref_media_player_message"
android:entryValues="@array/media_player_values"/>
- </PreferenceCategory>
-
- <PreferenceCategory android:title="@string/experimental_pref">
<SwitchPreferenceCompat
android:defaultValue="false"
android:enabled="true"
diff --git a/app/src/main/res/xml/preferences_user_interface.xml b/app/src/main/res/xml/preferences_user_interface.xml
index 203e14d42..a3cb53307 100644
--- a/app/src/main/res/xml/preferences_user_interface.xml
+++ b/app/src/main/res/xml/preferences_user_interface.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android">
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:search="http://schemas.android.com/apk/com.bytehamster.lib.preferencesearch">
<PreferenceCategory android:title="@string/appearance">
<ListPreference
@@ -44,7 +45,8 @@
android:enabled="true"
android:key="prefExpandNotify"
android:summary="@string/pref_expandNotify_sum"
- android:title="@string/pref_expandNotify_title"/>
+ android:title="@string/pref_expandNotify_title"
+ search:ignore="true"/>
<SwitchPreferenceCompat
android:defaultValue="true"
android:enabled="true"
diff --git a/app/src/play/java/de/danoeh/antennapod/dialog/RatingDialog.java b/app/src/play/java/de/danoeh/antennapod/dialog/RatingDialog.java
index cfadf0772..66072e2fa 100644
--- a/app/src/play/java/de/danoeh/antennapod/dialog/RatingDialog.java
+++ b/app/src/play/java/de/danoeh/antennapod/dialog/RatingDialog.java
@@ -7,7 +7,6 @@ import android.content.SharedPreferences;
import androidx.annotation.VisibleForTesting;
import android.util.Log;
-import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;
diff --git a/config/checkstyle/checkstyle-new-code.xml b/config/checkstyle/checkstyle-new-code.xml
index cb2129a60..3bb35f2cc 100644
--- a/config/checkstyle/checkstyle-new-code.xml
+++ b/config/checkstyle/checkstyle-new-code.xml
@@ -34,6 +34,7 @@
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<module name="AvoidStarImport"/>
+ <module name="UnusedImports"/>
<module name="OneTopLevelClass"/>
<module name="NoLineWrap"/>
<module name="EmptyBlock">
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index d36c1585a..e23962381 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -26,6 +26,7 @@
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="AvoidStarImport"/>
+ <module name="UnusedImports"/>
<module name="OneTopLevelClass"/>
<module name="NoLineWrap"/>
<module name="EmptyBlock">
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java b/core/src/androidTest/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java
deleted file mode 100644
index 1ab194133..000000000
--- a/core/src/androidTest/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package de.danoeh.antennapod.core.syndication.namespace.atom;
-
-import androidx.test.filters.SmallTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-import static org.junit.runners.Parameterized.Parameter;
-import static org.junit.runners.Parameterized.Parameters;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Unit test for {@link AtomText}.
- */
-@SmallTest
-@RunWith(Parameterized.class)
-public class AtomTextTest {
-
- @Parameter(value = 0)
- public String input;
-
- @Parameter(value = 1)
- public String expectedOutput;
-
- @Parameters
- public static Collection<Object[]> initParameters() {
- return Arrays.asList(new Object[][] {
- {"&gt;", ">"},
- {">", ">"},
- {"&lt;Fran&ccedil;ais&gt;", "<Français>"},
- {"ßÄÖÜ", "ßÄÖÜ"},
- {"&quot;", "\""},
- {"&szlig;", "ß"},
- {"&#8217;", "’"},
- {"&#x2030;", "‰"},
- {"&euro;", "€"},
- });
- }
-
- @Test
- public void testProcessingHtml() {
- final AtomText atomText = new AtomText("", new NSAtom(), AtomText.TYPE_HTML);
- atomText.setContent(input);
- assertEquals(expectedOutput, atomText.getProcessedContent());
- }
-}
diff --git a/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
index 04d74f2a2..8fd1df35c 100644
--- a/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
+++ b/core/src/free/java/de/danoeh/antennapod/core/ClientConfig.java
@@ -9,6 +9,7 @@ import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.preferences.UsageStatistics;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
+import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
@@ -32,7 +33,7 @@ public class ClientConfig {
public static PlaybackServiceCallbacks playbackServiceCallbacks;
- public static DBTasksCallbacks dbTasksCallbacks;
+ public static AutomaticDownloadAlgorithm automaticDownloadAlgorithm;
public static CastCallbacks castCallbacks;
diff --git a/core/src/main/assets/html-export-template.html b/core/src/main/assets/html-export-template.html
index 19d63f6ca..e4d3ffd31 100644
--- a/core/src/main/assets/html-export-template.html
+++ b/core/src/main/assets/html-export-template.html
@@ -5,14 +5,15 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* {
- font-family: 'Lato', sans-serif;
+ font-family: "Sarabun", sans-serif;
font-weight: 300;
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
- background: #3498db;
+ background: #0d8eff;
+ background-image: linear-gradient(180deg, #0f9cff, #0682ff);
text-align: center;
padding: 10px;
}
@@ -20,7 +21,7 @@
color: #fff;
font-weight: 300;
display: inline-block;
- margin-top: 40px;
+ margin-top: 30px;
margin-bottom: 20px;
vertical-align: top;
}
@@ -31,7 +32,7 @@
width: 100%;
max-width: 500px;
display: block;
- display: inline-flex;
+ display: inline-flex;
padding: 10px;
}
li > div {
@@ -60,12 +61,14 @@
height: 100px;
margin-right: 10px;
}
- li > div > img {
- float: left;
- }
- li > div > p {
- width: 100%;
- }
+ li > div > img {
+ float: left;
+ text-indent: -10000px;
+ background: #eee;
+ }
+ li > div > p {
+ width: 100%;
+ }
body > a {
color: #ffffff;
display: inline-block;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/DBTasksCallbacks.java b/core/src/main/java/de/danoeh/antennapod/core/DBTasksCallbacks.java
deleted file mode 100644
index 11a6b2c9f..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/DBTasksCallbacks.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.danoeh.antennapod.core;
-
-import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm;
-import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
-
-/**
- * Callbacks for the DBTasks class of the storage module.
- */
-public interface DBTasksCallbacks {
-
- /**
- * Returns the client's implementation of the AutomaticDownloadAlgorithm interface.
- */
- AutomaticDownloadAlgorithm getAutomaticDownloadAlgorithm();
-
- /**
- * Returns the client's implementation of the EpisodeCacheCleanupAlgorithm interface.
- */
- EpisodeCleanupAlgorithm getEpisodeCacheCleanupAlgorithm();
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/DownloadServiceCallbacks.java b/core/src/main/java/de/danoeh/antennapod/core/DownloadServiceCallbacks.java
index ad3fb8d42..ae9b47629 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/DownloadServiceCallbacks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/DownloadServiceCallbacks.java
@@ -37,7 +37,7 @@ public interface DownloadServiceCallbacks {
* <p/>
* The PendingIntent takes users to an activity where they can look at all successful and failed downloads.
*
- * @return A non-null PendingIntent for the notification or null if shouldCreateReport()==false
+ * @return A non-null PendingIntent for the notification
*/
PendingIntent getReportNotificationContentIntent(Context context);
@@ -47,14 +47,8 @@ public interface DownloadServiceCallbacks {
* <p/>
* The PendingIntent takes users to an activity where they can look at their episode queue.
*
- * @return A non-null PendingIntent for the notification or null if shouldCreateReport()==false
+ * @return A non-null PendingIntent for the notification
*/
PendingIntent getAutoDownloadReportNotificationContentIntent(Context context);
-
- /**
- * Returns true if the DownloadService should create a report that shows the number of failed
- * downloads when the service shuts down.
- */
- boolean shouldCreateReport();
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/PlaybackServiceCallbacks.java b/core/src/main/java/de/danoeh/antennapod/core/PlaybackServiceCallbacks.java
index 194ee65ae..3dcaac4dc 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/PlaybackServiceCallbacks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/PlaybackServiceCallbacks.java
@@ -19,11 +19,4 @@ public interface PlaybackServiceCallbacks {
* @return A non-null activity intent.
*/
Intent getPlayerActivityIntent(Context context, MediaType mediaType, boolean remotePlayback);
-
- /**
- * Returns true if the PlaybackService should load new episodes from the queue when playback ends
- * and false if the PlaybackService should ignore the queue and load no more episodes when playback
- * finishes.
- */
- boolean useQueue();
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java
deleted file mode 100644
index 4504b2e7f..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FeedRemover.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package de.danoeh.antennapod.core.asynctask;
-
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.os.AsyncTask;
-
-import java.util.concurrent.ExecutionException;
-
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
-import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.util.IntentUtils;
-
-/** Removes a feed in the background. */
-public class FeedRemover extends AsyncTask<Void, Void, Void> {
- private final Context context;
- private ProgressDialog dialog;
- private final Feed feed;
- public boolean skipOnCompletion = false;
-
- public FeedRemover(Context context, Feed feed) {
- super();
- this.context = context;
- this.feed = feed;
- }
-
- @Override
- protected Void doInBackground(Void... params) {
- try {
- DBWriter.deleteFeed(context, feed.getId()).get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if(dialog != null && dialog.isShowing()) {
- dialog.dismiss();
- }
- if(skipOnCompletion) {
- IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SKIP_CURRENT_EPISODE);
- }
- }
-
- @Override
- protected void onPreExecute() {
- dialog = new ProgressDialog(context);
- dialog.setMessage(context.getString(R.string.feed_remover_msg));
- dialog.setIndeterminate(true);
- dialog.setCancelable(false);
- dialog.show();
- }
-
- public void executeAsync() {
- executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
index 4c11d0489..c05e2e9f1 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
@@ -20,6 +20,7 @@ import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.math.BigInteger;
+import java.nio.charset.Charset;
import java.security.DigestInputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
@@ -34,7 +35,6 @@ import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
-import de.danoeh.antennapod.core.util.LangUtils;
public class OpmlBackupAgent extends BackupAgentHelper {
private static final String OPML_BACKUP_KEY = "opml";
@@ -73,9 +73,9 @@ public class OpmlBackupAgent extends BackupAgentHelper {
try {
digester = MessageDigest.getInstance("MD5");
writer = new OutputStreamWriter(new DigestOutputStream(byteStream, digester),
- LangUtils.UTF_8);
+ Charset.forName("UTF-8"));
} catch (NoSuchAlgorithmException e) {
- writer = new OutputStreamWriter(byteStream, LangUtils.UTF_8);
+ writer = new OutputStreamWriter(byteStream, Charset.forName("UTF-8"));
}
try {
@@ -138,9 +138,9 @@ public class OpmlBackupAgent extends BackupAgentHelper {
try {
digester = MessageDigest.getInstance("MD5");
reader = new InputStreamReader(new DigestInputStream(data, digester),
- LangUtils.UTF_8);
+ Charset.forName("UTF-8"));
} catch (NoSuchAlgorithmException e) {
- reader = new InputStreamReader(data, LangUtils.UTF_8);
+ reader = new InputStreamReader(data, Charset.forName("UTF-8"));
}
try {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
index b9d79715a..16ab5a171 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilter.java
@@ -1,10 +1,8 @@
package de.danoeh.antennapod.core.feed;
import android.text.TextUtils;
-import android.util.Log;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import de.danoeh.antennapod.core.storage.DBReader;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
index 88945b930..4857e899d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.media.MediaMetadataRetriever;
+import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.Nullable;
@@ -165,13 +166,20 @@ public class FeedMedia extends FeedFile implements Playable {
*/
public MediaBrowserCompat.MediaItem getMediaItem() {
Playable p = this;
- MediaDescriptionCompat description = new MediaDescriptionCompat.Builder()
+ MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder()
.setMediaId(String.valueOf(id))
.setTitle(p.getEpisodeTitle())
.setDescription(p.getFeedTitle())
- .setSubtitle(p.getFeedTitle())
- .build();
- return new MediaBrowserCompat.MediaItem(description, MediaBrowserCompat.MediaItem.FLAG_PLAYABLE);
+ .setSubtitle(p.getFeedTitle());
+ if (item != null) {
+ // getImageLocation() also loads embedded images, which we can not send to external devices
+ if (item.getImageUrl() != null) {
+ builder.setIconUri(Uri.parse(item.getImageUrl()));
+ } else if (item.getFeed() != null && item.getFeed().getImageLocation() != null) {
+ builder.setIconUri(Uri.parse(item.getFeed().getImageLocation()));
+ }
+ }
+ return new MediaBrowserCompat.MediaItem(builder.build(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE);
}
/**
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 971808eb4..d0e15d591 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
@@ -6,14 +6,13 @@ import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.text.TextUtils;
+import androidx.annotation.NonNull;
import androidx.documentfile.provider.DocumentFile;
-import org.apache.commons.lang3.StringUtils;
-
+import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
@@ -22,7 +21,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.ExecutionException;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
@@ -34,17 +32,31 @@ import de.danoeh.antennapod.core.util.DownloadError;
public class LocalFeedUpdater {
+ static final String[] PREFERRED_FEED_IMAGE_FILENAMES = { "folder.jpg", "Folder.jpg", "folder.png", "Folder.png" };
+
public static void updateFeed(Feed feed, Context context) {
+ try {
+ tryUpdateFeed(feed, context);
+
+ if (mustReportDownloadSuccessful(feed)) {
+ reportSuccess(feed);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ reportError(feed, e.getMessage());
+ }
+ }
+
+ private static void tryUpdateFeed(Feed feed, Context context) throws IOException {
String uriString = feed.getDownload_url().replace(Feed.PREFIX_LOCAL_FOLDER, "");
DocumentFile documentFolder = DocumentFile.fromTreeUri(context, Uri.parse(uriString));
if (documentFolder == null) {
- reportError(feed, "Unable to retrieve document tree."
+ throw new IOException("Unable to retrieve document tree. "
+ "Try re-connecting the folder on the podcast info page.");
- return;
}
if (!documentFolder.exists() || !documentFolder.canRead()) {
- reportError(feed, "Cannot read local directory. Try re-connecting the folder on the podcast info page.");
- return;
+ throw new IOException("Cannot read local directory. "
+ + "Try re-connecting the folder on the podcast info page.");
}
if (feed.getItems() == null) {
@@ -85,37 +97,43 @@ public class LocalFeedUpdater {
}
}
- List<String> iconLocations = Arrays.asList("folder.jpg", "Folder.jpg", "folder.png", "Folder.png");
- for (String iconLocation : iconLocations) {
- DocumentFile image = documentFolder.findFile(iconLocation);
- if (image != null) {
- feed.setImageUrl(image.getUri().toString());
- break;
- }
- }
- if (StringUtils.isBlank(feed.getImageUrl())) {
- // set default feed image
- feed.setImageUrl(getDefaultIconUrl(context));
- }
- if (feed.getPreferences().getAutoDownload()) {
- feed.getPreferences().setAutoDownload(false);
- feed.getPreferences().setAutoDeleteAction(FeedPreferences.AutoDeleteAction.NO);
- try {
- DBWriter.setFeedPreferences(feed.getPreferences()).get();
- } catch (ExecutionException | InterruptedException e) {
- e.printStackTrace();
- }
- }
+ feed.setImageUrl(getImageUrl(context, documentFolder));
+
+ feed.getPreferences().setAutoDownload(false);
+ feed.getPreferences().setAutoDeleteAction(FeedPreferences.AutoDeleteAction.NO);
+ feed.setDescription(context.getString(R.string.local_feed_description));
+ feed.setAuthor(context.getString(R.string.local_folder));
// update items, delete items without existing file;
// only delete items if the folder contains at least one element to avoid accidentally
// deleting played state or position in case the folder is temporarily unavailable.
boolean removeUnlistedItems = (newItems.size() >= 1);
DBTasks.updateFeed(context, feed, removeUnlistedItems);
+ }
- if (mustReportDownloadSuccessful(feed)) {
- reportSuccess(feed);
+ /**
+ * Returns the image URL for the local feed.
+ */
+ @NonNull
+ static String getImageUrl(@NonNull Context context, @NonNull DocumentFile documentFolder) {
+ // look for special file names
+ for (String iconLocation : PREFERRED_FEED_IMAGE_FILENAMES) {
+ DocumentFile image = documentFolder.findFile(iconLocation);
+ if (image != null) {
+ return image.getUri().toString();
+ }
}
+
+ // use the first image in the folder if existing
+ for (DocumentFile file : documentFolder.listFiles()) {
+ String mime = file.getType();
+ if (mime != null && (mime.startsWith("image/jpeg") || mime.startsWith("image/png"))) {
+ return file.getUri().toString();
+ }
+ }
+
+ // use default icon as fallback
+ return getDefaultIconUrl(context);
}
/**
@@ -139,46 +157,50 @@ public class LocalFeedUpdater {
}
private static FeedItem createFeedItem(Feed feed, DocumentFile file, Context context) {
- String uuid = UUID.randomUUID().toString();
+ FeedItem item = new FeedItem(0, file.getName(), UUID.randomUUID().toString(),
+ file.getName(), new Date(file.lastModified()), FeedItem.UNPLAYED, feed);
+ item.setAutoDownload(false);
+
+ long size = file.length();
+ FeedMedia media = new FeedMedia(0, item, 0, 0, size, file.getType(),
+ file.getUri().toString(), file.getUri().toString(), false, null, 0, 0);
+ item.setMedia(media);
+
+ try {
+ loadMetadata(item, file, context);
+ } catch (Exception e) {
+ item.setDescription(e.getMessage());
+ }
+
+ return item;
+ }
+ private static void loadMetadata(FeedItem item, DocumentFile file, Context context) {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(context, file.getUri());
- String dateStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE);
- Date date = null;
+ String dateStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE);
if (!TextUtils.isEmpty(dateStr)) {
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.getDefault());
- date = simpleDateFormat.parse(dateStr);
+ item.setPubDate(simpleDateFormat.parse(dateStr));
} catch (ParseException parseException) {
- date = DateUtils.parse(dateStr);
- if (date == null) {
- date = new Date(file.lastModified());
+ Date date = DateUtils.parse(dateStr);
+ if (date != null) {
+ item.setPubDate(date);
}
}
- } else {
- date = new Date(file.lastModified());
}
- FeedItem item = new FeedItem(0, file.getName(), uuid, file.getName(), date,
- FeedItem.UNPLAYED, feed);
- item.setAutoDownload(false);
-
- String durationStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
String title = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
if (!TextUtils.isEmpty(title)) {
item.setTitle(title);
}
- //add the media to the item
- long duration = Long.parseLong(durationStr);
- long size = file.length();
- FeedMedia media = new FeedMedia(0, item, (int) duration, 0, size, file.getType(),
- file.getUri().toString(), file.getUri().toString(), false, null, 0, 0);
- media.setHasEmbeddedPicture(mediaMetadataRetriever.getEmbeddedPicture() != null);
- item.setMedia(media);
+ String durationStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
+ item.getMedia().setDuration((int) Long.parseLong(durationStr));
- return item;
+ item.getMedia().setHasEmbeddedPicture(mediaMetadataRetriever.getEmbeddedPicture() != null);
}
private static void reportError(Feed feed, String reasonDetailed) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/util/PlaybackSpeedUtils.java b/core/src/main/java/de/danoeh/antennapod/core/feed/util/PlaybackSpeedUtils.java
index 0d5ecbb71..d6740994d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/util/PlaybackSpeedUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/util/PlaybackSpeedUtils.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.core.feed.util;
+import android.util.Log;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
@@ -14,6 +15,7 @@ import static de.danoeh.antennapod.core.feed.FeedPreferences.SPEED_USE_GLOBAL;
* Utility class to use the appropriate playback speed based on {@link PlaybackPreferences}
*/
public final class PlaybackSpeedUtils {
+ private static final String TAG = "PlaybackSpeedUtils";
private PlaybackSpeedUtils() {
}
@@ -33,8 +35,10 @@ public final class PlaybackSpeedUtils {
FeedItem item = ((FeedMedia) media).getItem();
if (item != null) {
Feed feed = item.getFeed();
- if (feed != null) {
+ if (feed != null && feed.getPreferences() != null) {
playbackSpeed = feed.getPreferences().getFeedPlaybackSpeed();
+ } else {
+ Log.d(TAG, "Can not get feed specific playback speed: " + feed);
}
}
}
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 ab4247cef..b3adc567e 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
@@ -10,7 +10,6 @@ import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;
import com.bumptech.glide.load.model.StringLoader;
-import com.bumptech.glide.load.model.UriLoader;
import com.bumptech.glide.module.AppGlideModule;
import de.danoeh.antennapod.core.util.EmbeddedChapterImage;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java
index 35a9d987b..519d625e2 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ChapterImageModelLoader.java
@@ -10,17 +10,13 @@ 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.core.ClientConfig;
-import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.core.util.EmbeddedChapterImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
-import java.net.URL;
import java.nio.ByteBuffer;
-import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.io.IOUtils;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
index 08ea27434..95b828e28 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
@@ -100,7 +100,7 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(PREF_CURRENT_PLAYER_STATUS)) {
+ if (PREF_CURRENT_PLAYER_STATUS.equals(key)) {
EventBus.getDefault().post(new PlayerStatusEvent());
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
index 56dd95fe6..ed9c519a6 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java
@@ -301,10 +301,30 @@ public class UserPreferences {
* @return {@code true} if download reports are shown, {@code false} otherwise
*/
public static boolean showDownloadReport() {
+ if (Build.VERSION.SDK_INT >= 26) {
+ return true; // System handles notification preferences
+ }
+ return prefs.getBoolean(PREF_SHOW_DOWNLOAD_REPORT, true);
+ }
+
+ /**
+ * Used for migration of the preference to system notification channels.
+ */
+ public static boolean getShowDownloadReportRaw() {
return prefs.getBoolean(PREF_SHOW_DOWNLOAD_REPORT, true);
}
public static boolean showAutoDownloadReport() {
+ if (Build.VERSION.SDK_INT >= 26) {
+ return true; // System handles notification preferences
+ }
+ return prefs.getBoolean(PREF_SHOW_AUTO_DOWNLOAD_REPORT, false);
+ }
+
+ /**
+ * Used for migration of the preference to system notification channels.
+ */
+ public static boolean getShowAutoDownloadReportRaw() {
return prefs.getBoolean(PREF_SHOW_AUTO_DOWNLOAD_REPORT, false);
}
@@ -728,6 +748,16 @@ public class UserPreferences {
}
public static boolean gpodnetNotificationsEnabled() {
+ if (Build.VERSION.SDK_INT >= 26) {
+ return true; // System handles notification preferences
+ }
+ return prefs.getBoolean(PREF_GPODNET_NOTIFICATIONS, true);
+ }
+
+ /**
+ * Used for migration of the preference to system notification channels.
+ */
+ public static boolean getGpodnetNotificationsEnabledRaw() {
return prefs.getBoolean(PREF_GPODNET_NOTIFICATIONS, true);
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java
index 2e592bdf5..9e9663205 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java
@@ -16,6 +16,9 @@ public class PlayerWidget extends AppWidgetProvider {
public static final String PREFS_NAME = "PlayerWidgetPrefs";
private static final String KEY_ENABLED = "WidgetEnabled";
public static final String KEY_WIDGET_COLOR = "widget_color";
+ public static final String KEY_WIDGET_SKIP = "widget_skip";
+ public static final String KEY_WIDGET_FAST_FORWARD = "widget_fast_forward";
+ public static final String KEY_WIDGET_REWIND = "widget_rewind";
public static final int DEFAULT_COLOR = 0x00262C31;
@Override
@@ -52,6 +55,9 @@ public class PlayerWidget extends AppWidgetProvider {
for (int appWidgetId : appWidgetIds) {
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
prefs.edit().remove(KEY_WIDGET_COLOR + appWidgetId).apply();
+ prefs.edit().remove(KEY_WIDGET_REWIND + appWidgetId).apply();
+ prefs.edit().remove(KEY_WIDGET_FAST_FORWARD + appWidgetId).apply();
+ prefs.edit().remove(KEY_WIDGET_SKIP + appWidgetId).apply();
}
super.onDeleted(context, appWidgetIds);
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java
index 74735a264..5af05b6d2 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java
@@ -102,9 +102,10 @@ public class PlayerWidgetJobService extends SafeJobIntentService {
ComponentName playerWidget = new ComponentName(this, PlayerWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
int[] widgetIds = manager.getAppWidgetIds(playerWidget);
- RemoteViews views = new RemoteViews(getPackageName(), R.layout.player_widget);
final PendingIntent startMediaPlayer = PendingIntent.getActivity(this, R.id.pending_intent_player_activity,
PlaybackService.getPlayerActivityIntent(this), PendingIntent.FLAG_UPDATE_CURRENT);
+ RemoteViews views;
+ views = new RemoteViews(getPackageName(), R.layout.player_widget);
boolean nothingPlaying = false;
Playable media;
@@ -119,6 +120,7 @@ public class PlayerWidgetJobService extends SafeJobIntentService {
if (media != null) {
views.setOnClickPendingIntent(R.id.layout_left, startMediaPlayer);
+ views.setOnClickPendingIntent(R.id.imgvCover, startMediaPlayer);
try {
Bitmap icon;
@@ -155,11 +157,18 @@ public class PlayerWidgetJobService extends SafeJobIntentService {
if (status == PlayerStatus.PLAYING) {
views.setImageViewResource(R.id.butPlay, R.drawable.ic_av_pause_white_48dp);
views.setContentDescription(R.id.butPlay, getString(R.string.pause_label));
+ views.setImageViewResource(R.id.butPlayExtended, R.drawable.ic_av_pause_white_48dp);
+ views.setContentDescription(R.id.butPlayExtended, getString(R.string.pause_label));
} else {
views.setImageViewResource(R.id.butPlay, R.drawable.ic_av_play_white_48dp);
views.setContentDescription(R.id.butPlay, getString(R.string.play_label));
+ views.setImageViewResource(R.id.butPlayExtended, R.drawable.ic_av_play_white_48dp);
+ views.setContentDescription(R.id.butPlayExtended, getString(R.string.play_label));
}
- views.setOnClickPendingIntent(R.id.butPlay, createMediaButtonIntent());
+ views.setOnClickPendingIntent(R.id.butPlay,
+ createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
+ views.setOnClickPendingIntent(R.id.butPlayExtended,
+ createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
} else {
nothingPlaying = true;
}
@@ -168,16 +177,20 @@ public class PlayerWidgetJobService extends SafeJobIntentService {
// start the app if they click anything
views.setOnClickPendingIntent(R.id.layout_left, startMediaPlayer);
views.setOnClickPendingIntent(R.id.butPlay, startMediaPlayer);
+ views.setOnClickPendingIntent(R.id.butPlayExtended,
+ createMediaButtonIntent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
views.setViewVisibility(R.id.txtvProgress, View.GONE);
views.setViewVisibility(R.id.txtvTitle, View.GONE);
views.setViewVisibility(R.id.txtNoPlaying, View.VISIBLE);
views.setImageViewResource(R.id.imgvCover, R.mipmap.ic_launcher_round);
views.setImageViewResource(R.id.butPlay, R.drawable.ic_av_play_white_48dp);
+ views.setImageViewResource(R.id.butPlayExtended, R.drawable.ic_av_play_white_48dp);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
for (int id : widgetIds) {
Bundle options = manager.getAppWidgetOptions(id);
+ SharedPreferences prefs = getSharedPreferences(PlayerWidget.PREFS_NAME, Context.MODE_PRIVATE);
int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
int columns = getCellsForSize(minWidth);
if (columns < 3) {
@@ -185,8 +198,18 @@ public class PlayerWidgetJobService extends SafeJobIntentService {
} else {
views.setViewVisibility(R.id.layout_center, View.VISIBLE);
}
+ boolean showRewind = prefs.getBoolean(PlayerWidget.KEY_WIDGET_REWIND + id, false);
+ boolean showFastForward = prefs.getBoolean(PlayerWidget.KEY_WIDGET_FAST_FORWARD + id, false);
+ boolean showSkip = prefs.getBoolean(PlayerWidget.KEY_WIDGET_SKIP + id, false);
+
+ if (showRewind || showSkip || showFastForward) {
+ views.setInt(R.id.extendedButtonsContainer, "setVisibility", View.VISIBLE);
+ views.setInt(R.id.butPlay, "setVisibility", View.GONE);
+ views.setInt(R.id.butRew, "setVisibility", showRewind ? View.VISIBLE : View.GONE);
+ views.setInt(R.id.butFastForward, "setVisibility", showFastForward ? View.VISIBLE : View.GONE);
+ views.setInt(R.id.butSkip, "setVisibility", showSkip ? View.VISIBLE : View.GONE);
+ }
- SharedPreferences prefs = getSharedPreferences(PlayerWidget.PREFS_NAME, Context.MODE_PRIVATE);
int backgroundColor = prefs.getInt(PlayerWidget.KEY_WIDGET_COLOR + id, PlayerWidget.DEFAULT_COLOR);
views.setInt(R.id.widgetLayout, "setBackgroundColor", backgroundColor);
@@ -200,13 +223,13 @@ public class PlayerWidgetJobService extends SafeJobIntentService {
/**
* Creates an intent which fakes a mediabutton press
*/
- private PendingIntent createMediaButtonIntent() {
- KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ private PendingIntent createMediaButtonIntent(int eventCode) {
+ KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, eventCode);
Intent startingIntent = new Intent(getBaseContext(), MediaButtonReceiver.class);
startingIntent.setAction(MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER);
startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event);
- return PendingIntent.getBroadcast(this, 0, startingIntent, 0);
+ return PendingIntent.getBroadcast(this, eventCode, startingIntent, 0);
}
private String getProgressString(int position, int duration, float speed) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
index de106a01e..6dbc4a82f 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
@@ -25,7 +25,6 @@ import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.io.IOException;
-import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -39,7 +38,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.feed.Feed;
@@ -168,6 +166,7 @@ public class DownloadService extends Service {
startForeground(R.id.notification_downloading, notification);
syncExecutor.execute(() -> onDownloadQueued(intent));
} else if (numberOfDownloads.get() == 0) {
+ stopForeground(true);
stopSelf();
} else {
Log.d(TAG, "onStartCommand: Unknown intent");
@@ -205,8 +204,7 @@ public class DownloadService extends Service {
isRunning = false;
boolean showAutoDownloadReport = UserPreferences.showAutoDownloadReport();
- if (ClientConfig.downloadServiceCallbacks.shouldCreateReport()
- && (UserPreferences.showDownloadReport() || showAutoDownloadReport)) {
+ if (UserPreferences.showDownloadReport() || showAutoDownloadReport) {
notificationManager.updateReport(reportQueue, showAutoDownloadReport);
reportQueue.clear();
}
@@ -326,18 +324,11 @@ public class DownloadService extends Service {
if (item == null) {
return;
}
- boolean httpNotFound = status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR
- && String.valueOf(HttpURLConnection.HTTP_NOT_FOUND).equals(status.getReasonDetailed());
- boolean forbidden = status.getReason() == DownloadError.ERROR_FORBIDDEN
- && String.valueOf(HttpURLConnection.HTTP_FORBIDDEN).equals(status.getReasonDetailed());
- boolean notEnoughSpace = status.getReason() == DownloadError.ERROR_NOT_ENOUGH_SPACE;
- boolean wrongFileType = status.getReason() == DownloadError.ERROR_FILE_TYPE;
- boolean httpGone = status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR
- && String.valueOf(HttpURLConnection.HTTP_GONE).equals(status.getReasonDetailed());
- boolean httpBadReq = status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR
- && String.valueOf(HttpURLConnection.HTTP_BAD_REQUEST).equals(status.getReasonDetailed());
-
- if (httpNotFound || forbidden || notEnoughSpace || wrongFileType || httpGone || httpBadReq ) {
+ boolean unknownHost = status.getReason() == DownloadError.ERROR_UNKNOWN_HOST;
+ boolean unsupportedType = status.getReason() == DownloadError.ERROR_UNSUPPORTED_TYPE;
+ boolean wrongSize = status.getReason() == DownloadError.ERROR_IO_WRONG_SIZE;
+
+ if (! (unknownHost || unsupportedType || wrongSize)) {
try {
DBWriter.saveFeedItemAutoDownloadFailed(item).get();
} catch (ExecutionException | InterruptedException e) {
@@ -429,7 +420,7 @@ public class DownloadService extends Service {
+ ", cleanupMedia=" + cleanupMedia);
if (cleanupMedia) {
- ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm()
+ UserPreferences.getEpisodeCleanupAlgorithm()
.makeRoomForEpisodes(getApplicationContext(), requests.size());
}
@@ -553,6 +544,7 @@ public class DownloadService extends Service {
if (numberOfDownloads.get() <= 0 && DownloadRequester.getInstance().hasNoDownloads()) {
Log.d(TAG, "Number of downloads is " + numberOfDownloads.get() + ", attempting shutdown");
+ stopForeground(true);
stopSelf();
if (notificationUpdater != null) {
notificationUpdater.run();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java
index 0715d50dd..fb6009c02 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java
@@ -148,7 +148,7 @@ public class DownloadServiceNotification {
id = R.id.notification_auto_download_report;
content = createAutoDownloadNotificationContent(reportQueue);
} else {
- channelId = NotificationUtils.CHANNEL_ID_ERROR;
+ channelId = NotificationUtils.CHANNEL_ID_DOWNLOAD_ERROR;
titleId = R.string.download_report_title;
iconId = R.drawable.ic_notification_sync_error;
intent = ClientConfig.downloadServiceCallbacks.getReportNotificationContentIntent(context);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
index 65b7ed7d1..b553a9d1f 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
@@ -4,7 +4,6 @@ import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
-import de.danoeh.antennapod.core.service.BasicAuthorizationInterceptor;
import okhttp3.CacheControl;
import org.apache.commons.io.IOUtils;
@@ -21,14 +20,12 @@ import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Date;
-import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.util.DateUtils;
import de.danoeh.antennapod.core.util.DownloadError;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.core.util.URIUtil;
-import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
@@ -226,7 +223,7 @@ public class HttpDownloader extends Downloader {
// written file. This check cannot be made if compression was used
if (!isGzip && request.getSize() != DownloadStatus.SIZE_UNKNOWN &&
request.getSoFar() != request.getSize()) {
- onFail(DownloadError.ERROR_IO_ERROR, "Download completed but size: " +
+ onFail(DownloadError.ERROR_IO_WRONG_SIZE, "Download completed but size: " +
request.getSoFar() + " does not equal expected size " + request.getSize());
return;
} else if (request.getSize() > 0 && request.getSoFar() == 0) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FailedDownloadHandler.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FailedDownloadHandler.java
index 041d26bd4..386e5e6f7 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FailedDownloadHandler.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FailedDownloadHandler.java
@@ -3,7 +3,6 @@ package de.danoeh.antennapod.core.service.download.handler;
import android.util.Log;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.service.download.DownloadRequest;
-import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.storage.DBWriter;
/**
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
index 71bbf2efd..9a8248984 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.playback;
import android.content.Context;
import android.net.Uri;
+import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import com.google.android.exoplayer2.C;
@@ -28,8 +29,10 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
+
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.service.download.HttpDownloader;
import de.danoeh.antennapod.core.util.playback.IPlayer;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -184,14 +187,22 @@ public class ExoPlayerWrapper implements IPlayer {
exoPlayer.setAudioAttributes(b.build());
}
- @Override
- public void setDataSource(String s) throws IllegalArgumentException, IllegalStateException {
+ public void setDataSource(String s, String user, String password)
+ throws IllegalArgumentException, IllegalStateException {
Log.d(TAG, "setDataSource: " + s);
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
ClientConfig.USER_AGENT, null,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
true);
+
+ if (!TextUtils.isEmpty(user) && !TextUtils.isEmpty(password)) {
+ httpDataSourceFactory.getDefaultRequestProperties().set("Authorization",
+ HttpDownloader.encodeCredentials(
+ user,
+ password,
+ "ISO-8859-1"));
+ }
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, null, httpDataSourceFactory);
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
extractorsFactory.setConstantBitrateSeekingEnabled(true);
@@ -200,6 +211,11 @@ public class ExoPlayerWrapper implements IPlayer {
}
@Override
+ public void setDataSource(String s) throws IllegalArgumentException, IllegalStateException {
+ setDataSource(s, null, null);
+ }
+
+ @Override
public void setDisplay(SurfaceHolder sh) {
exoPlayer.setVideoSurfaceHolder(sh);
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
index ae5d62872..98280f54d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
@@ -1,7 +1,6 @@
package de.danoeh.antennapod.core.service.playback;
import android.content.Context;
-import android.media.AudioAttributes;
import android.media.AudioManager;
import android.os.PowerManager;
import androidx.annotation.NonNull;
@@ -261,7 +260,16 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
callback.onMediaChanged(false);
setPlaybackParams(PlaybackSpeedUtils.getCurrentPlaybackSpeed(media), UserPreferences.isSkipSilence());
if (stream) {
- mediaPlayer.setDataSource(media.getStreamUrl());
+ if (playable instanceof FeedMedia) {
+ FeedMedia feedMedia = (FeedMedia) playable;
+ FeedPreferences preferences = feedMedia.getItem().getFeed().getPreferences();
+ mediaPlayer.setDataSource(
+ media.getStreamUrl(),
+ preferences.getUsername(),
+ preferences.getPassword());
+ } else {
+ mediaPlayer.setDataSource(media.getStreamUrl());
+ }
} else if (media.getLocalMediaUrl() != null && new File(media.getLocalMediaUrl()).canRead()) {
mediaPlayer.setDataSource(media.getLocalMediaUrl());
} else {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
index 60075dda6..c1500d78b 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
@@ -7,6 +7,7 @@ import android.app.UiModeManager;
import android.bluetooth.BluetoothA2dp;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -51,7 +52,6 @@ import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.ServiceEvent;
@@ -149,7 +149,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public static final String ACTION_PAUSE_PLAY_CURRENT_EPISODE = "action.de.danoeh.antennapod.core.service.pausePlayCurrentEpisode";
/**
- * Custom action used by Android Wear
+ * Custom action used by Android Wear, Android Auto
*/
private static final String CUSTOM_ACTION_FAST_FORWARD = "action.de.danoeh.antennapod.core.service.fastForward";
private static final String CUSTOM_ACTION_REWIND = "action.de.danoeh.antennapod.core.service.rewind";
@@ -370,9 +370,26 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
private MediaBrowserCompat.MediaItem createBrowsableMediaItemForRoot() {
+ Uri uri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+ .authority(getResources().getResourcePackageName(R.drawable.ic_playlist_black))
+ .appendPath(getResources().getResourceTypeName(R.drawable.ic_playlist_black))
+ .appendPath(getResources().getResourceEntryName(R.drawable.ic_playlist_black))
+ .build();
+
+ String subtitle = "";
+ try {
+ int count = taskManager.getQueue().size();
+ subtitle = getResources().getQuantityString(R.plurals.num_episodes, count, count);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
MediaDescriptionCompat description = new MediaDescriptionCompat.Builder()
+ .setIconUri(uri)
.setMediaId(getResources().getString(R.string.queue_label))
.setTitle(getResources().getString(R.string.queue_label))
+ .setSubtitle(subtitle)
.build();
return new MediaBrowserCompat.MediaItem(description,
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE);
@@ -517,11 +534,12 @@ public class PlaybackService extends MediaBrowserServiceCompat {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
playableLoaded -> {
- mediaPlayer.playMediaObject(playable, stream, startWhenPrepared,
+ mediaPlayer.playMediaObject(playableLoaded, stream, startWhenPrepared,
prepareImmediately);
- addPlayableToQueue(playable);
+ addPlayableToQueue(playableLoaded);
}, error -> {
Log.d(TAG, "Playable was not found. Stopping service.");
+ error.printStackTrace();
stateManager.stopService();
});
return Service.START_NOT_STICKY;
@@ -729,6 +747,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
addPlayableToQueue(playable);
}, error -> {
Log.d(TAG, "Playable was not loaded from preferences. Stopping service.");
+ error.printStackTrace();
stateManager.stopService();
});
}
@@ -971,10 +990,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
Log.d(TAG, "getNextInQueue(), but playable not an instance of FeedMedia, so not proceeding");
return null;
}
- if (!ClientConfig.playbackServiceCallbacks.useQueue()) {
- Log.d(TAG, "getNextInQueue(), but queue not in use by this app");
- return null;
- }
Log.d(TAG, "getNextInQueue()");
FeedMedia media = (FeedMedia) currentMedia;
try {
@@ -1022,6 +1037,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
*/
private void onPlaybackEnded(MediaType mediaType, boolean stopPlaying) {
Log.d(TAG, "Playback ended");
+ PlaybackPreferences.clearCurrentlyPlayingTemporaryPlaybackSpeed();
if (stopPlaying) {
taskManager.cancelPositionSaver();
cancelPositionObserver();
@@ -1060,7 +1076,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
*/
private void onPostPlayback(final Playable playable, boolean ended, boolean skipped,
boolean playingNext) {
- PlaybackPreferences.clearCurrentlyPlayingTemporaryPlaybackSpeed();
if (playable == null) {
Log.e(TAG, "Cannot do post-playback processing: media was null");
return;
@@ -1206,6 +1221,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
sessionState.setState(state, getCurrentPosition(), getCurrentPlaybackSpeed());
long capabilities = PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_REWIND
+ | PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_FAST_FORWARD
| PlaybackStateCompat.ACTION_SKIP_TO_NEXT
| PlaybackStateCompat.ACTION_SEEK_TO;
@@ -1236,17 +1252,24 @@ public class PlaybackService extends MediaBrowserServiceCompat {
CUSTOM_ACTION_FAST_FORWARD,
getString(R.string.fast_forward_label), R.drawable.ic_notification_fast_forward)
.build());
+ } else {
+ // This would give the PIP of videos a play button
+ capabilities = capabilities | PlaybackStateCompat.ACTION_PLAY;
+ if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_WATCH) {
+ flavorHelper.sessionStateAddActionForWear(sessionState,
+ CUSTOM_ACTION_REWIND,
+ getString(R.string.rewind_label),
+ android.R.drawable.ic_media_rew);
+ flavorHelper.sessionStateAddActionForWear(sessionState,
+ CUSTOM_ACTION_FAST_FORWARD,
+ getString(R.string.fast_forward_label),
+ android.R.drawable.ic_media_ff);
+ flavorHelper.mediaSessionSetExtraForWear(mediaSession);
+ }
}
sessionState.setActions(capabilities);
- flavorHelper.sessionStateAddActionForWear(sessionState,
- CUSTOM_ACTION_REWIND, getString(R.string.rewind_label), android.R.drawable.ic_media_rew);
- flavorHelper.sessionStateAddActionForWear(sessionState,
- CUSTOM_ACTION_FAST_FORWARD, getString(R.string.fast_forward_label), android.R.drawable.ic_media_ff);
-
- flavorHelper.mediaSessionSetExtraForWear(mediaSession);
-
mediaSession.setPlaybackState(sessionState.build());
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java
index 632ac07ea..9d249620d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceNotificationBuilder.java
@@ -69,7 +69,7 @@ public class PlaybackServiceNotificationBuilder {
}
public void loadIcon() {
- int iconSize = context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width);
+ int iconSize = (int) (128 * context.getResources().getDisplayMetrics().density);
try {
icon = Glide.with(context)
.asBitmap()
diff --git a/core/src/main/java/de/danoeh/antennapod/core/ssl/BackportCaCerts.java b/core/src/main/java/de/danoeh/antennapod/core/ssl/BackportCaCerts.java
index 720d6a9d9..78c105e38 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/ssl/BackportCaCerts.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/ssl/BackportCaCerts.java
@@ -70,4 +70,36 @@ public class BackportCaCerts {
+ "0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB\n"
+ "NVOFBkpdn627G190\n"
+ "-----END CERTIFICATE-----";
+
+ public static final String LETSENCRYPT_ISRG = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n"
+ + "TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n"
+ + "cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\n"
+ + "WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\n"
+ + "ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\n"
+ + "MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\n"
+ + "h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\n"
+ + "0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U\n"
+ + "A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW\n"
+ + "T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH\n"
+ + "B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC\n"
+ + "B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv\n"
+ + "KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn\n"
+ + "OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn\n"
+ + "jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw\n"
+ + "qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI\n"
+ + "rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n"
+ + "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq\n"
+ + "hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\n"
+ + "ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ\n"
+ + "3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK\n"
+ + "NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5\n"
+ + "ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur\n"
+ + "TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC\n"
+ + "jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc\n"
+ + "oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\n"
+ + "4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA\n"
+ + "mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n"
+ + "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n"
+ + "-----END CERTIFICATE-----";
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/ssl/BackportTrustManager.java b/core/src/main/java/de/danoeh/antennapod/core/ssl/BackportTrustManager.java
index b8fe950b2..81d2a0709 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/ssl/BackportTrustManager.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/ssl/BackportTrustManager.java
@@ -45,6 +45,8 @@ public class BackportTrustManager {
new ByteArrayInputStream(BackportCaCerts.COMODO.getBytes(Charset.forName("UTF-8")))));
keystore.setCertificateEntry("SECTIGO_USER_TRUST_CA", cf.generateCertificate(
new ByteArrayInputStream(BackportCaCerts.SECTIGO_USER_TRUST.getBytes(Charset.forName("UTF-8")))));
+ keystore.setCertificateEntry("LETSENCRYPT_ISRG_CA", cf.generateCertificate(
+ new ByteArrayInputStream(BackportCaCerts.LETSENCRYPT_ISRG.getBytes(Charset.forName("UTF-8")))));
List<X509TrustManager> managers = new ArrayList<>();
managers.add(getSystemTrustManager(keystore));
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java
index 7ec4db5dd..061d6cf3f 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/APDownloadAlgorithm.java
@@ -65,7 +65,7 @@ public class APDownloadAlgorithm implements AutomaticDownloadAlgorithm {
Iterator<FeedItem> it = candidates.iterator();
while (it.hasNext()) {
FeedItem item = it.next();
- if (!item.isAutoDownloadable()) {
+ if (!item.isAutoDownloadable() || item.getFeed().isLocalFeed()) {
it.remove();
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
index 2ba817b94..58f838a75 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
@@ -7,10 +7,10 @@ import androidx.collection.ArrayMap;
import android.text.TextUtils;
import android.util.Log;
+import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -799,7 +799,7 @@ public final class DBReader {
feedTotalTime += media.getDuration() / 1000;
if (media.isDownloaded()) {
- totalDownloadSize = totalDownloadSize + media.getSize();
+ totalDownloadSize += new File(media.getFile_url()).length();
episodesDownloadCount++;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
index c059e696a..ec39e7144 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
@@ -6,7 +6,6 @@ import android.database.Cursor;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
-import androidx.annotation.VisibleForTesting;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.event.FeedItemEvent;
@@ -290,7 +289,7 @@ public final class DBTasks {
*/
public static Future<?> autodownloadUndownloadedItems(final Context context) {
Log.d(TAG, "autodownloadUndownloadedItems");
- return autodownloadExec.submit(ClientConfig.dbTasksCallbacks.getAutomaticDownloadAlgorithm()
+ return autodownloadExec.submit(ClientConfig.automaticDownloadAlgorithm
.autoDownloadUndownloadedItems(context));
}
@@ -304,7 +303,7 @@ public final class DBTasks {
* @param context Used for accessing the DB.
*/
public static void performAutoCleanup(final Context context) {
- ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm().performCleanup(context);
+ UserPreferences.getEpisodeCleanupAlgorithm().performCleanup(context);
}
/**
@@ -445,7 +444,8 @@ public final class DBTasks {
// as the most recent item
// (if the most recent date is null then we can assume there are no items
// and this is the first, hence 'new')
- if (priorMostRecentDate == null
+ // New items that do not have a pubDate set are always marked as new
+ if (item.getPubDate() == null || priorMostRecentDate == null
|| priorMostRecentDate.before(item.getPubDate())
|| priorMostRecentDate.equals(item.getPubDate())) {
Log.d(TAG, "Marking item published on " + item.getPubDate()
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
index 9e6041df3..84cc4b6a8 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java
@@ -21,8 +21,8 @@ import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
-import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.event.DownloadLogEvent;
import de.danoeh.antennapod.core.event.FavoritesEvent;
@@ -74,6 +74,18 @@ public class DBWriter {
}
/**
+ * Wait until all threads are finished to avoid the "Illegal connection pointer" error of
+ * Robolectric. Call this method only for unit tests.
+ */
+ public static void tearDownTests() {
+ try {
+ dbExec.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // ignore error
+ }
+ }
+
+ /**
* Deletes a downloaded FeedMedia file from the storage device.
*
* @param context A context that is used for opening a database connection.
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java b/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
index 2f48cfc07..ea62065fc 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/FeedSearcher.java
@@ -3,10 +3,8 @@ package de.danoeh.antennapod.core.storage;
import android.content.Context;
import androidx.annotation.NonNull;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
index a02cce504..7eae8b9f0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.core.storage;
-import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
@@ -317,46 +316,44 @@ public class PodDBAdapter {
+ JOIN_FEED_ITEM_AND_MEDIA;
private static Context context;
+ private static PodDBAdapter instance;
- private static volatile SQLiteDatabase db;
+ private final SQLiteDatabase db;
+ private final PodDBHelper dbHelper;
public static void init(Context context) {
PodDBAdapter.context = context.getApplicationContext();
}
- // Bill Pugh Singleton Implementation
- private static class SingletonHolder {
- private static final PodDBHelper dbHelper = new PodDBHelper(PodDBAdapter.context, DATABASE_NAME, null);
- private static final PodDBAdapter dbAdapter = new PodDBAdapter();
- }
-
public static PodDBAdapter getInstance() {
- return SingletonHolder.dbAdapter;
+ if (instance == null) {
+ instance = new PodDBAdapter();
+ }
+ return instance;
}
private PodDBAdapter() {
+ dbHelper = new PodDBHelper(PodDBAdapter.context, DATABASE_NAME, null);
+ db = openDb();
}
- public synchronized PodDBAdapter open() {
- if (db == null || !db.isOpen() || db.isReadOnly()) {
- db = openDb();
- }
- return this;
- }
-
- @SuppressLint("NewApi")
private SQLiteDatabase openDb() {
SQLiteDatabase newDb;
try {
- newDb = SingletonHolder.dbHelper.getWritableDatabase();
+ newDb = dbHelper.getWritableDatabase();
newDb.disableWriteAheadLogging();
} catch (SQLException ex) {
Log.e(TAG, Log.getStackTraceString(ex));
- newDb = SingletonHolder.dbHelper.getReadableDatabase();
+ newDb = dbHelper.getReadableDatabase();
}
return newDb;
}
+ public synchronized PodDBAdapter open() {
+ // do nothing
+ return this;
+ }
+
public synchronized void close() {
// do nothing
}
@@ -372,8 +369,8 @@ public class PodDBAdapter {
* <a href="https://github.com/robolectric/robolectric/issues/1890">robolectric/robolectric#1890</a>.</p>
*/
public static void tearDownTests() {
- db = null;
- SingletonHolder.dbHelper.close();
+ getInstance().dbHelper.close();
+ instance = null;
}
public static boolean deleteDatabase() {
@@ -381,7 +378,7 @@ public class PodDBAdapter {
adapter.open();
try {
for (String tableName : ALL_TABLES) {
- db.delete(tableName, "1", null);
+ adapter.db.delete(tableName, "1", null);
}
return true;
} finally {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java b/core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java
index 1f5d9b75f..7563ab715 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java
@@ -80,7 +80,7 @@ public class SyncService extends Worker {
if (!GpodnetPreferences.loggedIn()) {
return Result.success();
}
- syncServiceImpl = new GpodnetService(AntennapodHttpClient.getHttpClient(), GpodnetService.DEFAULT_BASE_HOST);
+ syncServiceImpl = new GpodnetService(AntennapodHttpClient.getHttpClient(), GpodnetPreferences.getHostname());
SharedPreferences.Editor prefs = getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
.edit();
prefs.putLong(PREF_LAST_SYNC_ATTEMPT_TIMESTAMP, System.currentTimeMillis()).apply();
@@ -485,7 +485,11 @@ public class SyncService extends Worker {
}
private void updateErrorNotification(SyncServiceException exception) {
- Log.d(TAG, "Posting error notification");
+ if (!UserPreferences.gpodnetNotificationsEnabled()) {
+ Log.d(TAG, "Skipping sync error notification because of user setting");
+ return;
+ }
+ Log.d(TAG, "Posting sync error notification");
final String description = getApplicationContext().getString(R.string.gpodnetsync_error_descr)
+ exception.getMessage();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java b/core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java
index 62c8ce5f3..75ac42b31 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/sync/gpoddernet/GpodnetService.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.sync.gpoddernet;
import android.util.Log;
import androidx.annotation.NonNull;
+import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetDevice;
import de.danoeh.antennapod.core.sync.model.EpisodeAction;
@@ -36,6 +37,7 @@ import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
@@ -47,6 +49,7 @@ public class GpodnetService implements ISyncService {
public static final String TAG = "GpodnetService";
public static final String DEFAULT_BASE_HOST = "gpodder.net";
private static final String BASE_SCHEME = "https";
+ private static final int PORT = 443;
private static final int UPLOAD_BULK_SIZE = 30;
private static final MediaType TEXT = MediaType.parse("plain/text; charset=utf-8");
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
@@ -71,7 +74,8 @@ public class GpodnetService implements ISyncService {
public List<GpodnetTag> getTopTags(int count) throws GpodnetServiceException {
URL url;
try {
- url = new URI(BASE_SCHEME, baseHost, String.format(Locale.US, "/api/2/tags/%d.json", count), null).toURL();
+ url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format(Locale.US, "/api/2/tags/%d.json", count), null, null).toURL();
} catch (MalformedURLException | URISyntaxException e) {
e.printStackTrace();
throw new GpodnetServiceException(e);
@@ -104,8 +108,8 @@ public class GpodnetService implements ISyncService {
public List<GpodnetPodcast> getPodcastsForTag(@NonNull GpodnetTag tag, int count)
throws GpodnetServiceException {
try {
- URL url = new URI(BASE_SCHEME, baseHost, String.format(Locale.US,
- "/api/2/tag/%s/%d.json", tag.getTag(), count), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format(Locale.US, "/api/2/tag/%s/%d.json", tag.getTag(), count), null, null).toURL();
Request.Builder request = new Request.Builder().url(url);
String response = executeRequest(request);
@@ -130,7 +134,8 @@ public class GpodnetService implements ISyncService {
}
try {
- URL url = new URI(BASE_SCHEME, baseHost, String.format(Locale.US, "/toplist/%d.json", count), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format(Locale.US, "/toplist/%d.json", count), null, null).toURL();
Request.Builder request = new Request.Builder().url(url);
String response = executeRequest(request);
@@ -161,8 +166,8 @@ public class GpodnetService implements ISyncService {
}
try {
- URL url = new URI(BASE_SCHEME, baseHost,
- String.format(Locale.US, "/suggestions/%d.json", count), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format(Locale.US, "/suggestions/%d.json", count), null, null).toURL();
Request.Builder request = new Request.Builder().url(url);
String response = executeRequest(request);
@@ -187,7 +192,7 @@ public class GpodnetService implements ISyncService {
.format(Locale.US, "q=%s&scale_logo=%d", query, scaledLogoSize) : String
.format("q=%s", query);
try {
- URL url = new URI(BASE_SCHEME, null, baseHost, -1, "/search.json",
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT, "/search.json",
parameters, null).toURL();
Request.Builder request = new Request.Builder().url(url);
String response = executeRequest(request);
@@ -214,7 +219,8 @@ public class GpodnetService implements ISyncService {
public List<GpodnetDevice> getDevices() throws GpodnetServiceException {
requireLoggedIn();
try {
- URL url = new URI(BASE_SCHEME, baseHost, String.format("/api/2/devices/%s.json", username), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/api/2/devices/%s.json", username), null, null).toURL();
Request.Builder request = new Request.Builder().url(url);
String response = executeRequest(request);
JSONArray devicesArray = new JSONArray(response);
@@ -226,6 +232,45 @@ public class GpodnetService implements ISyncService {
}
/**
+ * Returns synchronization status of devices.
+ * <p/>
+ * This method requires authentication.
+ *
+ * @throws GpodnetServiceAuthenticationException If there is an authentication error.
+ */
+ public List<List<String>> getSynchronizedDevices() throws GpodnetServiceException {
+ requireLoggedIn();
+ try {
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/api/2/sync-devices/%s.json", username), null, null).toURL();
+ Request.Builder request = new Request.Builder().url(url);
+ String response = executeRequest(request);
+ JSONObject syncStatus = new JSONObject(response);
+ List<List<String>> result = new ArrayList<>();
+
+ JSONArray synchronizedDevices = syncStatus.getJSONArray("synchronized");
+ for (int i = 0; i < synchronizedDevices.length(); i++) {
+ JSONArray groupDevices = synchronizedDevices.getJSONArray(i);
+ List<String> group = new ArrayList<>();
+ for (int j = 0; j < groupDevices.length(); j++) {
+ group.add(groupDevices.getString(j));
+ }
+ result.add(group);
+ }
+
+ JSONArray notSynchronizedDevices = syncStatus.getJSONArray("not-synchronized");
+ for (int i = 0; i < notSynchronizedDevices.length(); i++) {
+ result.add(Collections.singletonList(notSynchronizedDevices.getString(i)));
+ }
+
+ return result;
+ } catch (JSONException | MalformedURLException | URISyntaxException e) {
+ e.printStackTrace();
+ throw new GpodnetServiceException(e);
+ }
+ }
+
+ /**
* Configures the device of a given user.
* <p/>
* This method requires authentication.
@@ -237,8 +282,8 @@ public class GpodnetService implements ISyncService {
throws GpodnetServiceException {
requireLoggedIn();
try {
- URL url = new URI(BASE_SCHEME, baseHost, String.format(
- "/api/2/devices/%s/%s.json", username, deviceId), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/api/2/devices/%s/%s.json", username, deviceId), null, null).toURL();
String content;
if (caption != null || type != null) {
JSONObject jsonContent = new JSONObject();
@@ -262,6 +307,39 @@ public class GpodnetService implements ISyncService {
}
/**
+ * Links devices for synchronization.
+ * <p/>
+ * This method requires authentication.
+ *
+ * @throws GpodnetServiceAuthenticationException If there is an authentication error.
+ */
+ public void linkDevices(@NonNull List<String> deviceIds) throws GpodnetServiceException {
+ requireLoggedIn();
+ try {
+ final URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/api/2/sync-devices/%s.json", username), null, null).toURL();
+ JSONObject jsonContent = new JSONObject();
+ JSONArray group = new JSONArray();
+ for (String deviceId : deviceIds) {
+ group.put(deviceId);
+ }
+
+ JSONArray synchronizedGroups = new JSONArray();
+ synchronizedGroups.put(group);
+ jsonContent.put("synchronize", synchronizedGroups);
+ jsonContent.put("stop-synchronize", new JSONArray());
+
+ Log.d("aaaa", jsonContent.toString());
+ RequestBody body = RequestBody.create(JSON, jsonContent.toString());
+ Request.Builder request = new Request.Builder().post(body).url(url);
+ executeRequest(request);
+ } catch (JSONException | MalformedURLException | URISyntaxException e) {
+ e.printStackTrace();
+ throw new GpodnetServiceException(e);
+ }
+ }
+
+ /**
* Returns the subscriptions of a specific device.
* <p/>
* This method requires authentication.
@@ -273,8 +351,8 @@ public class GpodnetService implements ISyncService {
public String getSubscriptionsOfDevice(@NonNull String deviceId) throws GpodnetServiceException {
requireLoggedIn();
try {
- URL url = new URI(BASE_SCHEME, baseHost, String.format(
- "/subscriptions/%s/%s.opml", username, deviceId), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/subscriptions/%s/%s.opml", username, deviceId), null, null).toURL();
Request.Builder request = new Request.Builder().url(url);
return executeRequest(request);
} catch (MalformedURLException | URISyntaxException e) {
@@ -295,7 +373,8 @@ public class GpodnetService implements ISyncService {
public String getSubscriptionsOfUser() throws GpodnetServiceException {
requireLoggedIn();
try {
- URL url = new URI(BASE_SCHEME, baseHost, String.format("/subscriptions/%s.opml", username), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/subscriptions/%s.opml", username), null, null).toURL();
Request.Builder request = new Request.Builder().url(url);
return executeRequest(request);
} catch (MalformedURLException | URISyntaxException e) {
@@ -319,8 +398,8 @@ public class GpodnetService implements ISyncService {
throws GpodnetServiceException {
requireLoggedIn();
try {
- URL url = new URI(BASE_SCHEME, baseHost, String.format(
- "/subscriptions/%s/%s.txt", username, deviceId), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/subscriptions/%s/%s.txt", username, deviceId), null, null).toURL();
StringBuilder builder = new StringBuilder();
for (String s : subscriptions) {
builder.append(s);
@@ -353,8 +432,8 @@ public class GpodnetService implements ISyncService {
@NonNull Collection<String> removed) throws GpodnetServiceException {
requireLoggedIn();
try {
- URL url = new URI(BASE_SCHEME, baseHost, String.format(
- "/api/2/subscriptions/%s/%s.json", username, deviceId), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/api/2/subscriptions/%s/%s.json", username, deviceId), null, null).toURL();
final JSONObject requestObject = new JSONObject();
requestObject.put("add", new JSONArray(added));
@@ -389,8 +468,7 @@ public class GpodnetService implements ISyncService {
String params = String.format(Locale.US, "since=%d", timestamp);
String path = String.format("/api/2/subscriptions/%s/%s.json", username, deviceId);
try {
- URL url = new URI(BASE_SCHEME, null, baseHost, -1, path, params,
- null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT, path, params, null).toURL();
Request.Builder request = new Request.Builder().url(url);
String response = executeRequest(request);
@@ -432,8 +510,8 @@ public class GpodnetService implements ISyncService {
throws SyncServiceException {
try {
Log.d(TAG, "Uploading partial actions " + from + " to " + to + " of " + episodeActions.size());
- URL url = new URI(BASE_SCHEME, baseHost, String.format(
- "/api/2/episodes/%s.json", username), null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/api/2/episodes/%s.json", username), null, null).toURL();
final JSONArray list = new JSONArray();
for (int i = from; i < to; i++) {
@@ -471,7 +549,7 @@ public class GpodnetService implements ISyncService {
String params = String.format(Locale.US, "since=%d", timestamp);
String path = String.format("/api/2/episodes/%s.json", username);
try {
- URL url = new URI(BASE_SCHEME, null, baseHost, -1, path, params, null).toURL();
+ URL url = new URI(BASE_SCHEME, null, baseHost, PORT, path, params, null).toURL();
Request.Builder request = new Request.Builder().url(url);
String response = executeRequest(request);
@@ -497,7 +575,8 @@ public class GpodnetService implements ISyncService {
public void authenticate(@NonNull String username, @NonNull String password) throws GpodnetServiceException {
URL url;
try {
- url = new URI(BASE_SCHEME, baseHost, String.format("/api/2/auth/%s/login.json", username), null).toURL();
+ url = new URI(BASE_SCHEME, null, baseHost, PORT,
+ String.format("/api/2/auth/%s/login.json", username), null, null).toURL();
} catch (MalformedURLException | URISyntaxException e) {
e.printStackTrace();
throw new GpodnetServiceException(e);
@@ -567,6 +646,13 @@ public class GpodnetService implements ISyncService {
if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
throw new GpodnetServiceAuthenticationException("Wrong username or password");
} else {
+ if (BuildConfig.DEBUG) {
+ try {
+ Log.d(TAG, response.body().string());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
throw new GpodnetServiceBadStatusCodeException("Bad response code: " + responseCode, responseCode);
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java
index e15ab2fdc..196583bcd 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java
@@ -22,14 +22,7 @@ public class DateUtils {
private DateUtils(){}
private static final String TAG = "DateUtils";
-
private static final TimeZone defaultTimezone = TimeZone.getTimeZone("GMT");
- private static final SimpleDateFormat dateFormatParser = new SimpleDateFormat("", Locale.US);
-
- static {
- dateFormatParser.setLenient(false);
- dateFormatParser.setTimeZone(defaultTimezone);
- }
public static Date parse(final String input) {
if (input == null) {
@@ -37,9 +30,12 @@ public class DateUtils {
}
String date = input.trim().replace('/', '-').replaceAll("( ){2,}+", " ");
+ // remove colon from timezone to avoid differences between Android and Java SimpleDateFormat
+ date = date.replaceAll("([+-]\\d\\d):(\\d\\d)$", "$1$2");
+
// CEST is widely used but not in the "ISO 8601 Time zone" list. Let's hack around.
- date = date.replaceAll("CEST$", "+02:00");
- date = date.replaceAll("CET$", "+01:00");
+ date = date.replaceAll("CEST$", "+0200");
+ date = date.replaceAll("CET$", "+0100");
// some generators use "Sept" for September
date = date.replaceAll("\\bSept\\b", "Sep");
@@ -99,12 +95,16 @@ public class DateUtils {
"EEE d MMM yyyy HH:mm:ss 'GMT'Z (z)"
};
+ SimpleDateFormat parser = new SimpleDateFormat("", Locale.US);
+ parser.setLenient(false);
+ parser.setTimeZone(defaultTimezone);
+
ParsePosition pos = new ParsePosition(0);
for (String pattern : patterns) {
- dateFormatParser.applyPattern(pattern);
+ parser.applyPattern(pattern);
pos.setIndex(0);
try {
- Date result = dateFormatParser.parse(date, pos);
+ Date result = parser.parse(date, pos);
if (result != null && pos.getIndex() == date.length()) {
return result;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DownloadError.java b/core/src/main/java/de/danoeh/antennapod/core/util/DownloadError.java
index 0c9989b43..babf3a846 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/DownloadError.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/DownloadError.java
@@ -19,11 +19,11 @@ public enum DownloadError {
ERROR_NOT_ENOUGH_SPACE(10, R.string.download_error_insufficient_space),
ERROR_UNKNOWN_HOST(11, R.string.download_error_unknown_host),
ERROR_REQUEST_ERROR(12, R.string.download_error_request_error),
- ERROR_DB_ACCESS_ERROR(13, R.string.download_error_db_access),
- ERROR_UNAUTHORIZED(14, R.string.download_error_unauthorized),
+ ERROR_DB_ACCESS_ERROR(13, R.string.download_error_db_access),
+ ERROR_UNAUTHORIZED(14, R.string.download_error_unauthorized),
ERROR_FILE_TYPE(15, R.string.download_error_file_type_type),
- ERROR_FORBIDDEN(16, R.string.download_error_forbidden);
-
+ ERROR_FORBIDDEN(16, R.string.download_error_forbidden),
+ ERROR_IO_WRONG_SIZE(17, R.string.download_error_forbidden);
private final int code;
private final int resId;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java b/core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java
index 2a387b7b0..69c23efc2 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/FileNameGenerator.java
@@ -13,7 +13,7 @@ import java.security.NoSuchAlgorithmException;
/** Generates valid filenames for a given string. */
public class FileNameGenerator {
@VisibleForTesting
- public static final int MAX_FILENAME_LENGTH = 255; // Limited by ext4
+ public static final int MAX_FILENAME_LENGTH = 242; // limited by CircleCI
private static final int MD5_HEX_LENGTH = 32;
private static final char[] validChars =
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/LangUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/LangUtils.java
deleted file mode 100644
index 20af6415e..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/LangUtils.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package de.danoeh.antennapod.core.util;
-
-import androidx.collection.ArrayMap;
-
-import java.nio.charset.Charset;
-
-public class LangUtils {
-
- private LangUtils(){}
-
- public static final Charset UTF_8 = Charset.forName("UTF-8");
-
- private static final ArrayMap<String, String> languages;
- static {
- languages = new ArrayMap<>();
- languages.put("af", "Afrikaans");
- languages.put("sq", "Albanian");
- languages.put("sq", "Albanian");
- languages.put("eu", "Basque");
- languages.put("be", "Belarusian");
- languages.put("bg", "Bulgarian");
- languages.put("ca", "Catalan");
- languages.put("Chinese (Simplified)", "zh-cn");
- languages.put("Chinese (Traditional)", "zh-tw");
- languages.put("hr", "Croatian");
- languages.put("cs", "Czech");
- languages.put("da", "Danish");
- languages.put("nl", "Dutch");
- languages.put("nl-be", "Dutch (Belgium)");
- languages.put("nl-nl", "Dutch (Netherlands)");
- languages.put("en", "English");
- languages.put("en-au", "English (Australia)");
- languages.put("en-bz", "English (Belize)");
- languages.put("en-ca", "English (Canada)");
- languages.put("en-ie", "English (Ireland)");
- languages.put("en-jm", "English (Jamaica)");
- languages.put("en-nz", "English (New Zealand)");
- languages.put("en-ph", "English (Phillipines)");
- languages.put("en-za", "English (South Africa)");
- languages.put("en-tt", "English (Trinidad)");
- languages.put("en-gb", "English (United Kingdom)");
- languages.put("en-us", "English (United States)");
- languages.put("en-zw", "English (Zimbabwe)");
- languages.put("et", "Estonian");
- languages.put("fo", "Faeroese");
- languages.put("fi", "Finnish");
- languages.put("fr", "French");
- languages.put("fr-be", "French (Belgium)");
- languages.put("fr-ca", "French (Canada)");
- languages.put("fr-fr", "French (France)");
- languages.put("fr-lu", "French (Luxembourg)");
- languages.put("fr-mc", "French (Monaco)");
- languages.put("fr-ch", "French (Switzerland)");
- languages.put("gl", "Galician");
- languages.put("gd", "Gaelic");
- languages.put("de", "German");
- languages.put("de-at", "German (Austria)");
- languages.put("de-de", "German (Germany)");
- languages.put("de-li", "German (Liechtenstein)");
- languages.put("de-lu", "German (Luxembourg)");
- languages.put("de-ch", "German (Switzerland)");
- languages.put("el", "Greek");
- languages.put("haw", "Hawaiian");
- languages.put("hu", "Hungarian");
- languages.put("is", "Icelandic");
- languages.put("in", "Indonesian");
- languages.put("ga", "Irish");
- languages.put("it", "Italian");
- languages.put("it-it", "Italian (Italy)");
- languages.put("it-ch", "Italian (Switzerland)");
- languages.put("ja", "Japanese");
- languages.put("ko", "Korean");
- languages.put("mk", "Macedonian");
- languages.put("no", "Norwegian");
- languages.put("pl", "Polish");
- languages.put("pt", "Portugese");
- languages.put("pt-br", "Portugese (Brazil)");
- languages.put("pt-pt", "Portugese (Portugal");
- languages.put("ro", "Romanian");
- languages.put("ro-mo", "Romanian (Moldova)");
- languages.put("ro-ro", "Romanian (Romania");
- languages.put("ru", "Russian");
- languages.put("ru-mo", "Russian (Moldova)");
- languages.put("ru-ru", "Russian (Russia)");
- languages.put("sr", "Serbian");
- languages.put("sk", "Slovak");
- languages.put("sl", "Slovenian");
- languages.put("es", "Spanish");
- languages.put("es-ar", "Spanish (Argentinia)");
- languages.put("es=bo", "Spanish (Bolivia)");
- languages.put("es-cl", "Spanish (Chile)");
- languages.put("es-co", "Spanish (Colombia)");
- languages.put("es-cr", "Spanish (Costa Rica)");
- languages.put("es-do", "Spanish (Dominican Republic)");
- languages.put("es-ec", "Spanish (Ecuador)");
- languages.put("es-sv", "Spanish (El Salvador)");
- languages.put("es-gt", "Spanish (Guatemala)");
- languages.put("es-hn", "Spanish (Honduras)");
- languages.put("es-mx", "Spanish (Mexico)");
- languages.put("es-ni", "Spanish (Nicaragua)");
- languages.put("es-pa", "Spanish (Panama)");
- languages.put("es-py", "Spanish (Paraguay)");
- languages.put("es-pe", "Spanish (Peru)");
- languages.put("es-pr", "Spanish (Puerto Rico)");
- languages.put("es-es", "Spanish (Spain)");
- languages.put("es-uy", "Spanish (Uruguay)");
- languages.put("es-ve", "Spanish (Venezuela)");
- languages.put("sv", "Swedish");
- languages.put("sv-fi", "Swedish (Finland)");
- languages.put("sv-se", "Swedish (Sweden)");
- languages.put("tr", "Turkish");
- languages.put("uk", "Ukranian");
- }
-
- /** Finds language string for key or returns the language key if it can't be found. */
- public static String getLanguageString(String key) {
- String language = languages.get(key);
- if (language != null) {
- return language;
- } else {
- return key;
- }
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java
index 3e9e8327e..2622d81aa 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java
@@ -19,74 +19,77 @@ import de.danoeh.antennapod.core.feed.FeedMedia;
/** Utility methods for sharing data */
public class ShareUtils {
- private static final String TAG = "ShareUtils";
-
- private ShareUtils() {}
-
- public static void shareLink(Context context, String text) {
- Intent i = new Intent(Intent.ACTION_SEND);
- i.setType("text/plain");
- i.putExtra(Intent.EXTRA_TEXT, text);
- context.startActivity(Intent.createChooser(i, context.getString(R.string.share_url_label)));
- }
+ private static final String TAG = "ShareUtils";
- public static void shareFeedlink(Context context, Feed feed) {
- shareLink(context, feed.getTitle() + ": " + feed.getLink());
- }
-
- public static void shareFeedDownloadLink(Context context, Feed feed) {
- shareLink(context, feed.getTitle() + ": " + feed.getDownload_url());
- }
+ private ShareUtils() {
+ }
- public static void shareFeedItemLink(Context context, FeedItem item) {
- shareFeedItemLink(context, item, false);
- }
+ public static void shareLink(Context context, String text) {
+ Intent i = new Intent(Intent.ACTION_SEND);
+ i.setType("text/plain");
+ i.putExtra(Intent.EXTRA_TEXT, text);
+ context.startActivity(Intent.createChooser(i, context.getString(R.string.share_url_label)));
+ }
- public static void shareFeedItemDownloadLink(Context context, FeedItem item) {
- shareFeedItemDownloadLink(context, item, false);
- }
+ public static void shareFeedlink(Context context, Feed feed) {
+ shareLink(context, feed.getTitle() + ": " + feed.getLink());
+ }
- private static String getItemShareText(FeedItem item) {
- return item.getFeed().getTitle() + ": " + item.getTitle();
- }
+ public static void shareFeedDownloadLink(Context context, Feed feed) {
+ shareLink(context, feed.getTitle() + ": " + feed.getDownload_url());
+ }
+
+ public static void shareFeedItemLink(Context context, FeedItem item) {
+ shareFeedItemLink(context, item, false);
+ }
+
+ public static void shareFeedItemDownloadLink(Context context, FeedItem item) {
+ shareFeedItemDownloadLink(context, item, false);
+ }
+
+ private static String getItemShareText(FeedItem item) {
+ return item.getFeed().getTitle() + ": " + item.getTitle();
+ }
public static boolean hasLinkToShare(FeedItem item) {
- return FeedItemUtil.getLinkWithFallback(item) != null;
+ return FeedItemUtil.getLinkWithFallback(item) != null;
}
- public static void shareFeedItemLink(Context context, FeedItem item, boolean withPosition) {
- String text = getItemShareText(item) + " " + FeedItemUtil.getLinkWithFallback(item);
- if(withPosition) {
- int pos = item.getMedia().getPosition();
- text += " [" + Converter.getDurationStringLong(pos) + "]";
- }
- shareLink(context, text);
- }
+ public static void shareFeedItemLink(Context context, FeedItem item, boolean withPosition) {
+ String text = getItemShareText(item) + " " + FeedItemUtil.getLinkWithFallback(item);
+ if (withPosition) {
+ int pos = item.getMedia().getPosition();
+ text += " [" + Converter.getDurationStringLong(pos) + "]";
+ }
+ shareLink(context, text);
+ }
- public static void shareFeedItemDownloadLink(Context context, FeedItem item, boolean withPosition) {
- String text = getItemShareText(item) + " " + item.getMedia().getDownload_url();
- if(withPosition) {
- int pos = item.getMedia().getPosition();
- text += " [" + Converter.getDurationStringLong(pos) + "]";
- }
- shareLink(context, text);
- }
+ public static void shareFeedItemDownloadLink(Context context, FeedItem item, boolean withPosition) {
+ String text = getItemShareText(item) + " " + item.getMedia().getDownload_url();
+ if (withPosition) {
+ int pos = item.getMedia().getPosition();
+ text += "#t=" + pos / 1000;
+ text += " [" + Converter.getDurationStringLong(pos) + "]";
+ }
+ shareLink(context, text);
+ }
- public static void shareFeedItemFile(Context context, FeedMedia media) {
- Intent i = new Intent(Intent.ACTION_SEND);
- i.setType(media.getMime_type());
- Uri fileUri = FileProvider.getUriForFile(context, context.getString(R.string.provider_authority),
- new File(media.getLocalMediaUrl()));
- i.putExtra(Intent.EXTRA_STREAM, fileUri);
- i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
- List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
- for (ResolveInfo resolveInfo : resInfoList) {
- String packageName = resolveInfo.activityInfo.packageName;
- context.grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
- }
- }
- context.startActivity(Intent.createChooser(i, context.getString(R.string.share_file_label)));
- Log.e(TAG, "shareFeedItemFile called");
- }
+ public static void shareFeedItemFile(Context context, FeedMedia media) {
+ Intent i = new Intent(Intent.ACTION_SEND);
+ i.setType(media.getMime_type());
+ Uri fileUri = FileProvider.getUriForFile(context, context.getString(R.string.provider_authority),
+ new File(media.getLocalMediaUrl()));
+ i.putExtra(Intent.EXTRA_STREAM, fileUri);
+ i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
+ List<ResolveInfo> resInfoList = context.getPackageManager()
+ .queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
+ for (ResolveInfo resolveInfo : resInfoList) {
+ String packageName = resolveInfo.activityInfo.packageName;
+ context.grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ }
+ }
+ context.startActivity(Intent.createChooser(i, context.getString(R.string.share_file_label)));
+ Log.e(TAG, "shareFeedItemFile called");
+ }
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java b/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java
index ac7f4848c..cb7db1709 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java
@@ -9,7 +9,6 @@ import de.danoeh.antennapod.core.BuildConfig;
import okhttp3.HttpUrl;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
/**
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/comparator/FeedItemPubdateComparator.java b/core/src/main/java/de/danoeh/antennapod/core/util/comparator/FeedItemPubdateComparator.java
index ad81a1d17..766986bed 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/comparator/FeedItemPubdateComparator.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/comparator/FeedItemPubdateComparator.java
@@ -14,8 +14,12 @@ public class FeedItemPubdateComparator implements Comparator<FeedItem> {
*/
@Override
public int compare(FeedItem lhs, FeedItem rhs) {
- if (rhs.getPubDate() == null || lhs.getPubDate() == null) {
+ if (rhs.getPubDate() == null && lhs.getPubDate() == null) {
return 0;
+ } else if (rhs.getPubDate() == null) {
+ return 1;
+ } else if (lhs.getPubDate() == null) {
+ return -1;
}
return rhs.getPubDate().compareTo(lhs.getPubDate());
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java
index ddbe68938..3101eac34 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java
@@ -2,28 +2,36 @@ package de.danoeh.antennapod.core.util.gui;
import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import androidx.annotation.RequiresApi;
import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
public class NotificationUtils {
public static final String CHANNEL_ID_USER_ACTION = "user_action";
public static final String CHANNEL_ID_DOWNLOADING = "downloading";
public static final String CHANNEL_ID_PLAYING = "playing";
- public static final String CHANNEL_ID_ERROR = "error";
+ public static final String CHANNEL_ID_DOWNLOAD_ERROR = "error";
public static final String CHANNEL_ID_SYNC_ERROR = "sync_error";
public static final String CHANNEL_ID_AUTO_DOWNLOAD = "auto_download";
+ public static final String GROUP_ID_ERRORS = "group_errors";
+ public static final String GROUP_ID_NEWS = "group_news";
+
public static void createChannels(Context context) {
- if (android.os.Build.VERSION.SDK_INT < 26) {
+ if (Build.VERSION.SDK_INT < 26) {
return;
}
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotificationManager != null) {
+ mNotificationManager.createNotificationChannelGroup(createGroupErrors(context));
+ mNotificationManager.createNotificationChannelGroup(createGroupNews(context));
+
mNotificationManager.createNotificationChannel(createChannelUserAction(context));
mNotificationManager.createNotificationChannel(createChannelDownloading(context));
mNotificationManager.createNotificationChannel(createChannelPlaying(context));
@@ -35,36 +43,43 @@ public class NotificationUtils {
@RequiresApi(api = Build.VERSION_CODES.O)
private static NotificationChannel createChannelUserAction(Context c) {
- NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_USER_ACTION,
+ NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID_USER_ACTION,
c.getString(R.string.notification_channel_user_action), NotificationManager.IMPORTANCE_HIGH);
- mChannel.setDescription(c.getString(R.string.notification_channel_user_action_description));
- return mChannel;
+ notificationChannel.setDescription(c.getString(R.string.notification_channel_user_action_description));
+ notificationChannel.setGroup(GROUP_ID_ERRORS);
+ return notificationChannel;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private static NotificationChannel createChannelDownloading(Context c) {
- NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_DOWNLOADING,
+ NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID_DOWNLOADING,
c.getString(R.string.notification_channel_downloading), NotificationManager.IMPORTANCE_LOW);
- mChannel.setDescription(c.getString(R.string.notification_channel_downloading_description));
- mChannel.setShowBadge(false);
- return mChannel;
+ notificationChannel.setDescription(c.getString(R.string.notification_channel_downloading_description));
+ notificationChannel.setShowBadge(false);
+ return notificationChannel;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private static NotificationChannel createChannelPlaying(Context c) {
- NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_PLAYING,
+ NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID_PLAYING,
c.getString(R.string.notification_channel_playing), NotificationManager.IMPORTANCE_LOW);
- mChannel.setDescription(c.getString(R.string.notification_channel_playing_description));
- mChannel.setShowBadge(false);
- return mChannel;
+ notificationChannel.setDescription(c.getString(R.string.notification_channel_playing_description));
+ notificationChannel.setShowBadge(false);
+ return notificationChannel;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private static NotificationChannel createChannelError(Context c) {
- NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_ERROR,
- c.getString(R.string.notification_channel_error), NotificationManager.IMPORTANCE_HIGH);
- mChannel.setDescription(c.getString(R.string.notification_channel_error_description));
- return mChannel;
+ NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID_DOWNLOAD_ERROR,
+ c.getString(R.string.notification_channel_download_error), NotificationManager.IMPORTANCE_HIGH);
+ notificationChannel.setDescription(c.getString(R.string.notification_channel_download_error_description));
+ notificationChannel.setGroup(GROUP_ID_ERRORS);
+
+ if (!UserPreferences.getShowDownloadReportRaw()) {
+ // Migration from app managed setting: disable notification
+ notificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
+ }
+ return notificationChannel;
}
@RequiresApi(api = Build.VERSION_CODES.O)
@@ -72,14 +87,38 @@ public class NotificationUtils {
NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID_SYNC_ERROR,
c.getString(R.string.notification_channel_sync_error), NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setDescription(c.getString(R.string.notification_channel_sync_error_description));
+ notificationChannel.setGroup(GROUP_ID_ERRORS);
+
+ if (!UserPreferences.getGpodnetNotificationsEnabledRaw()) {
+ // Migration from app managed setting: disable notification
+ notificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
+ }
return notificationChannel;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private static NotificationChannel createChannelAutoDownload(Context c) {
- NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_AUTO_DOWNLOAD,
- c.getString(R.string.notification_channel_auto_download), NotificationManager.IMPORTANCE_DEFAULT);
- mChannel.setDescription(c.getString(R.string.notification_channel_episode_auto_download));
- return mChannel;
+ NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID_AUTO_DOWNLOAD,
+ c.getString(R.string.notification_channel_auto_download), NotificationManager.IMPORTANCE_NONE);
+ notificationChannel.setDescription(c.getString(R.string.notification_channel_episode_auto_download));
+ notificationChannel.setGroup(GROUP_ID_NEWS);
+
+ if (UserPreferences.getShowAutoDownloadReportRaw()) {
+ // Migration from app managed setting: enable notification
+ notificationChannel.setImportance(NotificationManager.IMPORTANCE_DEFAULT);
+ }
+ return notificationChannel;
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ private static NotificationChannelGroup createGroupErrors(Context c) {
+ return new NotificationChannelGroup(GROUP_ID_ERRORS,
+ c.getString(R.string.notification_group_errors));
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ private static NotificationChannelGroup createGroupNews(Context c) {
+ return new NotificationChannelGroup(GROUP_ID_NEWS,
+ c.getString(R.string.notification_group_news));
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java
index fecb14d25..c948d98a3 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java
@@ -1,7 +1,6 @@
package de.danoeh.antennapod.core.util.playback;
import android.content.Context;
-import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
import android.util.Log;
import android.view.SurfaceHolder;
@@ -11,6 +10,7 @@ import org.antennapod.audio.MediaPlayer;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import java.io.IOException;
import java.util.Collections;
import java.util.List;
@@ -21,7 +21,7 @@ public class AudioPlayer extends MediaPlayer implements IPlayer {
super(context, true, ClientConfig.USER_AGENT);
PreferenceManager.getDefaultSharedPreferences(context)
.registerOnSharedPreferenceChangeListener((sharedPreferences, key) -> {
- if (key.equals(UserPreferences.PREF_MEDIA_PLAYER)) {
+ if (UserPreferences.PREF_MEDIA_PLAYER.equals(key)) {
checkMpi();
}
});
@@ -65,4 +65,9 @@ public class AudioPlayer extends MediaPlayer implements IPlayer {
public int getSelectedAudioTrack() {
return -1;
}
+
+ @Override
+ public void setDataSource(String streamUrl, String username, String password) throws IOException {
+ setDataSource(streamUrl);
+ }
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java
index 363004709..a511916fa 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java
@@ -35,6 +35,8 @@ public interface IPlayer {
void setDataSource(String path) throws IllegalStateException, IOException,
IllegalArgumentException, SecurityException;
+ void setDataSource(String streamUrl, String username, String password) throws IOException;
+
void setDisplay(SurfaceHolder sh);
void setPlaybackParams(float speed, boolean skipSilence);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
index 425a07f4a..e1b4c967c 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java
@@ -564,6 +564,13 @@ public class PlaybackController {
}
}
+ public void extendSleepTimer(long extendTime) {
+ long timeLeft = getSleepTimerTimeLeft();
+ if (playbackService != null && timeLeft != INVALID_TIME) {
+ setSleepTimer(timeLeft + extendTime);
+ }
+ }
+
public void setSleepTimer(long time) {
if (playbackService != null) {
playbackService.setSleepTimer(time);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java
index b12967264..107399e60 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java
@@ -2,7 +2,6 @@ package de.danoeh.antennapod.core.util.playback;
import android.content.Context;
import android.content.Intent;
-import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java
index d18801870..6728c027d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.util.playback;
import android.media.MediaPlayer;
import android.util.Log;
+import java.io.IOException;
import java.util.Collections;
import java.util.List;
@@ -52,4 +53,9 @@ public class VideoPlayer extends MediaPlayer implements IPlayer {
public int getSelectedAudioTrack() {
return -1;
}
+
+ @Override
+ public void setDataSource(String streamUrl, String username, String password) throws IOException {
+ setDataSource(streamUrl);
+ }
}
diff --git a/core/src/main/res/drawable-v21/ic_filter_close.xml b/core/src/main/res/drawable-v21/ic_filter_close.xml
new file mode 100644
index 000000000..9e0a26905
--- /dev/null
+++ b/core/src/main/res/drawable-v21/ic_filter_close.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:bottom="5dp"
+ android:left="5dp"
+ android:right="5dp"
+ android:top="5dp">
+
+ <shape android:shape="oval">
+ <stroke
+ android:width="4dp"
+ android:color="?attr/filter_dialog_clear" />
+ </shape>
+ </item>
+
+ <!-- x -->
+ <item
+ android:bottom="12dp"
+ android:left="12dp"
+ android:right="12dp"
+ android:top="12dp">
+ <rotate
+ android:fromDegrees="135"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:toDegrees="135">
+ <shape android:shape="line">
+ <stroke
+ android:width="4dp"
+ android:color="?attr/filter_dialog_clear" />
+ </shape>
+ </rotate>
+ </item>
+
+ <item
+ android:bottom="12dp"
+ android:left="12dp"
+ android:right="12dp"
+ android:top="12dp">
+ <rotate
+ android:fromDegrees="45"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:toDegrees="45">
+ <shape android:shape="line">
+ <stroke
+ android:width="4dp"
+ android:color="?attr/filter_dialog_clear" />
+ </shape>
+
+ </rotate>
+ </item>
+
+</layer-list> \ No newline at end of file
diff --git a/core/src/main/res/drawable/ic_av_replay_black_48dp.xml b/core/src/main/res/drawable/ic_av_replay_black_48dp.xml
new file mode 100644
index 000000000..1446ae48b
--- /dev/null
+++ b/core/src/main/res/drawable/ic_av_replay_black_48dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:width="48dp"
+ android:height="48dp">
+ <path
+ android:pathData="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6 -6 6 -6 -2.69 -6 -6H4c0 4.42 3.58 8 8 8s8 -3.58 8 -8 -3.58 -8 -8 -8z"
+ android:fillColor="#000000" />
+</vector>
diff --git a/core/src/main/res/drawable/ic_av_replay_white_48dp.xml b/core/src/main/res/drawable/ic_av_replay_white_48dp.xml
new file mode 100644
index 000000000..b6343effc
--- /dev/null
+++ b/core/src/main/res/drawable/ic_av_replay_white_48dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:width="48dp"
+ android:height="48dp">
+ <path
+ android:pathData="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6 -6 6s-6 -2.69 -6 -6H4c0 4.42 3.58 8 8 8s8 -3.58 8 -8S16.42 5 12 5z"
+ android:fillColor="#FFFFFF" />
+</vector>
diff --git a/core/src/main/res/drawable/ic_filter_close.xml b/core/src/main/res/drawable/ic_filter_close.xml
index 9e0a26905..4d7eedb30 100644
--- a/core/src/main/res/drawable/ic_filter_close.xml
+++ b/core/src/main/res/drawable/ic_filter_close.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
+ <!-- Fall-back for old Android devices that do not support attrs as colors -->
<item
android:bottom="5dp"
android:left="5dp"
@@ -10,7 +10,7 @@
<shape android:shape="oval">
<stroke
android:width="4dp"
- android:color="?attr/filter_dialog_clear" />
+ android:color="#555" />
</shape>
</item>
@@ -28,7 +28,7 @@
<shape android:shape="line">
<stroke
android:width="4dp"
- android:color="?attr/filter_dialog_clear" />
+ android:color="#555" />
</shape>
</rotate>
</item>
@@ -46,7 +46,7 @@
<shape android:shape="line">
<stroke
android:width="4dp"
- android:color="?attr/filter_dialog_clear" />
+ android:color="#555" />
</shape>
</rotate>
diff --git a/core/src/main/res/drawable/ic_share_black.xml b/core/src/main/res/drawable/ic_share_black.xml
new file mode 100644
index 000000000..f396c50de
--- /dev/null
+++ b/core/src/main/res/drawable/ic_share_black.xml
@@ -0,0 +1,7 @@
+<vector android:height="24dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
+</vector>
diff --git a/core/src/main/res/drawable/ic_share_white.xml b/core/src/main/res/drawable/ic_share_white.xml
new file mode 100644
index 000000000..ae1b3d12b
--- /dev/null
+++ b/core/src/main/res/drawable/ic_share_white.xml
@@ -0,0 +1,7 @@
+<vector android:height="24dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
+</vector>
diff --git a/core/src/main/res/layout/player_widget.xml b/core/src/main/res/layout/player_widget.xml
index 8e38d7f6e..ab42e4cb4 100644
--- a/core/src/main/res/layout/player_widget.xml
+++ b/core/src/main/res/layout/player_widget.xml
@@ -27,7 +27,7 @@
<LinearLayout
android:id="@+id/layout_left"
- android:layout_width="0dp"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
@@ -59,7 +59,7 @@
android:maxLines="3"
android:text="@string/no_media_playing_label"
android:textColor="@color/white"
- android:textSize="@dimen/text_size_medium"
+ android:textSize="16sp"
android:textStyle="bold" />
<TextView
@@ -67,8 +67,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
+ android:ellipsize="end"
android:textColor="@color/white"
- android:textSize="@dimen/text_size_medium"
+ android:textSize="16sp"
android:textStyle="bold"
android:visibility="gone" />
@@ -78,9 +79,61 @@
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/white"
+ android:textSize="14sp"
android:visibility="gone" />
+
+ <LinearLayout
+ android:id="@+id/extendedButtonsContainer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="gone">
+
+ <ImageButton
+ android:id="@+id/butRew"
+ android:layout_width="36dp"
+ android:layout_height="36dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@string/rewind_label"
+ android:layout_marginRight="2dp"
+ android:layout_marginEnd="2dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/ic_av_fast_rewind_white_48dp"/>
+
+ <ImageButton
+ android:id="@+id/butPlayExtended"
+ android:layout_width="36dp"
+ android:layout_height="36dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@string/play_label"
+ android:layout_marginRight="2dp"
+ android:layout_marginEnd="2dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/ic_av_play_white_48dp"/>
+
+ <ImageButton
+ android:id="@+id/butFastForward"
+ android:layout_width="36dp"
+ android:layout_height="36dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@string/fast_forward_label"
+ android:layout_marginRight="2dp"
+ android:layout_marginEnd="2dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/ic_av_fast_forward_white_48dp"/>
+
+ <ImageButton
+ android:id="@+id/butSkip"
+ android:layout_width="36dp"
+ android:layout_height="36dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@string/skip_episode_label"
+ android:layout_marginRight="2dp"
+ android:layout_marginEnd="2dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/ic_av_skip_white_24dp"/>
+ </LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
-
</FrameLayout> \ No newline at end of file
diff --git a/core/src/main/res/values-br/strings.xml b/core/src/main/res/values-br/strings.xml
index 12fbbdb23..3ff5df24f 100644
--- a/core/src/main/res/values-br/strings.xml
+++ b/core/src/main/res/values-br/strings.xml
@@ -26,16 +26,13 @@
<string name="playback_statistics_label">Lenn</string>
<string name="download_statistics_label">Pellgargadurioù</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Padelezh selaouet hollek</string>
<string name="statistics_details_dialog">%1$d war %2$d rann kroget.\n\nLennet %3$s war %4$s.</string>
<string name="statistics_mode">Doareoù stadegoù</string>
<string name="statistics_mode_normal">Jediñ ar padelezh selaouet e gwirionez. Ar rannoù selaouet div wech a gont doubl hag ar re merket evel anlennet ne gontont ket</string>
- <string name="statistics_mode_count_all">Sammañ an holl bodskignadoù merket evel lennet</string>
<string name="statistics_speed_not_counted">Evezhiadenn: tizh al lenn n\'eo morse kemeret e kont.</string>
<string name="statistics_reset_data">Adderaouekaat ar roadennoù stadegoù</string>
<string name="statistics_reset_data_msg">Dilemel a raio roll istor ar padelezh lennet evit an holl rannoù. Sur oc\'h e fell deoc\'h kenderc\'hel?</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Ment pellgarget hollek</string>
<!--Main activity-->
<string name="drawer_open">Digeriñ al lañser</string>
<string name="drawer_close">Serriñ al lañser</string>
@@ -49,6 +46,7 @@
<string name="drawer_feed_counter_unplayed">Niver a rannoù n\'int ket bet lennet</string>
<string name="drawer_feed_counter_downloaded">Niver a rannoù pelglarget</string>
<string name="drawer_feed_counter_none">Hini ebet</string>
+ <!--Bug report activity-->
<!--Webview actions-->
<string name="open_in_browser_label">Digeriñ er merdeer</string>
<string name="copy_url_label">Eilañ an URL</string>
@@ -133,14 +131,7 @@
<string name="feed_settings_label">Arventennoù ar podskignad</string>
<string name="rename_feed_label">Adenvel ar podskignad</string>
<string name="remove_feed_label">Dilemel ar podskignad</string>
- <string name="share_label">Rannañ...</string>
- <string name="share_link_label">Rannañ an ere</string>
- <string name="share_link_with_position_label">Rannañ an ere gant al lec\'hiadur</string>
<string name="share_file_label">Rannañ ar restr</string>
- <string name="share_website_url_label">Rannañ ere al lec\'hienn</string>
- <string name="share_feed_url_label">Rannañ ere ar podskignad</string>
- <string name="share_item_url_label">Rannañ ere ar restr</string>
- <string name="share_item_url_with_position_label">Rannañ ere ar restr gant al lec\'hiadur</string>
<string name="feed_delete_confirmation_msg">Kadarnait e fell deoc\'h dilemel ar podskignad \"%1$s\" hag e holl rannoù pellgarget.</string>
<string name="feed_remover_msg">O tilemel ar podskignad</string>
<string name="load_complete_feed">Hizivaat ar podskignad a-bezh</string>
@@ -148,14 +139,9 @@
<string name="select_all_above">Diuzañ gant ar re a-us</string>
<string name="select_all_below">Diuzañ gant ar re dindan</string>
<string name="hide_unplayed_episodes_label">Amlennet</string>
- <string name="hide_paused_episodes_label">Ehanet</string>
- <string name="hide_played_episodes_label">Lennet</string>
<string name="hide_queued_episodes_label">El lost</string>
<string name="hide_not_queued_episodes_label">N\'emañ ket el lost</string>
- <string name="hide_downloaded_episodes_label">Pellgarget</string>
- <string name="hide_not_downloaded_episodes_label">N\'eo ket pellgarget</string>
<string name="hide_has_media_label">Gant ur media</string>
- <string name="hide_is_favorite_label">Ur sined eo</string>
<string name="filtered_label">Silet</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} C\'hwitet war an azgrenaat diwezhañ</string>
<string name="open_podcast">Digeriñ ar podskignad</string>
@@ -175,13 +161,6 @@
<string name="delete_label">Dilemel</string>
<string name="delete_failed">N\'haller ket dilemel ar restr. Gallout a rit klask adloc\'hañ.</string>
<string name="delete_episode_label">Dilemel ar rann</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d rann dilamet </item>
- <item quantity="two">%d rann dilamet </item>
- <item quantity="few">%d rann dilamet </item>
- <item quantity="many">%d rann dilamet </item>
- <item quantity="other">%d rann dilamet </item>
- </plurals>
<string name="remove_new_flag_label">Tennañ ar merk \"nevez\"</string>
<string name="removed_new_flag_label">Tennet eo bet ar merk \"nevez\"</string>
<string name="mark_read_label">Merkañ evel lennet</string>
@@ -268,7 +247,6 @@
</plurals>
<string name="downloads_processing">O keweriañ ar pellgargadennoù</string>
<string name="download_notification_title">O pellgargañ roadennoù ar podskignad</string>
- <string name="download_report_content">%1$d rann pellgarget gant berzh, %2$d c\'hwitet</string>
<string name="download_log_title_unknown">Titl dianav</string>
<string name="download_type_feed">Lanv</string>
<string name="download_type_media">Restr media</string>
@@ -281,7 +259,6 @@
<string name="confirm_mobile_download_dialog_message">Diweredekaet eo ar pellgargadur war ar c\'hennask hezoug en arventennoù.\n\nFellout a ra deoc\'h aotren ent padennek?\n\n<small>Dalc\'het vo soñj eus ho tibab e-pad 10 munutenn.</small></string>
<string name="confirm_mobile_streaming_notification_title">Kadarnaat ar streaming hezoug</string>
<string name="confirm_mobile_streaming_notification_message">Diweredekaet eo ar streaming war ar c\'hennask hezoug en arventennoù. Stokit da lenn e streaming memestra.</string>
- <string name="confirm_mobile_streaming_button_always">Aotren atav</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Lakaat el lost</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Aotren ent padennek</string>
<!--Mediaplayer messages-->
@@ -327,7 +304,6 @@
<string name="download_plugin_label">Pellgargañ un enlugellad</string>
<string name="no_playback_plugin_title">N\'eo ket bet staliet an enlugellad</string>
<string name="no_playback_plugin_or_sonic_msg">Evit gallout kemmañ tizh al lenn ez eo erbedet gweredekaat al lenner media diabarzh Sonic.</string>
- <string name="set_playback_speed_label">Tizh lenn</string>
<string name="enable_sonic">Gweredekaat Sonic</string>
<!--Empty list labels-->
<string name="no_items_header_label">Rann ebet er roll len</string>
@@ -401,7 +377,6 @@
<string name="pref_autoUpdateIntervallOrTime_every">bep %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">da %1$s</string>
<string name="pref_followQueue_title">Lenn kendalc\'hus</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Digennask ar selaouelloù</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Lugañ ar selaouelloù</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Adkennaskañ ar bluetooth</string>
<string name="pref_stream_over_download_title">Ober gant ar streaming da gentañ</string>
@@ -414,7 +389,6 @@
<string name="pref_mobileUpdate_episode_download">Pellgargañ ar rann</string>
<string name="pref_mobileUpdate_streaming">Streaming</string>
<string name="user_interface_label">Ketal arveriad</string>
- <string name="user_interface_sum">Neuz, urzh ar c\'houmanantoù, skramm prennañ</string>
<string name="pref_set_theme_title">Dibab un neuz</string>
<string name="pref_nav_drawer_items_title">Kemmañ elfennoù ar stalaf merdeiñ</string>
<string name="pref_nav_drawer_items_sum">Kemmañ an elfennoù diskouezet er stalaf merdeiñ</string>
@@ -453,10 +427,7 @@
<string name="pref_gpodnet_full_sync_title">Rediañ ur goubredañ klok</string>
<string name="pref_gpodnet_full_sync_sum">Goubredañ an holl goumanantoù ha stadoù ar rannoù gant gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Kennasket evel <i>%1$s</i> gant ar benveg <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Diskouez ar rebuzadurioù fazioù goubredañ</string>
<string name="pref_gpodnet_notifications_sum">An arventenn-mañ na vez ket arloet d\'ar rebuzadurioù fazi.</string>
- <string name="pref_playback_speed_title">Tizhioù lenn</string>
- <string name="pref_playback_speed_sum">Dibab an tizhioù a c\'haller dibab pa vez lennet ar son</string>
<string name="pref_feed_playback_speed_sum">Tizh dre ziouer ar rannoù</string>
<string name="pref_feed_skip">Lamm emgefreek</string>
<string name="pref_feed_skip_sum">Tremen penn-kentañ ha dibenn ar rannoù</string>
@@ -476,15 +447,11 @@
<string name="pref_expandNotify_sum">Sañset e brasa ar rebuzadur evit diskouez an afelloù lenn.</string>
<string name="pref_persistNotify_title">Afelloù lenn peurzalc\'hus</string>
<string name="pref_persistNotify_sum">Mirout ar rebuzadur ha reoliadurioù ar skramm prennañ p\'eo ehanet al lenn.</string>
- <string name="pref_compact_notification_buttons_title">Despizañ an afelloù war ar skramm-prennañ</string>
- <string name="pref_compact_notification_buttons_sum">Kemmañ a ra an afelloù lenn war ar skramm-prennañ. An afell lenn/ehan a vo diskouezet bepred.</string>
<string name="pref_compact_notification_buttons_dialog_title">Dibab %1$d elfenn d\'ar muiañ</string>
<string name="pref_compact_notification_buttons_dialog_error">Gallout a rit dibab %1$d elfenn d\'ar muiañ.</string>
<string name="pref_lockscreen_background_title">Kemmañ skramm-prennañ an drekleur</string>
<string name="pref_lockscreen_background_sum">Lakaat skeudenn ar rann e plas skeudenn drekleur ar skramm-prennañ. Diskouez a raio ivez ar skeudenn en arloadoù all.</string>
- <string name="pref_showDownloadReport_title">Diskouez danevell ar pellgargadurioù</string>
<string name="pref_showDownloadReport_sum">Ma c\'hwit ar pellgargadurioù, sevel un danevell a ziskouez munudoù ar c\'hwitadenn.</string>
- <string name="pref_showAutoDownloadReport_title">Rentañ-kont ar pellgargañ emgefreek</string>
<string name="pref_showAutoDownloadReport_sum">Diskouez ur rebuzadur evit ar rannoù pellgarget ent emgefreek.</string>
<string name="pref_expand_notify_unsupport_toast">Handelvoù Android a-raok 4.1 na skoront ket ar rebuzadurioù astennet.</string>
<string name="pref_enqueue_location_title">Lec\'hiadur ar rannoù el lost</string>
@@ -583,7 +550,6 @@
<string name="export_success_sum">Ezporzhiet eo bet ar restr e:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Ret eo aotren haeziñ ar c\'hadaviñ diavaez evit lenn ar restr OPML</string>
<string name="import_select_file">Diuzit ar restr da enporzhiañ</string>
- <string name="import_ok">Enporzhiet gant berzh.\n\nPouezit war OK evit adloc\'hañ AntennaPod</string>
<string name="import_no_downgrade">Enporzhiet eo bet ar stlennvon gant un handelv nevesoc\'h eus AntennPod. Ho staliadur bremanel na oar ket c\'hoazh penaos merañ ar restr-mañ.</string>
<string name="favorites_export_label">Ezporzhiañ ar sinedoù</string>
<string name="favorites_export_summary">Ezporzhiañ ar sinedoù en ur restr</string>
@@ -687,7 +653,6 @@
<string name="decrease_speed">Gorrekaat</string>
<string name="media_type_audio_label">Aodio</string>
<string name="media_type_video_label">Vdeo</string>
- <string name="navigate_upwards_label">Merdeiñ en nec\'h</string>
<string name="status_downloading_label">War bellgargañ emañ ar ran</string>
<string name="in_queue_label">El lost emañ ar rann</string>
<string name="is_favorite_label">Ouzhpennet eo bet ar rann er sinedoù</string>
@@ -717,16 +682,14 @@
<string name="search_itunes_label">Klask war iTunes</string>
<string name="search_fyyd_label">Klask war fydd</string>
<string name="advanced">Araokaet</string>
- <string name="add_podcast_by_url">Ouzhpennañ ur podskignad gant e URL</string>
<string name="browse_gpoddernet_label">Klask war gpodder.net</string>
<string name="discover">Dizoloeiñ</string>
<string name="discover_more">muioc\'h »</string>
- <string name="search_powered_by">Klask gant %1$s</string>
+ <!--Local feeds-->
<string name="filter">Sil</string>
<!--Episodes apply actions-->
<string name="all_label">An holl</string>
<string name="selected_all_label">Diuzet eo bet an holl rannoù</string>
- <string name="none_label">Hini ebet</string>
<string name="deselected_all_label">Diziuzet eo bet an holl rannoù</string>
<string name="played_label">Lennet</string>
<string name="selected_played_label">Rannoù lennet diuzet</string>
@@ -736,12 +699,17 @@
<string name="selected_downloaded_label">Rannoù pellgarget diuzet</string>
<string name="not_downloaded_label">N\'eo ket pellgarget</string>
<string name="selected_not_downloaded_label">Rannoù n\'int ket pellgarget diuzet</string>
- <string name="queued_label">Lakaet el lost</string>
<string name="selected_queued_label">Rannoù diuzet el lost</string>
- <string name="not_queued_label">N\'emañ ket el lost</string>
<string name="selected_not_queued_label">Rannoù diuzet n\'int ket el lost</string>
- <string name="has_media">Gant ur media</string>
<string name="selected_has_media_label">Diuzañ ar rannoù gant media</string>
+ <string name="hide_is_favorite_label">Ur sined eo</string>
+ <string name="hide_downloaded_episodes_label">Pellgarget</string>
+ <string name="hide_not_downloaded_episodes_label">N\'eo ket pellgarget</string>
+ <string name="queued_label">Lakaet el lost</string>
+ <string name="not_queued_label">N\'emañ ket el lost</string>
+ <string name="has_media">Gant ur media</string>
+ <string name="hide_paused_episodes_label">Ehanet</string>
+ <string name="hide_played_episodes_label">Lennet</string>
<!--Sort-->
<string name="sort_title_a_z">Titl (A \u2192 Z)</string>
<string name="sort_title_z_a">Titl (Z \u2192 A)</string>
@@ -761,6 +729,7 @@
<string name="rating_never_label">Laoskit ac\'hanon e peoc\'h</string>
<string name="rating_later_label">Adlakaat da soñj diwezhatoc\'h</string>
<string name="rating_now_label">Deomp dezhi!</string>
+ <!--Share episode dialog-->
<!--Audio controls-->
<string name="audio_controls">Reoliadurioù aodio</string>
<string name="playback_speed">Tizh lenn</string>
@@ -807,7 +776,6 @@
<string name="notification_channel_playing">O lenn</string>
<string name="notification_channel_playing_description">Evit reoliañ al lenn. Ar rebuzadur pennañ an hini eo pa lennit ur podskignat.</string>
<string name="notification_channel_error">Fazioù</string>
- <string name="notification_channel_error_description">Diskouezet eo pa vez ur gudenn, ma c\'hwit ur pellgargadur pe ur goubredañ.</string>
<string name="notification_channel_auto_download">Pellgargañ emgefreek</string>
<string name="notification_channel_episode_auto_download">Diskouezet eo pa vez pellgarget rannoù ent emgefreek</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-ca/strings.xml b/core/src/main/res/values-ca/strings.xml
index 998d06213..616efedba 100644
--- a/core/src/main/res/values-ca/strings.xml
+++ b/core/src/main/res/values-ca/strings.xml
@@ -26,16 +26,13 @@
<string name="playback_statistics_label">Reproducció</string>
<string name="download_statistics_label">Baixades</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Temps total de podcasts reproduïts</string>
<string name="statistics_details_dialog">%1$d de %2$depisodis començats.\n\nReproduïts %3$s de %4$s.</string>
<string name="statistics_mode">Mode d\'estadístiques</string>
<string name="statistics_mode_normal">Calcula el temps que realment s\'ha reproduït. La reproducció repetida es comptarà repetides vegades, mentre que no es tindrà en compte si s\'ha marcat com a reproduït. </string>
- <string name="statistics_mode_count_all">Suma tots els podcasts marcats com a reproduïts</string>
<string name="statistics_speed_not_counted">Avís: la velocitat de reproducció mai no es té en compte.</string>
<string name="statistics_reset_data">Resetejar dades estadístiques</string>
<string name="statistics_reset_data_msg">Açò esborrarà l\'històric de la duració reproduïda per a tots els episodis. ¿Segur que vols continuar?</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Mida total dels podcasts baixats:</string>
<!--Main activity-->
<string name="drawer_open">Obre menú</string>
<string name="drawer_close">Tanca menú</string>
@@ -49,6 +46,7 @@
<string name="drawer_feed_counter_unplayed">Número d\'episodis per reproduir</string>
<string name="drawer_feed_counter_downloaded">Número d\'episodis descarregats</string>
<string name="drawer_feed_counter_none">Cap</string>
+ <!--Bug report activity-->
<!--Webview actions-->
<string name="open_in_browser_label">Obre en un navegador</string>
<string name="copy_url_label">Copia l\'enllaç</string>
@@ -124,14 +122,7 @@
<string name="feed_settings_label">Configuració del podcast</string>
<string name="rename_feed_label">Canvia el nom al podcast</string>
<string name="remove_feed_label">Suprimeix podcast</string>
- <string name="share_label">Comparteix...</string>
- <string name="share_link_label">Comparteix l\'adreça de l\'episodi</string>
- <string name="share_link_with_position_label">Comparteix l\'adreça de l\'episodi i la posició</string>
<string name="share_file_label">Comparteix el fitxer</string>
- <string name="share_website_url_label">Comparteix URL de la pàgina </string>
- <string name="share_feed_url_label">Comparteix URL de podcast</string>
- <string name="share_item_url_label">Comparteix l\'adreça del fitxer multimèdia</string>
- <string name="share_item_url_with_position_label">Comparteix l\'adreça del fitxer multimèdia i la posició</string>
<string name="feed_delete_confirmation_msg">Si us plau, confirmeu que voleu eliminar el podcast \"%1$s\" i tots els seus episodis (fins i tot els ja baixats).</string>
<string name="feed_remover_msg">Eliminant podcast</string>
<string name="load_complete_feed">Refrescar tot el podcast</string>
@@ -139,14 +130,9 @@
<string name="select_all_above">Seleccionar tots cap amunt</string>
<string name="select_all_below">Seleccionar cap a baix</string>
<string name="hide_unplayed_episodes_label">Per reproduir</string>
- <string name="hide_paused_episodes_label">Pausat</string>
- <string name="hide_played_episodes_label">Reproduit</string>
<string name="hide_queued_episodes_label">En cua</string>
<string name="hide_not_queued_episodes_label">No en cua</string>
- <string name="hide_downloaded_episodes_label">Baixat</string>
- <string name="hide_not_downloaded_episodes_label">No baixat</string>
<string name="hide_has_media_label">Conté medis</string>
- <string name="hide_is_favorite_label">És preferint</string>
<string name="filtered_label">Filtrat</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Darrera actualització fallida</string>
<string name="open_podcast">Obrir podcast</string>
@@ -163,10 +149,6 @@
<string name="delete_label">Esborrar</string>
<string name="delete_failed">No s\'ha pogut esborrar el fitxer. Reiniciar el dispositiu pot ajudar.</string>
<string name="delete_episode_label">Esborrar episodi.</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d episodi esborrat.</item>
- <item quantity="other">%d episodis esborrats.</item>
- </plurals>
<string name="remove_new_flag_label">Retirar bandera de \"nou\"</string>
<string name="removed_new_flag_label">Retirada bandera de \"nou\"</string>
<string name="mark_read_label">Marca com a llegit</string>
@@ -238,7 +220,6 @@
</plurals>
<string name="downloads_processing">S\'estan processant les baixades</string>
<string name="download_notification_title">S\'estan baixant les dades del podcast</string>
- <string name="download_report_content">%1$d baixades finalitzades, %2$d fallides</string>
<string name="download_log_title_unknown">Títol desconegut</string>
<string name="download_type_feed">Canal</string>
<string name="download_type_media">Fitxer</string>
@@ -251,7 +232,6 @@
<string name="confirm_mobile_download_dialog_message">La baixada amb connexió de dades mòbils està desactivada.\n\nVols permetre la descàrrega de forma temporal?\n\n<small>La teva tria es recordarà durant 10 minuts.</small></string>
<string name="confirm_mobile_streaming_notification_title">Confirmar streaming per mòbil.</string>
<string name="confirm_mobile_streaming_notification_message">Streaming per xarxa mòbil està deshabilitat als ajustos. Toca la pantalla per a fer-ho de totes maners.</string>
- <string name="confirm_mobile_streaming_button_always">Permet sempre.</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">En cua</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Permetre temporalment</string>
<!--Mediaplayer messages-->
@@ -297,7 +277,6 @@
<string name="download_plugin_label">Baixa el connector</string>
<string name="no_playback_plugin_title">Connector no instal·lat</string>
<string name="no_playback_plugin_or_sonic_msg">Per a que la velocitat de reproducció variable funcione recomanem activar el reproductor de medis Sonic.</string>
- <string name="set_playback_speed_label">Velocitats de reproducció</string>
<string name="enable_sonic">Activa Sonic</string>
<!--Empty list labels-->
<string name="no_items_header_label">No hi ha episodis a la cua.</string>
@@ -371,7 +350,6 @@
<string name="pref_autoUpdateIntervallOrTime_every">cada %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">als %1$s</string>
<string name="pref_followQueue_title">Reproducció continuada</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Desconnexió d\'auriculars</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Connexió d\'auriculars</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Connexió de bluetooth</string>
<string name="pref_stream_over_download_title">Preferir streaming</string>
@@ -384,7 +362,6 @@
<string name="pref_mobileUpdate_episode_download">Baixada d\'episodis</string>
<string name="pref_mobileUpdate_streaming">Streaming</string>
<string name="user_interface_label">Interfície d\'usuari</string>
- <string name="user_interface_sum">Aparença, Ordre de les subscripcions, pantalla de bloqueig</string>
<string name="pref_set_theme_title">Selecciona el tema</string>
<string name="pref_nav_drawer_items_title">Estableix els elements del calaix de navegació</string>
<string name="pref_nav_drawer_items_sum">Canvia els elements que apareixen al calaix de navegació.</string>
@@ -423,10 +400,7 @@
<string name="pref_gpodnet_full_sync_title">Força sincronització completa</string>
<string name="pref_gpodnet_full_sync_sum">Sincronitza amb gpodder.net totes les subscripcions i els estats dels episodis.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Connectat com a <i>%1$s</i> amb el dispositiu <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Notifica els errors de sincronització</string>
<string name="pref_gpodnet_notifications_sum">Aquest paràmetre no s\'aplica als errors d\'autenticació. </string>
- <string name="pref_playback_speed_title">Velocitats de reproducció</string>
- <string name="pref_playback_speed_sum">Personalitzeu les velocitats disponibles per a una velocitat de reproducció d\'àudio variable</string>
<string name="pref_feed_playback_speed_sum">La velocitat a usar quan comence la reproducció per a episodis en aquest podcast</string>
<string name="pref_feed_skip">Auto Ometre</string>
<string name="pref_feed_skip_sum">Omet introduccions i crèdits finals</string>
@@ -446,15 +420,11 @@
<string name="pref_expandNotify_sum">Açò normalment expandeix la notificació per a mostrar botons de reproducció</string>
<string name="pref_persistNotify_title">Botons de reproducció persistents</string>
<string name="pref_persistNotify_sum">Manté els controls a l\'àrea de notificacions i pantalla de bloqueig quan la reproducció estigui aturada</string>
- <string name="pref_compact_notification_buttons_title">Estableix els botons del bloqueig de pantalla</string>
- <string name="pref_compact_notification_buttons_sum">Canvia els botons de reproducció al bloqueig de pantalla. Els de pausa i reproducció sempre estan inclosos. </string>
<string name="pref_compact_notification_buttons_dialog_title">Selecciona un màxim de %1$d elements.</string>
<string name="pref_compact_notification_buttons_dialog_error">Només pots seleccionar un màxim de %1$d elements.</string>
<string name="pref_lockscreen_background_title">Estableix el fons del bloqueig de pantalla</string>
<string name="pref_lockscreen_background_sum">Estableix el fons del bloqueig de pantalla a la imatge de l\'episodi actual. Com a efecte secundari, això també mostrarà la imatge en aplicacions de tercers.</string>
- <string name="pref_showDownloadReport_title">Mostra informació de baixades</string>
<string name="pref_showDownloadReport_sum">Si les descàrregues fallen, genera un informe que mostra els detalls de la fallada.</string>
- <string name="pref_showAutoDownloadReport_title">Mostra Informe de baixades automàtiques</string>
<string name="pref_showAutoDownloadReport_sum">Mostra una notificació per a episodis descarregats automàticament</string>
<string name="pref_expand_notify_unsupport_toast">Les versions d\'Android anteriors a la 4.1 no suporten les notificacions ampliades.</string>
<string name="pref_enqueue_location_title">Posició d\'entrada en cola</string>
@@ -553,7 +523,6 @@
<string name="export_success_sum">S\'ha exportat el fitxer a:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Per llegir arxius OPML és necessari accés a la memòria externa</string>
<string name="import_select_file">Tria un fitxer per a importar</string>
- <string name="import_ok">S\'ha importat amb èxit.\n\nPremeu D\'acord per a reiniciar l\'AntennaPod.</string>
<string name="import_no_downgrade">Aquesta base de dades va ser exportada amb una versió més nova d\'AntennaPod. La versió que tens ara mateixa no sap com processar-la.</string>
<string name="favorites_export_label">Exportar preferits</string>
<string name="favorites_export_summary">Exportar episodis favorits a un arxiu</string>
@@ -648,7 +617,6 @@
<string name="decrease_speed">Disminueix la velocitat</string>
<string name="media_type_audio_label">Àudio</string>
<string name="media_type_video_label">Vídeo</string>
- <string name="navigate_upwards_label">Navega cap amunt</string>
<string name="status_downloading_label">S\'està baixant l\'episodi</string>
<string name="in_queue_label">S\'ha afegit l\'episodi a la cua</string>
<string name="is_favorite_label">L\'episodi està marcat com a favorit</string>
@@ -678,16 +646,14 @@
<string name="search_itunes_label">Cerca a iTunes</string>
<string name="search_fyyd_label">Cerca a fyyd</string>
<string name="advanced">Avançat</string>
- <string name="add_podcast_by_url">Afegir podcast per URL</string>
<string name="browse_gpoddernet_label">Navega gpodder.net</string>
<string name="discover">Descobreix</string>
<string name="discover_more">més »</string>
- <string name="search_powered_by">Cerca feta per %1$s</string>
+ <!--Local feeds-->
<string name="filter">Filtra</string>
<!--Episodes apply actions-->
<string name="all_label">Tot</string>
<string name="selected_all_label">Selecciona tots els episodis</string>
- <string name="none_label">Cap</string>
<string name="deselected_all_label">Deselecciona tots els episodis</string>
<string name="played_label">Reproduit</string>
<string name="selected_played_label">Selecciona episodis reproduits</string>
@@ -697,12 +663,17 @@
<string name="selected_downloaded_label">Selecciona episodis descarregats</string>
<string name="not_downloaded_label">No baixat</string>
<string name="selected_not_downloaded_label">Selecciona episodis sense descarregar</string>
- <string name="queued_label">En cua</string>
<string name="selected_queued_label">Episodis en cua seleccionats</string>
- <string name="not_queued_label">No encuat</string>
<string name="selected_not_queued_label">Episodis seleccionats i no a la cua</string>
- <string name="has_media">Té mitjans</string>
<string name="selected_has_media_label">Episodis amb mitjans seleccionats</string>
+ <string name="hide_is_favorite_label">És preferint</string>
+ <string name="hide_downloaded_episodes_label">Baixat</string>
+ <string name="hide_not_downloaded_episodes_label">No baixat</string>
+ <string name="queued_label">En cua</string>
+ <string name="not_queued_label">No encuat</string>
+ <string name="has_media">Té mitjans</string>
+ <string name="hide_paused_episodes_label">Pausat</string>
+ <string name="hide_played_episodes_label">Reproduit</string>
<!--Sort-->
<string name="sort_title_a_z">Títol (A \u2192 Z)</string>
<string name="sort_title_z_a">Títol (Z \u2192 A)</string>
@@ -722,6 +693,7 @@
<string name="rating_never_label">Deixa\'m tranquil</string>
<string name="rating_later_label">Pregunta\'m més tard</string>
<string name="rating_now_label">I tant, fem-ho!</string>
+ <!--Share episode dialog-->
<!--Audio controls-->
<string name="audio_controls">Controls d\'audio</string>
<string name="playback_speed">Velocitat de reproducció</string>
@@ -768,7 +740,6 @@
<string name="notification_channel_playing">Reproducció actual</string>
<string name="notification_channel_playing_description">Permet controlar la reproducció. Aquesta és la notificació principal que veureu durant la reproducció d\'un podcast.</string>
<string name="notification_channel_error">Errors</string>
- <string name="notification_channel_error_description">Mostrar si quelcom va malament, per exemple si una baixada o sincronització fallen.</string>
<string name="notification_channel_auto_download">Baixades automàtiques</string>
<string name="notification_channel_episode_auto_download">Mostrat quan els episodis han sigut descarregats automàticament</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-cs/strings.xml b/core/src/main/res/values-cs/strings.xml
index ec6f20941..ba9ebd1f2 100644
--- a/core/src/main/res/values-cs/strings.xml
+++ b/core/src/main/res/values-cs/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Došlo k zaplnění limitu odkládacího prostoru pro epizody. Můžete navýšit vyhrazený prostor v Nastavení.</string>
<string name="playback_statistics_label">Přehrávání</string>
<string name="download_statistics_label">Stažené</string>
+ <string name="notification_pref_fragment">Upozornění</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Celkový čas poslechnutých podcastů:</string>
+ <string name="total_time_listened_to_podcasts">Celkový čas přehraných epizod:</string>
<string name="statistics_details_dialog">%1$d z %2$d započatých epizod.\n\nPřehraných %3$s z %4$s.</string>
<string name="statistics_mode">Režim statistik</string>
<string name="statistics_mode_normal">Počítat skutečně přehraný čas. Tj. 5 minutová epizoda poslechnutá dvakrát je 10 minut, 7 minutová epizoda pouze označená jako poslechnutá je 0 minut.</string>
- <string name="statistics_mode_count_all">Sečíst délky všech podcastů označených jako poslechnutých.</string>
+ <string name="statistics_mode_count_all">Sečíst délky všech epizod označených jako poslechnuté</string>
<string name="statistics_speed_not_counted">Upozornění: Rychlost přehrávání se nikdy nebere v potaz.</string>
<string name="statistics_reset_data">Vynulovat statistiky</string>
<string name="statistics_reset_data_msg">Toto smaže veškerou historii přehrávání pro všechny epizody. Vážně chcete pokračovat?</string>
+ <string name="statistics_counting_since">Od %s,\nbylo přehráváno</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Celková velikost stažených podcastů:</string>
+ <string name="total_size_downloaded_podcasts">Celková velikost epizod na přístroji:</string>
<!--Main activity-->
<string name="drawer_open">Otevřít menu</string>
<string name="drawer_close">Zavřít menu</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Počet nepřehraných epizod</string>
<string name="drawer_feed_counter_downloaded">Počet stažených epizod</string>
<string name="drawer_feed_counter_none">Žádné</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Nenalezena kompatibilní aplikace</string>
<!--Webview actions-->
<string name="open_in_browser_label">Otevřít v prohlížeči</string>
<string name="copy_url_label">Kopírovat URL</string>
@@ -132,28 +136,21 @@
<string name="rename_feed_label">Přejmenovat podcast</string>
<string name="remove_feed_label">Odstranit podcast</string>
<string name="share_label">Sdílet</string>
- <string name="share_link_label">Sdílet URL epizody</string>
- <string name="share_link_with_position_label">Sdílet URL epizody s časovou značkou</string>
+ <string name="share_label_with_ellipses">Sdílet…</string>
<string name="share_file_label">Sdílet soubor</string>
- <string name="share_website_url_label">Sdílet URL webu</string>
- <string name="share_feed_url_label">Sdílet URL podcastu</string>
- <string name="share_item_url_label">Sdílet URL souboru</string>
- <string name="share_item_url_with_position_label">Sdílet URL souboru s časovou značkou</string>
+ <string name="share_website_url_label">Adresa webu</string>
+ <string name="share_feed_url_label">URL kanálu podcastu</string>
<string name="feed_delete_confirmation_msg">Potvrďte prosím, že chcete smazat podcast „%1$s“ a VŠECHNY jeho epizody (včetně stažených epizod).</string>
+ <string name="feed_delete_confirmation_local_msg">Potvrďte odstranění podcastu \"%1$s\". Soubory v místním úložišti nebudou smazány.</string>
<string name="feed_remover_msg">Odstraňování podcastu</string>
<string name="load_complete_feed">Aktualizovat celý podcast</string>
<string name="multi_select">Výběr více položek</string>
<string name="select_all_above">Vybrat všechny výše</string>
<string name="select_all_below">Vybrat všechny níže</string>
<string name="hide_unplayed_episodes_label">Neposlechnuté</string>
- <string name="hide_paused_episodes_label">Pozastavené</string>
- <string name="hide_played_episodes_label">Poslechnuté</string>
<string name="hide_queued_episodes_label">Ve frontě</string>
<string name="hide_not_queued_episodes_label">Mimo frontu</string>
- <string name="hide_downloaded_episodes_label">Stažené</string>
- <string name="hide_not_downloaded_episodes_label">Nestažené</string>
<string name="hide_has_media_label">Obsahuje média</string>
- <string name="hide_is_favorite_label">Je mezi oblíbenými</string>
<string name="filtered_label">Filtrované</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Poslední aktualizace selhala</string>
<string name="open_podcast">Otevřít podcast</string>
@@ -172,12 +169,6 @@
<string name="delete_label">Smazat</string>
<string name="delete_failed">Nelze smazat soubor. Restart přístroje může pomoci.</string>
<string name="delete_episode_label">Smazat epizodu</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d epizoda stažena.</item>
- <item quantity="few">%d epizody staženy.</item>
- <item quantity="many">%d epizod staženo.</item>
- <item quantity="other">%d epizod staženo.</item>
- </plurals>
<string name="remove_new_flag_label">Odstranit příznak „nová“</string>
<string name="removed_new_flag_label">Příznak „nová“ odstraněn</string>
<string name="mark_read_label">Označit jako poslechnuté</string>
@@ -259,7 +250,12 @@
</plurals>
<string name="downloads_processing">Probíhá stahování</string>
<string name="download_notification_title">Stahuji podcast data</string>
- <string name="download_report_content">%1$d úspěšných stahování, %2$d selhalo</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d úspěšné stažení, %d selhalo</item>
+ <item quantity="few">%d úspěšná stažení, %d selhala</item>
+ <item quantity="many">%d úspěšných stažení, %d selhalo</item>
+ <item quantity="other">%d úspěšných stažení, %d selhalo</item>
+ </plurals>
<string name="download_log_title_unknown">Neznámý název</string>
<string name="download_type_feed">Kanál</string>
<string name="download_type_media">Soubor</string>
@@ -272,7 +268,8 @@
<string name="confirm_mobile_download_dialog_message">Stahování dat přes mobilní připojení je v nastavení vypnuto.\n\nDočasně povolit?\n\n<small>Tato volba bude platná po dalších 10 minut.</small></string>
<string name="confirm_mobile_streaming_notification_title">Potvrďtě prosím streamování přes mobilní data</string>
<string name="confirm_mobile_streaming_notification_message">Streamování přes mobilní data je zakázáno v nastavení. Streamování můžete spustit dotykem, pokud i přesto chcete streamovat přes mobilní data.</string>
- <string name="confirm_mobile_streaming_button_always">Vždy povolit</string>
+ <string name="confirm_mobile_streaming_button_always">Vždy</string>
+ <string name="confirm_mobile_streaming_button_once">Jednou</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Pouze přidat do fronty</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Dočasně povolit</string>
<!--Mediaplayer messages-->
@@ -318,16 +315,17 @@
<string name="download_plugin_label">Stáhnout modul</string>
<string name="no_playback_plugin_title">Modul není nainstalován</string>
<string name="no_playback_plugin_or_sonic_msg">Pro správnou funkci proměnlivé rychlosti přehrávání je doporučeno povolit vestavěný přehrávač Sonic.</string>
- <string name="set_playback_speed_label">Rychlosti přehrávání</string>
<string name="enable_sonic">Povolit Sonic</string>
+ <string name="speed_presets">Předvolby</string>
+ <string name="preset_already_exists">%1$.2fx je již uloženo jako předvolba.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Žádné epizody ve frontě</string>
<string name="no_items_label">Přidejte epizodu stažením nebo dlouhým dotykem a volbou „Přidat do fronty“.</string>
<string name="no_shownotes_label">Tato epizoda neobsahuje žádné poznámky.</string>
<string name="no_run_downloads_head_label">Neběží žádná stahování</string>
- <string name="no_run_downloads_label">Můžete stáhnout epizody tohoto podcastu z obrazovky s jeho detaily.</string>
+ <string name="no_run_downloads_label">Epizody lze stáhnout na obrazovce detailů o tomto podcastu.</string>
<string name="no_comp_downloads_head_label">Žádné stažené epizody</string>
- <string name="no_comp_downloads_label">Můžete stáhnout epizody tohoto podcastu z obrazovky s jeho detaily.</string>
+ <string name="no_comp_downloads_label">Epizody lze stáhnout na obrazovce detailů o tomto podcastu.</string>
<string name="no_log_downloads_head_label">Žádné záznamy o stahování</string>
<string name="no_log_downloads_label">Až proběhnou nějaká stahování, tak se záznamy o nich objeví zde.</string>
<string name="no_history_head_label">Žádná historie</string>
@@ -340,7 +338,7 @@
<string name="no_fav_episodes_label">Epizody si můžete přidat mezi oblíbené dlouhým dotykem.</string>
<string name="no_chapters_head_label">Žádné kapitoly</string>
<string name="no_chapters_label">Tato epizoda nemá žádné kapitoly.</string>
- <string name="no_subscriptions_head_label">Žádené sbírky</string>
+ <string name="no_subscriptions_head_label">Žádné sbírky</string>
<string name="no_subscriptions_label">Pro přidání podcastu do sbírky se dotkněte ikonky plus níže.</string>
<!--Preferences-->
<string name="storage_pref">Úložiště</string>
@@ -377,7 +375,7 @@
<string name="pref_smart_mark_as_played_title">Chytré označování jako poslechnuté</string>
<string name="pref_skip_keeps_episodes_sum">Neodstraňovat epizody při jejich přeskočení</string>
<string name="pref_skip_keeps_episodes_title">Nemazat přeskočené epizody</string>
- <string name="pref_favorite_keeps_episodes_sum">Nemazat epizody, které jsou mezi oblíbenými.</string>
+ <string name="pref_favorite_keeps_episodes_sum">Nemazat epizody označené jako oblíbené.</string>
<string name="pref_favorite_keeps_episodes_title">Nemazat oblíbené epizody</string>
<string name="playback_pref">Přehrávání</string>
<string name="playback_pref_sum">Ovládání tlačítky sluchátek, přeskakování, fronta</string>
@@ -392,7 +390,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">každých %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">v %1$s</string>
<string name="pref_followQueue_title">Kontinuální přehrávání</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Sluchátka odpojena</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Sluchátka nebo Bluetooth odpojeno</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Sluchátka připojena</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth připojeno</string>
<string name="pref_stream_over_download_title">Upřednostnit streamování</string>
@@ -405,7 +403,7 @@
<string name="pref_mobileUpdate_episode_download">Stahování epizod</string>
<string name="pref_mobileUpdate_streaming">Streamování</string>
<string name="user_interface_label">Uživatelské rozhraní</string>
- <string name="user_interface_sum">Vzhled, poradí ve sbírce, uzamčená obrazovka</string>
+ <string name="user_interface_sum">Vzhled, odběry, uzamčená obrazovka</string>
<string name="pref_set_theme_title">Vybrat motiv</string>
<string name="pref_nav_drawer_items_title">Změnit navigační panel</string>
<string name="pref_nav_drawer_items_sum">Upravit zobrazení položek v navigačním panelu.</string>
@@ -424,7 +422,7 @@
<string name="pref_episode_cache_title">Historie epizod</string>
<string name="pref_episode_cache_summary">Celkový počet epizod stažených na zařízení. Automatické stahování se zastaví při dosažení této hodnoty.</string>
<string name="pref_episode_cover_title">Použít obrázek epizody</string>
- <string name="pref_episode_cover_summary">Použít obrázek přímo z epizody, pokud je k dispozici. Není-li tato možnost zaškrtnuta, tak se vžy použije obrázek podcastu.</string>
+ <string name="pref_episode_cover_summary">Použít obrázek přímo z epizody, pokud je k dispozici. Není-li tato možnost zaškrtnuta, tak se vždy použije obrázek podcastu.</string>
<string name="pref_theme_title_use_system">Použít systémové téma</string>
<string name="pref_theme_title_light">Světlý</string>
<string name="pref_theme_title_dark">Tmavý</string>
@@ -444,10 +442,9 @@
<string name="pref_gpodnet_full_sync_title">Synchronizovat vše ihned</string>
<string name="pref_gpodnet_full_sync_sum">Synchronizovat všechny odběry a stav epizod s gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Přihlášen jako <i>%1$s</i> z přístroje <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Zobrazovat oznámení o chybách synchronizace</string>
+ <string name="pref_gpodnet_notifications_title">Synchronizace selhala</string>
<string name="pref_gpodnet_notifications_sum">Toto nastavení se netýká chyb přihlášení.</string>
- <string name="pref_playback_speed_title">Rychlosti přehrávání</string>
- <string name="pref_playback_speed_sum">Přizpůsobení rychlosti je dostupné pro přehrávání zvuku různými rychlostmi</string>
+ <string name="pref_playback_speed_sum">Upravit předvybrané možnosti pro přehrávání zvuku různými rychlostmi</string>
<string name="pref_feed_playback_speed_sum">Rychlost, která bude použita při zahájení přehrávání epizod tohoto podcastu</string>
<string name="pref_feed_skip">Automatické přeskočení</string>
<string name="pref_feed_skip_sum">Přeskočit úvod a závěr.</string>
@@ -467,15 +464,15 @@
<string name="pref_expandNotify_sum">Toto obvykle přidá tlačítka ovládání přehrávání do zpráv upozornění</string>
<string name="pref_persistNotify_title">Pevné ovládání přehrávání</string>
<string name="pref_persistNotify_sum">Zachovat oznámení a ovládání na obrazovce uzamčení i při pozastaveném přehrávání.</string>
- <string name="pref_compact_notification_buttons_title">Nastavení tlačítek uzamčené obrazovky</string>
- <string name="pref_compact_notification_buttons_sum">Změnit tlačítka ovládání na obrazovce uzamčení. Tlačítka přehrát/pozastavit jsou vždy zobrazena.</string>
+ <string name="pref_compact_notification_buttons_title">Nastavit tlačítka rychlých upozornění</string>
+ <string name="pref_compact_notification_buttons_sum">Změnit tlačítka ovládání po zarolování upozornění. Tlačítka přehrát/pozastavit jsou vždy zobrazena.</string>
<string name="pref_compact_notification_buttons_dialog_title">Vybrat maximálně %1$d položek</string>
<string name="pref_compact_notification_buttons_dialog_error">Lze vybrat maximálně %1$d položek.</string>
<string name="pref_lockscreen_background_title">Nastavit pozadí uzamčené obrazovky</string>
<string name="pref_lockscreen_background_sum">Nastavit pozadí uzamčené obrazovky na obrázek aktuální epizody. Jako vedlejší efekt zobrazí toto nastavení obrázek i v aplikacích třetích stran. </string>
- <string name="pref_showDownloadReport_title">Zobrazit report stahování</string>
+ <string name="pref_showDownloadReport_title">Stahování selhalo</string>
<string name="pref_showDownloadReport_sum">Pokud selže stahování, vygenerovat report zobrazující detaily o chybě.</string>
- <string name="pref_showAutoDownloadReport_title">Zobrazovat hlášení automatického stahování</string>
+ <string name="pref_showAutoDownloadReport_title">Automatické stahování dokončeno</string>
<string name="pref_showAutoDownloadReport_sum">Zobrazovat oznámení o automaticky stažených epizodách.</string>
<string name="pref_expand_notify_unsupport_toast">Verze Androidu nižší než 4.1 nepodporují rozšířená oznámení.</string>
<string name="pref_enqueue_location_title">Pozice přidávání do fronty</string>
@@ -488,7 +485,7 @@
<string name="pref_image_cache_size_sum">Velikost diskové paměti pro obrázky.</string>
<string name="visit_user_forum">Uživatelské fórum</string>
<string name="bug_report_title">Nahlásit chybu</string>
- <string name="open_bug_tracker">Otevřít systém pro sledování a hlášení chyb (bug tracker)</string>
+ <string name="open_bug_tracker">Otevřít systém pro sledování a hlášení chyb</string>
<string name="export_logs">Exportovat záznamy</string>
<string name="copy_to_clipboard">Zkopírovat do schránky</string>
<string name="copied_to_clipboard">Zkopírováno do schránky</string>
@@ -505,6 +502,7 @@
<string name="pref_enqueue_downloaded_title">Zařadit stažené</string>
<string name="pref_enqueue_downloaded_summary">Přidat stažené epizody do fronty</string>
<string name="media_player_builtin">Vestavěný přehrávač Androidu</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (doporučen)</string>
<string name="media_player_switch_to_exoplayer">Přepnout na ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Přepnuto na ExoPlayer</string>
<string name="pref_skip_silence_title">Přeskočit ticho v audio souboru</string>
@@ -525,6 +523,15 @@
<string name="back_button_go_to_page_title">Vybrat stránku</string>
<string name="pref_delete_removes_from_queue_title">Mazání také odstraňuje epizody z fronty</string>
<string name="pref_delete_removes_from_queue_sum">Automaticky odstraní epizodu z fronty poté, co je smazána.</string>
+ <string name="pref_filter_feed_title">Filtr sbírek</string>
+ <string name="pref_filter_feed_sum">Filtrujte svoje sbírky v navigačním panelu a na obrazovce odebíraných kanálů.</string>
+ <string name="no_filter_label">Žádné</string>
+ <string name="subscriptions_are_filtered">Odebírané sbírky jsou filtrovány.</string>
+ <string name="subscriptions_counter_greater_zero">Počet vyšší než nula</string>
+ <string name="auto_downloaded">Automaticky stahováno</string>
+ <string name="not_auto_downloaded">Nebylo automaticky staženo</string>
+ <string name="kept_updated">Udržováno aktuální</string>
+ <string name="not_kept_updated">Neaktualizováno</string>
<!--About screen-->
<string name="about_pref">O aplikaci</string>
<string name="antennapod_version">Verze aplikace AntennaPod</string>
@@ -549,7 +556,7 @@
<string name="sync_status_success">Synchronizace proběhla úspěšně</string>
<string name="sync_status_error">Synchronizace selhala</string>
<!--import and export-->
- <string name="import_export_summary">Přesunout zbírky a frontu do jiného zařízení</string>
+ <string name="import_export_summary">Přesunout sbírky a frontu do jiného zařízení</string>
<string name="database">Databáze</string>
<string name="opml">OPML</string>
<string name="html">HTML</string>
@@ -559,6 +566,7 @@
<string name="database_export_summary">Přenést sbírky, poslechnuté epizody a frontu do aplikace AntennaPod na jiném zařízení</string>
<string name="database_import_summary">Importovat AntennaPod databázi z jiného zařízení</string>
<string name="opml_import_label">OPML import</string>
+ <string name="opml_add_podcast_label">Importovat podcasty (OPML)</string>
<string name="opml_reader_error">Došlo k chybě při čtení OPML dokumentu:</string>
<string name="opml_import_error_no_file">Nebyl vybrán žádný soubor!</string>
<string name="select_all_label">Označit vše</string>
@@ -574,7 +582,8 @@
<string name="export_success_sum">Exportovaný soubor zapsán do:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Pro přečtení OPML souboru je vyžadován přístup k externímu úložišti</string>
<string name="import_select_file">Vybrat soubor pro import</string>
- <string name="import_ok">Import úspěšný.\n\nPotvrďte restart AntennaPod tlačítkem OK</string>
+ <string name="successful_import_label">Import úspěšný</string>
+ <string name="import_ok">Ťuknutím na OK restartujte AntenaPod</string>
<string name="import_no_downgrade">Tato databáze byla exportována z novější verze aplikace AntennaPod. Vaše instalovaná verze není schopná ji zpracovat.</string>
<string name="favorites_export_label">Export oblíbených</string>
<string name="favorites_export_summary">Exportovat oblíbené do souboru</string>
@@ -646,7 +655,7 @@
<string name="choose_data_directory">Vybrat umístění dat</string>
<string name="choose_data_directory_message">Vyberte prosím váš výchozí datový adresář. AntennaPod vytvoří všechny potřebné podadresáře.</string>
<string name="choose_data_directory_permission_rationale">Ke změně datového adresáře je vyžadován přístup k externímu úložišti</string>
- <string name="choose_data_directory_available_space">%1$s z %2$s zdarma</string>
+ <string name="choose_data_directory_available_space">%1$s z %2$s volných</string>
<string name="create_folder_msg">Vytvořit adresář \"%1$s\"?</string>
<string name="create_folder_success">Nový adresář vytvořen</string>
<string name="create_folder_error_no_write_access">Nelze zapisovat do adresáře</string>
@@ -675,7 +684,6 @@
<string name="decrease_speed">Snížit rychlost</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Navigovat vzhůru</string>
<string name="status_downloading_label">Epizoda je právě stahována</string>
<string name="in_queue_label">Epizoda je ve frontě</string>
<string name="is_favorite_label">Epizoda je označená jako oblíbená</string>
@@ -696,6 +704,10 @@
<string name="keep_updated">Udržovat aktuální</string>
<string name="keep_updated_summary">Zahrnout tento podcast při (automatickém) obnovování všech podcastů</string>
<string name="auto_download_disabled_globally">Automatické stahování je zakázané v hlavním nastavení AntennaPodu</string>
+ <string name="statistics_listened_for">Posloucháno po:</string>
+ <string name="statistics_episodes_on_device">Epizod na přístroji:</string>
+ <string name="statistics_space_used">Zabírá místa:</string>
+ <string name="statistics_view_all">Náhled všech podcastů »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Probíhá aktualizace databáze</string>
<!--AntennaPodSP-->
@@ -703,18 +715,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Vyhledat podcast…</string>
<string name="search_itunes_label">Prohledat iTunes</string>
+ <string name="search_podcastindex_label">Prohledat Podcastindex.org</string>
<string name="search_fyyd_label">Prohledat fyyd</string>
<string name="advanced">Pokročilé</string>
- <string name="add_podcast_by_url">Přidat podcast pomocí URL</string>
+ <string name="add_podcast_by_url">Přidat podcast pomocí RSS</string>
<string name="browse_gpoddernet_label">Prohledávat gpodder.net</string>
<string name="discover">Objevit</string>
+ <string name="discover_hide">Skrýt</string>
+ <string name="discover_is_hidden">Zvolili jste skrýt doporučení.</string>
<string name="discover_more">více »</string>
- <string name="search_powered_by">Vyhledávání poskytuje %1$s</string>
+ <string name="discover_powered_by_itunes">iTunes doporučuje</string>
+ <string name="search_powered_by">Výsledky dle %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Přidat místní adresář</string>
+ <string name="local_folder">Místní adresář</string>
+ <string name="reconnect_local_folder">Znovu připojit místní adresář</string>
+ <string name="reconnect_local_folder_warning">V případě zamítnutých oprávnění může být tato možnost použita pro připojení ke stejnému adresáři. Nevybírejte ale jiný adresář.</string>
+ <string name="local_feed_description">Byl založen následující virtuální podcast vytvořením adresáře v AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Nedaří se spustit správce souborů</string>
<string name="filter">Filtr</string>
<!--Episodes apply actions-->
<string name="all_label">Vše</string>
<string name="selected_all_label">Vybrány všechny epizody</string>
- <string name="none_label">Žádné</string>
+ <string name="select_none_label">Žádné</string>
<string name="deselected_all_label">Odebrány všechny epizody</string>
<string name="played_label">Přehrány</string>
<string name="selected_played_label">Vybrány přehrané epizody</string>
@@ -724,12 +747,21 @@
<string name="selected_downloaded_label">Vybrány stažené epizody</string>
<string name="not_downloaded_label">Nestažené</string>
<string name="selected_not_downloaded_label">Vybrány nestažené epizody</string>
- <string name="queued_label">Ve frontě</string>
<string name="selected_queued_label">Vybrané epizody ve frontě</string>
- <string name="not_queued_label">Mimo frontu</string>
<string name="selected_not_queued_label">Vybrané epizody mimo frontu</string>
- <string name="has_media">Obsahuje média</string>
<string name="selected_has_media_label">Vybrané epizody s médii</string>
+ <string name="hide_is_favorite_label">Je mezi oblíbenými</string>
+ <string name="not_favorite">Není mezi oblíbenými</string>
+ <string name="hide_downloaded_episodes_label">Stažené</string>
+ <string name="hide_not_downloaded_episodes_label">Nestažené</string>
+ <string name="queued_label">Ve frontě</string>
+ <string name="not_queued_label">Mimo frontu</string>
+ <string name="has_media">Obsahuje média</string>
+ <string name="no_media">Žádná média</string>
+ <string name="hide_paused_episodes_label">Pozastavené</string>
+ <string name="not_paused">Nepozastaveno</string>
+ <string name="hide_played_episodes_label">Poslechnuté</string>
+ <string name="not_played">Nepřehraných</string>
<!--Sort-->
<string name="sort_title_a_z">Názvu (A \u2192 Z)</string>
<string name="sort_title_z_a">Názvu (Z \u2192 A)</string>
@@ -749,6 +781,12 @@
<string name="rating_never_label">Neobtěžuj mě</string>
<string name="rating_later_label">Upozornit později</string>
<string name="rating_now_label">Jasně, s radostí!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Zahrnout:</string>
+ <string name="share_playback_position_dialog_label">Pozice přehrávání</string>
+ <string name="share_dialog_media_file_url_label">Adresa souboru media</string>
+ <string name="share_dialog_episode_website_label">Webová stránka epizody</string>
+ <string name="share_dialog_media_file_label">Soubor medií</string>
<!--Audio controls-->
<string name="audio_controls">Audio ovládání</string>
<string name="playback_speed">Rychlost přehrávání</string>
@@ -795,7 +833,9 @@
<string name="notification_channel_playing">Přehrává se</string>
<string name="notification_channel_playing_description">Umožňuje ovládat přehrávání. Toto je to hlavní oznámení, které uvidité při přehrávání podcastu.</string>
<string name="notification_channel_error">Chyby</string>
- <string name="notification_channel_error_description">Zobrazuje se, když se něco nepovedlo. Například pokud selhalo stahování anebo synchronizace gpodder.</string>
+ <string name="notification_channel_error_description">Upozorňovat pokud něco selže, například stahování či aktualizace odebíraného kanálu.</string>
+ <string name="notification_channel_sync_error">Chyby synchronizace</string>
+ <string name="notification_channel_sync_error_description">Zobrazovat chybu synchronizace s gpodder.</string>
<string name="notification_channel_auto_download">Automatické stahování</string>
<string name="notification_channel_episode_auto_download">Zobrazuje se po automatickém stažení epizod.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-da/strings.xml b/core/src/main/res/values-da/strings.xml
index 01026e021..1fc7e1d69 100644
--- a/core/src/main/res/values-da/strings.xml
+++ b/core/src/main/res/values-da/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Der er ikke mere plads i mellemlageret for udsendelser. Du kan øge størrelsen på mellemlageret i Indstillinger.</string>
<string name="playback_statistics_label">Afspilning</string>
<string name="download_statistics_label">Overførsler</string>
+ <string name="notification_pref_fragment">Påmindelser</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Samlet varighed for afspillede podcasts:</string>
+ <string name="total_time_listened_to_podcasts">Samlet tid for afspillede udsendelser:</string>
<string name="statistics_details_dialog">%1$d af %2$d udsendelser startet.\n\nAfspillet %3$s af %4$s.</string>
<string name="statistics_mode">Statistiktilstand</string>
<string name="statistics_mode_normal">Beregn den varighed som faktisk blev afspillet. Afspilning af en udsendelse to gange tæller dobbelt, mens en markering som værende afspillet ikke tælles med.</string>
- <string name="statistics_mode_count_all">Opsummer alle podcasts markeret som afspillet</string>
+ <string name="statistics_mode_count_all">Summér alle udsendelser markeret som afspillet</string>
<string name="statistics_speed_not_counted">Bemærk: Afspilningshastigheden har ingen betydning</string>
<string name="statistics_reset_data">Nulstil statistik</string>
<string name="statistics_reset_data_msg">Dette vil slette historikken over hvor meget der er afspillet af alle udsendelser.</string>
+ <string name="statistics_counting_since">Siden %s\nhar du afspillet</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Total størrelse af overførte podcasts:</string>
+ <string name="total_size_downloaded_podcasts">Samlet størrelse af udsendelserne på enheden:</string>
<!--Main activity-->
<string name="drawer_open">Åbn menu</string>
<string name="drawer_close">Luk menu</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Antal uafspillede udsendelser</string>
<string name="drawer_feed_counter_downloaded">Antal overførte udsendelser</string>
<string name="drawer_feed_counter_none">Ingen</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Ingen kompatible apper fundet.</string>
<!--Webview actions-->
<string name="open_in_browser_label">Åbn i browser</string>
<string name="copy_url_label">Kopier webadresse</string>
@@ -71,7 +75,7 @@
<string name="error_msg_prefix">En fejl er opstået:</string>
<string name="needs_storage_permission">Tilladelse til lageradgang kræves for denne handling</string>
<string name="refresh_label">Opdater</string>
- <string name="external_storage_error_msg">Ingen ekstern harddisk er tilgængelig. Vær venlig at sørge for at den eksterne hukommelse er monteret så app\'en kan fungere korrekt.</string>
+ <string name="external_storage_error_msg">Ingen ekstern lagerenhed er tilgængelig. Sørg for at den eksterne lagerenhed er tilsluttet, så appen kan fungere korrekt.</string>
<string name="chapters_label">Kapitler</string>
<string name="chapter_duration">Varighed: %1$s</string>
<string name="description_label">Beskrivelse</string>
@@ -80,7 +84,7 @@
<string name="save_username_password_label">Gem brugernavn og adgangskode</string>
<string name="close_label">Luk</string>
<string name="retry_label">Prøv igen</string>
- <string name="auto_download_label">Inkluder i Automatisk overførsel</string>
+ <string name="auto_download_label">Inkludér i automatiske overførsler</string>
<string name="auto_download_apply_to_items_title">Anvend på tidligere udsendelser</string>
<string name="auto_download_apply_to_items_message">Den nye <i>Automatisk overførsel</i>-indstilling vil automatisk blive anvendt på nye udsendelser.\nVil du også anvende den på tidligere udsendelser?</string>
<string name="auto_delete_label">Slet udsendelser automatisk</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Podcast-indstillinger</string>
<string name="rename_feed_label">Omdøb podcast</string>
<string name="remove_feed_label">Fjern podcast</string>
- <string name="share_label">Del…</string>
- <string name="share_link_label">Del udsendelsens webadresse</string>
- <string name="share_link_with_position_label">Del webadresse for udsendelse med position</string>
+ <string name="share_label">Del</string>
+ <string name="share_label_with_ellipses">Del...</string>
<string name="share_file_label">Del fil</string>
- <string name="share_website_url_label">Del webstedets adresse</string>
- <string name="share_feed_url_label">Del podcast URL</string>
- <string name="share_item_url_label">Del webadresse for mediefil</string>
- <string name="share_item_url_with_position_label">Del webadresse for mediefil med position</string>
+ <string name="share_website_url_label">Netsted adresse</string>
+ <string name="share_feed_url_label">Podcast-adresse</string>
<string name="feed_delete_confirmation_msg">Bekræft venligst at du ønsker at slette podcasten \"%1$s\" og ALLE dens udsendelser (inklusive overførte udsendelser)</string>
+ <string name="feed_delete_confirmation_local_msg">Bekræft venligst at du vil fjerne podcasten \"%1$s\". Filerne i den lokale kildemappe vil ikke blive slettet.</string>
<string name="feed_remover_msg">Fjerner podcast</string>
<string name="load_complete_feed">Opdater komplet podcast</string>
<string name="multi_select">Vælg flere</string>
<string name="select_all_above">Vælg alt ovenfor</string>
<string name="select_all_below">Vælg alt nedenfor</string>
<string name="hide_unplayed_episodes_label">Uafspillede</string>
- <string name="hide_paused_episodes_label">Sat på pause</string>
- <string name="hide_played_episodes_label">Afspillede</string>
<string name="hide_queued_episodes_label">Sat i kø</string>
<string name="hide_not_queued_episodes_label">Ikke sat i kø</string>
- <string name="hide_downloaded_episodes_label">Overførte</string>
- <string name="hide_not_downloaded_episodes_label">Ikke overførte</string>
<string name="hide_has_media_label">Har medier</string>
- <string name="hide_is_favorite_label">Er foretrukken</string>
<string name="filtered_label">Filtrerede</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Sidste opdatering fejlede</string>
<string name="open_podcast">Åbn podcast</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Slet</string>
<string name="delete_failed">Kan ikke slette fil. En genstart af enheden vil sandsynligvis hjælpe.</string>
<string name="delete_episode_label">Slet udsendelse</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d udsendelse slettet.</item>
- <item quantity="other">%d udsendelser slettet.</item>
- </plurals>
<string name="remove_new_flag_label">Fjern \"ny\"-markering</string>
<string name="removed_new_flag_label">Fjernet \"ny\"-markering</string>
<string name="mark_read_label">Marker som afspillet</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Bearbejder overførte data</string>
<string name="download_notification_title">Henter podcast-data</string>
- <string name="download_report_content">%1$d overførsler lykkedes, %2$d fejlede</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d overførsel lykkedes, %d fejlede</item>
+ <item quantity="other">%d overførsler lykkedes, %d fejlede</item>
+ </plurals>
<string name="download_log_title_unknown">Ukendt titel</string>
<string name="download_type_feed">Feed</string>
<string name="download_type_media">Mediefil</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Overførsel over mobil dataforbindelse er slået fra i indstillingerne.\n\nVil du tillade overførsel midlertidigt?\n\n<small>Dit valg vil blive husket i 10 minutter.</small></string>
<string name="confirm_mobile_streaming_notification_title">Bekræft mobil streaming</string>
<string name="confirm_mobile_streaming_notification_message">Streaming via mobildata er slået fra i indstillingerne. Tryk for at streame alligevel.</string>
- <string name="confirm_mobile_streaming_button_always">Tillad altid</string>
+ <string name="confirm_mobile_streaming_button_always">Altid</string>
+ <string name="confirm_mobile_streaming_button_once">Én gang</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Sæt i kø</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Tillad midlertidigt</string>
<!--Mediaplayer messages-->
@@ -260,7 +257,7 @@
<string name="player_preparing_msg">Forbereder</string>
<string name="player_ready_msg">Klar</string>
<string name="player_seeking_msg">Søger</string>
- <string name="playback_error_server_died">Server døde</string>
+ <string name="playback_error_server_died">Serveren døde</string>
<string name="playback_error_unsupported">Kan ikke afspille denne medietype</string>
<string name="playback_error_timeout">Handlingen annulleret fordi den tog for lang tid</string>
<string name="playback_error_source">Kunne ikke tilgå mediefil</string>
@@ -297,18 +294,19 @@
<string name="download_plugin_label">Hent plugin</string>
<string name="no_playback_plugin_title">Plugin er ikke installeret</string>
<string name="no_playback_plugin_or_sonic_msg">For ændring af afspilningshastighed, vi forslår at bruge den indbyggede Sonic medie afspiller.</string>
- <string name="set_playback_speed_label">Afspilningshastigheder</string>
<string name="enable_sonic">Slå Sonic til</string>
+ <string name="speed_presets">Forudindstillinger</string>
+ <string name="preset_already_exists">%1$.2fx er allerede gemt som en forudindstilling.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Ingen udsendelser i køen</string>
- <string name="no_items_label">Tilføj en episode ved at downloade den, eller lang tryk på episoden og klik \"Tilføj til afspilningsliste\"</string>
+ <string name="no_items_label">Tilføj en udsendelse ved at downloade den, eller tryk og hold på episoden og vælg \"Føj til kø\".</string>
<string name="no_shownotes_label">Denne udsendelse har ingen beskrivelse.</string>
<string name="no_run_downloads_head_label">Ingen overførsler i gang</string>
<string name="no_run_downloads_label">Du kan downloade episode ved podcastens beskrivelse</string>
<string name="no_comp_downloads_head_label">Ingen overførte udsendelser</string>
<string name="no_comp_downloads_label">Du kan downloade episoden på podcastens detaljerede skærm. </string>
<string name="no_log_downloads_head_label">Ingen overførselslog</string>
- <string name="no_log_downloads_label">Download raport vil blive vist her når muligt</string>
+ <string name="no_log_downloads_label">Overførselslog vil blive vist her når tilgængelig.</string>
<string name="no_history_head_label">Ingen historik</string>
<string name="no_history_label">Når du har hørt en episode, vil den blive vist her.</string>
<string name="no_all_episodes_head_label">Ingen udsendelser</string>
@@ -326,7 +324,7 @@
<string name="storage_sum">Automatisk sletning, Importer, Exporter af episoder</string>
<string name="project_pref">Projekt</string>
<string name="queue_label">Kø</string>
- <string name="synchronization_pref">synkronisering</string>
+ <string name="synchronization_pref">Synkronisering</string>
<string name="synchronization_sum">Synkroniser med andre enheder ved hjælp af gpodder.net</string>
<string name="automation">Automatisering</string>
<string name="download_pref_details">Detaljer</string>
@@ -349,7 +347,7 @@
<string name="pref_hardwareForwardButtonSkips_sum">Når der trykkes på næste knappen på de tilsluttede høretelefoner, skift til næste episode istedet for at springe frem.</string>
<string name="pref_hardwarePreviousButtonRestarts_title">Tilbageknap genstarter</string>
<string name="pref_hardwarePreviousButtonRestarts_sum">Når der trykkes på en fysisk tilbageknap, skal den aktuelle udsendelse afspilles forfra i stedet for at der spoles tilbage.</string>
- <string name="pref_followQueue_sum">Spring til næste element i køen når afspilningen er færdig</string>
+ <string name="pref_followQueue_sum">Gå til næste element i køen når afspilningen er færdig</string>
<string name="pref_auto_delete_sum">Slet udsendelsen når afspilningen er færdig</string>
<string name="pref_auto_delete_title">Slet automatisk</string>
<string name="pref_smart_mark_as_played_sum">Marker udsendelser som værende afspillet, selv om op til et angivet antal sekunders spilletid stadig mangler</string>
@@ -361,37 +359,37 @@
<string name="playback_pref">Afspilning</string>
<string name="playback_pref_sum">Hovedtelefon kontrol, Overspring intervaller, Kø</string>
<string name="network_pref">Netværk</string>
- <string name="network_pref_sum">Opdateringsinterval, hente kontroller, mobildata</string>
+ <string name="network_pref_sum">Opdateringsinterval, overførselsindstillinger, mobildata</string>
<string name="pref_autoUpdateIntervallOrTime_title">Opdateringsinterval eller -klokkeslæt</string>
- <string name="pref_autoUpdateIntervallOrTime_sum">Spicifik interval, eller spicifik tid på dagen, genindlæs podcasts automatisk</string>
- <string name="pref_autoUpdateIntervallOrTime_message">Du kan indstille et <i>interval</i> som \"hver anden time\", indstille et bestemt <i>klokkeslæt</i> som \"7:00\", eller <i>slå</i> automatiske opdateringer helt <i>fra</i>.\n\n<small>Bemærk: Opdateringstider er ikke eksakte. Du kan opleve en kort forsinkelse.</small></string>
+ <string name="pref_autoUpdateIntervallOrTime_sum">Angiv et tidsinterval eller et bestemt klokkeslæt hvor podcastene skal opdateres automatisk</string>
+ <string name="pref_autoUpdateIntervallOrTime_message">Du kan indstille et <i>interval</i> som \"hver 2. time\", indstille et bestemt <i>klokkeslæt</i> som \"7:00\", eller <i>slå</i> automatiske opdateringer helt <i>fra</i>.\n\n<small>Bemærk: Opdateringstider er ikke eksakte. Du kan opleve en kort forsinkelse.</small></string>
<string name="pref_autoUpdateIntervallOrTime_Disable">Slå fra</string>
<string name="pref_autoUpdateIntervallOrTime_Interval">Indstil interval</string>
<string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Indstil klokkeslæt</string>
<string name="pref_autoUpdateIntervallOrTime_every">hver %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">kl. %1$s</string>
<string name="pref_followQueue_title">Kontinuerlig afspilning</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Afbrydelse af hovedtelefoner</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Hovedtelefoner eller bluetooth afbrudt</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Tilslutning af hovedtelefoner igen</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth forbundet igen</string>
<string name="pref_stream_over_download_title">Foretræk streaming</string>
<string name="pref_stream_over_download_sum">Vis stream knap, i stedet for download knap i listen.</string>
<string name="pref_mobileUpdate_title">Mobile opdateringer</string>
- <string name="pref_mobileUpdate_sum">Vælg hvad der skal være tilladt via mobil data forbindelse</string>
+ <string name="pref_mobileUpdate_sum">Vælg hvad der skal være tilladt via mobil dataforbindelse</string>
<string name="pref_mobileUpdate_refresh">Opdatere podcast</string>
- <string name="pref_mobileUpdate_images">Omslag billeder</string>
+ <string name="pref_mobileUpdate_images">Billeder</string>
<string name="pref_mobileUpdate_auto_download">Hent automatisk</string>
<string name="pref_mobileUpdate_episode_download">Download af udsendelser</string>
<string name="pref_mobileUpdate_streaming">Streaming</string>
<string name="user_interface_label">Brugergrænseflade</string>
- <string name="user_interface_sum">Udseende, abonnements ordre, låseskærm</string>
+ <string name="user_interface_sum">Udseende, abonnementer, låseskærm</string>
<string name="pref_set_theme_title">Vælg tema</string>
<string name="pref_nav_drawer_items_title">Vælg elementer i navigationspanelet</string>
<string name="pref_nav_drawer_items_sum">Vælg hvilke elementer, der skal vises i navigationspanelet.</string>
<string name="pref_nav_drawer_feed_order_title">Vælg abonnementsorden</string>
<string name="pref_nav_drawer_feed_order_sum">Ændr rækkefølgen af dine abonnementer</string>
<string name="pref_nav_drawer_feed_counter_title">Indstil abonnementstæller</string>
- <string name="pref_nav_drawer_feed_counter_sum">Ændre informationen vist af abonnoment tæller. Ændre også ved abonnement rækkefølge, hvis abonnement rækkefølge er sat til \'Tæller\'</string>
+ <string name="pref_nav_drawer_feed_counter_sum">Ændr informationen vist af abonnementstælleren. Påvirker også rækkefølgen af abonnementer, hvis abonnementsrækkefølgen er sat til \'Tæller\'.</string>
<string name="pref_set_theme_sum">Ændr AntennaPods udseende.</string>
<string name="pref_automatic_download_title">Automatisk overførsel</string>
<string name="pref_automatic_download_sum">Konfigurer automatisk overførsel af udsendelser</string>
@@ -402,8 +400,8 @@
<string name="pref_parallel_downloads_title">Parallelle overførsler</string>
<string name="pref_episode_cache_title">Mellemlager for udsendelser</string>
<string name="pref_episode_cache_summary">Total nummer af episoder downloades på din enhed. Stop automatisk download, når dette nummer nåes.</string>
- <string name="pref_episode_cover_title">Brug afsnit omslag</string>
- <string name="pref_episode_cover_summary">Brug det specifikke episode cover, når muligt. Hvis tændt, vil app\'en altid bruge podcast cover billedet.</string>
+ <string name="pref_episode_cover_title">Brug udsendelsesbillede</string>
+ <string name="pref_episode_cover_summary">Brug det udsendelsesspecifikke billede når muligt. Hvis dette slås fra, vil appen altid bruge podcastens billede.</string>
<string name="pref_theme_title_use_system">Brug systemtema</string>
<string name="pref_theme_title_light">Lys</string>
<string name="pref_theme_title_dark">Mørk</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Tving fuld synkronisering</string>
<string name="pref_gpodnet_full_sync_sum">Synkroniser tilstande for alle abonnementer og udsendelser med gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Logget ind som <i>%1$s</i> med enheden <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Vis notifikationer med synkroniseringsfejl</string>
+ <string name="pref_gpodnet_notifications_title">Synkronisering mislykkedes</string>
<string name="pref_gpodnet_notifications_sum">Denne indstilling vedrører ikke godkendelsesfejl.</string>
- <string name="pref_playback_speed_title">Afspilningshastigheder</string>
- <string name="pref_playback_speed_sum">Tilpas tilgængelige hastigheder for lydafspilning med variabel hastighed</string>
+ <string name="pref_playback_speed_sum">Tilpas de tilgængelige hastigheder for afspilning med variabel hastighed</string>
<string name="pref_feed_playback_speed_sum">Hastighed, der skal bruges, når lydafspilning startes til afsnit i denne podcast</string>
<string name="pref_feed_skip">Overspring automatisk</string>
<string name="pref_feed_skip_sum">Overspring introduktioner og slut kreditter.</string>
@@ -441,20 +438,20 @@
<string name="pref_rewind">Tidshop for tilbagespoling</string>
<string name="pref_rewind_sum">Indstil antallet af sekunder, der skal springes tilbage, når der trykkes på tilbagespolingsknappen</string>
<string name="pref_gpodnet_sethostname_title">Indstil værtsnavn</string>
- <string name="pref_gpodnet_sethostname_use_default_host">Brug standard vært</string>
+ <string name="pref_gpodnet_sethostname_use_default_host">Brug standardvært</string>
<string name="pref_expandNotify_title">Høj prioritet for notifikation</string>
<string name="pref_expandNotify_sum">Dette udvider normalt notifikationen til at vise afspilningsknapper.</string>
<string name="pref_persistNotify_title">Vedholdende afspilningsknapper</string>
<string name="pref_persistNotify_sum">Behold notifikation og knapper på låseskærmen, når afspilningen sættes på pause.</string>
- <string name="pref_compact_notification_buttons_title">Indstil knapper på låseskærm</string>
- <string name="pref_compact_notification_buttons_sum">Vælg afspilningsknapper på låseskærmen. Afspil/pause-knappen medtages altid.</string>
+ <string name="pref_compact_notification_buttons_title">Indstil kompakte notifikationsknapper</string>
+ <string name="pref_compact_notification_buttons_sum">Ændr afspilningsknapperne når notifikationen minimeres. Afspil/pause-knappen vises altid.</string>
<string name="pref_compact_notification_buttons_dialog_title">Vælg højst %1$d knapper</string>
<string name="pref_compact_notification_buttons_dialog_error">Du kan højst vælge %1$d knapper.</string>
<string name="pref_lockscreen_background_title">Indstil baggrund på låseskærmen</string>
<string name="pref_lockscreen_background_sum">Sæt baggrunden på låseskærmen til billedet for den aktuelle udsendelse. Som en sidevirkning vil det også vise billedet i tredjepartsapps.</string>
- <string name="pref_showDownloadReport_title">Vis rapport over overførsler</string>
+ <string name="pref_showDownloadReport_title">Overførsel mislykkedes</string>
<string name="pref_showDownloadReport_sum">Lav en rapport, som viser detaljer om fejlene, hvis overførsler fejler</string>
- <string name="pref_showAutoDownloadReport_title">Vis rapport over automatiske overførsler</string>
+ <string name="pref_showAutoDownloadReport_title">Automatisk overførsel fuldført</string>
<string name="pref_showAutoDownloadReport_sum">Vis en notifikation for automatisk overførte udsendelser</string>
<string name="pref_expand_notify_unsupport_toast">Android-versioner før 4.1 understøtter ikke udvidede notifikationer.</string>
<string name="pref_enqueue_location_title">Placering i kø</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Sæt overførte udsendelser i kø</string>
<string name="pref_enqueue_downloaded_summary">Føj downloadede udsendelser til køen</string>
<string name="media_player_builtin">Indbygget Android-afspiller</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (anbefalet)</string>
<string name="media_player_switch_to_exoplayer">Skift til ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Skiftet til ExoPlayer.</string>
<string name="pref_skip_silence_title">Overspring stilhed i lyd</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Vælg side</string>
<string name="pref_delete_removes_from_queue_title">Slet fjernet fra kø</string>
<string name="pref_delete_removes_from_queue_sum">Fjern automatisk afsnit fra køen, når den slettes.</string>
+ <string name="pref_filter_feed_title">Abonnement filter</string>
+ <string name="pref_filter_feed_sum">Filtrer dine abonnementer i navigationspanelet og på abonnementsoversigten.</string>
+ <string name="no_filter_label">Ingen</string>
+ <string name="subscriptions_are_filtered">Abonnementer er filtreret.</string>
+ <string name="subscriptions_counter_greater_zero">Tæller større end 0</string>
+ <string name="auto_downloaded">Automatisk hentet</string>
+ <string name="not_auto_downloaded">Ikke automatisk hentet</string>
+ <string name="kept_updated">Holdt opdateret</string>
+ <string name="not_kept_updated">Ikke holdt opdateret</string>
<!--About screen-->
<string name="about_pref">Om</string>
<string name="antennapod_version">AntennaPod version</string>
@@ -538,11 +545,12 @@
<string name="database_export_summary">Flyt abonnementer, aflyttede afsnit og kø til AntennaPod på en anden enhed</string>
<string name="database_import_summary">Importere AntennaPod database fra anden enhed</string>
<string name="opml_import_label">OPML-import</string>
- <string name="opml_reader_error">Der opstod en fejl, da OPML-dokumentet blev forsøgt indlæst</string>
+ <string name="opml_add_podcast_label">Importere podcast liste (OPML)</string>
+ <string name="opml_reader_error">Der opstod en fejl, da OPML-dokumentet blev forsøgt indlæst:</string>
<string name="opml_import_error_no_file">Ingen fil valgt!</string>
<string name="select_all_label">Vælg alle</string>
<string name="deselect_all_label">Fravælg alle</string>
- <string name="opml_export_label">OPML eksport</string>
+ <string name="opml_export_label">OPML-eksport</string>
<string name="html_export_label">HTML-eksport</string>
<string name="database_export_label">Eksportere database</string>
<string name="database_import_label">Importere database</string>
@@ -553,14 +561,15 @@
<string name="export_success_sum">Den eksporterede fil blev skrevet til:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Adgang til eksternt lager er påkrævet for at læse OPML-filen</string>
<string name="import_select_file">Vælg fil til import</string>
- <string name="import_ok">Importen lykkedes.\n\nTryk venligst OK for at genstarte AntennaPod</string>
+ <string name="successful_import_label">Importeret</string>
+ <string name="import_ok">Tryk venligst OK for at genstarte AntennaPod</string>
<string name="import_no_downgrade">Databasen var exporteret af en nyere version af AntennaPod. Din nuværende installation ved ikke endnu hvordan den skal håndtere denne fil.</string>
<string name="favorites_export_label">Foretrukne eksport</string>
<string name="favorites_export_summary">Eksportere gemte foretrukne til fil</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Indstil søvntimer</string>
<string name="disable_sleeptimer_label">Slå søvntimer fra</string>
- <string name="sleep_timer_label">Søvn timer</string>
+ <string name="sleep_timer_label">Søvntimer</string>
<string name="time_dialog_invalid_input">Ugyldig indtastning: tid skal være et heltal</string>
<string name="shake_to_reset_label">Ryst for at nulstille</string>
<string name="timer_vibration_label">Vibrere kort før afslutning</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Mindsk hastighed</string>
<string name="media_type_audio_label">Lyd</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Naviger opad</string>
<string name="status_downloading_label">Udsendelse overføres</string>
<string name="in_queue_label">Udsendelse er i køen</string>
<string name="is_favorite_label">Afsnit er markeret som favorit</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Hold opdateret</string>
<string name="keep_updated_summary">Inkludere denne podcast når alle podcast genindlæses</string>
<string name="auto_download_disabled_globally">Automatisk download slået fra i de generelle AntennaPod indstilinger</string>
+ <string name="statistics_listened_for">Lytter efter:</string>
+ <string name="statistics_episodes_on_device">Afsnit på enhed:</string>
+ <string name="statistics_space_used">Plads brugt:</string>
+ <string name="statistics_view_all">Vis for alle podcasts »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Opgraderer databasen</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Søg efter podcast ...</string>
<string name="search_itunes_label">Søg i iTunes</string>
+ <string name="search_podcastindex_label">Søg på Podcastindex.org</string>
<string name="search_fyyd_label">Søg i fyyd</string>
<string name="advanced">Avanceret</string>
- <string name="add_podcast_by_url">Tilføje podcast ved URL</string>
+ <string name="add_podcast_by_url">Tilføj podcast via RSS adresse</string>
<string name="browse_gpoddernet_label">Gennemse gpodder.net</string>
<string name="discover">Opdag</string>
+ <string name="discover_hide">Gem</string>
+ <string name="discover_is_hidden">Du valgte at skjule forslag.</string>
<string name="discover_more">mere »</string>
- <string name="search_powered_by">Søgning drevet af %1$s</string>
+ <string name="discover_powered_by_itunes">iTunes forslag</string>
+ <string name="search_powered_by">Resultater fra %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Tilføj lokal mappe</string>
+ <string name="local_folder">Lokal mappe</string>
+ <string name="reconnect_local_folder">Genforbind lokal mappe</string>
+ <string name="reconnect_local_folder_warning">I tilfælde af nægtelse af tilladelse kan du bruge denne til at forbinde til præcis den samme mappe. Vælg ikke en anden mappe.</string>
+ <string name="local_feed_description">Denne virtuelle podcast blev oprettet ved at en mappe blev føjet til AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Kunne ikke starte system filhåndtering</string>
<string name="filter">Filtrér</string>
<!--Episodes apply actions-->
<string name="all_label">Alle</string>
<string name="selected_all_label">Markerede alle udsendelser</string>
- <string name="none_label">Ingen</string>
+ <string name="select_none_label">Ingen</string>
<string name="deselected_all_label">Afmarkerede alle udsendelser</string>
<string name="played_label">Afspillede</string>
<string name="selected_played_label">Markerede afspillede udsendelser</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Markerede overførte udsendelser</string>
<string name="not_downloaded_label">Ikke-overførte</string>
<string name="selected_not_downloaded_label">Markerede ikke-overførte udsendelser</string>
- <string name="queued_label">Sat i kø</string>
<string name="selected_queued_label">Markerede udsendelser, der er sat i kø</string>
- <string name="not_queued_label">Ikke sat i kø</string>
<string name="selected_not_queued_label">Markerede udsendelser, der ikke er sat i kø</string>
- <string name="has_media">Har medier</string>
<string name="selected_has_media_label">Markerede udsendelser med medier</string>
+ <string name="hide_is_favorite_label">Er foretrukken</string>
+ <string name="not_favorite">Ikke foretrukken</string>
+ <string name="hide_downloaded_episodes_label">Overførte</string>
+ <string name="hide_not_downloaded_episodes_label">Ikke overførte</string>
+ <string name="queued_label">Sat i kø</string>
+ <string name="not_queued_label">Ikke sat i kø</string>
+ <string name="has_media">Har medier</string>
+ <string name="no_media">Ingen medier</string>
+ <string name="hide_paused_episodes_label">Sat på pause</string>
+ <string name="not_paused">Ikke sat på pause</string>
+ <string name="hide_played_episodes_label">Afspillede</string>
+ <string name="not_played">Ikke afspillet</string>
<!--Sort-->
<string name="sort_title_a_z">Titel (A \u2192 Å)</string>
<string name="sort_title_z_a">Titel (Å \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Lad mig være</string>
<string name="rating_later_label">Påmind mig senere</string>
<string name="rating_now_label">Klart, lad os gøre det!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Medtag:</string>
+ <string name="share_playback_position_dialog_label">Afspilningsposition</string>
+ <string name="share_dialog_media_file_url_label">Adresse på mediefil</string>
+ <string name="share_dialog_episode_website_label">Afsnit netsted</string>
+ <string name="share_dialog_media_file_label">Mediefil</string>
<!--Audio controls-->
<string name="audio_controls">Lydknapper</string>
<string name="playback_speed">Afspilningshastighed</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Spiller nu</string>
<string name="notification_channel_playing_description">Giver adgang til at kontrollere afspilning. Dette er den mest normale notifikation du vil se, mens du afspiller en podcast.</string>
<string name="notification_channel_error">Fejl</string>
- <string name="notification_channel_error_description">Vist hvis noget gik galt, for eksempel ved download eller gpodder synkroniserings fejl.</string>
+ <string name="notification_channel_error_description">Vises hvis noget gik galt, for eksempel hvis en overførsel eller feed-opdatering fejlede.</string>
+ <string name="notification_channel_sync_error">Synkroniseringsfejl</string>
+ <string name="notification_channel_sync_error_description">Vises når gpodder-synkronisering fejler.</string>
<string name="notification_channel_auto_download">Automatisk hentninger</string>
<string name="notification_channel_episode_auto_download">Vist når episoder automatisk var blevet downloaded.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-de/strings.xml b/core/src/main/res/values-de/strings.xml
index c9fd04079..1beeeb0af 100644
--- a/core/src/main/res/values-de/strings.xml
+++ b/core/src/main/res/values-de/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Der Episodenspeicher ist voll. Du kannst die Größe des Episodenspeichers in den Einstellungen erhöhen.</string>
<string name="playback_statistics_label">Wiedergabe</string>
<string name="download_statistics_label">Downloads</string>
+ <string name="notification_pref_fragment">Benachrichtigungen</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Gesamtzeit gespielter Podcasts:</string>
+ <string name="total_time_listened_to_podcasts">Gesamtzeit aller gespielten Episoden</string>
<string name="statistics_details_dialog">%1$d von %2$d Episoden gestartet.\n\n%3$s von %4$s Episoden gespielt.</string>
<string name="statistics_mode">Statistik-Modus</string>
<string name="statistics_mode_normal">Berechne die tatsächlich gespielte Dauer. Zweimaliges Abspielen wird auch zwei Mal gezählt, als gespielt markierte Episoden jedoch gar nicht</string>
- <string name="statistics_mode_count_all">Aufsummieren aller als gespielt markierter Episoden</string>
+ <string name="statistics_mode_count_all">Alle als gespielt markierten Episoden summieren</string>
<string name="statistics_speed_not_counted">Hinweis: Die Abspielgeschwindigkeit wird nicht berücksichtigt.</string>
<string name="statistics_reset_data">Statistiken zurücksetzen</string>
<string name="statistics_reset_data_msg">Die Abspieldauer wird für alle Episoden gelöscht. Möchtest du wirklich fortfahren?</string>
+ <string name="statistics_counting_since">Seit %s,\nhast du abgespielt</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Gesamtgröße der heruntergeladenen Podcasts:</string>
+ <string name="total_size_downloaded_podcasts">Gesamtgröße der Episoden auf dem Gerät:</string>
<!--Main activity-->
<string name="drawer_open">Menü öffnen</string>
<string name="drawer_close">Menü schließen</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Anzahl ungespielter Episoden</string>
<string name="drawer_feed_counter_downloaded">Anzahl heruntergeladener Episoden</string>
<string name="drawer_feed_counter_none">Keine</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Keine kompatiblen Apps gefunden</string>
<!--Webview actions-->
<string name="open_in_browser_label">Im Browser öffnen</string>
<string name="copy_url_label">URL kopieren</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Podcast-Einstellungen</string>
<string name="rename_feed_label">Podcast umbenennen</string>
<string name="remove_feed_label">Podcast entfernen</string>
- <string name="share_label">Teilen…</string>
- <string name="share_link_label">Episoden URL Teilen</string>
- <string name="share_link_with_position_label">Teile Link mit Zeitmarke</string>
+ <string name="share_label">Teilen</string>
+ <string name="share_label_with_ellipses">Teilen...</string>
<string name="share_file_label">Teile Datei</string>
- <string name="share_website_url_label">Teile URL der Website</string>
- <string name="share_feed_url_label">Podcast-URL teilen</string>
- <string name="share_item_url_label">Teile URL der Episodendatei</string>
- <string name="share_item_url_with_position_label">Teile URL der Episodendatei mit Zeitmarke</string>
+ <string name="share_website_url_label">Adresse der Website</string>
+ <string name="share_feed_url_label">Podcast feed URL</string>
<string name="feed_delete_confirmation_msg">Bitte bestätige, dass du den Podcast \"%1$s\" und ALL dessen Episoden entfernen möchtest (auch heruntergeladene).</string>
+ <string name="feed_delete_confirmation_local_msg">Bitte bestätigen Sie, dass Sie den Podcast \"%1$s\" entfernen möchten. Die Dateien im lokalen Quellordner werden nicht gelöscht.</string>
<string name="feed_remover_msg">Podcast wird entfernt</string>
<string name="load_complete_feed">Kompletten Podcast aktualisieren</string>
<string name="multi_select">Mehrere auswählen</string>
<string name="select_all_above">Alles oberhalb auswählen</string>
<string name="select_all_below">Alles unterhalb auswählen</string>
<string name="hide_unplayed_episodes_label">Ungespielt</string>
- <string name="hide_paused_episodes_label">Pausiert</string>
- <string name="hide_played_episodes_label">Gespielt</string>
<string name="hide_queued_episodes_label">In Warteschlange</string>
<string name="hide_not_queued_episodes_label">Nicht in Warteschlange</string>
- <string name="hide_downloaded_episodes_label">Heruntergeladen</string>
- <string name="hide_not_downloaded_episodes_label">Nicht heruntergeladen</string>
<string name="hide_has_media_label">Hat Medien</string>
- <string name="hide_is_favorite_label">Favorit</string>
<string name="filtered_label">Gefiltert</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Aktualisierung fehlgeschlagen</string>
<string name="open_podcast">Podcast öffnen</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Löschen</string>
<string name="delete_failed">Die Datei kann nicht gelöscht werden. Eventuell hilft es, das Gerät neu zu starten.</string>
<string name="delete_episode_label">Episode löschen</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d Episode gelöscht.</item>
- <item quantity="other">%d Episoden gelöscht.</item>
- </plurals>
<string name="remove_new_flag_label">\"Neu\"-Markierung entfernen</string>
<string name="removed_new_flag_label">\"Neu\"-Markierung entfernt</string>
<string name="mark_read_label">Als gespielt markieren</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Verarbeite Downloads</string>
<string name="download_notification_title">Lade Podcast-Daten</string>
- <string name="download_report_content">%1$d Downloads erfolgreich, %2$d fehlgeschlagen</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d Download erfolgreich, %d fehlgeschlagen</item>
+ <item quantity="other">%d Downloads erfolgreich, %d fehlgeschlagen</item>
+ </plurals>
<string name="download_log_title_unknown">Unbekannter Titel</string>
<string name="download_type_feed">Feed</string>
<string name="download_type_media">Mediendatei</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Das Herunterladen über die mobile Datenverbindung ist in den Einstellungen deaktiviert.\n\nVorübergehend erlauben?\n\n<small>Deine Entscheidung wird für 10 Minuten gespeichert.</small></string>
<string name="confirm_mobile_streaming_notification_title">Mobiles Streamen bestätigen</string>
<string name="confirm_mobile_streaming_notification_message">Streamen über mobile Datenverbindung ist in den Einstellungen deaktiviert. Tippen, um trotzdem zu streamen.</string>
- <string name="confirm_mobile_streaming_button_always">Immer erlauben</string>
+ <string name="confirm_mobile_streaming_button_always">Immer</string>
+ <string name="confirm_mobile_streaming_button_once">Einmalig</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Zur Warteschlange hinzufügen</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Vorübergehend erlauben</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Plugin herunterladen</string>
<string name="no_playback_plugin_title">Plugin nicht installiert</string>
<string name="no_playback_plugin_or_sonic_msg">Um variable Wiedergabegeschwindigkeit benutzen zu können, empfehlen wir, den integrierten Sonic Mediaplayer zu aktivieren.</string>
- <string name="set_playback_speed_label">Wiedergabegeschwindigkeiten</string>
<string name="enable_sonic">Sonic aktivieren</string>
+ <string name="speed_presets">Voreinstellung</string>
+ <string name="preset_already_exists">%1$.2fx ist bereits als Voreinstellung gespeichert.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Leere Warteschlange</string>
<string name="no_items_label">Du kannst Episoden hinzufügen, indem du sie herunterlädst oder sie lange antippst und \"Zur Warteschlange hinzufügen\" auswählst.</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">jede %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">um %1$s</string>
<string name="pref_followQueue_title">Durchgehendes Abspielen</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Kopfhörer-Trennung</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Kopfhörer oder Bluetooth getrennt</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Kopfhörer wieder eingesteckt</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth wieder verbunden</string>
<string name="pref_stream_over_download_title">Streamen bevorzugen</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Episoden herunterladen</string>
<string name="pref_mobileUpdate_streaming">Streamen</string>
<string name="user_interface_label">Benutzeroberfläche</string>
- <string name="user_interface_sum">Erscheinungsbild, Reihenfolge der Abonnements, Sperrbildschirm</string>
+ <string name="user_interface_sum">Darstellung, Abonnements, Sperrbildschirm</string>
<string name="pref_set_theme_title">Theme auswählen</string>
<string name="pref_nav_drawer_items_title">Seitenleiste ändern</string>
<string name="pref_nav_drawer_items_sum">Ändere, welche Einträge in der Seitenleiste erscheinen</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Komplette Synchronisation erzwingen</string>
<string name="pref_gpodnet_full_sync_sum">Kompletten Abonnement- und Episoden-Status mit gpodder.net synchronisieren.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Eingeloggt als <i>%1$s</i> mit dem Gerät <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Zeige Benachrichtungen bei Synchronisierungsfehlern</string>
+ <string name="pref_gpodnet_notifications_title">Synchronisation fehlgeschlagen</string>
<string name="pref_gpodnet_notifications_sum">Diese Einstellung gilt nicht für Authentifizierungsfehler.</string>
- <string name="pref_playback_speed_title">Wiedergabegeschwindigkeiten</string>
- <string name="pref_playback_speed_sum">Lege die verfügbaren Werte für die Veränderung der Wiedergabeschwindigkeit fest</string>
+ <string name="pref_playback_speed_sum">Anpassen der verfügbaren Geschwindigkeiten für die Wiedergabe mit variabler Geschwindigkeit</string>
<string name="pref_feed_playback_speed_sum">Abspielgeschwindigkeit für Episoden dieses Podcasts</string>
<string name="pref_feed_skip">Automatisches Überspringen</string>
<string name="pref_feed_skip_sum">Einleitung und Ende überspringen.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Dies erweitert normalerweise die Benachrichtigung und zeigt so die Wiedergabe-Buttons an.</string>
<string name="pref_persistNotify_title">Persistente Wiedergabesteuerung</string>
<string name="pref_persistNotify_sum">Zeige Wiedergabebedienelemente in der Benachrichtigung und im Lockscreen an, während die Wiedergabe pausiert ist.</string>
- <string name="pref_compact_notification_buttons_title">Lockscreen-Wiedergabetasten festlegen</string>
- <string name="pref_compact_notification_buttons_sum">Verändere die Wiedergabetasten auf dem Lockscreen. Die Abspielen-/Pause-Taste wird immer angezeigt.</string>
+ <string name="pref_compact_notification_buttons_title">Kompakte Benachrichtigungsbuttons</string>
+ <string name="pref_compact_notification_buttons_sum">Verändere die Wiedergabetasten, wenn eine Benachrichtigung ausgeklappt ist. Die Wiedergabe/Pause-Taste wird immer angezeigt.</string>
<string name="pref_compact_notification_buttons_dialog_title">Wähle bis zu %1$d Elemente aus</string>
<string name="pref_compact_notification_buttons_dialog_error">Du kannst maximal %1$d Elemente auswählen.</string>
<string name="pref_lockscreen_background_title">Lockscreen-Hintergrund einstellen</string>
<string name="pref_lockscreen_background_sum">Verwende das aktuelle Episodenbild als Lockscreen-Hintergrund. Es wird als Nebeneffekt auch in anderen Apps gezeigt.</string>
- <string name="pref_showDownloadReport_title">Zeige Download-Bericht</string>
+ <string name="pref_showDownloadReport_title">Download fehlgeschlagen</string>
<string name="pref_showDownloadReport_sum">Wenn Downloads fehlschlagen, erstelle einen Bericht, der die Details des Fehlschlages beschreibt.</string>
- <string name="pref_showAutoDownloadReport_title">Zeige Bericht über Automatische Downloads</string>
+ <string name="pref_showAutoDownloadReport_title">Automatischer Download abgeschlossen</string>
<string name="pref_showAutoDownloadReport_sum">Zeige eine Benachrichtigung für automatisch heruntergeladene Episoden.</string>
<string name="pref_expand_notify_unsupport_toast">Android-Versionen vor 4.1 unterstützen keine erweiterten Benachrichtigungen.</string>
<string name="pref_enqueue_location_title">Position beim Einreihen</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Downloads einreihen</string>
<string name="pref_enqueue_downloaded_summary">Füge heruntergeladene Episoden zur Warteschlange hinzu</string>
<string name="media_player_builtin">Androids eingebauter Abspieler</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (empfohlen)</string>
<string name="media_player_switch_to_exoplayer">Zu ExoPlayer wechseln</string>
<string name="media_player_switched_to_exoplayer">Zu ExoPlayer gewechselt.</string>
<string name="pref_skip_silence_title">Stille im Ton überspringen</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Seite auswählen</string>
<string name="pref_delete_removes_from_queue_title">Löschen entfernt aus Warteschlange</string>
<string name="pref_delete_removes_from_queue_sum">Entferne Episoden automatisch aus der Warteschlange, wenn sie gelöscht werden.</string>
+ <string name="pref_filter_feed_title">Abonnement-Filter</string>
+ <string name="pref_filter_feed_sum">Filtere deine Abonnements in der Navigation und auf der Abonnement-Übersicht. </string>
+ <string name="no_filter_label">Keine</string>
+ <string name="subscriptions_are_filtered">Abonnements sind gefiltert</string>
+ <string name="subscriptions_counter_greater_zero">Anzahl größer als Null</string>
+ <string name="auto_downloaded">Automatisch heruntergeladen </string>
+ <string name="not_auto_downloaded">Nicht automatisch heruntergeladen</string>
+ <string name="kept_updated">Aktuell gehalten</string>
+ <string name="not_kept_updated">Nicht aktuell gehalten</string>
<!--About screen-->
<string name="about_pref">Über</string>
<string name="antennapod_version">AntennaPod-Version</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Deine Abonnements, gehörte Episoden und die Warteschlange auf AntennaPod auf einem anderen Gerät übertragen</string>
<string name="database_import_summary">AntennaPod-Datenbank von einem anderen Gerät importieren</string>
<string name="opml_import_label">OPML Import</string>
+ <string name="opml_add_podcast_label">Podcast-Liste importieren (OPML)</string>
<string name="opml_reader_error">Beim Einlesen der OPML-Datei ist ein Fehler aufgetreten:</string>
<string name="opml_import_error_no_file">Keine Datei ausgewählt!</string>
<string name="select_all_label">Alle auswählen</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">Die exportierte Datei wurde geschrieben nach:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Zugriff auf externen Speicher wird benötigt, um die OPML Datei zu lesen</string>
<string name="import_select_file">Zu importierende Datei auswählen</string>
- <string name="import_ok">Import erfolgreich.\n\nBitte OK drücken, um AntennaPod neuzustarten</string>
+ <string name="successful_import_label">Import erfolgreich</string>
+ <string name="import_ok">Bitte drücken Sie OK, um AntennaPod neu zu starten.</string>
<string name="import_no_downgrade">Diese Datenbank wurde mit einer neueren Version von AntennaPod exportiert. Deine im Moment installierte Version kann die Datei leider nicht bearbeiten.</string>
<string name="favorites_export_label">Favoriten exportieren</string>
<string name="favorites_export_summary">Speichere Favoriten in einer Datei</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Geschwindigkeit reduzieren</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Nach oben navigieren</string>
<string name="status_downloading_label">Episode wird heruntergeladen</string>
<string name="in_queue_label">Episode befindet sich in der Warteschlange</string>
<string name="is_favorite_label">Episode ist als Favorit markiert</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Aktuell halten</string>
<string name="keep_updated_summary">Diesen Podcast bei der (automatischen) Aktualisierung berücksichtigen</string>
<string name="auto_download_disabled_globally">Automatisches Herunterladen ist in den Einstellungen deaktiviert</string>
+ <string name="statistics_listened_for">Angehört für:</string>
+ <string name="statistics_episodes_on_device">Episoden auf dem Gerät:</string>
+ <string name="statistics_space_used">Verwendeter Speicherplatz:</string>
+ <string name="statistics_view_all">Für alle Podcasts ansehen »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Datenbank wird aktualisiert</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Podcast suchen…</string>
<string name="search_itunes_label">iTunes durchsuchen</string>
+ <string name="search_podcastindex_label">Podcastindex.org durchsuchen</string>
<string name="search_fyyd_label">fyyd durchsuchen</string>
<string name="advanced">Fortgeschritten</string>
- <string name="add_podcast_by_url">Podcast über URL hinzufügen</string>
+ <string name="add_podcast_by_url">Podcast über RSS-Adresse hinzufügen</string>
<string name="browse_gpoddernet_label">gpodder.net durchsuchen</string>
<string name="discover">Entdecken</string>
+ <string name="discover_hide">Ausblenden</string>
+ <string name="discover_is_hidden">Sie haben ausgewählt, Vorschläge auszublenden.</string>
<string name="discover_more">mehr »</string>
- <string name="search_powered_by">Suche bereitgestellt durch %1$s</string>
+ <string name="discover_powered_by_itunes">Vorschläge von iTunes</string>
+ <string name="search_powered_by">Ergebnisse von %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Lokalen Ordner hinzufügen</string>
+ <string name="local_folder">Lokaler Ordner</string>
+ <string name="reconnect_local_folder">Lokalen Ordner erneut verbinden</string>
+ <string name="reconnect_local_folder_warning">Im Falle von Berechtigungsverweigerungen können Sie hiermit eine erneute Verbindung zu genau demselben Ordner herstellen. Wählen Sie keinen anderen Ordner aus.</string>
+ <string name="local_feed_description">Dieser virtuelle Podcast wurde durch einen lokalen Ordner hinzugefügt.</string>
+ <string name="unable_to_start_system_file_manager">System-Dateimanager kann nicht gestartet werden</string>
<string name="filter">Filtern</string>
<!--Episodes apply actions-->
<string name="all_label">Alle</string>
<string name="selected_all_label">Alle Episoden ausgewählt</string>
- <string name="none_label">Keine</string>
+ <string name="select_none_label">Keine</string>
<string name="deselected_all_label">Alle Episoden abgewählt</string>
<string name="played_label">Gespielt</string>
<string name="selected_played_label">Gespielte Episoden ausgewählt</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Heruntergeladene Episoden ausgewählt</string>
<string name="not_downloaded_label">Nicht heruntergeladen</string>
<string name="selected_not_downloaded_label">Nicht heruntergeladene Episoden ausgewählt</string>
- <string name="queued_label">In Warteschlange</string>
<string name="selected_queued_label">Episoden in der Warteschlange ausgewählt</string>
- <string name="not_queued_label">Nicht in Warteschlange</string>
<string name="selected_not_queued_label">Episoden nicht in der Warteschlange ausgewählt</string>
- <string name="has_media">Hat Medien</string>
<string name="selected_has_media_label">Episoden mit Medien ausgewählt</string>
+ <string name="hide_is_favorite_label">Favorit</string>
+ <string name="not_favorite">Nicht favorisiert</string>
+ <string name="hide_downloaded_episodes_label">Heruntergeladen</string>
+ <string name="hide_not_downloaded_episodes_label">Nicht heruntergeladen</string>
+ <string name="queued_label">In Warteschlange</string>
+ <string name="not_queued_label">Nicht in Warteschlange</string>
+ <string name="has_media">Hat Medien</string>
+ <string name="no_media">Keine Medien</string>
+ <string name="hide_paused_episodes_label">Pausiert</string>
+ <string name="not_paused">Nicht pausiert</string>
+ <string name="hide_played_episodes_label">Gespielt</string>
+ <string name="not_played">Nicht abgespielt</string>
<!--Sort-->
<string name="sort_title_a_z">Titel (A \u2192 Z)</string>
<string name="sort_title_z_a">Titel (Z \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Lass mich in Ruhe</string>
<string name="rating_later_label">Erinnere mich später</string>
<string name="rating_now_label">Sicher, los geht\'s!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Beinhaltet</string>
+ <string name="share_playback_position_dialog_label">Abspielposition</string>
+ <string name="share_dialog_media_file_url_label">Adresse der Mediendatei</string>
+ <string name="share_dialog_episode_website_label">Webseite der Episode</string>
+ <string name="share_dialog_media_file_label">Mediendatei</string>
<!--Audio controls-->
<string name="audio_controls">Audioregler</string>
<string name="playback_speed">Abspielgeschwindigkeit</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Jetzt spielt</string>
<string name="notification_channel_playing_description">Erlaubt es, die Wiedergabe zu steuern. Dies ist die Hauptbenachrichtigung, die du siehst, während ein Podcast abgespielt wird.</string>
<string name="notification_channel_error">Fehler</string>
- <string name="notification_channel_error_description">Wird gezeigt, wenn etwas schief gegangen ist, etwa wenn das Herunterladen oder die gpodder-Synchronisierung fehlschlägt.</string>
+ <string name="notification_channel_error_description">Wird bei einem Problem angezeigt, wenn zum Beispiel ein Download oder die Aktualisierung eines Feed fehlschlägt.</string>
+ <string name="notification_channel_sync_error">Fehler bei der Synchronisation</string>
+ <string name="notification_channel_sync_error_description">Wird angezeigt, wenn die gpodder-Synchronisierung fehlschlägt.</string>
<string name="notification_channel_auto_download">Automatische Downloads</string>
<string name="notification_channel_episode_auto_download">Wird angezeigt, wenn Episoden automatisch heruntergeladen worden sind.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-es/strings.xml b/core/src/main/res/values-es/strings.xml
index e3a443991..433fad64e 100644
--- a/core/src/main/res/values-es/strings.xml
+++ b/core/src/main/res/values-es/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Se ha alcanzado el límite de almacenamiento de episodios. Puede aumentar el tamaño en opciones.</string>
<string name="playback_statistics_label">Reproducción</string>
<string name="download_statistics_label">Descargas</string>
+ <string name="notification_pref_fragment">Notificaciones</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Tiempo total de reproducción de pódcast:</string>
+ <string name="total_time_listened_to_podcasts">Tiempo total de reproducción de episodios:</string>
<string name="statistics_details_dialog">%1$d episodios iniciados de %2$d.\n\nReproducidos %3$s de %4$s.</string>
<string name="statistics_mode">Modo de estadísticas</string>
<string name="statistics_mode_normal">Calcula la duración real reproducida. Reproducir dos veces cuenta doble y marcar como leído no cuenta como reproducido</string>
- <string name="statistics_mode_count_all">Suma de todos los pódcast marcados como reproducidos</string>
+ <string name="statistics_mode_count_all">Suma de todos los episodios marcados como reproducidos</string>
<string name="statistics_speed_not_counted">Aviso: La velocidad de reproducción nunca se tiene en cuenta.</string>
<string name="statistics_reset_data">Borrar estadísticas</string>
<string name="statistics_reset_data_msg">Esto borrará el historial de duración reproducida de todos los episodios. ¿Confirma que quiere hacerlo?</string>
+ <string name="statistics_counting_since">Desde %s,\nhas reproducido</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Tamaño total de pódcast descargados:</string>
+ <string name="total_size_downloaded_podcasts">Tamaño total de episodios en dispositivo:</string>
<!--Main activity-->
<string name="drawer_open">Abrir menú</string>
<string name="drawer_close">Cerrar menú</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Número de episodios no reproducidos</string>
<string name="drawer_feed_counter_downloaded">Número de episodios descargados</string>
<string name="drawer_feed_counter_none">Ninguno</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">No se encontraro apps compatibles</string>
<!--Webview actions-->
<string name="open_in_browser_label">Abrir en el navegador</string>
<string name="copy_url_label">Copiar URL</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Ajustes del pódcast</string>
<string name="rename_feed_label">Renombrar el pódcast</string>
<string name="remove_feed_label">Eliminar el pódcast</string>
- <string name="share_label">Compartir…</string>
- <string name="share_link_label">Compartir URL del episodio</string>
- <string name="share_link_with_position_label">Compartir URL del episodio con posición</string>
+ <string name="share_label">Compartir</string>
+ <string name="share_label_with_ellipses">Compartir…</string>
<string name="share_file_label">Compartir el archivo</string>
- <string name="share_website_url_label">Compartir URL Web</string>
- <string name="share_feed_url_label">Compartir URL del Podcast</string>
- <string name="share_item_url_label">Compartir URL del archivo</string>
- <string name="share_item_url_with_position_label">Compartir URL del archivo con posición</string>
+ <string name="share_website_url_label">Dirección web</string>
+ <string name="share_feed_url_label">URL del feed del podcast</string>
<string name="feed_delete_confirmation_msg">Confirme que quiere borrar el pódcast \"%1$s\" y TODOS los episodios (incluidos los descargados).</string>
+ <string name="feed_delete_confirmation_local_msg">Confirme que quiere borrar el podcast \"%1$s\". Los archivos en la carpeta origen local no serán borrados.</string>
<string name="feed_remover_msg">Eliminando el pódcast</string>
<string name="load_complete_feed">Actualizar el pódcast completo</string>
<string name="multi_select">Multi selección</string>
<string name="select_all_above">Seleccionar todo lo anterior</string>
<string name="select_all_below">Seleccionar todo lo siguiente</string>
<string name="hide_unplayed_episodes_label">No reproducidos</string>
- <string name="hide_paused_episodes_label">Pausados</string>
- <string name="hide_played_episodes_label">Reproducidos</string>
<string name="hide_queued_episodes_label">En cola</string>
<string name="hide_not_queued_episodes_label">No en cola</string>
- <string name="hide_downloaded_episodes_label">Descargados</string>
- <string name="hide_not_downloaded_episodes_label">No descargados</string>
<string name="hide_has_media_label">Tiene multimedia</string>
- <string name="hide_is_favorite_label">Es favorito</string>
<string name="filtered_label">Filtrados</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Error en la última actualización</string>
<string name="open_podcast">Abrir pódcast</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Borrar</string>
<string name="delete_failed">No se puede borrar el fichero. Reiniciar el dispositivo podría ayudar.</string>
<string name="delete_episode_label">Borrar Episodio</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%depisodio borrado.</item>
- <item quantity="other">%depisodios borrados.</item>
- </plurals>
<string name="remove_new_flag_label">Eliminar marca \"nuevo\"</string>
<string name="removed_new_flag_label">Eliminada marca \"nuevo\"</string>
<string name="mark_read_label">Marcar como reproducido</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Procesando descargas</string>
<string name="download_notification_title">Descargando datos del pódcast</string>
- <string name="download_report_content">%1$d descargas exitosas, %2$d fallidas</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d descarga exitosa, %d fallidas</item>
+ <item quantity="other">%d descargas exitosas, %d fallidas</item>
+ </plurals>
<string name="download_log_title_unknown">Título desconocido</string>
<string name="download_type_feed">Canal</string>
<string name="download_type_media">Archivo multimedia</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Se desactivaron las descargas por red de datos móviles en la configuración.\n\n¿Quiere permitir las descargas temporalmente?\n\n<small>Se recordará su elección durante 10 minutos.</small></string>
<string name="confirm_mobile_streaming_notification_title">Confirmar streaming por red móvil</string>
<string name="confirm_mobile_streaming_notification_message">El streaming sobre datos móviles está deshabilitado en los ajustes. Toca para hacer el streaming de todas formas.</string>
- <string name="confirm_mobile_streaming_button_always">Permitir siempre</string>
+ <string name="confirm_mobile_streaming_button_always">Siempre</string>
+ <string name="confirm_mobile_streaming_button_once">Una vez</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Añadir a la cola</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Permitir temporalmente</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Descargar complemento</string>
<string name="no_playback_plugin_title">Complemento no instalado</string>
<string name="no_playback_plugin_or_sonic_msg">Para que funcione la reproducción a velocidad variable, recomendamos habilitar el reproductor incorporado Sonic.</string>
- <string name="set_playback_speed_label">Velocidades de reproducción</string>
<string name="enable_sonic">Activar Sonic</string>
+ <string name="speed_presets">Presets</string>
+ <string name="preset_already_exists">%1$.2fx ya existe como preset.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Sin episodios en la cola</string>
<string name="no_items_label">Añada un episodio descargándolo o presione prolongadamente un episodio y seleccione \"Añadir a la cola\".</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">todos los %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">a las %1$s</string>
<string name="pref_followQueue_title">Reproducción continua</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Desconectar sin los auriculares</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Desconexión de los auricuales o Bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Reconectar con los auriculares</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Reconectar con Bluetooth</string>
<string name="pref_stream_over_download_title">Preferir Streaming</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Descarga de episodio</string>
<string name="pref_mobileUpdate_streaming">Streaming</string>
<string name="user_interface_label">Interfaz de usuario</string>
- <string name="user_interface_sum">Apariencia, Orden de suscripción, Pantalla de bloqueo</string>
+ <string name="user_interface_sum">Apariencia, Suscripción, Pantalla de bloqueo</string>
<string name="pref_set_theme_title">Elegir un tema</string>
<string name="pref_nav_drawer_items_title">Cambiar el cajón de navegación</string>
<string name="pref_nav_drawer_items_sum">Cambiar los ítems que aparecen en el cajón de navegación</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Forzar la sincronización completa</string>
<string name="pref_gpodnet_full_sync_sum">Sincronizar todas las suscripciones y episodios con gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Identificado como <i>%1$s</i> con dispositivo <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Mostrar errores de sincronización</string>
+ <string name="pref_gpodnet_notifications_title">Error en la sincronización</string>
<string name="pref_gpodnet_notifications_sum">Este ajuste no afecta a los errores de autenticación.</string>
- <string name="pref_playback_speed_title">Velocidades de reproducción</string>
- <string name="pref_playback_speed_sum">Personalice las velocidades disponibles en la reproducción de audio a velocidad variable</string>
+ <string name="pref_playback_speed_sum">Personalice las velocidades disponibles en la reproducción a velocidad variable</string>
<string name="pref_feed_playback_speed_sum">La velocidad a la que comenzarán los episodios de este podcast</string>
<string name="pref_feed_skip">Saltar automático</string>
<string name="pref_feed_skip_sum">Saltar introducción y créditos finales.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Esto suele expandir las notificaciones para mostrar los botones de reproducción.</string>
<string name="pref_persistNotify_title">Controles de reproducción persistentes</string>
<string name="pref_persistNotify_sum">Mantener las notificaciones y los controles en pantalla de bloqueo cuando se pausa la reproducción.</string>
- <string name="pref_compact_notification_buttons_title">Configurar botones en la pantalla de bloqueo</string>
- <string name="pref_compact_notification_buttons_sum">Cambiar los botones en la pantalla de bloqueo. El botón reproducir/pausar siempre está incluido.</string>
+ <string name="pref_compact_notification_buttons_title">Activar botones de notificación compactos</string>
+ <string name="pref_compact_notification_buttons_sum">Cambiar los botones cuando la notificación está contraída. El botón reproducir/pausar siempre está incluido.</string>
<string name="pref_compact_notification_buttons_dialog_title">Seleccionar máximo %1$d elementos</string>
<string name="pref_compact_notification_buttons_dialog_error">Sólo puede seleccionar un máximo de %1$d elementos.</string>
<string name="pref_lockscreen_background_title">Establecer fondo de pantalla de bloqueo</string>
<string name="pref_lockscreen_background_sum">Establecer el fondo de pantalla de bloqueo desde la imagen del episodio. Como efecto secundario, esto también mostrarán las imagen de aplicaciones de terceros.</string>
- <string name="pref_showDownloadReport_title">Mostrar informe de descarga</string>
+ <string name="pref_showDownloadReport_title">Descarga fallida</string>
<string name="pref_showDownloadReport_sum">Si la descarga falla, generar un informe con los detalles del fallo</string>
- <string name="pref_showAutoDownloadReport_title">Mostrar Informe de Auto Descarga</string>
+ <string name="pref_showAutoDownloadReport_title">Auto-descarga completada</string>
<string name="pref_showAutoDownloadReport_sum">Mostrar una notificación de los episodios descargados automáticamente.</string>
<string name="pref_expand_notify_unsupport_toast">Las versiones de Android anteriores a la 4.1 no soportan notificaciones expandidas</string>
<string name="pref_enqueue_location_title">Añadir a la cola en cierta ubicación</string>
@@ -504,9 +501,19 @@
<string name="back_button_go_to_page_title">Seleccionar página</string>
<string name="pref_delete_removes_from_queue_title">Eliminar quita de la cola</string>
<string name="pref_delete_removes_from_queue_sum">Quitar automáticamente un episodio de la cola cuando se elimina.</string>
+ <string name="pref_filter_feed_title">Filtro de suscripción</string>
+ <string name="pref_filter_feed_sum">Filtra tus suscripciones en el cajón de navegación y pantallas de suscripción.</string>
+ <string name="no_filter_label">Ninguno</string>
+ <string name="subscriptions_are_filtered">Las suscripciones están filtradas.</string>
+ <string name="auto_downloaded">Auto-descargado</string>
+ <string name="not_auto_downloaded"> No auto-descargado</string>
+ <string name="kept_updated">Mantenido actualizado</string>
+ <string name="not_kept_updated">No mantenido actualizado</string>
<!--About screen-->
<string name="about_pref">Acerca de</string>
<string name="antennapod_version">Versión de AntennaPod</string>
+ <string name="contributors">Contribuidores</string>
+ <string name="contributors_summary">Todo el mundo puede ayudar a mejorar AntennaPod - con código, traducciones o ayudando a usuarios del foro</string>
<string name="developers">Desarrolladores</string>
<string name="translators">Traductores</string>
<string name="special_thanks">Gracias especiales</string>
@@ -536,6 +543,7 @@
<string name="database_export_summary">Transferir suscripciones, episodios escuchados y la cola a AntennaPod en otro dispositivo</string>
<string name="database_import_summary">Importar base de datos de AntennaPod desde otro dispositivo</string>
<string name="opml_import_label">Importar de OPML</string>
+ <string name="opml_add_podcast_label">Importar lista de podcast (OPML)</string>
<string name="opml_reader_error">Error al leer el documento OPML:</string>
<string name="opml_import_error_no_file">¡Debe seleccionar un archivo!</string>
<string name="select_all_label">Seleccionar todo</string>
@@ -551,9 +559,11 @@
<string name="export_success_sum">El archivo exportado fue guardado en:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Necesita acceso al almacenamiento externo para leer archivos OPML</string>
<string name="import_select_file">Seleccionar archivo a importar</string>
- <string name="import_ok">Importación exitosa.\n\nPulse OK para reiniciar AntennaPod</string>
+ <string name="successful_import_label">Importación exitosa</string>
+ <string name="import_ok">Pulse OK para reiniciar AntennaPod</string>
<string name="import_no_downgrade">Esta base de datos fue exportada con una versión más moderna de AntennaPod. La versión instalada no puede manejarla.</string>
<string name="favorites_export_label">Exportar favoritos</string>
+ <string name="favorites_export_summary">Se exportaron los favoritos al archivo</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Establecer un temporizador</string>
<string name="disable_sleeptimer_label">Desactivar el temporizador</string>
@@ -645,7 +655,6 @@
<string name="decrease_speed">Reducir velocidad</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Vídeo</string>
- <string name="navigate_upwards_label">Navegar hacia arriba</string>
<string name="status_downloading_label">El episodio se está descargando</string>
<string name="in_queue_label">El episodio está en la cola</string>
<string name="is_favorite_label">Episodio marcado como favorito</string>
@@ -666,6 +675,10 @@
<string name="keep_updated">Mantener actualizado</string>
<string name="keep_updated_summary">Incluir este podcast cuando se (auto-)refresquen todas las fuentes</string>
<string name="auto_download_disabled_globally">La descarga automática está deshabilitada en las preferencias generales de AntennaPod</string>
+ <string name="statistics_listened_for">Escuchado durante:</string>
+ <string name="statistics_episodes_on_device">Episodios en el dispositivo:</string>
+ <string name="statistics_space_used">Espacio usado:</string>
+ <string name="statistics_view_all">Ver para todos los podcasts »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Actualizando la base de datos</string>
<!--AntennaPodSP-->
@@ -673,18 +686,27 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Buscar podcast...</string>
<string name="search_itunes_label">Buscar en iTunes</string>
+ <string name="search_podcastindex_label">Buscar en Podcastindex.org</string>
<string name="search_fyyd_label">Buscar en fyyd</string>
<string name="advanced">Avanzado</string>
- <string name="add_podcast_by_url">Añadir Podcast por URL</string>
+ <string name="add_podcast_by_url">Añadir Podcast por dirección RSS</string>
<string name="browse_gpoddernet_label">Explorar en gpodder.net</string>
<string name="discover">Descubrir</string>
+ <string name="discover_hide">Esconder</string>
+ <string name="discover_is_hidden">Elegiste esconder las sugerencias.</string>
<string name="discover_more">más »</string>
- <string name="search_powered_by">Búsqueda gracias a %1$s</string>
+ <string name="discover_powered_by_itunes">Sugerencias de iTunes</string>
+ <string name="search_powered_by">Resultados de %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Añadir carpeta local</string>
+ <string name="reconnect_local_folder">Re-conectar carpeta local</string>
+ <string name="reconnect_local_folder_warning">En caso de falta de permisos, puedes usar esto para re-conectar la misma carpeta. No selecciones otra carpeta.</string>
+ <string name="local_feed_description">Este podcast virtual fue creado añadiendo una carpeta a AntennaPod.</string>
<string name="filter">Filtro</string>
<!--Episodes apply actions-->
<string name="all_label">Todos</string>
<string name="selected_all_label">Todos los episodios seleccionados</string>
- <string name="none_label">Ninguno</string>
+ <string name="select_none_label">Ninguno</string>
<string name="deselected_all_label">Ningún episodio seleccionado</string>
<string name="played_label">Reproducidos</string>
<string name="selected_played_label">Episodios reproducidos seleccionados</string>
@@ -694,12 +716,21 @@
<string name="selected_downloaded_label">Episodios descargados seleccionados</string>
<string name="not_downloaded_label">No descargado</string>
<string name="selected_not_downloaded_label">Episodios no descargados seleccionados</string>
- <string name="queued_label">En cola</string>
<string name="selected_queued_label">Episodios en cola seleccionados</string>
- <string name="not_queued_label">No están en cola</string>
<string name="selected_not_queued_label">Episodios que no están en cola seleccionados</string>
- <string name="has_media">Tiene multimedia</string>
<string name="selected_has_media_label">Episodios con multimedia seleccionados</string>
+ <string name="hide_is_favorite_label">Es favorito</string>
+ <string name="not_favorite">No favorito</string>
+ <string name="hide_downloaded_episodes_label">Descargados</string>
+ <string name="hide_not_downloaded_episodes_label">No descargados</string>
+ <string name="queued_label">En cola</string>
+ <string name="not_queued_label">No están en cola</string>
+ <string name="has_media">Tiene multimedia</string>
+ <string name="no_media">Sin medios</string>
+ <string name="hide_paused_episodes_label">Pausados</string>
+ <string name="not_paused">No pausado</string>
+ <string name="hide_played_episodes_label">Reproducidos</string>
+ <string name="not_played">No reproducido</string>
<!--Sort-->
<string name="sort_title_a_z">Título (A \u2192 Z)</string>
<string name="sort_title_z_a">Título (Z \u2192 A)</string>
@@ -719,6 +750,12 @@
<string name="rating_never_label">Déjame en paz</string>
<string name="rating_later_label">Recuérdamelo más tarde</string>
<string name="rating_now_label">¡Venga, hagámoslo!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Incluir:</string>
+ <string name="share_playback_position_dialog_label">Posición de reproducción</string>
+ <string name="share_dialog_media_file_url_label">Dirección del archivo de medios</string>
+ <string name="share_dialog_episode_website_label">Página del episodio</string>
+ <string name="share_dialog_media_file_label">Archivo de medios</string>
<!--Audio controls-->
<string name="audio_controls">Controles de audio</string>
<string name="playback_speed">Velocidad de reproducción</string>
@@ -765,7 +802,9 @@
<string name="notification_channel_playing">Reproduciendo</string>
<string name="notification_channel_playing_description">Permite controlar la reproducción. Es la notificación principal que se ve mientras se reproduce un pódcast.</string>
<string name="notification_channel_error">Errores</string>
- <string name="notification_channel_error_description">Muestra si algo salió mal, por ejemplo, si falla la descarga o la sincronización de gpodder</string>
+ <string name="notification_channel_error_description">Muestra si algo salió mal, por ejemplo, si falla la descarga o la actualización del feed.</string>
+ <string name="notification_channel_sync_error">Errores de sincronización</string>
+ <string name="notification_channel_sync_error_description">Mostrar cuando falle la sincronización de gpodder.</string>
<string name="notification_channel_auto_download">Descargas automáticas</string>
<string name="notification_channel_episode_auto_download">Mostrar cuándo los episodios se han descargado automáticamente.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-et/strings.xml b/core/src/main/res/values-et/strings.xml
index db10f6ca4..65e20126b 100644
--- a/core/src/main/res/values-et/strings.xml
+++ b/core/src/main/res/values-et/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Saadete vahemälu limiit on täis. Vahemälu limiiti saab suurendada seadete alt.</string>
<string name="playback_statistics_label">Esitamine</string>
<string name="download_statistics_label">Allalaadimised</string>
+ <string name="notification_pref_fragment">Teavitused</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Kuulatud taskuhäälingute kogupikkus:</string>
+ <string name="total_time_listened_to_podcasts">Saadete kogupikkus:</string>
<string name="statistics_details_dialog">%1$d %2$d-st saatest on alustatud.\n\nKuulatud on %3$s saadet %4$s-st.</string>
<string name="statistics_mode">Statistika režiim</string>
<string name="statistics_mode_normal">Arvuta kuulamise pikkus tegelikult kuulatud aja järgi. Kaks korda kuulatud koht arvestatakse topelt, aga kuulatuks märkimist ei arvestata</string>
- <string name="statistics_mode_count_all">Liidetakse kõik saated, mis on märgitud kuulatuks</string>
+ <string name="statistics_mode_count_all">Kokkuvõte kõigist esitatud saadetest</string>
<string name="statistics_speed_not_counted">Märkus: taasesituse kiirust ei arvestata kunagi.</string>
<string name="statistics_reset_data">Lähtesta statistika andmed</string>
<string name="statistics_reset_data_msg">See lähtestab kõigi esitatud saadete kuulamise pikkuse ajaloo. Kas oled kindel, et tahad jätkata?</string>
+ <string name="statistics_counting_since">Alates %s,\nmängisid</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Allalaaditud taskuhäälingute kogumaht:</string>
+ <string name="total_size_downloaded_podcasts">Saadete kogusuurus seadmes:</string>
<!--Main activity-->
<string name="drawer_open">Ava menüü</string>
<string name="drawer_close">Sulge menüü</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Kuulamata saadete arv</string>
<string name="drawer_feed_counter_downloaded">Allalaaditud saadete arv</string>
<string name="drawer_feed_counter_none">Pole</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Ühtegi ühilduvat rakendust ei leitud</string>
<!--Webview actions-->
<string name="open_in_browser_label">Ava veebisirvijas</string>
<string name="copy_url_label">Kopeeri URL</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Taskuhäälingu seaded</string>
<string name="rename_feed_label">Muuda taskuhäälingu nime</string>
<string name="remove_feed_label">Eemalda taskuhääling</string>
- <string name="share_label">Jaga...</string>
- <string name="share_link_label">Jaga saate linki</string>
- <string name="share_link_with_position_label">Jaga saate linki koos asukohaga</string>
+ <string name="share_label">Jaga</string>
+ <string name="share_label_with_ellipses">Jaga...</string>
<string name="share_file_label">Jaga faili</string>
- <string name="share_website_url_label">Jaga veebilehe linki</string>
- <string name="share_feed_url_label">Jaga taskuhäälingu linki</string>
- <string name="share_item_url_label">Jaga meediafaili linki</string>
- <string name="share_item_url_with_position_label">Jaga meediafaili linki koos asukohaga</string>
+ <string name="share_website_url_label">Veebisaidi aadress</string>
+ <string name="share_feed_url_label">Taskuhäälingu voo URL</string>
<string name="feed_delete_confirmation_msg">Palun kinnita, et tahad kustutada taskuhäälingu \"%1$s\" ja KÕIK selle saated (ka allalaaditud saated).</string>
+ <string name="feed_delete_confirmation_local_msg">Palun kinnita, et tahad eemaldada taskuhäälingu \"%1$s\". Kohalikus kaustas olevaid saateid ei kustutata.</string>
<string name="feed_remover_msg">Taskuhäälingu eemaldamine</string>
<string name="load_complete_feed">Värskenda kogu taskuhääling</string>
<string name="multi_select">Mitme valimine</string>
<string name="select_all_above">Vali kõik ülemised</string>
<string name="select_all_below">Vali kõik alumised</string>
<string name="hide_unplayed_episodes_label">Esitamata</string>
- <string name="hide_paused_episodes_label">Peatatud</string>
- <string name="hide_played_episodes_label">Esitatud</string>
<string name="hide_queued_episodes_label">Järjekorras</string>
<string name="hide_not_queued_episodes_label">Pole järjekorras</string>
- <string name="hide_downloaded_episodes_label">Alla laaditud</string>
- <string name="hide_not_downloaded_episodes_label">Pole alla laaditud</string>
<string name="hide_has_media_label">On meediafaile</string>
- <string name="hide_is_favorite_label">On lemmik</string>
<string name="filtered_label">Filtreeritud</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Viimane värskendamine ebaõnnestus</string>
<string name="open_podcast">Ava taskuhääling</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Kustuta</string>
<string name="delete_failed">Faili ei saa kustutada. Aidata võib seadme taaskäivitamine.</string>
<string name="delete_episode_label">Kustuta saade</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">Kustutati %d saade.</item>
- <item quantity="other">Kustutati %d saadet.</item>
- </plurals>
<string name="remove_new_flag_label">Eemalda silt \"uus\"</string>
<string name="removed_new_flag_label">Eemaldati silt \"uus\"</string>
<string name="mark_read_label">Märgi kuulatuks</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Allalaadimiste töötlemine</string>
<string name="download_notification_title">Taskuhäälingu andmete allalaadimine</string>
- <string name="download_report_content">%1$d allalaadimine õnnestus, %2$d nurjus</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d allalaadimine õnnestus, %d ebaõnnestus</item>
+ <item quantity="other">%d allalaadimist õnnestus, %d ebaõnnestus</item>
+ </plurals>
<string name="download_log_title_unknown">Tundmatu pealkiri</string>
<string name="download_type_feed">Uudisvoog</string>
<string name="download_type_media">Meediafail</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Allalaadimine mobiilse andmeside kaudu on seadetest keelatud.\n\nKas tahad allalaadimise ajutiselt lubada?\n\n<small>Sinu valikut peetakse meeles 10 minutit.</small></string>
<string name="confirm_mobile_streaming_notification_title">Kinnita voogedastus andmeside kaudu</string>
<string name="confirm_mobile_streaming_notification_message">Voogedastus andmeside kaudu on seadetest keelatud. Koputa, et ikka striimida.</string>
- <string name="confirm_mobile_streaming_button_always">Luba alati</string>
+ <string name="confirm_mobile_streaming_button_always">Alati</string>
+ <string name="confirm_mobile_streaming_button_once">Üks kord</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Järjekorda</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Luba ajutiselt</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Laadi plugin alla</string>
<string name="no_playback_plugin_title">Pluginat pole paigaldatud</string>
<string name="no_playback_plugin_or_sonic_msg">Muutuva kiirusega taasesituse jaoks soovitame lubada sisseehitatud Sonic meediaesitaja.</string>
- <string name="set_playback_speed_label">Esitamise kiirused</string>
<string name="enable_sonic">Luba Sonicu kasutamine</string>
+ <string name="speed_presets">Eelseaded</string>
+ <string name="preset_already_exists">%1$.2fx on juba eelseadena salvestatud.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Järjekorras ei ole saateid</string>
<string name="no_items_label">Saate lisamiseks laadi see alla või hoia pikalt saatel ja vali \"Lisa järjekorda\".</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">iga %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">kell %1$s</string>
<string name="pref_followQueue_title">Pidev esitamine</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Kõrvaklappide eemaldamine</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Peakomplekti või Bluetoothi lahti ühendamisel</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Kõrvaklappide uuesti ühendamine</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetoothi uuesti ühendamine</string>
<string name="pref_stream_over_download_title">Eelista voogedastust</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Saate allalaadimine</string>
<string name="pref_mobileUpdate_streaming">Voogedastus</string>
<string name="user_interface_label">Kasutajaliides</string>
- <string name="user_interface_sum">Välimus, tellimuste järjekord, lukuekraan</string>
+ <string name="user_interface_sum">Välimus, tellimused, lukustusekraan</string>
<string name="pref_set_theme_title">Vali teema</string>
<string name="pref_nav_drawer_items_title">Määra peamenüü osad</string>
<string name="pref_nav_drawer_items_sum">Määra, mis osad on peamenüüs.</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Nõua täielikku sünkroonimist</string>
<string name="pref_gpodnet_full_sync_sum">Sünkroniseeri kõiki tellimusi ja saate olekuid gpodder.net-iga.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Sisseloginud kui <i>%1$s</i> seadmega <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Kuva sünkroniseerimise vigu teadaannetena</string>
+ <string name="pref_gpodnet_notifications_title">Sünkroniseerimine ebaõnnestus</string>
<string name="pref_gpodnet_notifications_sum">See seadistus ei rakendu autentimise vigadele.</string>
- <string name="pref_playback_speed_title">Esitamise kiirused</string>
- <string name="pref_playback_speed_sum">Muuda, millised valikud on audio esitamisel kiiruste loendis</string>
+ <string name="pref_playback_speed_sum">Kohanda kiiruseid, mis on esitamisel saadaval</string>
<string name="pref_feed_playback_speed_sum">Millise kiirusega esitatakse selle tellimuse saadete heli</string>
<string name="pref_feed_skip">Automaatne vahelejätmine</string>
<string name="pref_feed_skip_sum">Sissejuhatuse ja lõputänu vahele jätmine.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">See tavaliselt kuvab teadet laiemana ning näha on esitusnupud.</string>
<string name="pref_persistNotify_title">Püsivad taasesitamise nupud</string>
<string name="pref_persistNotify_sum">Säilita märguande ja lukustuskuva juhtnupud, kui esitus on pausil.</string>
- <string name="pref_compact_notification_buttons_title">Määra lukustusekraani nupud</string>
- <string name="pref_compact_notification_buttons_sum">Muuda esituse nuppe lukuekraanil. Esitamise/pausi nupp on alati olemas.</string>
+ <string name="pref_compact_notification_buttons_title">Vali kompaktsed teavituste nupud</string>
+ <string name="pref_compact_notification_buttons_sum">Muuda esitamise nuppe, kui teavitus on suletud. Eritamise/pausi nupp on alati saadaval.</string>
<string name="pref_compact_notification_buttons_dialog_title">Vali maksimaalselt %1$d kirjet</string>
<string name="pref_compact_notification_buttons_dialog_error">Maksimaalselt saab valida %1$d kirjet.</string>
<string name="pref_lockscreen_background_title">Määra lukustusekraani taustapilt</string>
<string name="pref_lockscreen_background_sum">Määra lukuekraani taustaks selle saate pilt. Kõrvalmõjuna kuvab see pilti ka teistes rakendustes.</string>
- <string name="pref_showDownloadReport_title">Näita allalaadimise aruannet</string>
+ <string name="pref_showDownloadReport_title">Allalaadimine ebaõnnestus</string>
<string name="pref_showDownloadReport_sum">Kui allalaadimised nurjuvad, genereeri raport, mis kuvab vea üksikasju.</string>
- <string name="pref_showAutoDownloadReport_title">Kuva automaatse allalaadimise raportit</string>
+ <string name="pref_showAutoDownloadReport_title">Automaatne allalaadimine on lõpetatud</string>
<string name="pref_showAutoDownloadReport_sum">Teate kuvamine automaatselt allalaaditud saadete kohta.</string>
<string name="pref_expand_notify_unsupport_toast">Vanemad Androidi versioonid kui 4.1 ei toeta laiendatud teavitusi.</string>
<string name="pref_enqueue_location_title">Järjekorra asukoht</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Järjekord allalaaditud</string>
<string name="pref_enqueue_downloaded_summary">Allalaaditud saadete lisamine järjekorda</string>
<string name="media_player_builtin">Sisseehitatud Androidi esitaja</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (soovitatud)</string>
<string name="media_player_switch_to_exoplayer">Vaheta ExoPlayerile</string>
<string name="media_player_switched_to_exoplayer">Vahetati ExoPlayerile.</string>
<string name="pref_skip_silence_title">Audios vaikuse vahele jätmine</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Vali leht</string>
<string name="pref_delete_removes_from_queue_title">Kustutamine eemaldab järjekorrast</string>
<string name="pref_delete_removes_from_queue_sum">Saade eemaldatakse järjekorrast pärast kustutamist automaatselt.</string>
+ <string name="pref_filter_feed_title">Tellimuste filter</string>
+ <string name="pref_filter_feed_sum">Filtreeri oma tellimusi navigeerimisribal ja tellimuste lehel.</string>
+ <string name="no_filter_label">Pole</string>
+ <string name="subscriptions_are_filtered">Tellimused on filtreeritud.</string>
+ <string name="subscriptions_counter_greater_zero">Loendur on suurem kui null</string>
+ <string name="auto_downloaded">Automaatselt alla laaditud</string>
+ <string name="not_auto_downloaded">Pole automaatselt alla laaditud</string>
+ <string name="kept_updated">Hoitakse uuendatuna</string>
+ <string name="not_kept_updated">Ei hoita uuendatuna</string>
<!--About screen-->
<string name="about_pref">Info</string>
<string name="antennapod_version">AntennaPodi versioon</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Tellimuste, kuulatud saadete ja ooterjärjekorra liigutamine AntennaPodi mõnes teises seadmes</string>
<string name="database_import_summary">AntennaPodi andmebaasi import teisest seadmest</string>
<string name="opml_import_label">OPML import</string>
+ <string name="opml_add_podcast_label">Impordi taskuhäälingute nimekiri (OPML)</string>
<string name="opml_reader_error">OPML dokumendi lugemisel tekkis tõrge:</string>
<string name="opml_import_error_no_file">Ühtegi faili pole valitud!</string>
<string name="select_all_label">Vali kõik</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">Eksporditud fail salvestati asukohta:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">OPML faili lugemiseks on vajalik ligipääs välisele salvestusruumile</string>
<string name="import_select_file">Vali fail, mida importida</string>
- <string name="import_ok">Importimine edukas.\n\nAntennaPodi taaskäivitamiseks vajuta OK</string>
+ <string name="successful_import_label">Importimine oli edukas</string>
+ <string name="import_ok">Vajuta OK, et AntennaPod taaskäivitada</string>
<string name="import_no_downgrade">See andmebaas on eksporditud AntennaPodi uuemast versioonist. Sinu praegune äpp ei oska seda faili käsitseda.</string>
<string name="favorites_export_label">Lemmikute eksport</string>
<string name="favorites_export_summary">Ekspordi salvestatud lemmikud faili</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Vähenda kiirust</string>
<string name="media_type_audio_label">Heli</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Liigu ülespoole</string>
<string name="status_downloading_label">Saade laaditakse alla</string>
<string name="in_queue_label">Saade on järjekorras</string>
<string name="is_favorite_label">Saade on märgitud lemmikuks</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Hoia uuendatuna</string>
<string name="keep_updated_summary">Uuenda koos teiste taskuhäälingute (automaatse) värskendamisega ka seda</string>
<string name="auto_download_disabled_globally">Automaatne allalaadimine on keelatud AntennaPodi peamistes seadetes</string>
+ <string name="statistics_listened_for">Kuulatud:</string>
+ <string name="statistics_episodes_on_device">Saated seadmes:</string>
+ <string name="statistics_space_used">Kasutatud kettaruum:</string>
+ <string name="statistics_view_all">Vaata kõiki taskuhäälinguid »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Andmebaasi uuendamine</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Otsi taskuhäälingut...</string>
<string name="search_itunes_label">Otsi iTunest</string>
+ <string name="search_podcastindex_label">Otsi saidilt Podcastindex.org</string>
<string name="search_fyyd_label">Search fyyd-ist</string>
<string name="advanced">Täpsem</string>
- <string name="add_podcast_by_url">Lisa taskuhääling URL abil</string>
+ <string name="add_podcast_by_url">Lisa taskuhääling RSS aadressiga</string>
<string name="browse_gpoddernet_label">Sirvi gpodder.net-i</string>
<string name="discover">Avasta</string>
+ <string name="discover_hide">Peida</string>
+ <string name="discover_is_hidden">Valisid soovituste peitmise.</string>
<string name="discover_more">veel »</string>
- <string name="search_powered_by">Otsingut pakub %1$s</string>
+ <string name="discover_powered_by_itunes">iTunes soovitab</string>
+ <string name="search_powered_by">Tulemused: %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Lisa kohalik kaust</string>
+ <string name="local_folder">Kohalik kaust</string>
+ <string name="reconnect_local_folder">Ühenda kohalik kaust uuesti</string>
+ <string name="reconnect_local_folder_warning">Ligipääsuõiguste keelamise puhul võid kasutada seda, et täpselt sama kausta uuesti ühendada. Ära valli mõnda teist kausta.</string>
+ <string name="local_feed_description">See virtuaalne taskuhääling loodi kausta lisamisega AntennaPodi.</string>
+ <string name="unable_to_start_system_file_manager">Süsteemi failihalduri käivitamine ebaõnnestus</string>
<string name="filter">Filter</string>
<!--Episodes apply actions-->
<string name="all_label">Kõik</string>
<string name="selected_all_label">Vali kõik saated</string>
- <string name="none_label">Pole</string>
+ <string name="select_none_label">Pole</string>
<string name="deselected_all_label">Tühista kõigi saadete valik</string>
<string name="played_label">Esitatud</string>
<string name="selected_played_label">Valitud kuulatud saated</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Valitud allalaaditud saated</string>
<string name="not_downloaded_label">Pole alla laaditud</string>
<string name="selected_not_downloaded_label">Valitud allalaadimata saated</string>
- <string name="queued_label">Järjekorras</string>
<string name="selected_queued_label">Valitud järjekorras olevad saated</string>
- <string name="not_queued_label">Pole järjekorras</string>
<string name="selected_not_queued_label">Valitud järjekorras mitte olevad saated</string>
- <string name="has_media">On meediafaile</string>
<string name="selected_has_media_label">Valitud saated meediafailidega</string>
+ <string name="hide_is_favorite_label">On lemmik</string>
+ <string name="not_favorite">Pole lemmik</string>
+ <string name="hide_downloaded_episodes_label">Alla laaditud</string>
+ <string name="hide_not_downloaded_episodes_label">Pole alla laaditud</string>
+ <string name="queued_label">Järjekorras</string>
+ <string name="not_queued_label">Pole järjekorras</string>
+ <string name="has_media">On meediafaile</string>
+ <string name="no_media">Meediafaile pole</string>
+ <string name="hide_paused_episodes_label">Peatatud</string>
+ <string name="not_paused">Pole pausitud</string>
+ <string name="hide_played_episodes_label">Esitatud</string>
+ <string name="not_played">Pole esitatud</string>
<!--Sort-->
<string name="sort_title_a_z">Pealkiri (A \u2192 Z)</string>
<string name="sort_title_z_a">Pealkiri (Z \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Jäta mind rahule</string>
<string name="rating_later_label">Tuleta hiljem meelde</string>
<string name="rating_now_label">Jah, otseloomulikult!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Kaasa:</string>
+ <string name="share_playback_position_dialog_label">Esitamise asukoht</string>
+ <string name="share_dialog_media_file_url_label">Meediafaili aadress</string>
+ <string name="share_dialog_episode_website_label">Saate veebisait</string>
+ <string name="share_dialog_media_file_label">Meediafail</string>
<!--Audio controls-->
<string name="audio_controls">Audioesitaja nupud</string>
<string name="playback_speed">Esitamise kiirus</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Praegu esitatakse</string>
<string name="notification_channel_playing_description">Võimaldab esitust juhtida. See on saate kuulamise ajal peamine teade.</string>
<string name="notification_channel_error">Vead</string>
- <string name="notification_channel_error_description">Näidatakse, kui miski läks valesti, näiteks allalaadimine või gpodderiga sükroonimine nurjus.</string>
+ <string name="notification_channel_error_description">Näita, kui midagi läks valest. Näiteks, kui allalaadimine või uudivoo uuendamine ebaõnnestus.</string>
+ <string name="notification_channel_sync_error">Sünkroniseerimise tõrked</string>
+ <string name="notification_channel_sync_error_description">Näidatakse, kui gpodder sünkroniseerimine ebaõnnestub.</string>
<string name="notification_channel_auto_download">Automaatsed allalaadimised</string>
<string name="notification_channel_episode_auto_download">Näita, kui saateid laaditi automaatselt alla.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-eu/strings.xml b/core/src/main/res/values-eu/strings.xml
index e4b4fe4b6..6bc7b3c9e 100644
--- a/core/src/main/res/values-eu/strings.xml
+++ b/core/src/main/res/values-eu/strings.xml
@@ -22,20 +22,22 @@
<string name="gpodnet_main_label">gpodder.net</string>
<string name="gpodnet_auth_label">Saioa hasi gpodder.net-en</string>
<string name="episode_cache_full_title">Saioen katxea beteta</string>
- <string name="episode_cache_full_message">Saioen katxeta mugara iritsi da. Ezarpenetan katxearen tamaina handitu dezakezu.</string>
- <string name="playback_statistics_label">Irakurketa</string>
+ <string name="episode_cache_full_message">Saioen katxea mugara iritsi da. Ezarpenetan katxearen tamaina handitu dezakezu.</string>
+ <string name="playback_statistics_label">Erreprodukzioa</string>
<string name="download_statistics_label">Deskargak</string>
+ <string name="notification_pref_fragment">Jakinarazpenak</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Ikusitako podcast denen denbora:</string>
+ <string name="total_time_listened_to_podcasts">Ikusitako saio denen denbora:</string>
<string name="statistics_details_dialog">%1$d kanpo %2$d hasitako saioetatik. %3$s \n\nErreproduzituak %4$setatik.</string>
<string name="statistics_mode">Estatistika modua</string>
<string name="statistics_mode_normal">Benetan ikusitakoen iraupena kalkulatzea. Bi aldiz ikustean bi aldiz kontatzen da; ikusita bezala markatzea, berriz, ez da kontatzen</string>
- <string name="statistics_mode_count_all">Ikusita markatutako podcast guztien laburpena</string>
+ <string name="statistics_mode_count_all">Ikusita markatutako saio guztien laburpena</string>
<string name="statistics_speed_not_counted">Oharra: erreprodukzioaren abiadura ez da sekula kontutan hartzen.</string>
<string name="statistics_reset_data">Estatistikak ezabatu</string>
<string name="statistics_reset_data_msg">Horrek atal guztien iraupenaren historia ezabatuko du. Ziur zaude egin nahi duzula?</string>
+ <string name="statistics_counting_since">%s,\n-tik hasita ikusi dituzu</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Deskargatutako podcasten tamaina:</string>
+ <string name="total_size_downloaded_podcasts">Gailuko saioen tamaina guztira:</string>
<!--Main activity-->
<string name="drawer_open">Zabaldu menua</string>
<string name="drawer_close">Itxi menua</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Ikusi gabeko saioen zenbatekoa</string>
<string name="drawer_feed_counter_downloaded">Deskargatutako saioen zenbatekoa</string>
<string name="drawer_feed_counter_none">Bat ere ez</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Ez dago app bateragarririk</string>
<!--Webview actions-->
<string name="open_in_browser_label">Nabigatzailean ireki</string>
<string name="copy_url_label">URLa kopiatu</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Podcastaren ezarpenak</string>
<string name="rename_feed_label">Berrizendatu podcasta</string>
<string name="remove_feed_label">Kendu podcasta</string>
- <string name="share_label">Partekatu...</string>
- <string name="share_link_label">Partekatu URL saioa</string>
- <string name="share_link_with_position_label">Partekatu URL saioa kokapenaz</string>
+ <string name="share_label">Partekatu</string>
+ <string name="share_label_with_ellipses">Partekatu...</string>
<string name="share_file_label">Partekatu fitxategia</string>
- <string name="share_website_url_label">URL web gunea partekatu</string>
- <string name="share_feed_url_label">Podcastaren lotura parteatu</string>
- <string name="share_item_url_label">Partekatu media fitxategiaren URLa</string>
- <string name="share_item_url_with_position_label">Partekatu Media Fitxategiaren URLa kokapenaz</string>
+ <string name="share_website_url_label">Web gunea</string>
+ <string name="share_feed_url_label">Fluxuaren lotura</string>
<string name="feed_delete_confirmation_msg">Mesedez berretsi \"%1$s\" podcasta eta bere saio \"guztiak\" (deskargatutako saioak barne) ezabatu nahi dituzula.</string>
+ <string name="feed_delete_confirmation_local_msg">Baieztatu, mesedez, \"%1$s\" podcasta ezabatu nahi duzula. Tokiko karpetako artxiboak ez dira ezabatukoThe files in the local source folder will not be deleted.</string>
<string name="feed_remover_msg">Podcasta ezabatzen</string>
<string name="load_complete_feed">Eguneratu osatutako podcasta</string>
<string name="multi_select">Hautaketa anitza</string>
<string name="select_all_above">Aukeratu dena goian</string>
<string name="select_all_below">Aukeratu dena behean</string>
<string name="hide_unplayed_episodes_label">Ikusi gabe</string>
- <string name="hide_paused_episodes_label">Geldirik</string>
- <string name="hide_played_episodes_label">Ikusita</string>
<string name="hide_queued_episodes_label">Ilaran</string>
<string name="hide_not_queued_episodes_label">Ez dago ilaran</string>
- <string name="hide_downloaded_episodes_label">Deskargatuta</string>
- <string name="hide_not_downloaded_episodes_label">Deskargatu gabe</string>
<string name="hide_has_media_label">Media du</string>
- <string name="hide_is_favorite_label">Gogokoa da</string>
<string name="filtered_label">Iragaziak</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Errorea azken eguneraketan</string>
<string name="open_podcast">Ireki podcasta</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Ezabatu</string>
<string name="delete_failed">Ezin da fitxategia ezabatu. Gailua berrabiarazteak lagun dezake.</string>
<string name="delete_episode_label">Saioa ezabatu</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%dsaio ezabatua.</item>
- <item quantity="other">%d saio ezabatuak.</item>
- </plurals>
<string name="remove_new_flag_label">Kendu \"berria\" ikurra</string>
<string name="removed_new_flag_label">\"Berria\" ikurra kendu da</string>
<string name="mark_read_label">Markatu ikusita bezala</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Deskargak prozesatzen</string>
<string name="download_notification_title">Podcastaren datuak deskargatzen</string>
- <string name="download_report_content">%1$d deskarga arrakastatsu, %2$d huts egin dute</string>
+ <plurals name="download_report_content">
+ <item quantity="one">Deskarga arrakastatsu %d , %d (e)k huts egin du(te)</item>
+ <item quantity="other">%d deskarga arrakastasuak, %d (e)k huts egin du(te)</item>
+ </plurals>
<string name="download_log_title_unknown">Izenburu ezezaguna</string>
<string name="download_type_feed">Kanala</string>
<string name="download_type_media">Media artxibategia</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Datu mugikorren sareko deskargak desaktibatu dira konfigurazioan.\n\n Deskargak aldi baterako baimendu nahi dituzu?\n\n<small>10 minutura haien aukeraketa gogora araziko da.</small></string>
<string name="confirm_mobile_streaming_notification_title">Berretsi datu mugikor bidezko zuzenekoa</string>
<string name="confirm_mobile_streaming_notification_message">Konexioaren datu bidezko zuzenekoa desgaiturik dago ezarpenetan. Sakatu halere ikusteko.</string>
- <string name="confirm_mobile_streaming_button_always">Baimendu beti</string>
+ <string name="confirm_mobile_streaming_button_always">Beti</string>
+ <string name="confirm_mobile_streaming_button_once">Behin</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Gehitu ilaran</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Baimendu aldi baterako</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Deskargatu osagarria</string>
<string name="no_playback_plugin_title">Osagarria instalatu gabe</string>
<string name="no_playback_plugin_or_sonic_msg">Abiadura aldakorreko erreprodukzioak funtziona dezan, Sonic multimedia-erreproduzitzailea gehitzea gomendatzen dugu.</string>
- <string name="set_playback_speed_label">Erreprodukzio abiadurak</string>
<string name="enable_sonic">Gaitu Sonic</string>
+ <string name="speed_presets">Aurrez ezarritakoak</string>
+ <string name="preset_already_exists">%1$.2f dagoeneko aurrez ezarria dago.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Saiorik ez ilaran</string>
<string name="no_items_label">Gehitu saio bat deskargatuz edo sakatu luzaro saio bat eta hautatu \"gehitu ilarari\".</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">%1$sdenak</string>
<string name="pref_autoUpdateIntervallOrTime_at">%1$setan</string>
<string name="pref_followQueue_title">Etengabeko erreprodukzioa</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Deskonektatu entzungailurik gabe</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Entzungailu edo Bluetootharen deskonexioa</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Birkonektatu entzungailuez</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Birkonektatu bluetooth bidez</string>
<string name="pref_stream_over_download_title">Nahiago zuzenean</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Saioaren deskarga</string>
<string name="pref_mobileUpdate_streaming"> Zuzenean</string>
<string name="user_interface_label">Erabiltzailearen interfazea</string>
- <string name="user_interface_sum">Itxura, harpidetzen ordena, blokeatzeko pantaila</string>
+ <string name="user_interface_sum">Itxura, izen emateak, blokeo pantaila</string>
<string name="pref_set_theme_title">Gai bat aukeratu</string>
<string name="pref_nav_drawer_items_title">Aldatu nabigatze kutxa</string>
<string name="pref_nav_drawer_items_sum">Aldatu nabigatze kutxan azaltzen diren elementuak</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Sinkronizazio osoa behartu</string>
<string name="pref_gpodnet_full_sync_sum">Sinkronizatu harpidetza denak eta saioak gpodder.net-ekin</string>
<string name="pref_gpodnet_login_status"><![CDATA[Horrela hasi du saioa <i>%1$s</i> gailu honekin <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Erakutsi sinkronizatze erroreak</string>
+ <string name="pref_gpodnet_notifications_title">Akatsa sinkronizazioan </string>
<string name="pref_gpodnet_notifications_sum">Ezarpen honek ez du eraginik saio hasierako erroretan eraginik.</string>
- <string name="pref_playback_speed_title">Erreproduzitzeko abiadurak</string>
- <string name="pref_playback_speed_sum">Pertsonalizatu eskura dauden abiadurak audio erreproduzitzeko abiadura aldakorrean</string>
+ <string name="pref_playback_speed_sum">Pertsonalizatu abiadura aldakorreko erreprodukzioan dauden abiadurak</string>
<string name="pref_feed_playback_speed_sum">Podcast hauen berezko irakurtze abiadura</string>
<string name="pref_feed_skip">Salto automatikoa</string>
<string name="pref_feed_skip_sum">Saltatu sarrera eta amaiera kredituak.</string>
@@ -448,15 +445,15 @@
<string name="pref_expandNotify_sum">Honek jakinarazpenak zabaltzen ditu erreprodukzio botoiak erakusteko</string>
<string name="pref_persistNotify_title">Erreprodukzio kontrol iraunkorrak</string>
<string name="pref_persistNotify_sum">Eutsi jakinarazpenak eta kontrolak blokeo pantailan erreprodukzioa gelditzean</string>
- <string name="pref_compact_notification_buttons_title">Konfiguratu botoiak blokeo pantailan</string>
- <string name="pref_compact_notification_buttons_sum">Aldatu botoiak blokeatze pantailan. Erreproduzitu/gelditu botoia beti azalduko da.</string>
+ <string name="pref_compact_notification_buttons_title">Aktibatu jakinarazpen-botoi trinkoak</string>
+ <string name="pref_compact_notification_buttons_sum">Aldatu botoiak jakinarazpena hartuta dagoenean. Erreproduzitu/eten botoia beti dago sartuta.</string>
<string name="pref_compact_notification_buttons_dialog_title">Aukeratu gehienez %1$d elementu</string>
<string name="pref_compact_notification_buttons_dialog_error">Ezingo duzu %1$d elementu baino gehiago aukeratu.</string>
<string name="pref_lockscreen_background_title">Ezarri blokeo pantailaren atzealdea</string>
<string name="pref_lockscreen_background_sum">Ezarri saioaren irudia blokeo pantailarako atzealdea moduan. Horren eraginez, hirugarrenen aplikazio irudiak ere azalduko dira.</string>
- <string name="pref_showDownloadReport_title">Deskarga txostena erakutsi</string>
+ <string name="pref_showDownloadReport_title">Deskargak huts egin du</string>
<string name="pref_showDownloadReport_sum">Deskargak huts egiten badu, sortu txostena akatsaren xehetasunekin.</string>
- <string name="pref_showAutoDownloadReport_title">Deskarga automatikoen txostena erakutsi</string>
+ <string name="pref_showAutoDownloadReport_title">Deskarga automatikoak osatuta</string>
<string name="pref_showAutoDownloadReport_sum">Erakutsi automatikoki deskargatutako saioen jakinarazpen bat.</string>
<string name="pref_expand_notify_unsupport_toast">Android 4.1 aurreko bertsioek ez dituzte zabaldutako jakinarazpenak jasaten</string>
<string name="pref_enqueue_location_title">Ilaran gehitu kokalekuan</string>
@@ -486,6 +483,7 @@
<string name="pref_enqueue_downloaded_title">Gehitu deskargatutakoak ilarara</string>
<string name="pref_enqueue_downloaded_summary">Gehitu deskargatutako saioak ilarara</string>
<string name="media_player_builtin">Integratutako Android erreproduzitzailea</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (gomendatua)</string>
<string name="media_player_switch_to_exoplayer">Aldatu ExoPlayer-era</string>
<string name="media_player_switched_to_exoplayer">ExoPlayer-era aldatu da.</string>
<string name="pref_skip_silence_title">Jauzi egin ixilunea audioan</string>
@@ -506,6 +504,15 @@
<string name="back_button_go_to_page_title">Aukeratu orrialdea</string>
<string name="pref_delete_removes_from_queue_title">Ezabatu ilaratik kendutakoak</string>
<string name="pref_delete_removes_from_queue_sum">Kendu saio bat automatikoki ilaratik ezabatzean.</string>
+ <string name="pref_filter_feed_title">Harpidetza iragazkia</string>
+ <string name="pref_filter_feed_sum">Iragazi harpidetzak nabigazio-kutxan eta harpidetza-pantailetan.</string>
+ <string name="no_filter_label">Batere ez</string>
+ <string name="subscriptions_are_filtered">Harpidetzak iragazita daude.</string>
+ <string name="subscriptions_counter_greater_zero">Kontagailua zero baino handiagoa</string>
+ <string name="auto_downloaded">Automatikoki deskargatuta</string>
+ <string name="not_auto_downloaded">Automatikoki deskargatu gabe</string>
+ <string name="kept_updated">Eguneratuta dago</string>
+ <string name="not_kept_updated">Ez dago eguneratuta</string>
<!--About screen-->
<string name="about_pref">Honi buruz</string>
<string name="antennapod_version">AntennaPod bertsioa</string>
@@ -540,6 +547,7 @@
<string name="database_export_summary">Bidali beste gailu batera harpidetzak, ikusitako saioak eta irakur zerrenda</string>
<string name="database_import_summary">Ekarri AntennaPodera datu basea beste gailu batetik</string>
<string name="opml_import_label">Inportatu OPMLtik</string>
+ <string name="opml_add_podcast_label">Podcasten zerrenda inportatu (OPML)</string>
<string name="opml_reader_error">Errorea OPML dokkumentua irakurtzean:</string>
<string name="opml_import_error_no_file">Artxibategi bat aukeratu behar duzu!</string>
<string name="select_all_label">Aukeratu dena</string>
@@ -555,7 +563,8 @@
<string name="export_success_sum">Esportatutako artxibategia hemen gorde da:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Kanpo biltegirako sarrera behar duzu OPML artxibategiak irakurtzeko</string>
<string name="import_select_file">Aukeratu inportatzeko fitxategia</string>
- <string name="import_ok">Inportazio arrakastatsua.\n\nSakatu OK, AntennaPod berrabiarazteko</string>
+ <string name="successful_import_label">Inportate arrakastatsua</string>
+ <string name="import_ok">Sakatu OK AntennaPod berrabiarazteko</string>
<string name="import_no_downgrade">Datu-basea AntennaPod-en bertsio berriago batekin esportatu zen. Uneko aplikazioak ez daki nola inportatu.</string>
<string name="favorites_export_label">Gogokoak esportatu</string>
<string name="favorites_export_summary">Gorde diren gogokoak esportatu artxibatzeko</string>
@@ -587,7 +596,7 @@
<string name="gpodnet_taglist_header">KATEGORIAK</string>
<string name="gpodnet_toplist_header">PODCASTIK ONENAK</string>
<string name="gpodnet_suggestions_header">IRADOKIZUNAK</string>
- <string name="gpodnet_search_hint">Bilatu gpodder.net-en bilatu</string>
+ <string name="gpodnet_search_hint">Bilatu gpodder.net-en</string>
<string name="gpodnetauth_login_title">Hasi saioa</string>
<string name="gpodnetauth_login_descr">Ongi etorri gpodder.net saio hasierara. Hasteko zure saio hasierako datuak sartu:</string>
<string name="gpodnetauth_login_butLabel">Hasi saioa</string>
@@ -650,7 +659,6 @@
<string name="decrease_speed">Gutxitu abiadura</string>
<string name="media_type_audio_label">Audioa</string>
<string name="media_type_video_label">Bideoa</string>
- <string name="navigate_upwards_label">Nabigatu gorantz </string>
<string name="status_downloading_label">Saioa deskargatzen ari da</string>
<string name="in_queue_label">Saioa ilaran dago</string>
<string name="is_favorite_label">Saioa gogokoa bezala markatu da</string>
@@ -671,6 +679,10 @@
<string name="keep_updated">Eguneratuta eduki</string>
<string name="keep_updated_summary">Sartu podcast hau (auto-) freskatzeko podcast guztiak</string>
<string name="auto_download_disabled_globally">Deskarga automatikoa desgaituta dago AntennaPod-en lehentasun orokorretan</string>
+ <string name="statistics_listened_for">Zenbat denboran entzuna:</string>
+ <string name="statistics_episodes_on_device">Gailuko saioak:</string>
+ <string name="statistics_space_used">Erabilitako espazioa:</string>
+ <string name="statistics_view_all">Podcast guztietarako ikusi »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Datu basea eguneratzen</string>
<!--AntennaPodSP-->
@@ -678,18 +690,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Bilatu podcasta</string>
<string name="search_itunes_label">Bilatu itunes-en</string>
+ <string name="search_podcastindex_label">Bilatu Podcastindex.org -en</string>
<string name="search_fyyd_label">Bilatu fyyd-en</string>
<string name="advanced">Aurreratua</string>
- <string name="add_podcast_by_url">Gehitu podcasta URL bidez</string>
- <string name="browse_gpoddernet_label">Bilatu gpodder.net-en bilatu</string>
+ <string name="add_podcast_by_url">Gehitu Podcasta RSS helbide bidez</string>
+ <string name="browse_gpoddernet_label">Bilatu gpodder.net-en</string>
<string name="discover">Aurkitu</string>
+ <string name="discover_hide">Ezkutatu</string>
+ <string name="discover_is_hidden">Iradokizunak ezkutatzea erabaki duzu.</string>
<string name="discover_more">gehiago »</string>
- <string name="search_powered_by">Honek bultzatutako bilaketa:%1$s</string>
+ <string name="discover_powered_by_itunes">iTunesen iradokizunak</string>
+ <string name="search_powered_by">%1$s -ren emaitzak</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Gehitu tokiko karpeta</string>
+ <string name="local_folder">Tokiko karpeta</string>
+ <string name="reconnect_local_folder">Birkonektatu tokiko karpeta</string>
+ <string name="reconnect_local_folder_warning">Baimenik izan ezean, hau erabil dezakezu karpeta berdina birkonektatzeko. Ez aukeratu beste karpetarik.</string>
+ <string name="local_feed_description">Podcast birtual hau AntennaPod-i karpeta bat gehituta sortu da</string>
+ <string name="unable_to_start_system_file_manager">Ezin da sistemaren fitxategi kudeatzailea abiarazi</string>
<string name="filter">Iragazia</string>
<!--Episodes apply actions-->
<string name="all_label">Denak</string>
<string name="selected_all_label">Aukeratutako saio denak</string>
- <string name="none_label">Bat ere ez</string>
+ <string name="select_none_label">Bat ere ez</string>
<string name="deselected_all_label">Ez dago aukeratutako saiorik</string>
<string name="played_label">Ikusita</string>
<string name="selected_played_label">Ikusitako saio denak</string>
@@ -699,12 +722,21 @@
<string name="selected_downloaded_label">Deskargatutako saio aukeratuak</string>
<string name="not_downloaded_label">Deskargatu gabe</string>
<string name="selected_not_downloaded_label">Deskargatu gabeko saio aukeratuak</string>
- <string name="queued_label">Ilaran</string>
<string name="selected_queued_label">Ilarako saio aukeratuak</string>
- <string name="not_queued_label">Ez dago ilaran</string>
<string name="selected_not_queued_label">Ilaran ez dauden saio aukeratuak</string>
- <string name="has_media">Media du</string>
<string name="selected_has_media_label">Media duten saio aukeratuak</string>
+ <string name="hide_is_favorite_label">Gogokoa da</string>
+ <string name="not_favorite">Ez da gogokoa</string>
+ <string name="hide_downloaded_episodes_label">Deskargatuta</string>
+ <string name="hide_not_downloaded_episodes_label">Deskargatu gabe</string>
+ <string name="queued_label">Ilaran</string>
+ <string name="not_queued_label">Ez dago ilaran</string>
+ <string name="has_media">Media du</string>
+ <string name="no_media">Bitartekorik gabe</string>
+ <string name="hide_paused_episodes_label">Geldirik</string>
+ <string name="not_paused">Gelditu gabea</string>
+ <string name="hide_played_episodes_label">Ikusita</string>
+ <string name="not_played">Erreproduzitu gabea</string>
<!--Sort-->
<string name="sort_title_a_z">Izenburua (A \u2192 Z)</string>
<string name="sort_title_z_a">Izenburua (Z \u2192 A)</string>
@@ -724,6 +756,12 @@
<string name="rating_never_label">Bakean utz nazazu</string>
<string name="rating_later_label">Gogoratu geroago</string>
<string name="rating_now_label">Tira, egin dezagun!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Gehitu:</string>
+ <string name="share_playback_position_dialog_label">Erreprodukzioaren unea</string>
+ <string name="share_dialog_media_file_url_label">Media artxibategien helbidea</string>
+ <string name="share_dialog_episode_website_label">Saioaren orrialdea</string>
+ <string name="share_dialog_media_file_label">Media artxibategiak</string>
<!--Audio controls-->
<string name="audio_controls">Audio kontrolak</string>
<string name="playback_speed">Erreprodukzio abiadura</string>
@@ -770,7 +808,9 @@
<string name="notification_channel_playing">Erreproduzitzen</string>
<string name="notification_channel_playing_description">Erreprodukzioa kontrolatzeko aukera ematen du. Podcast bat erreproduzitzen den bitartean ikusten den jakinarazpen nagusia da.</string>
<string name="notification_channel_error">Erroreak</string>
- <string name="notification_channel_error_description">Zerbait gaizki atera den erakusten du, adibidez, gpodder deskargak edo sinkronizazioak huts egiten duen.</string>
+ <string name="notification_channel_error_description">Zerbait gaizki irten bada erakusten du, adibidez, jeitsi edo feed-eguneraketak huts egiten badute.</string>
+ <string name="notification_channel_sync_error">Akatsak sinkronizazioan </string>
+ <string name="notification_channel_sync_error_description">Erakutsi gpoder -en sinkronizazioak huts egitean.</string>
<string name="notification_channel_auto_download">Deskarga automatikoak</string>
<string name="notification_channel_episode_auto_download">Pasarteak automatikoki deskargatu direnean erakusten da.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-fa/strings.xml b/core/src/main/res/values-fa/strings.xml
index 0ac3b684d..d4bb6a29c 100644
--- a/core/src/main/res/values-fa/strings.xml
+++ b/core/src/main/res/values-fa/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">حد مجاز تکمیل شده است. شما می‌توانید اندازه حافظه پنهان را در تنظیمات افزایش دهید.</string>
<string name="playback_statistics_label">پخش</string>
<string name="download_statistics_label">بارگیری‌ها</string>
+ <string name="notification_pref_fragment">اعلان ها</string>
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">مجموع زمان پادکست‌های پخش‌شده:</string>
<string name="statistics_details_dialog">%1$d از %2$d قسمت‌ها شروع شده است.\n\n%3$s از %4$s پخش.</string>
<string name="statistics_mode">حالت آمار</string>
<string name="statistics_mode_normal">مدت زمان واقعی پخش را محاسبه کنید. دو بار پخش کردن دو بار شمارش می‌شود، در حالیکه علامت‌گذاری‌شده به‌عنوان پخش‌شده محاسبه نمی‌شود.</string>
- <string name="statistics_mode_count_all">جمع مجموع پادکست‌هایی که تعیین‌شده به‌عنوان پخش‌شده</string>
+ <string name="statistics_mode_count_all">مجموع اپیزودها را به عنوان پخش شده علامت گذاری کن.</string>
<string name="statistics_speed_not_counted">توجه: سرعت پخش هرگز به حساب نمی‌آید.</string>
<string name="statistics_reset_data">بازنشانی داده‌های آماری</string>
<string name="statistics_reset_data_msg">این همهٔ تاریخچهٔ طول پخش همهٔ قسمت‌های را پاک می‌کند. مطمئنید که می‌خواید ادامه دهید؟</string>
+ <string name="statistics_counting_since">از %s، شما اجرا نمودید</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">جمع کل پادکست‌های بارگیری شده:</string>
+ <string name="total_size_downloaded_podcasts">حجم کل پادکست‌های بارگیری شده:</string>
<!--Main activity-->
<string name="drawer_open">باز کردن منو</string>
<string name="drawer_close">بستن منو</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">تعداد قسمت‌های پخش‌نشده</string>
<string name="drawer_feed_counter_downloaded">تعداد قسمت‌های بارگیری‌شده</string>
<string name="drawer_feed_counter_none">هیچ‌یک</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">هیچ اپ سازگاری پیدا نشد</string>
<!--Webview actions-->
<string name="open_in_browser_label">باز کردن در مرورگر</string>
<string name="copy_url_label">کپی کردن URL</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">تنظیمات پادکست</string>
<string name="rename_feed_label">تغییر نام پادکست</string>
<string name="remove_feed_label">پاک کردن پادکست</string>
- <string name="share_label">هم‌رسانی…</string>
- <string name="share_link_label">هم‌رسانی نشانی پادکست</string>
- <string name="share_link_with_position_label">هم‌رسانی URL قسمت با موقعیت پخش</string>
+ <string name="share_label">هم‌رسانی</string>
+ <string name="share_label_with_ellipses">هم‌رسانی…</string>
<string name="share_file_label">هم‌رسانی پرونده</string>
- <string name="share_website_url_label">هم‌رسانی نشانی تارنما</string>
- <string name="share_feed_url_label">هم‌رسانی نشانی پادکست</string>
- <string name="share_item_url_label">هم‌رسانی نشانی پروندهٔ رسانه‌ای</string>
- <string name="share_item_url_with_position_label">هم‌رسانی URL فایل قسمت با موقعیت پخش</string>
+ <string name="share_website_url_label">نشانی وب سایت</string>
+ <string name="share_feed_url_label">نشانی فید پادکست</string>
<string name="feed_delete_confirmation_msg">لطفا تأیید کنید که می‌خواهید پادکست «%1$s» و تمام قسمت‌های آن که بارگیری کرده‌اید را حذف کنید.</string>
+ <string name="feed_delete_confirmation_local_msg">لطفا تایید کنید که مایل به حذف پادکست می باشید. «%1$s » . فایلها در فولدر داخلی حذف نخواهد شد.</string>
<string name="feed_remover_msg">در حال پاک کردن پادکست</string>
<string name="load_complete_feed">تازه‌سازی تمام پادکست</string>
<string name="multi_select">چندانتخابی</string>
<string name="select_all_above">انتخاب همهٔ بالایی‌ها</string>
<string name="select_all_below">انتخاب همهٔ پایینی‌ها</string>
<string name="hide_unplayed_episodes_label">پخش‌نشده</string>
- <string name="hide_paused_episodes_label">متوقف شد</string>
- <string name="hide_played_episodes_label">پخش شد</string>
<string name="hide_queued_episodes_label">در صف</string>
<string name="hide_not_queued_episodes_label">خارج از صف</string>
- <string name="hide_downloaded_episodes_label">بارگیری‌شده</string>
- <string name="hide_not_downloaded_episodes_label">بارگیری‌نشده</string>
<string name="hide_has_media_label">دارای رسانه</string>
- <string name="hide_is_favorite_label">مورد علاقه</string>
<string name="filtered_label">فیلتر شده</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} آخرین تازه‌سازی ناموفق بود</string>
<string name="open_podcast">باز کردن پادکست</string>
@@ -163,10 +160,6 @@
<string name="delete_label">حذف</string>
<string name="delete_failed">پرونده حذف نشد. راه‌اندازی مجدد دستگاه می‌تواند کمک کند.</string>
<string name="delete_episode_label">حذف قسمت</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d قسمت حذف شد.</item>
- <item quantity="other">%d قسمت حذف شد.</item>
- </plurals>
<string name="remove_new_flag_label">حذف نشان «جدید»</string>
<string name="removed_new_flag_label">نشان «جدید» حذف شد</string>
<string name="mark_read_label">علامت‌گذاری به‌عنوان پخش‌شده</string>
@@ -238,7 +231,6 @@
</plurals>
<string name="downloads_processing">پردازش بارگیری‌ها</string>
<string name="download_notification_title">بارگیری داده پادکست</string>
- <string name="download_report_content">%1$d بارگیری موفق شد، %2$d شکست خورد</string>
<string name="download_log_title_unknown">عنوان ناشناخته</string>
<string name="download_type_feed">خوراک</string>
<string name="download_type_media">پرونده رسانه</string>
@@ -251,7 +243,8 @@
<string name="confirm_mobile_download_dialog_message">بارگیری بر روی اتصال داده‌ای همراه در تنظیمات غیر فعال شده است.\n\nمایلید به صورت موقت بارگیری صورت گیرد؟\n\n<small>انتخاب شما برای ۱۰ دقیقهٔ آینده به خاطر سپرده می‌شود.</small></string>
<string name="confirm_mobile_streaming_notification_title">پخش جریانی همراه</string>
<string name="confirm_mobile_streaming_notification_message">پخش جریانی بر روی اتصال داده‌ای همراه در تنظیمات غیر فعال شده است. برای پخش جریانی به هر روی کلیک کنید.</string>
- <string name="confirm_mobile_streaming_button_always">همیشه مجاز کن</string>
+ <string name="confirm_mobile_streaming_button_always">همیشه</string>
+ <string name="confirm_mobile_streaming_button_once">یکبار</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">در صف قرار دادن</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">اجازهٔ موقت</string>
<!--Mediaplayer messages-->
@@ -297,8 +290,9 @@
<string name="download_plugin_label">بارگیری افزایه</string>
<string name="no_playback_plugin_title">افزایه نصب‌نشده</string>
<string name="no_playback_plugin_or_sonic_msg">برای اینکه سرعت بازپخش متغیر کار کند، پیشنهاد می‌دهید که پخش‌کنندهٔ داخلی Sonic را استفاده کنید.</string>
- <string name="set_playback_speed_label">سرعت‌های پخش</string>
<string name="enable_sonic">فعال‌سازی Sonic</string>
+ <string name="speed_presets">از پیش نشاندن</string>
+ <string name="preset_already_exists">%1$.2f قبلاً به عنوان یک پیش تنظیم ذخیره شده است.</string>
<!--Empty list labels-->
<string name="no_items_header_label">بدون قسمت صف‌شده</string>
<string name="no_items_label">افزودن یک قسمت با بارگیری آن، یا فرشدن طولانی یک قسمت و انتخاب «افزودن به صف».</string>
@@ -346,15 +340,65 @@
<string name="pref_unpauseOnHeadsetReconnect_sum">ادامه پخش وقتی که هدفن‌ها دوباره متصل شود</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">ادامه پخش هنگامی که بلوتوث دوباره متصل شود</string>
<string name="pref_hardwareForwardButtonSkips_title">دکمه پرش‌های به جلو</string>
+ <string name="pref_hardwareForwardButtonSkips_sum">هنگام فشار دادن دکمه جلو بر روی دستگاه متصل به بلوتوث ، به جای فوروارد ، به قسمت بعدی بروید</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">دکمه «قبلی» دوباره راه اندازی شد</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">هنگام فشار دادن دکمه فیزیکی «قبلی» ، قسمت فعلی را دوباره شروع کنید بجای عقب رفتن</string>
+ <string name="pref_followQueue_sum">پس از پایان پخش ، به مورد صف بعدی بروید</string>
+ <string name="pref_auto_delete_sum">با پایان پخش ، قسمت حذف شود</string>
<string name="pref_auto_delete_title">حذف خودکار</string>
+ <string name="pref_smart_mark_as_played_sum">قسمتها را به عنوان پخش علامت بزنید حتی اگر چندین ثانیه از زمان پخش باقی مانده باشد</string>
+ <string name="pref_smart_mark_as_played_title">علامت گذاری هوشمند به عنوان «اجرا شده»</string>
+ <string name="pref_skip_keeps_episodes_sum">اپیزودها را نگه دار وقتی از روی آنها پرش میشود</string>
+ <string name="pref_skip_keeps_episodes_title">اپیزودهای پرش شده نگه داشته شده</string>
+ <string name="pref_favorite_keeps_episodes_sum">اپیزودها را نگه دار وقتی به عنوان علاقمندی علامت گذاری میشود</string>
+ <string name="pref_favorite_keeps_episodes_title">اپیزودهای مورد علاقه نگه داشته شده</string>
<string name="playback_pref">پخش</string>
+ <string name="playback_pref_sum">کنترل هدفون ، رد کردن فواصل ، صف</string>
<string name="network_pref">شبکه</string>
+ <string name="network_pref_sum">فاصله به روزرسانی ، کنترل های بارگیری ، داده تلفن همراه</string>
+ <string name="pref_autoUpdateIntervallOrTime_title">فاصله یا زمان روز را به روز کنید</string>
+ <string name="pref_autoUpdateIntervallOrTime_sum">یک بازه یا زمان مشخص از روز را برای بروزرسازی خودکار پادکست ها مشخص کنید</string>
+ <string name="pref_autoUpdateIntervallOrTime_message">شما می توانید یک بازه مانند \"هر 2 ساعت\" یا یک ساعت خاص از روز را مانند \"7:00 صبح\" تنظیم کنید. شما همچنین می توانید به طور کامل به روزرسانی های خودکار را غیرفعال کنید.\n\n لطفا توجه داشته باشید: زمان بروزرسانی دقیق نیست و شما ممکن است با تأخیر کوتاه روبرو شوید.</string>
<string name="pref_autoUpdateIntervallOrTime_Disable">از کار انداختن</string>
<string name="pref_autoUpdateIntervallOrTime_Interval">تنظیم بازه</string>
<string name="pref_autoUpdateIntervallOrTime_TimeOfDay">تنظیم زمان روز</string>
+ <string name="pref_autoUpdateIntervallOrTime_every">هر %1$s</string>
+ <string name="pref_autoUpdateIntervallOrTime_at">در %1$s</string>
+ <string name="pref_followQueue_title">پخش مداوم</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">قطع اتصال هدفون یا بلوتوث</string>
+ <string name="pref_unpauseOnHeadsetReconnect_title">وصل دوباره هدفون</string>
+ <string name="pref_unpauseOnBluetoothReconnect_title">وصل دوباره وصل دوباره</string>
+ <string name="pref_stream_over_download_title">ترجیح به پخش جریانی</string>
+ <string name="pref_stream_over_download_sum">دکمه پخش جریان را به جای دکمه بارگیری در لیست ها نمایش بده.</string>
+ <string name="pref_mobileUpdate_title">به روزرسانی های موبایل</string>
+ <string name="pref_mobileUpdate_sum">آنچه که باید از طریق اتصال داده تلفن همراه مجاز است را انتخاب کنید</string>
+ <string name="pref_mobileUpdate_refresh">تازه سازی پادکست</string>
+ <string name="pref_mobileUpdate_images">تصویر جلد</string>
+ <string name="pref_mobileUpdate_auto_download">بارگیری‌های خودکار</string>
+ <string name="pref_mobileUpdate_episode_download">دانلود اپیزود</string>
+ <string name="pref_mobileUpdate_streaming">جاری شدن</string>
<string name="user_interface_label">رابط کاربری</string>
+ <string name="user_interface_sum">ظاهر ، اشتراک ها ، صفحه قفل</string>
<string name="pref_set_theme_title">انتخاب پوسته</string>
+ <string name="pref_nav_drawer_items_title">تنظیم موارد کشوی پیمایش</string>
+ <string name="pref_nav_drawer_items_sum">تغییر موارد قابل نمایش در کشوی پیمایش</string>
+ <string name="pref_nav_drawer_feed_order_title">تنظیم سفارش اشتراک</string>
+ <string name="pref_nav_drawer_feed_order_sum">تغییر ترتیب اشتراک هایتان</string>
+ <string name="pref_nav_drawer_feed_counter_title">تنظیم پیشخوان اشتراک</string>
+ <string name="pref_nav_drawer_feed_counter_sum">اطلاعات نمایش داده شده توسط پیشخوان اشتراک را تغییر دهید. همچنین اگر «سفارش اشتراک» روی «پیشخوان» تنظیم شود ، بر مرتب سازی اشتراک ها نیز تأثیر می گذارد.</string>
+ <string name="pref_set_theme_sum">تغییر ظاهر آنتن پاد</string>
+ <string name="pref_automatic_download_title">بارگیری خودکار</string>
+ <string name="pref_automatic_download_sum">بارگیری خودکار قسمتها را پیکربندی کنید.</string>
+ <string name="pref_autodl_wifi_filter_title">فیلتر Wi-Fi را فعال کنید</string>
+ <string name="pref_autodl_wifi_filter_sum">بارگیری خودکار فقط باید از طریق شبکه های Wi-Fi انتخاب شده مجاز باشد.</string>
+ <string name="pref_automatic_download_on_battery_title">بارگیری زمانی که سیستم شارژ نمیشود مجاز باشد</string>
+ <string name="pref_automatic_download_on_battery_sum">وقتی باتری شارژ نمی شود ، امکان بارگیری خودکار وجود داشته باشد</string>
+ <string name="pref_parallel_downloads_title">بارگیری موازی</string>
+ <string name="pref_episode_cache_title">قسمت های ذخیره شده</string>
+ <string name="pref_episode_cache_summary">تعداد کل قسمتهای قابل بارگیری در ذخیره گاه دستگاه. در صورت رسیدن به این تعداد بارگیری خودکار به حالت تعلیق در می آید.</string>
<string name="pref_episode_cover_title">استفاده از عکس قسمت</string>
+ <string name="pref_episode_cover_summary">هر زمان که جلد مخصوص قسمت در دسترس بود از آن استفاده کن. در صورت لغو انتخاب ، برنامه همیشه از تصویر جلد پادکست استفاده می کند.</string>
+ <string name="pref_theme_title_use_system">از طرح زمینه سیستم استفاده کنید</string>
<string name="pref_theme_title_light">روشن</string>
<string name="pref_theme_title_dark">تاریک</string>
<string name="pref_theme_title_trueblack">سیاه (مناسب AMOLED)</string>
@@ -363,42 +407,161 @@
<string name="pref_update_interval_hours_singular">ساعت</string>
<string name="pref_update_interval_hours_manual">دستی</string>
<string name="pref_gpodnet_authenticate_title">ورود</string>
+ <string name="pref_gpodnet_authenticate_sum">برای همگام سازی اشتراک های خود با حساب gpodder.net وارد شوید.</string>
<string name="pref_gpodnet_logout_title">خروج</string>
<string name="pref_gpodnet_logout_toast">خروج موفقیت‌آمیز بود</string>
<string name="pref_gpodnet_setlogin_information_title">تغییر اطلاعات ورود</string>
- <string name="pref_playback_speed_title">سرعت‌های پخش</string>
+ <string name="pref_gpodnet_setlogin_information_sum">اطلاعات ورود به سیستم حساب gpodder.net خود را تغییر دهید.</string>
+ <string name="pref_gpodnet_sync_changes_title">اکنون همگام سازی کنید</string>
+ <string name="pref_gpodnet_sync_changes_sum">تغییرات اشتراک و وضعیت اپیزود را با gpodder.net همگام سازی کنید.</string>
+ <string name="pref_gpodnet_full_sync_title">همگام سازی کامل را اجبار کن</string>
+ <string name="pref_gpodnet_full_sync_sum">همه اشتراک ها و حالت های قسمت را با gpodder.net همگام سازی کنید.</string>
+ <string name="pref_gpodnet_login_status"><![CDATA[وارد شد به عنوان <i>%1$s</i> با وسیله <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">همگام سازی انجام نشد</string>
+ <string name="pref_gpodnet_notifications_sum">این تنظیمات در مورد خطاهای احراز هویت اعمال نمی شود.</string>
+ <string name="pref_playback_speed_sum">سرعتهای موجود برای بازپخش با سرعت متغیر را سفارشی کنید</string>
+ <string name="pref_feed_playback_speed_sum">سرعت شروع بازپخش صدا برای قسمت های این پادکست</string>
+ <string name="pref_feed_skip">پرش خودکار</string>
+ <string name="pref_feed_skip_sum">از اجرای قسمت معرفی و پایانی صرف نظر کن.</string>
+ <string name="pref_feed_skip_ending">پرش به آخر</string>
+ <string name="pref_feed_skip_intro">پرش به اول</string>
+ <string name="pref_feed_skip_ending_toast">پرش از %d ثانیه آخر</string>
+ <string name="pref_feed_skip_intro_toast">پرش از %d ثانیه اول</string>
+ <string name="pref_playback_time_respects_speed_title">اطلاعات رسانه را برای سرعت بازپخش تنظیم کنید</string>
+ <string name="pref_playback_time_respects_speed_sum">موقعیت و مدت نمایش داده شده با سرعت پخش سازگار شده</string>
+ <string name="pref_fast_forward">زمان پرش برای جلو رفتن سریع</string>
+ <string name="pref_fast_forward_sum">با کلیک بر روی دکمه سریع جلو ، تعداد ثانیه ها را برای پرش به جلو تنظیم کنید</string>
+ <string name="pref_rewind">زمان پرش برای عقب رفتن سریع</string>
+ <string name="pref_rewind_sum">با کلیک روی دکمه برگشت تعداد ثانیه ها را برای پرش به عقب تنظیم کنید</string>
+ <string name="pref_gpodnet_sethostname_title">تنظیم نام میزبان</string>
+ <string name="pref_gpodnet_sethostname_use_default_host">استفاده از میزبان پیش فرض</string>
+ <string name="pref_expandNotify_title">اعلان با الویت بالا</string>
+ <string name="pref_expandNotify_sum">این معمولاً اعلان را برای نمایش دکمه های پخش گسترش می دهد.</string>
+ <string name="pref_persistNotify_title">کنترلهای پخش مداوم</string>
+ <string name="pref_persistNotify_sum">وقتی پخش متوقف شد ، اعلان ها را نگه دار و کنترل های صفحه را قفل کن.</string>
+ <string name="pref_compact_notification_buttons_title">تنظیم دکمه های اطلاع رسانی فشرده</string>
+ <string name="pref_compact_notification_buttons_sum">با باز شدن اعلان ، دکمه های پخش را تغییر دهید. دکمه پخش / مکث همیشه در آن گنجانده شده است.</string>
+ <string name="pref_compact_notification_buttons_dialog_title">حداکثر %1$d مورد را انتخاب کنید</string>
+ <string name="pref_compact_notification_buttons_dialog_error">شما فقط می توانید حداکثر %1$d مورد را انتخاب کنید.</string>
<string name="pref_lockscreen_background_title">تنظیم پس‌زمینه صفحهٔ قفل</string>
- <string name="pref_showDownloadReport_title">نمایش گزارش بارگیری</string>
+ <string name="pref_lockscreen_background_sum">پس زمینه صفحه قفل را روی تصویر جلد قسمت فعلی تنظیم کن. به عنوان اثر جانبی ، این تصویر در برنامه های شخص ثالث نیز نشان داده خواهد شد.</string>
+ <string name="pref_showDownloadReport_title">دانلود ناموفق</string>
<string name="pref_showDownloadReport_sum">در صورت شکست در بارگیری، گزارشی تولید شود که جزئیات شکست را نشان دهد.</string>
- <string name="pref_showAutoDownloadReport_title">نمایش گزارش بارگیری خودکار</string>
+ <string name="pref_showAutoDownloadReport_title">بارگیری خودکار انجام شد</string>
+ <string name="pref_showAutoDownloadReport_sum">اعلانی را برای قسمتهای بارگیری خودکار نشان دهید.</string>
<string name="pref_expand_notify_unsupport_toast">اندرویدهای قدیمی‌تر از نسخه ۴٫۱ از اعلان‌های بسط‌یافته پشتیبانی نمی‌کنند.</string>
+ <string name="pref_enqueue_location_title">مکان را از صف در آور</string>
+ <string name="pref_enqueue_location_sum">قسمتها را به اضافه کنید به : %1$s</string>
+ <string name="enqueue_location_back">عقب</string>
+ <string name="enqueue_location_front">جلو</string>
+ <string name="enqueue_location_after_current">بعد از اپیزود فعلی</string>
<string name="pref_smart_mark_as_played_disabled">غیرفعال</string>
+ <string name="pref_image_cache_size_title">اندازه حافظه پنهان تصویر</string>
+ <string name="pref_image_cache_size_sum">اندازه حافظه پنهان دیسک برای تصاویر.</string>
+ <string name="visit_user_forum">تالار گفتمان کاربر</string>
<string name="bug_report_title">گزارش مشکل</string>
+ <string name="open_bug_tracker">باز کردن ردیاب اشکال</string>
+ <string name="export_logs">خارج کردن گزارشها</string>
+ <string name="copy_to_clipboard">کپی به کلیپ بورد</string>
+ <string name="copied_to_clipboard">در کلیپ بورد کپی شد</string>
<string name="experimental_pref">آزمایشی</string>
+ <string name="pref_media_player_message">انتخاب کنید از کدام دستگاه پخش کننده رسانه برای پخش فایلها استفاده شود</string>
+ <string name="pref_current_value">مقدار فعلی: %1$s</string>
<string name="pref_proxy_title">پروکسی</string>
<string name="pref_proxy_sum">تنظیم پروکسی شبکه</string>
+ <string name="pref_faq">سوالات متداول</string>
<string name="pref_no_browser_found">مرورگر وب پیدا نشد.</string>
<string name="pref_cast_title">پشتیبانی از کروم‌کست</string>
+ <string name="pref_cast_message_play_flavor">پشتیبانی از پخش از راه دور رسانه را در دستگاه های Cast فعال کنید (مانند Chromecast ، بلندگوهای صوتی یا Android TV)</string>
<string name="pref_cast_message_free_flavor">کروم‌کست نیازمند کتاب‌خانه‌های غیرآزاد است که در این نسخه از AntennaPod غیر فعال هستند</string>
<string name="pref_enqueue_downloaded_title">در صف نهادن بارگیری‌شده‌ها</string>
+ <string name="pref_enqueue_downloaded_summary">قسمتهای بارگیری شده را به صف اضافه کنید</string>
<string name="media_player_builtin">پخش‌کننده پیش‌فرض اندروید</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (توصیه می شود)</string>
+ <string name="media_player_switch_to_exoplayer">به ExoPlayer بروید</string>
+ <string name="media_player_switched_to_exoplayer">به ExoPlayer تغییر وضعیت داده شد.</string>
+ <string name="pref_skip_silence_title">رد کردن سکوت در صدا</string>
+ <string name="pref_videoBehavior_title">هنگام خروج از ویدئو</string>
+ <string name="pref_videoBehavior_sum">رفتار هنگام ترک پخش فیلم</string>
<string name="stop_playback">توقف پخش</string>
<string name="continue_playback">ادامه پخش صدا</string>
+ <string name="behavior">رفتار</string>
+ <string name="pref_back_button_behavior_title">رفتار دکمه برگشت</string>
+ <string name="pref_back_button_behavior_sum">تغییر رفتار دکمه بازگشت</string>
+ <string name="back_button_default">پیش فرض</string>
+ <string name="back_button_open_drawer">کشوی ناوبری را باز کنید</string>
+ <string name="back_button_double_tap">برای خروج دو ضربه سریع بزنید</string>
+ <string name="back_button_show_prompt">برای خروج تأیید کنید</string>
+ <string name="close_prompt">آیا مطمئن هستید که می خواهید انتن پاد را ببندید؟</string>
+ <string name="double_tap_toast">برای خروج دوباره روی دکمه برگشت ضربه بزنید</string>
+ <string name="back_button_go_to_page">برو به صفحه...</string>
+ <string name="back_button_go_to_page_title">انتخاب صفحه</string>
+ <string name="pref_delete_removes_from_queue_title">حذف باعث پاک شدن از صف شود</string>
+ <string name="pref_delete_removes_from_queue_sum">وقتی اپیزود حذف شد ، به طور خودکار از صف حذف شود.</string>
+ <string name="pref_filter_feed_title">فیلتر اشتراک</string>
+ <string name="pref_filter_feed_sum">اشتراک های خود را در کشوی ناوبری و صفحه اشتراک ها فیلتر کنید.</string>
+ <string name="no_filter_label">هیچ یک</string>
+ <string name="subscriptions_are_filtered">اشتراک ها فیلتر می شوند.</string>
+ <string name="subscriptions_counter_greater_zero">شمارنده بزرگتر از صفر</string>
+ <string name="auto_downloaded">بارگیری خودکار</string>
+ <string name="not_auto_downloaded">بارگیری خودکار انجام نشود</string>
+ <string name="kept_updated">بروز نگهداری شد</string>
+ <string name="not_kept_updated">بروز نگهداری نشد</string>
<!--About screen-->
<string name="about_pref">درباره</string>
<string name="antennapod_version">نسخه AntennaPod</string>
+ <string name="contributors">همکاران</string>
+ <string name="contributors_summary">هر کس می تواند به بهتر شدن آنتن پاد کمک کند - با کد ، ترجمه یا با کمک به کاربران در انجمن ما</string>
<string name="developers">توسعه‌دهندگان</string>
<string name="translators">مترجمان</string>
+ <string name="special_thanks">تشکر ویژه</string>
<string name="privacy_policy">سیاست حریم شخصی</string>
<string name="licenses">پروانه‌ها</string>
+ <string name="licenses_summary"> آنتن پاد از نرم افزارهای عالی دیگری نیز استفاده می کند</string>
<!--Search-->
<string name="search_status_no_results">نتیجه‌ای یافت نشد</string>
<string name="search_label">جستجو</string>
+ <string name="no_results_for_query">هیچ نتیجه ای برای \"%1$s\" یافت نشد</string>
<!--Synchronization-->
+ <string name="sync_status_started">همگام سازی شروع شد</string>
+ <string name="sync_status_episodes_upload">در حال بارگذاری تغییرات قسمت ...</string>
+ <string name="sync_status_episodes_download">در حال بارگیری تغییرات قسمت ...</string>
+ <string name="sync_status_upload_played">در حال بارگذاری وضعیت پخش شده</string>
+ <string name="sync_status_subscriptions">همگام سازی اشتراک ها ...</string>
+ <string name="sync_status_success">همگام سازی موفقیت آمیز</string>
+ <string name="sync_status_error">همگام سازی ناموفقیت آمیز</string>
<!--import and export-->
+ <string name="import_export_summary">اشتراک ها و صف را به دستگاه دیگری منتقل کنید</string>
+ <string name="database">پایگاه داده</string>
+ <string name="opml">OPML</string>
+ <string name="html">HTML</string>
+ <string name="html_export_summary">اشتراک های خود را به یک دوست نشان دهید</string>
+ <string name="opml_export_summary">اشتراک های خود را به یک برنامه پادکست دیگر منتقل کنید</string>
+ <string name="opml_import_summary">اشتراک های خود را از برنامه پادکست دیگری وارد کنید</string>
+ <string name="database_export_summary">اشتراک ها ، قسمت های گوش داده شده و صف را به آنتن پاد در یک دستگاه دیگر منتقل کنید</string>
+ <string name="database_import_summary">پایگاه داده آنتن پاد را از دستگاه دیگری وارد کنید</string>
+ <string name="opml_import_label">وارد کردن OPML</string>
+ <string name="opml_add_podcast_label">وارد کردن لیست پادکست (OPML)</string>
+ <string name="opml_reader_error">هنگام خواندن سند OPML خطایی رخ داده است:</string>
+ <string name="opml_import_error_no_file">هیچ فایلی انتخاب نشده است!</string>
<string name="select_all_label">انتخاب همه</string>
<string name="deselect_all_label">انتخاب هیچ</string>
+ <string name="opml_export_label">خارج کردن OPML</string>
+ <string name="html_export_label">خارج کردن HTML</string>
+ <string name="database_export_label">خارج کردن پایگاه داده</string>
+ <string name="database_import_label">وارد کردن پایگاه داده</string>
+ <string name="database_import_warning">وارد کردن یک پایگاه داده باعث جایگزین تمام اشتراکهای فعلی و سابقه پخش شما خواهد شد. شما باید پایگاه داده فعلی خود را به عنوان پشتیبان خارج کنید. آیا شما میخواهید جایگزین کنید؟</string>
+ <string name="please_wait">صبر کنید لطفا ...</string>
+ <string name="export_error_label">خطا در خارج کردن</string>
+ <string name="export_success_title">خارج کردن موفقیت آمیز</string>
+ <string name="export_success_sum">پرونده خارج شده در اینجا نوشته شده است :\n\n %1$s</string>
+ <string name="opml_import_ask_read_permission">برای خواندن فایل OPML دسترسی به حافظه خارجی لازم است</string>
+ <string name="import_select_file">فایل را برای وارد کردن انتخاب کنید</string>
+ <string name="successful_import_label">وارد کردن موفقیت آمیز</string>
+ <string name="import_ok">لطفاً OK را فشار دهید تا آنتن پاد دوباره راه اندازی شود</string>
<string name="import_no_downgrade">پایگاه داده با نسخه‌از جدیدتر از AntennaPod خروجی گرفته شده است. نسخه نصب شده فعلی شما هنوز نمی‌داند که چگونه باید با این پرونده کار کند.</string>
+ <string name="favorites_export_label">خارج کردن علاقه مندی ها</string>
+ <string name="favorites_export_summary">موارد مورد علاقه ذخیره شده خارج شد</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">تنظیم زمان‌سنج خواب</string>
<string name="disable_sleeptimer_label">از کار انداختن زمان‌سنج خواب</string>
@@ -445,6 +608,7 @@
<string name="gpodnetauth_device_caption_errorEmpty">عنوان نباید خالی باشد</string>
<string name="gpodnetauth_device_butChoose">گزینش</string>
<string name="gpodnetauth_finish_title">ورود موفق!</string>
+ <string name="gpodnetauth_finish_descr">تبریک می گویم! حساب gpodder.net شما اکنون با دستگاه شما پیوند داده شده است. آنتن پاد از این پس اشتراک های دستگاه شما را با حساب gpodder.net خود به طور خودکار همگام سازی می کند.</string>
<string name="gpodnetauth_finish_butsyncnow">شروع همگام‌سازی</string>
<string name="gpodnetauth_finish_butgomainscreen">رفتن به صفحهٔ اصلی</string>
<string name="gpodnetsync_auth_error_title">خطای تأیید هویت gpodder.net</string>
@@ -458,6 +622,9 @@
<string name="selected_folder_label">پوشهٔ انتخاب‌شده:</string>
<string name="create_folder_label">ساخت پوشه</string>
<string name="choose_data_directory">انتخاب پوشه داده‌ها</string>
+ <string name="choose_data_directory_message">لطفاً مکان اصلی پوشه داده خود را انتخاب کنید. آنتن پاد زیر فهرستهای مناسب را ایجاد می کند.</string>
+ <string name="choose_data_directory_permission_rationale">دسترسی به فضای ذخیره سازی خارجی برای تغییر پوشه داده مورد نیاز است</string>
+ <string name="choose_data_directory_available_space">%1$s از %2$s آزاد</string>
<string name="create_folder_msg">ایجاد پوشهٔ جدید با نام %1$s؟</string>
<string name="create_folder_success">ساخت پوشه جدید</string>
<string name="create_folder_error_no_write_access">نمی‌توان در این پوشه نوشت</string>
@@ -467,24 +634,185 @@
<string name="folder_not_readable_error">%1$s قابل خواندن نیست</string>
<string name="folder_not_writable_error">%1$s قابل نوشتن نیست</string>
<string name="folder_not_empty_dialog_title">پوشه خالی نیست</string>
+ <string name="folder_not_empty_dialog_msg">پوشه ای که انتخاب کرده اید خالی نیست. بارگیری رسانه و سایر پرونده ها مستقیماً در این پوشه قرار می گیرند. ادامه بدهم ؟</string>
<string name="set_to_default_folder">انتخاب پوشه پیش‌فرض</string>
+ <string name="pref_pausePlaybackForFocusLoss_sum">وقتی برنامه دیگری می خواهد صداها را پخش کند ، به جای کاهش میزان صدا ، پخش را متوقف کن</string>
+ <string name="pref_pausePlaybackForFocusLoss_title">مکث برای وقفه ها</string>
+ <string name="pref_resumeAfterCall_sum">پس از اتمام تماس تلفنی ، پخش را از سر بگیرید</string>
+ <string name="pref_resumeAfterCall_title">بعد از تماس ادامه بده</string>
+ <string name="pref_restart_required">برای اینکه این تغییر اعمال شود ، آنتن پاد باید دوباره راه اندازی شود.</string>
<!--Online feed view-->
<string name="subscribe_label">اشتراک</string>
+ <string name="subscribing_label">مشترک شدن ...</string>
+ <string name="preview_episode">پیش نمایش</string>
+ <string name="stop_preview">توقف پیش نمایش</string>
<!--Content descriptions for image buttons-->
+ <string name="rewind_label">عقب زدن</string>
+ <string name="fast_forward_label">حرکت سریع به جلو</string>
+ <string name="increase_speed">افزایش سرعت</string>
+ <string name="decrease_speed">کاهش سرعت</string>
+ <string name="media_type_audio_label">سمعی</string>
+ <string name="media_type_video_label">ویدئو</string>
+ <string name="status_downloading_label">قسمت در حال بارگیری است</string>
+ <string name="in_queue_label">قسمت در صف است</string>
+ <string name="is_favorite_label">قسمت به عنوان موردعلاقه علامت گذاری شده است</string>
+ <string name="drag_handle_content_description">برای تغییر موقعیت این مورد را بکشید</string>
+ <string name="load_next_page_label">صفحه بعدی را لود کن</string>
+ <string name="switch_pages">تغییر صفحات</string>
+ <string name="position">موقعیت: %1$s</string>
+ <string name="apply_action">حرکت را اعمال کن</string>
<!--Feed information screen-->
+ <string name="authentication_label">احراز هویت</string>
+ <string name="authentication_descr">تغییر نام کاربری و رمز ورود خود را برای این پادکست و قسمت های آن</string>
+ <string name="auto_download_settings_label">تنظیمات بارگیری خودکار</string>
+ <string name="episode_filters_label">فیلتر قسمت</string>
+ <string name="episode_filters_description">لیست اصطلاحاتی که برای تصمیم گیری در مورد درج یا حذف یک قسمت هنگام بارگیری خودکار استفاده می شود</string>
+ <string name="episode_filters_include">شامل </string>
+ <string name="episode_filters_exclude">مستثنی</string>
+ <string name="episode_filters_hint">تک کلمه \n \"چند کلمه\"</string>
+ <string name="keep_updated">به روز باش</string>
+ <string name="keep_updated_summary">هنگام بازخوانی (خودکار) همه پادکست ها ، این پادکست را وارد کنید</string>
+ <string name="auto_download_disabled_globally">بارگیری خودکار در تنظیمات اصلی آنتن پاد غیرفعال است</string>
+ <string name="statistics_listened_for">گوش داده شده برای:</string>
+ <string name="statistics_episodes_on_device">قسمت های موجود در دستگاه:</string>
+ <string name="statistics_space_used">فضای مورد استفاده:</string>
+ <string name="statistics_view_all">مشاهده همه پادکست ها »</string>
<!--Progress information-->
+ <string name="progress_upgrading_database">به روز رسانی پایگاه داده</string>
<!--AntennaPodSP-->
+ <string name="sp_apps_importing_feeds_msg">وارد کردن اشتراک از برنامه های تک منظوره</string>
<!--Add podcast fragment-->
+ <string name="search_podcast_hint">جستجوی پادکست ...</string>
+ <string name="search_itunes_label">در iTunes جستجو کن</string>
+ <string name="search_podcastindex_label">در Podcastindex.org جستجو کن</string>
+ <string name="search_fyyd_label">در fyyd جستجو کن</string>
+ <string name="advanced">پیشرفته</string>
+ <string name="add_podcast_by_url">اضافه کردن پادکست توسط آدرس RSS</string>
<string name="browse_gpoddernet_label">مرور gpodder.net</string>
+ <string name="discover">کشف کردن</string>
+ <string name="discover_hide">پنهان کردن</string>
+ <string name="discover_is_hidden">شما مخفی کردن پیشنهادات را انتخاب کرده اید.</string>
+ <string name="discover_more">بیشتر </string>
+ <string name="discover_powered_by_itunes">پیشنهادات توسط iTunes</string>
+ <string name="search_powered_by">نتایج توسط %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">پوشه محلی را اضافه کنید</string>
+ <string name="local_folder">پوشه محلی</string>
+ <string name="reconnect_local_folder">اتصال دوباره پوشه محلی</string>
+ <string name="reconnect_local_folder_warning">در صورت عدم پذیرش اجازه ، می توانید این را برای اتصال مجدد به همان پوشه قبلی استفاده کنید. پوشه دیگری را انتخاب نکنید.</string>
+ <string name="local_feed_description">این پادکست مجازی با افزودن پوشه ای به آنتن پاد ایجاد شده است.</string>
+ <string name="unable_to_start_system_file_manager">مدیریت فایل سیستم امکان پذیر نیست</string>
+ <string name="filter">فیلتر</string>
<!--Episodes apply actions-->
+ <string name="all_label">همه</string>
+ <string name="selected_all_label">همه قسمت ها انتخاب شد</string>
+ <string name="select_none_label">هیچ یک</string>
+ <string name="deselected_all_label">لغو انتخاب همه قسمت ها</string>
+ <string name="played_label">اجرا شد</string>
+ <string name="selected_played_label">قسمتهای پخش شده انتخاب شده</string>
+ <string name="unplayed_label">اجرا نشده</string>
+ <string name="selected_unplayed_label">قسمتهای پخش نشده انتخاب شده</string>
+ <string name="downloaded_label">بارگیری شد</string>
+ <string name="selected_downloaded_label">قسمتهای بارگیری شده انتخاب شد</string>
+ <string name="not_downloaded_label">دانلود نشده</string>
+ <string name="selected_not_downloaded_label">قسمتهای بارگیری نشده انتخاب شد</string>
+ <string name="selected_queued_label">قسمتهای در صف انتخاب شده</string>
+ <string name="selected_not_queued_label">قسمتهای خارج صف انتخاب شده</string>
+ <string name="selected_has_media_label">قسمتهای با رسانه انتخاب شده</string>
+ <string name="hide_is_favorite_label">مورد علاقه</string>
+ <string name="not_favorite">مورد علاقه نیست</string>
+ <string name="hide_downloaded_episodes_label">بارگیری‌شده</string>
+ <string name="hide_not_downloaded_episodes_label">بارگیری‌نشده</string>
+ <string name="queued_label">در صف گذاشته شد</string>
+ <string name="not_queued_label">در صف گذاشته نشد</string>
+ <string name="has_media">رسانه دارد</string>
+ <string name="no_media">رسانه ندارد</string>
+ <string name="hide_paused_episodes_label">متوقف شد</string>
+ <string name="not_paused">مکث نشده</string>
+ <string name="hide_played_episodes_label">پخش شد</string>
+ <string name="not_played">اجرا نشده</string>
<!--Sort-->
+ <string name="sort_title_a_z">عنوان (الفبایی معکوس)</string>
+ <string name="sort_title_z_a">عنوان (الفبایی)</string>
+ <string name="sort_date_new_old">تاریخ (جدید به قدیم)</string>
+ <string name="sort_date_old_new">تاریخ (قدیم به جدید)</string>
+ <string name="sort_duration_short_long">طول (کوتاه به بلند)</string>
+ <string name="sort_duration_long_short">طول (بلند به کوتاه)</string>
+ <string name="sort_a_z">برعکس الفبایی</string>
+ <string name="sort_z_a">الفبایی</string>
+ <string name="sort_new_old">جدید به قدیم</string>
+ <string name="sort_old_new">قدیم به جدید</string>
+ <string name="sort_short_long">کوتاه به بلند</string>
+ <string name="sort_long_short">بلند به کوتاه</string>
<!--Rating dialog-->
+ <string name="rating_title">علاقهمند به آنتن پاد ؟</string>
+ <string name="rating_message">اگر وقت بگذارید و به آنتن پاد امتیاز دهید ، از آن استقبال می کنیم.</string>
+ <string name="rating_never_label">دست از سر من بردار</string>
+ <string name="rating_later_label">بعدا به من یادآوری کن</string>
+ <string name="rating_now_label">مطمئنا ، بریم این کار را انجام بدیم!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">عبارتند از:</string>
+ <string name="share_playback_position_dialog_label">موقعیت پخش</string>
+ <string name="share_dialog_media_file_url_label">آدرس فایل رسانه</string>
+ <string name="share_dialog_episode_website_label">صفحه وب این قسمت</string>
+ <string name="share_dialog_media_file_label">فایل رسانه</string>
<!--Audio controls-->
+ <string name="audio_controls">کنترل های صوتی</string>
+ <string name="playback_speed">سرعت پخش</string>
+ <string name="volume">درجه صدا</string>
+ <string name="left_short">L</string>
+ <string name="right_short">R</string>
+ <string name="audio_effects">جلوه های صوتی</string>
+ <string name="stereo_to_mono">Downmix: استریو به مونو</string>
+ <string name="sonic_only">فقط صوتی</string>
+ <string name="exoplayer_only">فقط ExoPlayer</string>
<!--proxy settings-->
+ <string name="proxy_type_label">نوع</string>
+ <string name="host_label">میزبان</string>
+ <string name="port_label">پورت</string>
+ <string name="optional_hint">(اختیاری)</string>
+ <string name="proxy_test_label">تست</string>
+ <string name="proxy_checking">چک کردن…</string>
+ <string name="proxy_test_successful">تست موفق بود</string>
+ <string name="proxy_test_failed">تست ناموفق بود</string>
+ <string name="proxy_host_empty_error">میزبان نمی تواند خالی باشد</string>
+ <string name="proxy_host_invalid_error">میزبان آدرس IP یا دامنه معتبر نیست</string>
+ <string name="proxy_port_invalid_error">پورت معتبر نیست</string>
<!--Subscriptions fragment-->
+ <string name="subscription_num_columns">تعداد ستون ها</string>
<!--Casting-->
+ <string name="cast_media_route_menu_title">اجرا در ...</string>
+ <string name="cast_disconnect_label">جلسه cast را قطع کنید</string>
+ <string name="cast_not_castable">رسانه انتخاب شده با دستگاه cast سازگار نیست</string>
+ <string name="cast_failed_to_play">شروع در پخش رسانه موفقیت آمیر نبود</string>
+ <string name="cast_failed_to_stop">توقف در پخش رسانه موفقیت آمیر نبود</string>
+ <string name="cast_failed_to_pause">مکث در پخش رسانه موفقیت آمیر نبود</string>
+ <string name="cast_failed_setting_volume">میزان صدا تنظیم نشد</string>
+ <string name="cast_failed_no_connection">هیچ ارتباطی با دستگاه cast وجود ندارد</string>
+ <string name="cast_failed_no_connection_trans">اتصال به دستگاه cast متوقف شده است. در صورت امکان ، برنامه در تلاش برای برقراری مجدد اتصال است. لطفا چند ثانیه صبر کنید و دوباره امتحان کنید.</string>
+ <string name="cast_failed_status_request">همگام سازی با دستگاه cast انجام نشد</string>
+ <string name="cast_failed_seek">جستجوی موقعیت جدید در دستگاه cast انجام نشد</string>
+ <string name="cast_failed_receiver_player_error">پخش کننده گیرنده با خطای شدیدی روبرو شده است</string>
+ <string name="cast_failed_media_error_skipping">خطا در پخش رسانه. رد شدن</string>
<!--Notification channels-->
+ <string name="notification_channel_user_action">نیاز به انجام کاری</string>
+ <string name="notification_channel_user_action_description">در صورت نیاز به اقدام به عملی ، به عنوان مثال در صورت نیاز به وارد کردن رمز عبور ، نشان داده شود.</string>
+ <string name="notification_channel_downloading">درحال بارگیری</string>
+ <string name="notification_channel_downloading_description">هنگام بارگیری نشان داده می شود.</string>
+ <string name="notification_channel_playing">در حال اجرا</string>
+ <string name="notification_channel_playing_description">امکان کنترل پخش را فراهم می کند. این اعلان اصلی است که هنگام پخش پادکست مشاهده می کنید.</string>
+ <string name="notification_channel_error">خطاها</string>
+ <string name="notification_channel_error_description">اگر مشکلی پیش آمد ، به عنوان مثال اگر در بارگیری یا به روزرسانی خبره مشکلی پیش آمد ، نشان داده می شود.</string>
+ <string name="notification_channel_sync_error">خطاهای همگام سازی</string>
+ <string name="notification_channel_sync_error_description">هنگامی که همگام سازی gpodder انجام نشد نشان داده می شود.</string>
<string name="notification_channel_auto_download">بارگیری‌های خودکار</string>
+ <string name="notification_channel_episode_auto_download">وقتی قسمتها به طور خودکار بارگیری می شوند ، نشان داده می شوند.</string>
<!--Widget settings-->
+ <string name="widget_settings">تنظیمات ویجت</string>
+ <string name="widget_create_button">ایجاد ویجت</string>
+ <string name="widget_opacity">تیرگی</string>
<!--On-Demand configuration-->
+ <string name="on_demand_config_setting_changed">تنظیم با موفقیت به روز شد.</string>
+ <string name="on_demand_config_stream_text">به نظر می رسد که زیاد پخش مستقیم دارید. آیا می خواهید در لیست های قسمت دکمه های پخش مستقیم نشان داده شود؟</string>
+ <string name="on_demand_config_download_text">به نظر می رسد که شما زیاد بارگیری می کنید. آیا می خواهید در لیست قسمت دکمه های بارگیری نشان داده شود؟</string>
</resources>
diff --git a/core/src/main/res/values-fi/strings.xml b/core/src/main/res/values-fi/strings.xml
index f30824d7a..ff6c9c773 100644
--- a/core/src/main/res/values-fi/strings.xml
+++ b/core/src/main/res/values-fi/strings.xml
@@ -26,16 +26,13 @@
<string name="playback_statistics_label">Toisto</string>
<string name="download_statistics_label">Lataukset</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Podcasteja soitettu yhteensä:</string>
<string name="statistics_details_dialog">%1$d jakso %2$d:sta aloitettu.\n\nSoitettu %3$s jaksoa %4$s:sta.</string>
<string name="statistics_mode">Tilastointitila</string>
<string name="statistics_mode_normal">Laske oikeasti soitettu aikamäärä. Uudelleensoitto lasketaan kahdesti, mutta soitetuksi merkattua ei lasketa.</string>
- <string name="statistics_mode_count_all">Laske yhteen kaikki soitetuksi merketatut podcastit</string>
<string name="statistics_speed_not_counted">Huomio: Soittonopeutta ei lasketa mukaan.</string>
<string name="statistics_reset_data">Nollaa tilastotiedot</string>
<string name="statistics_reset_data_msg">Tämä poistaa kaikkien jaksojen soiton keston historian. Haluatko varmasti jatkaa?</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Ladattujen podcastien yhteiskoko</string>
<!--Main activity-->
<string name="drawer_open">Avaa menu</string>
<string name="drawer_close">Sulje menu</string>
@@ -49,6 +46,7 @@
<string name="drawer_feed_counter_unplayed">Soittamattomia jaksoja</string>
<string name="drawer_feed_counter_downloaded">Ladattuja jaksoja</string>
<string name="drawer_feed_counter_none">Ei yhtään</string>
+ <!--Bug report activity-->
<!--Webview actions-->
<string name="open_in_browser_label">Avaa selaimessa</string>
<string name="copy_url_label">Kopioi URL</string>
@@ -124,14 +122,7 @@
<string name="feed_settings_label">Podcastin asetukset</string>
<string name="rename_feed_label">Uudelleennimeä podcast </string>
<string name="remove_feed_label">Poista podcast</string>
- <string name="share_label">Jaa...</string>
- <string name="share_link_label">Jaa jakson URL</string>
- <string name="share_link_with_position_label">Jaa jakson URL soittoajan kanssa</string>
<string name="share_file_label">Jaa tietodosto</string>
- <string name="share_website_url_label">Jaa verkkosivuston URL</string>
- <string name="share_feed_url_label">Jaa podcastin URL</string>
- <string name="share_item_url_label">Jaa mediatiedoston URL</string>
- <string name="share_item_url_with_position_label">Jaa mediatiedoston URL toistosijainnin kanssa</string>
<string name="feed_delete_confirmation_msg">Vahvista, että haluat poistaa podcastin \"%1$s\" ja KAIKKI sen jaksot (mukaan lukien ladatut jaksot).</string>
<string name="feed_remover_msg">Poistetaan podcast</string>
<string name="load_complete_feed">Päivitä podcast</string>
@@ -139,14 +130,9 @@
<string name="select_all_above">Valitse kaikki yllä</string>
<string name="select_all_below">Valitse kaikki alla</string>
<string name="hide_unplayed_episodes_label">Soittamaton</string>
- <string name="hide_paused_episodes_label">Pause</string>
- <string name="hide_played_episodes_label">Soitettu</string>
<string name="hide_queued_episodes_label">Jonossa</string>
<string name="hide_not_queued_episodes_label">Ei jonossa</string>
- <string name="hide_downloaded_episodes_label">Ladattu</string>
- <string name="hide_not_downloaded_episodes_label">Ei ladattu</string>
<string name="hide_has_media_label">Sisältää mediaa</string>
- <string name="hide_is_favorite_label">On suosikki</string>
<string name="filtered_label">Suodatettu</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Viimeisin päivitys epäonnistui</string>
<string name="open_podcast">Avaa podcast</string>
@@ -163,10 +149,6 @@
<string name="delete_label">Poista</string>
<string name="delete_failed">Ei voida poistaa tiedostoa. Laitteen uudelleenkäynnistys saattaa auttaa.</string>
<string name="delete_episode_label">Poista jakso</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d jakso poistettu.</item>
- <item quantity="other">%d jaksoa poistettu.</item>
- </plurals>
<string name="remove_new_flag_label">Poista \"uusi\"-lippu</string>
<string name="removed_new_flag_label">Poistettiin \"uusi\"-lippu</string>
<string name="mark_read_label">Merkitse soitetuksi</string>
@@ -238,7 +220,6 @@
</plurals>
<string name="downloads_processing">Käsitellään latauksia</string>
<string name="download_notification_title">Ladataan podcastin tietoja</string>
- <string name="download_report_content">%1$d latausta onnistui, %2$d epäonnistui</string>
<string name="download_log_title_unknown">Tuntematon otsikko</string>
<string name="download_type_feed">Syöte</string>
<string name="download_type_media">Mediatiedosto</string>
@@ -251,7 +232,6 @@
<string name="confirm_mobile_download_dialog_message">Lataaminen mobiilidatayhteydellä on estetty asetuksissa.\n\nHaluatko sallia lataamisen väliaikaisesti?\n\n<small>Valinta muistetaan 10 minuutin ajan.</small></string>
<string name="confirm_mobile_streaming_notification_title">Vahvista suoratoisto mobiilidatayhteydellä</string>
<string name="confirm_mobile_streaming_notification_message">Suoratoisto mobiilidatayhteydellä on estetty asetuksissa. Napsauta suoratoistaaksesi silti.</string>
- <string name="confirm_mobile_streaming_button_always">Salli aina</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Lisää jonoon</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Salli väliaikaisesti</string>
<!--Mediaplayer messages-->
@@ -297,7 +277,6 @@
<string name="download_plugin_label">Lataa laajennus</string>
<string name="no_playback_plugin_title">Laajennus ei asennettu</string>
<string name="no_playback_plugin_or_sonic_msg">Vaihtelevan nopeuden toiston toimimiseksi suosittelemme ottamaan käyttöön sisäänrakennetun Sonic-mediasoittimen.</string>
- <string name="set_playback_speed_label">Soittonopeudet</string>
<string name="enable_sonic">Ota Sonic käyttöön</string>
<!--Empty list labels-->
<string name="no_items_header_label">Ei jaksoja jonossa</string>
@@ -371,7 +350,6 @@
<string name="pref_autoUpdateIntervallOrTime_every">joka %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">aika %1$s</string>
<string name="pref_followQueue_title">Jatkuva toisto</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Kuulokkeiden irrotus</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Kuulokkeiden uudelleenyhdistyminen</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth uudelleenyhdistyminen</string>
<string name="pref_stream_over_download_title">Suosi suoratoistoa</string>
@@ -384,7 +362,6 @@
<string name="pref_mobileUpdate_episode_download">Jaksojen lataus</string>
<string name="pref_mobileUpdate_streaming">Suoratoisto</string>
<string name="user_interface_label">Käyttöliittymä</string>
- <string name="user_interface_sum">Ulkonäkö, tilausten järjestys, lukitusnäyttö</string>
<string name="pref_set_theme_title">Valitse teema</string>
<string name="pref_nav_drawer_items_title">Aseta navigointihyllyn asiat</string>
<string name="pref_nav_drawer_items_sum">Vaihda navigointihyllyssä esiintyviä asioita.</string>
@@ -420,10 +397,7 @@
<string name="pref_gpodnet_sync_changes_sum">Synkronoi tilaukset ja jaksojen tilojen muutokset gpodder.net.</string>
<string name="pref_gpodnet_full_sync_sum">Synkronoi kaikki tilaukset ja jaksojen tilastot gpodder.net</string>
<string name="pref_gpodnet_login_status"><![CDATA[Kirjauduttu <i>%1$s</i> laitteella <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Näytä synkronointivirheet ilmoituksissa</string>
<string name="pref_gpodnet_notifications_sum">Tämä asetus ei vaikuta autentikointivirheisiin.</string>
- <string name="pref_playback_speed_title">Soittonopeudet</string>
- <string name="pref_playback_speed_sum">Kustomoi muuttuvia soittonopeuksia</string>
<string name="pref_playback_time_respects_speed_title">Mukauta mediatietoja soiton nopeuteen</string>
<string name="pref_playback_time_respects_speed_sum">Näytetty aika ja kesto mukautuvat soiton nopeuteen</string>
<string name="pref_fast_forward">Seuraava skippaa aikaa</string>
@@ -436,13 +410,10 @@
<string name="pref_expandNotify_sum">Tämä laajentaa ilmoituksen näyttämään soittonapit</string>
<string name="pref_persistNotify_title">Pysyvät soittokontrollit</string>
<string name="pref_persistNotify_sum">Säilytä ilmoitus ja lukituskuvan kontrollit kun soitto on pysäytetty.</string>
- <string name="pref_compact_notification_buttons_title">Aseta lukituskuvan napit</string>
- <string name="pref_compact_notification_buttons_sum">Vaihda lukituskuvan soittonapit. Soitto/Pause napit on aina mukana.</string>
<string name="pref_compact_notification_buttons_dialog_title">Valitse maksimi %1$d asioita</string>
<string name="pref_compact_notification_buttons_dialog_error">Voit valita vain maksimissaan %1$d asioita.</string>
<string name="pref_lockscreen_background_title">Aseta lukitusruudun taustakuva</string>
<string name="pref_lockscreen_background_sum">Aseta lukitusruudun taustakuva nykyisen jakson kuvaan. Tämä kuva näkyy kolmannen osapuolen sovelluksissa.</string>
- <string name="pref_showDownloadReport_title">Näytä latausraportti</string>
<string name="pref_showDownloadReport_sum">Jos lataus epäonnistuu, generoi raportti joka näyttää virheen tiedot.</string>
<string name="pref_expand_notify_unsupport_toast">Android versiot ennen 4.1 eivät tue laajenettuja ilmoituksia.</string>
<string name="pref_smart_mark_as_played_disabled">Poissa käytöstä</string>
@@ -498,7 +469,6 @@
<string name="export_success_sum">Viety tiedosto on kirjoitettu:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Pääsy ulkoiseen solvellukseen tarvitaan OPML tiedoston lukemiseen</string>
<string name="import_select_file">Valitse tiedosto tuontiin</string>
- <string name="import_ok">Tuonti onnistui.\n\nPaina OK uudelleenkäynnistääksesi AntennaPod</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Aseta uniajastin</string>
<string name="disable_sleeptimer_label">Lopeta uniajastin</string>
@@ -583,7 +553,6 @@
<string name="fast_forward_label">Hyppää eteen</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Navigoi eteenpäoin</string>
<string name="status_downloading_label">Jaksoa ladataan</string>
<string name="in_queue_label">Jakso on jonossa</string>
<string name="drag_handle_content_description">Raahaa muuttaen tilaa</string>
@@ -610,11 +579,11 @@
<string name="browse_gpoddernet_label">Selaa gpodder.net</string>
<string name="discover">Löydä</string>
<string name="discover_more">lisää »</string>
+ <!--Local feeds-->
<string name="filter">Filteri</string>
<!--Episodes apply actions-->
<string name="all_label">Kaikki</string>
<string name="selected_all_label">Valitse kaikki jaksot</string>
- <string name="none_label">Ei mitään</string>
<string name="deselected_all_label">Poista valinta kaikista</string>
<string name="played_label">Soitettu</string>
<string name="selected_played_label">Valitut soitetut jaksot</string>
@@ -624,12 +593,17 @@
<string name="selected_downloaded_label">Valittut ladatut jaksot</string>
<string name="not_downloaded_label">Ei ladattu</string>
<string name="selected_not_downloaded_label">Valitut ei ladatut jaksot</string>
- <string name="queued_label">Jonossa</string>
<string name="selected_queued_label">Valitut jaksot jonossa</string>
- <string name="not_queued_label">Ei jonossa</string>
<string name="selected_not_queued_label">Valitut jaksot ei jonossa</string>
- <string name="has_media">On media</string>
<string name="selected_has_media_label">Valitut jaksot joissa media</string>
+ <string name="hide_is_favorite_label">On suosikki</string>
+ <string name="hide_downloaded_episodes_label">Ladattu</string>
+ <string name="hide_not_downloaded_episodes_label">Ei ladattu</string>
+ <string name="queued_label">Jonossa</string>
+ <string name="not_queued_label">Ei jonossa</string>
+ <string name="has_media">On media</string>
+ <string name="hide_paused_episodes_label">Pause</string>
+ <string name="hide_played_episodes_label">Soitettu</string>
<!--Sort-->
<string name="sort_title_a_z">Otsikko (A \u2192 Z)</string>
<string name="sort_title_z_a">Otsikko (Z \u2192 A)</string>
@@ -643,6 +617,7 @@
<string name="rating_never_label">Jätä minut rauhaan</string>
<string name="rating_later_label">Muistuta minua myöhemmin</string>
<string name="rating_now_label">Miksei, tehdään tämä!</string>
+ <!--Share episode dialog-->
<!--Audio controls-->
<string name="audio_controls">Audiokontrollit</string>
<string name="playback_speed">Soittonopeus</string>
@@ -689,7 +664,6 @@
<string name="notification_channel_playing">Soittaa nyt</string>
<string name="notification_channel_playing_description">Sallii soiton kontrollit. Tämä on pääilmoitus, jonka näet kun podcast soitetaan.</string>
<string name="notification_channel_error">Virheet</string>
- <string name="notification_channel_error_description">Näytetään kun jotain meni vikaan, esimerkiksi jos lataus tai gpodder synkronointi epäonnistui.</string>
<!--Widget settings-->
<!--On-Demand configuration-->
</resources>
diff --git a/core/src/main/res/values-fr/strings.xml b/core/src/main/res/values-fr/strings.xml
index 04e4eb695..a0d86ea91 100644
--- a/core/src/main/res/values-fr/strings.xml
+++ b/core/src/main/res/values-fr/strings.xml
@@ -25,30 +25,34 @@
<string name="episode_cache_full_message">Le nombre maximal d\'épisodes téléchargés a été atteint. Vous pouvez changer ce nombre dans les paramètres.</string>
<string name="playback_statistics_label">Lecture</string>
<string name="download_statistics_label">Téléchargements</string>
+ <string name="notification_pref_fragment">Notifications</string>
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">Durée totale d\'écoute :</string>
<string name="statistics_details_dialog">%1$d épisodes démarrés sur %2$d\nsoit %3$s de lues sur %4$s.</string>
<string name="statistics_mode">Type de statistiques</string>
<string name="statistics_mode_normal">Calculer la durée réellement écoutée. Les épisodes écoutés deux fois comptent double alors que ceux simplement marqués lus ne sont pas comptés</string>
- <string name="statistics_mode_count_all">Additionner tous les podcasts marqués comme lus</string>
+ <string name="statistics_mode_count_all">Compter tous les épisodes marqués comme lus</string>
<string name="statistics_speed_not_counted">Note : la vitesse de lecture n\'est jamais prise en compte.</string>
<string name="statistics_reset_data">Réinitialiser les statistiques </string>
<string name="statistics_reset_data_msg">L\'information des temps de lecture va être effacée. Etes-vous sûr de vouloir continuer ?</string>
+ <string name="statistics_counting_since">Depuis le %s,\nvous avez lu</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Volume total des podcasts téléchargés :</string>
+ <string name="total_size_downloaded_podcasts">Volume total des épisodes téléchargés :</string>
<!--Main activity-->
<string name="drawer_open">Ouvrir le menu</string>
<string name="drawer_close">Fermer le menu</string>
<string name="drawer_preferences">Préférences du volet</string>
<string name="drawer_feed_order_unplayed_episodes">Trier par compteur</string>
- <string name="drawer_feed_order_alphabetical">Trier alphabétiquement</string>
+ <string name="drawer_feed_order_alphabetical">Trier par ordre alphabétique</string>
<string name="drawer_feed_order_last_update">Trier par date de publication</string>
<string name="drawer_feed_order_most_played">Trier par nombre lus</string>
- <string name="drawer_feed_counter_new_unplayed">Nombre de nouveaux épisodes non-lus</string>
- <string name="drawer_feed_counter_new">Nombre de nouveaux épisodes</string>
- <string name="drawer_feed_counter_unplayed">Nombre d\'épisodes non-lus</string>
- <string name="drawer_feed_counter_downloaded">Nombre d\'épisodes téléchargés</string>
+ <string name="drawer_feed_counter_new_unplayed">Nouveaux épisodes et non lus</string>
+ <string name="drawer_feed_counter_new">Nouveaux épisodes</string>
+ <string name="drawer_feed_counter_unplayed">Episodes non-lus</string>
+ <string name="drawer_feed_counter_downloaded">Episodes téléchargés</string>
<string name="drawer_feed_counter_none">Aucun</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Aucune application compatible trouvée</string>
<!--Webview actions-->
<string name="open_in_browser_label">Ouvrir dans le navigateur</string>
<string name="copy_url_label">Copier le lien</string>
@@ -124,32 +128,25 @@
<string name="feed_settings_label">Paramètres du podcast</string>
<string name="rename_feed_label">Renommer le podcast</string>
<string name="remove_feed_label">Supprimer le podcast</string>
- <string name="share_label">Partager...</string>
- <string name="share_link_label">Partager le lien</string>
- <string name="share_link_with_position_label">Partager le lien avec la position</string>
+ <string name="share_label">Partager</string>
+ <string name="share_label_with_ellipses">Partager...</string>
<string name="share_file_label">Partager le fichier</string>
- <string name="share_website_url_label">Partager le lien du site</string>
- <string name="share_feed_url_label">Partager le lien du podcast</string>
- <string name="share_item_url_label">Partager le lien du fichier</string>
- <string name="share_item_url_with_position_label">Partager le lien du fichier avec la position</string>
+ <string name="share_website_url_label">Lien du site web</string>
+ <string name="share_feed_url_label">Lien du flux</string>
<string name="feed_delete_confirmation_msg">Confirmer que vous voulez supprimer le podcast \"%1$s\" et TOUS ses épisodes téléchargés.</string>
+ <string name="feed_delete_confirmation_local_msg">Merci de confirmer que vous voulez supprimer le podcast \"%1$s\". Les fichiers du dossier local / source ne seront pas effacés.</string>
<string name="feed_remover_msg">Podcast en cours de suppression</string>
<string name="load_complete_feed">Mettre à jour tout le podcast</string>
<string name="multi_select">Sélection multiple</string>
<string name="select_all_above">Sélectionner avec ceux au-dessus</string>
<string name="select_all_below">Sélectionner avec ceux en-dessous</string>
<string name="hide_unplayed_episodes_label">Non lu</string>
- <string name="hide_paused_episodes_label">En pause</string>
- <string name="hide_played_episodes_label">Lu</string>
<string name="hide_queued_episodes_label">Dans la liste de lecture</string>
<string name="hide_not_queued_episodes_label">Pas dans la liste de lecture</string>
- <string name="hide_downloaded_episodes_label">Téléchargé</string>
- <string name="hide_not_downloaded_episodes_label">Non téléchargé</string>
<string name="hide_has_media_label">Avec média</string>
- <string name="hide_is_favorite_label">Est un favori</string>
<string name="filtered_label">Filtré</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} La dernière mise à jour a échoué</string>
- <string name="open_podcast">Ouvrir Podcast</string>
+ <string name="open_podcast">Ouvrir le podcast</string>
<string name="please_wait_for_data">Merci d\'attendre la fin du téléchargement des données</string>
<!--actions on feeditems-->
<string name="download_label">Télécharger</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Supprimer</string>
<string name="delete_failed">Suppression du fichier impossible. Redémarrer pourrait aider.</string>
<string name="delete_episode_label">Suppression de l\'épisode</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d épisode supprimé.</item>
- <item quantity="other">%d épisodes supprimés.</item>
- </plurals>
<string name="remove_new_flag_label">Ne plus considérer nouveau</string>
<string name="removed_new_flag_label">Le statut \"nouveau\" a été supprimé</string>
<string name="mark_read_label">Marquer comme lu</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Traitement des téléchargements</string>
<string name="download_notification_title">Téléchargement des données du podcast</string>
- <string name="download_report_content">%1$d téléchargements réussis, %2$d échoués</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%1$d téléchargement réussi, %2$d échoué</item>
+ <item quantity="other">%1$d téléchargements réussis, %2$d échoués</item>
+ </plurals>
<string name="download_log_title_unknown">Titre inconnu</string>
<string name="download_type_feed">Flux</string>
<string name="download_type_media">Fichier média</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Le téléchargement avec la connexion mobile est désactivé dans les options.\n\nVoulez-vous autoriser temporairement le téléchargement?\n\n<small>Votre choix sera retenu pour les 10 prochaines minutes.</small></string>
<string name="confirm_mobile_streaming_notification_title">Toucher pour autoriser le streaming avec la connexion mobile</string>
<string name="confirm_mobile_streaming_notification_message">Le streaming avec la connexion mobile est désactivé dans les paramètres. Toucher pour streamer quand même.</string>
- <string name="confirm_mobile_streaming_button_always">Toujours autoriser</string>
+ <string name="confirm_mobile_streaming_button_always">Toujours</string>
+ <string name="confirm_mobile_streaming_button_once">Une seule fois</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Rajouter à la liste de lecture</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Autoriser temporairement</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Télécharger une extension</string>
<string name="no_playback_plugin_title">Extension non installée</string>
<string name="no_playback_plugin_or_sonic_msg">Pour pouvoir changer la vitesse de lecture il est recommandé d\'activer le lecteur interne Sonic.</string>
- <string name="set_playback_speed_label">Vitesses de lecture</string>
<string name="enable_sonic">Activer Sonic</string>
+ <string name="speed_presets">Enregistrées</string>
+ <string name="preset_already_exists">%1$.2fx est déjà enregistrée.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Aucun épisode dans la liste de lecture</string>
<string name="no_items_label">Pour ajouter un épisode, téléchargez le ou faites une pression longue dessus et taper sur \"Ajouter à la liste de lecture\".</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Téléchargement d\'épisodes</string>
<string name="pref_mobileUpdate_streaming">Streaming</string>
<string name="user_interface_label">Interface utilisateur</string>
- <string name="user_interface_sum">Apparence, ordre des abonnements, écran de verrouillage</string>
+ <string name="user_interface_sum">Apparence, abonnements, écran de verrouillage</string>
<string name="pref_set_theme_title">Choisir un thème</string>
<string name="pref_nav_drawer_items_title">Changer les éléments du volet de navigation</string>
<string name="pref_nav_drawer_items_sum">Choisir quels éléments apparaissent dans le volet de navigation</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Forcer une synchronisation totale</string>
<string name="pref_gpodnet_full_sync_sum">Synchroniser tous les abonnements et tous les états des épisodes avec gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Connecté comme <i>%1$s</i> avec l\'appareil <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Notification des erreurs de synchronisation</string>
+ <string name="pref_gpodnet_notifications_title">La synchronisation a échoué</string>
<string name="pref_gpodnet_notifications_sum">Ce paramètre ne s\'applique pas aux erreurs d\'authentification.</string>
- <string name="pref_playback_speed_title">Vitesses de lecture</string>
- <string name="pref_playback_speed_sum">Définir les vitesses disponibles lors de la lecture audio</string>
+ <string name="pref_playback_speed_sum">Définir les vitesses disponibles lors de la lecture</string>
<string name="pref_feed_playback_speed_sum">Vitesse de lecture par défaut des épisodes</string>
<string name="pref_feed_skip">Saut automatique</string>
<string name="pref_feed_skip_sum">Sauter le début et la fin des épisodes</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Permet, généralement, d\'étendre la notification pour montrer les boutons de lecture</string>
<string name="pref_persistNotify_title">Boutons de lecture permanents</string>
<string name="pref_persistNotify_sum">Garder les notifications et les boutons de lecture sur l\'écran de verrouillage quand la lecture est en pause</string>
- <string name="pref_compact_notification_buttons_title">Définir les boutons de l\'écran de verrouillage</string>
- <string name="pref_compact_notification_buttons_sum">Change les boutons de lecture sur l\'écran de verrouillage. Le bouton de lecture/pause est toujours affiché.</string>
+ <string name="pref_compact_notification_buttons_title">Boutons pour la notification réduite</string>
+ <string name="pref_compact_notification_buttons_sum">Définir les boutons de lecture quand la notification est réduite. Le bouton de lecture/pause est toujours affiché.</string>
<string name="pref_compact_notification_buttons_dialog_title">Choisir un maximum de %1$d éléments</string>
<string name="pref_compact_notification_buttons_dialog_error">Vous ne pouvez pas choisir plus de %1$d éléments.</string>
<string name="pref_lockscreen_background_title">Changer l’arrière plan de l\'écran de verrouillage</string>
<string name="pref_lockscreen_background_sum">Placer l\'image de l’épisode en arrière plan de l\'écran de verrouillage. Cela aura aussi pour effet de montrer l\'image dans les autres applications.</string>
- <string name="pref_showDownloadReport_title">Afficher le rapport des téléchargements</string>
+ <string name="pref_showDownloadReport_title">Le téléchargement a échoué</string>
<string name="pref_showDownloadReport_sum">Si les téléchargements échouent, générer un rapport détaillé des échecs.</string>
- <string name="pref_showAutoDownloadReport_title">Rapport du téléchargement automatique</string>
+ <string name="pref_showAutoDownloadReport_title">Le téléchargement automatique est terminé</string>
<string name="pref_showAutoDownloadReport_sum">Afficher une notification pour les épisodes téléchargés automatiquement.</string>
<string name="pref_expand_notify_unsupport_toast">Les versions d\'Android antérieures à 4.1 ne sont pas compatibles avec les notifications élargies</string>
<string name="pref_enqueue_location_title">Emplacement des épisodes téléchargés</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Ajouter à la liste après téléchargement</string>
<string name="pref_enqueue_downloaded_summary">Mettre les épisodes dans la la liste de lecture après téléchargement</string>
<string name="media_player_builtin">Lecteur natif d\'Android</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (recommendé)</string>
<string name="media_player_switch_to_exoplayer">Utiliser ExoPlayer pour la lecture</string>
<string name="media_player_switched_to_exoplayer">Lecteur changé pour ExoPlayer</string>
<string name="pref_skip_silence_title">Supprimer les silences audios</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Sélectionner une page</string>
<string name="pref_delete_removes_from_queue_title">Supprimer retire de la liste de lecture</string>
<string name="pref_delete_removes_from_queue_sum">Retirer de la liste de lecture un épisode quand son fichier est supprimé.</string>
+ <string name="pref_filter_feed_title">Filtre des abonnements</string>
+ <string name="pref_filter_feed_sum">Filtrer les abonnements dans le volet de navigation et dans l\'écran des abonnements.</string>
+ <string name="no_filter_label">Aucun</string>
+ <string name="subscriptions_are_filtered">Les abonnements sont filtrés.</string>
+ <string name="subscriptions_counter_greater_zero">Compteur supérieur à zéro</string>
+ <string name="auto_downloaded">Avec téléchargement automatique</string>
+ <string name="not_auto_downloaded">Sans téléchargement automatique</string>
+ <string name="kept_updated">Maintenu à jour</string>
+ <string name="not_kept_updated">Non maintenu à jour</string>
<!--About screen-->
<string name="about_pref">À propos</string>
<string name="antennapod_version">Version d\'AntennaPod</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Transférer les abonnements, les épisodes écoutés et la liste de lecture sur un autre appareil</string>
<string name="database_import_summary">Importer une base de données AntennaPod d\'un autre appareil</string>
<string name="opml_import_label">Importer un fichier OPML</string>
+ <string name="opml_add_podcast_label">Importer une liste de podcasts (fichier OPML)</string>
<string name="opml_reader_error">Une erreur s\'est produite pendant la lecture du fichier OPML :</string>
<string name="opml_import_error_no_file">Aucun fichier sélectionné !</string>
<string name="select_all_label">Tout choisir</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">Le fichier a été exporté dans :\n\n%1$s</string>
<string name="opml_import_ask_read_permission">L\'accès au stockage externe est requis pour lire le fichier OPML</string>
<string name="import_select_file">Sélectionner le fichier à importer</string>
- <string name="import_ok">Import réussi.\n\nAppuyer sur OK pour redémarrer AntennaPod</string>
+ <string name="successful_import_label">Import réussi</string>
+ <string name="import_ok">Appuyer sur OK pour redémarrer AntennaPod</string>
<string name="import_no_downgrade">La base de données a été exportée avec une version plus récente d\'AntennaPod. L\'application actuelle ne sait pas comment l\'importer.</string>
<string name="favorites_export_label">Exporter les favoris</string>
<string name="favorites_export_summary">Exporter les favoris dans un fichier</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Diminuer la vitesse</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Vidéo</string>
- <string name="navigate_upwards_label">Naviguer vers le haut</string>
<string name="status_downloading_label">L\'épisode est en train d\'être téléchargé</string>
<string name="in_queue_label">L\'épisode est dans la liste de lecture</string>
<string name="is_favorite_label">L\'épisode a été ajouté aux favoris</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Maintenir à jour</string>
<string name="keep_updated_summary">Inclure ce podcast lors de la mise à jour des podcasts</string>
<string name="auto_download_disabled_globally">Le téléchargement automatique n\'est pas activé dans les préférences</string>
+ <string name="statistics_listened_for">Temps d\'écoute :</string>
+ <string name="statistics_episodes_on_device">Episodes sur l\'appareil :</string>
+ <string name="statistics_space_used">Place utilisée :</string>
+ <string name="statistics_view_all">Voir les statistiques pour tous les podcasts »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Mise à jour de la base de données</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Trouver un podcast...</string>
<string name="search_itunes_label">Chercher sur iTunes</string>
+ <string name="search_podcastindex_label">Chercher sur Podcastindex.org</string>
<string name="search_fyyd_label">Chercher sur fyyd</string>
<string name="advanced">Avancé</string>
- <string name="add_podcast_by_url">Ajouter un podcast à partir de son lien</string>
+ <string name="add_podcast_by_url">Ajouter un lien RSS</string>
<string name="browse_gpoddernet_label">Chercher sur gpodder.net</string>
<string name="discover">Découvrir</string>
+ <string name="discover_hide">Ne pas montrer</string>
+ <string name="discover_is_hidden">Vous avez choisi de cacher les suggestions.</string>
<string name="discover_more">plus »</string>
- <string name="search_powered_by">Recherche avec %1$s</string>
+ <string name="discover_powered_by_itunes">Suggestions de iTunes</string>
+ <string name="search_powered_by">Résultats de %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Ajouter un dossier</string>
+ <string name="local_folder">Dossier local</string>
+ <string name="reconnect_local_folder">Se reconnecter au dossier</string>
+ <string name="reconnect_local_folder_warning">En cas de refus de permission vous pouvez utiliser cette option pour vous reconnecter au même dossier. Ne sélectionnez pas un autre dossier.</string>
+ <string name="local_feed_description">Ce podcast a été crée à partir d\'un dossier ajouté à AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Impossible d\'ouvrir le gestionnaire de fichier</string>
<string name="filter">Filtrer</string>
<!--Episodes apply actions-->
<string name="all_label">Tous</string>
<string name="selected_all_label">Tous les épisodes ont été sélectionné</string>
- <string name="none_label">Aucun</string>
+ <string name="select_none_label">Aucun</string>
<string name="deselected_all_label">Tous les épisodes ont été désélectionné</string>
<string name="played_label">Lus</string>
<string name="selected_played_label">Episodes lus sélectionnés</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Episodes téléchargés sélectionnés</string>
<string name="not_downloaded_label">Non téléchargés</string>
<string name="selected_not_downloaded_label">Épisodes non téléchargés sélectionnés</string>
- <string name="queued_label">Dans la liste de lecture</string>
<string name="selected_queued_label">Épisodes présents dans la liste de lecture sélectionnés</string>
- <string name="not_queued_label">Pas dans la liste de lecture</string>
<string name="selected_not_queued_label">Episodes absents de la liste de lecture sélectionnés</string>
- <string name="has_media">Avec média</string>
<string name="selected_has_media_label">Sélectionner les épisodes avec des médias</string>
+ <string name="hide_is_favorite_label">Est un favori</string>
+ <string name="not_favorite">N\'est pas un favori</string>
+ <string name="hide_downloaded_episodes_label">Téléchargé</string>
+ <string name="hide_not_downloaded_episodes_label">Non téléchargé</string>
+ <string name="queued_label">Dans la liste de lecture</string>
+ <string name="not_queued_label">Pas dans la liste de lecture</string>
+ <string name="has_media">Avec média</string>
+ <string name="no_media">Sans média</string>
+ <string name="hide_paused_episodes_label">En pause</string>
+ <string name="not_paused">Pas en en pause</string>
+ <string name="hide_played_episodes_label">Lu</string>
+ <string name="not_played">Non lu</string>
<!--Sort-->
<string name="sort_title_a_z">Titre (A \u2192 Z)</string>
<string name="sort_title_z_a">Titre (Z \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Laissez moi tranquille</string>
<string name="rating_later_label">Rappelez le moi plus tard</string>
<string name="rating_now_label">Okay, c\'est parti !</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Inclure :</string>
+ <string name="share_playback_position_dialog_label">Position de lecture</string>
+ <string name="share_dialog_media_file_url_label">Lien du fichier de l\'épisode</string>
+ <string name="share_dialog_episode_website_label">Lien de la page web de l\'épisode</string>
+ <string name="share_dialog_media_file_label">Fichier de l\'épisode</string>
<!--Audio controls-->
<string name="audio_controls">Contrôles audio</string>
<string name="playback_speed">Vitesse de lecture</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Lecture en cours</string>
<string name="notification_channel_playing_description">Permet de contrôler la lecture. C\'est la notification principale pendant la lecture d\'un podcast.</string>
<string name="notification_channel_error">Erreurs</string>
- <string name="notification_channel_error_description">S\'affiche en cas de problème. Par exemple, un téléchargement ou une synchronisation qui échoue.</string>
+ <string name="notification_channel_error_description">S\'affiche quand quelque chose c\'est mal passé. Par exemple, un téléchargement ou une mise à jour de flux qui échoue.</string>
+ <string name="notification_channel_sync_error">Erreurs de synchronisation</string>
+ <string name="notification_channel_sync_error_description">S\'affiche quand la synchronisation avec gpodder échoue.</string>
<string name="notification_channel_auto_download">Téléchargement automatique</string>
<string name="notification_channel_episode_auto_download">S\'affiche lorsque des épisodes ont été téléchargés automatiquement.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-gl/strings.xml b/core/src/main/res/values-gl/strings.xml
index a2756cf07..4f3d385bc 100644
--- a/core/src/main/res/values-gl/strings.xml
+++ b/core/src/main/res/values-gl/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Acadouse o límite de espazo na caché de episodios. Podes incrementalo nos Axustes do tamaño da caché.</string>
<string name="playback_statistics_label">Reprodución</string>
<string name="download_statistics_label">Descargas</string>
+ <string name="notification_pref_fragment">Notificacións</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Tempo total dos podcast reproducidos:</string>
+ <string name="total_time_listened_to_podcasts">Duración total dos episodios reproducidos:</string>
<string name="statistics_details_dialog">%1$d de %2$d episodios iniciados.\n\nReproducidos %3$s de %4$s.</string>
<string name="statistics_mode">Modo de estatísticas</string>
<string name="statistics_mode_normal">Calcular a duración que foi realmente reproducida. Reproducir dúas veces conta dobre, mentres que marcar como lido non conta</string>
- <string name="statistics_mode_count_all">Sumar todos os podcast marcados como reproducidos</string>
+ <string name="statistics_mode_count_all">Suma todos os episodios marcados como reproducidos</string>
<string name="statistics_speed_not_counted">Aviso: A velocidade de reprodución non se ten en conta en ningún caso.</string>
<string name="statistics_reset_data">Restablecer estatísticas</string>
<string name="statistics_reset_data_msg">Esto borrará o histórico de escoita de todos os episodios. Seguro que queres borralo?</string>
+ <string name="statistics_counting_since">Desde %s,\nescoitaches</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Tamaño dos podcasts descargados:</string>
+ <string name="total_size_downloaded_podcasts">Tamaño total dos episodios no dispositivo:</string>
<!--Main activity-->
<string name="drawer_open">Abrir menú</string>
<string name="drawer_close">Pechar menú</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Número de episodios non reproducidos</string>
<string name="drawer_feed_counter_downloaded">Número de episodios descargados</string>
<string name="drawer_feed_counter_none">Ningún</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Non se atopan apps compatibles</string>
<!--Webview actions-->
<string name="open_in_browser_label">Abrir no navegador</string>
<string name="copy_url_label">Copiar URL</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Axustes do podcast</string>
<string name="rename_feed_label">Mudar nome do podcast</string>
<string name="remove_feed_label">Eliminar o podcast</string>
- <string name="share_label">Compartir...</string>
- <string name="share_link_label">Compartir a URL do episodio</string>
- <string name="share_link_with_position_label">Compartir a URL do ficheiro do episodio coa posición</string>
+ <string name="share_label">Compartir</string>
+ <string name="share_label_with_ellipses">Compartir...</string>
<string name="share_file_label">Compartir ficheiro</string>
- <string name="share_website_url_label">Compartir URL da web</string>
- <string name="share_feed_url_label">Compartir URL da fonte</string>
- <string name="share_item_url_label">Compartir a URL do ficheiro multimedia</string>
- <string name="share_item_url_with_position_label">Compartir a URL do ficheiro multimedia coa posición</string>
+ <string name="share_website_url_label">Enderezo sitio web</string>
+ <string name="share_feed_url_label">URL da fonte do podcast</string>
<string name="feed_delete_confirmation_msg">Por favor, confirme que quere eliminar o podcast \"%1$s\" e TODOS os seus episodios (incluídos os xa descargados).</string>
+ <string name="feed_delete_confirmation_local_msg">Confirma que queres eliminar o podcast \"%1$s\". Os ficheiros no cartafol local non serán eliminados.</string>
<string name="feed_remover_msg">Eliminando o podcast</string>
<string name="load_complete_feed">Actualizar o podcast completo</string>
<string name="multi_select">Selección múltiple</string>
<string name="select_all_above">Seleccionar todo arriba</string>
<string name="select_all_below">Seleccionar todo debaixo</string>
<string name="hide_unplayed_episodes_label">Non reproducido</string>
- <string name="hide_paused_episodes_label">En pausa</string>
- <string name="hide_played_episodes_label">Reproducido</string>
<string name="hide_queued_episodes_label">Na cola</string>
<string name="hide_not_queued_episodes_label">Fora da cola</string>
- <string name="hide_downloaded_episodes_label">Descargado</string>
- <string name="hide_not_downloaded_episodes_label">Non descargado</string>
<string name="hide_has_media_label">Ten multimedia</string>
- <string name="hide_is_favorite_label">É favorito</string>
<string name="filtered_label">Filtrado</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Erro na última actualización</string>
<string name="open_podcast">Abrir podcast</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Borrar</string>
<string name="delete_failed">Non se puido eliminar o ficheiro. Reiniciar o dispositivo podería axudar.</string>
<string name="delete_episode_label">Eliminar episodio</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d episodio eliminado.</item>
- <item quantity="other">%d episodios eliminados.</item>
- </plurals>
<string name="remove_new_flag_label">Quitar marca \"novo\"</string>
<string name="removed_new_flag_label">Eliminouse marca \"novo\"</string>
<string name="mark_read_label">Marcar como reproducido</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Procesando as descargas</string>
<string name="download_notification_title">Descargando datos do podcast</string>
- <string name="download_report_content">%1$d descargas con éxito, %2$d fallaron</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d descarga correcta, %d fallou</item>
+ <item quantity="other">%d descargas correctas, %d fallaron</item>
+ </plurals>
<string name="download_log_title_unknown">Título descoñecido</string>
<string name="download_type_feed">Fonte</string>
<string name="download_type_media">Ficheiro de medios</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">A descarga con datos móbiles está desactivada nos axustes.\n\nQuere permitir a descarga temporalmente?\n\n <small>A súa decisión lembrarase durante 10 minutos.</small></string>
<string name="confirm_mobile_streaming_notification_title">Confirmar retransmisión Móbil</string>
<string name="confirm_mobile_streaming_notification_message">Desactivouse nos axustes Retransmitir mediante a conexión de datos. Toque para retransmitir igualmente.</string>
- <string name="confirm_mobile_streaming_button_always">Permitir sempre</string>
+ <string name="confirm_mobile_streaming_button_always">Sempre</string>
+ <string name="confirm_mobile_streaming_button_once">Unha vez</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Engadir a cola</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Permitir temporalmente</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Descargar engadido</string>
<string name="no_playback_plugin_title">Engadido non instalado</string>
<string name="no_playback_plugin_or_sonic_msg">Recomendamos activar o reprodutor Sonic incluído para que funcione ben a velocidade variable de reprodución.</string>
- <string name="set_playback_speed_label">Velocidade de reproducións</string>
<string name="enable_sonic">Habilitar Sonic</string>
+ <string name="speed_presets">Axustes establecidos</string>
+ <string name="preset_already_exists">%1$.2fx xa está gardado como un axuste previo.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Sen episodios na cola</string>
<string name="no_items_label">Engade un episodio descargándoo, ou mantén preso un episodio e escolle \"Engadir a cola\".</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">cada %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">as %1$s</string>
<string name="pref_followQueue_title">Reprodución continua</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Desconexión de auriculares</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Auriculares ou Bluetooth desconectados</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Reconexión de auriculares</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Reconexión bluetooth</string>
<string name="pref_stream_over_download_title">Preferir Difusión</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Descarga de episodio</string>
<string name="pref_mobileUpdate_streaming">Retransmisión</string>
<string name="user_interface_label">Interface de usuaria</string>
- <string name="user_interface_sum">Aparencia, Orde das subscricións, Bloqueo de pantalla</string>
+ <string name="user_interface_sum">Aparencia, Subscricións, Bloqueo de pantalla</string>
<string name="pref_set_theme_title">Escolle o decorado</string>
<string name="pref_nav_drawer_items_title">Escoller os elementos da Caixa de navegación</string>
<string name="pref_nav_drawer_items_sum">Cambie os elementos que aparecerán na Caixa de navegación</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Forzar sincronización completa</string>
<string name="pref_gpodnet_full_sync_sum">Sincronizar todas as subscricións e estados de episodios con gpodder.net</string>
<string name="pref_gpodnet_login_status"><![CDATA[Conectada como <i>%1$s</i> co dispositivo <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Mostrar notificacións de erros na sincronización.</string>
+ <string name="pref_gpodnet_notifications_title">Fallou a sincronización</string>
<string name="pref_gpodnet_notifications_sum">Esta preferencia non se aplica a fallos na autenticación.</string>
- <string name="pref_playback_speed_title">Velocidades de reprodución</string>
- <string name="pref_playback_speed_sum">Personaliza a velocidade variable de reprodución de audio</string>
+ <string name="pref_playback_speed_sum">Personaliza as velocidades dispoñibles para reprodución de velocidade variable</string>
<string name="pref_feed_playback_speed_sum">A velocidade para reproducir o contido dos episodios deste podcast</string>
<string name="pref_feed_skip">Salto automático</string>
<string name="pref_feed_skip_sum">Saltar introducións e créditos finais.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Isto expande as notificacións para mostrar os botóns de reprodución</string>
<string name="pref_persistNotify_title">Controles persistentes de reprodución</string>
<string name="pref_persistNotify_sum">Manter notificación e controles na pantalla de bloqueo cando a reprodución está pausada.</string>
- <string name="pref_compact_notification_buttons_title">Establecer botóns de pantalla de bloqueo</string>
- <string name="pref_compact_notification_buttons_sum">Cambiar os botóns de reprodución na pantalla de bloqueo. O botón reproducir/pausa sempre se inclúe.</string>
+ <string name="pref_compact_notification_buttons_title">Establecer botóns de notificación compactos</string>
+ <string name="pref_compact_notification_buttons_sum">Cambia os botóns de reprodución cando a notificación está comprimida. O botón reproducir/pausar sempre se inclúe.</string>
<string name="pref_compact_notification_buttons_dialog_title">Escolle un máximo de %1$d elementos</string>
<string name="pref_compact_notification_buttons_dialog_error">Só podes selecionar un máximo de %1$d elementos.</string>
<string name="pref_lockscreen_background_title">Establecer fondo da pantalla de bloqueo</string>
<string name="pref_lockscreen_background_sum">Establecer o fondo de pantalla de bloqueo coa imaxe do episodio actual. Como consecuencia, esto tamén mostrará a imaxe en aplicacións de terceiros.</string>
- <string name="pref_showDownloadReport_title">Mostrar informe de descarga</string>
+ <string name="pref_showDownloadReport_title">Fallou a descarga</string>
<string name="pref_showDownloadReport_sum">Si falla a descarga, xerar un informe que informe dos detalles do fallo.</string>
- <string name="pref_showAutoDownloadReport_title">Mostra informe de descarga automática</string>
+ <string name="pref_showAutoDownloadReport_title">Descarga automática completada</string>
<string name="pref_showAutoDownloadReport_sum">Mostra unha notificación para os episodios descargados automáticamente.</string>
<string name="pref_expand_notify_unsupport_toast">As versións de Android anteriores a 4.1 non teñen soporte para notificacións expandidas.</string>
<string name="pref_enqueue_location_title">Situación na cola</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Foron descargados os elementos da cola</string>
<string name="pref_enqueue_downloaded_summary">Engadir os episodios descargados a cola</string>
<string name="media_player_builtin">Reprodutor android nativo</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (recomendado)</string>
<string name="media_player_switch_to_exoplayer">Cambiar a ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Cambiaches a ExoPlayer.</string>
<string name="pref_skip_silence_title">Saltar silencio no Audio</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Seleccionar páxina</string>
<string name="pref_delete_removes_from_queue_title">Eliminar quita da Cola</string>
<string name="pref_delete_removes_from_queue_sum">Eliminar automáticamente un episodio da cola cando se elimina.</string>
+ <string name="pref_filter_feed_title">Filtro da subscrición</string>
+ <string name="pref_filter_feed_sum">Filtra as subscricións no panel de navegación e pantalla de subscricións.</string>
+ <string name="no_filter_label">Nada</string>
+ <string name="subscriptions_are_filtered">As subscricións están filtradas.</string>
+ <string name="subscriptions_counter_greater_zero">Contador maior a cero</string>
+ <string name="auto_downloaded">Descargado automáticamente</string>
+ <string name="not_auto_downloaded">Non descargado automáticamente</string>
+ <string name="kept_updated">Manter actualizado</string>
+ <string name="not_kept_updated">Non manter actualizado</string>
<!--About screen-->
<string name="about_pref">Sobre</string>
<string name="antennapod_version">Versión AntennaPod</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Mover as subscricións, episodios escoitados e cola a AntennaPod en outro dispositivo</string>
<string name="database_import_summary">Importar a base de datos AntennaPod desde outro dispositivo</string>
<string name="opml_import_label">Importar OPML</string>
+ <string name="opml_add_podcast_label">Importar lista de podcast (OPML)</string>
<string name="opml_reader_error">Houbo un fallo ao ler o documento OPML:</string>
<string name="opml_import_error_no_file">Non hai ficheiro seleccionado!</string>
<string name="select_all_label">Seleccionar todo</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">Escribeuse o ficheiro exportado en:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Precísase acceso ao almacenamento externo para ler o ficheiro OPML</string>
<string name="import_select_file">Escolle o ficheiro a importar</string>
- <string name="import_ok">Importación correcta.\n\nPulse OK para reiniciar AntennaPod</string>
+ <string name="successful_import_label">Importación correcta</string>
+ <string name="import_ok">Preme OK para reiniciar AntennaPod</string>
<string name="import_no_downgrade">A base de datos foi exportada cunha versión máis recente de AntennaPod. A instalación actual non sabe como xestionar este ficheiro.</string>
<string name="favorites_export_label">Exportar favoritos</string>
<string name="favorites_export_summary">Exportar os favoritos a un ficheiro</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Diminuír velocidade</string>
<string name="media_type_audio_label">Son</string>
<string name="media_type_video_label">Vídeo</string>
- <string name="navigate_upwards_label">Navegar hacia arriba</string>
<string name="status_downloading_label">Estase a descargar o episodio</string>
<string name="in_queue_label">O episodio está na cola</string>
<string name="is_favorite_label">Episodio marcado como favorito</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Manter actualizado</string>
<string name="keep_updated_summary">Incluír este podcast ao (auto-)actualizar todos os podcast</string>
<string name="auto_download_disabled_globally">A descarga automática está desactivada nos axustes principais de AntennaPod</string>
+ <string name="statistics_listened_for">Escoitado durante:</string>
+ <string name="statistics_episodes_on_device">Episodios no dispositivo:</string>
+ <string name="statistics_space_used">Espazo utilizado:</string>
+ <string name="statistics_view_all">Vista para todos os podcats »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Actualizando a base de datos</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Buscar podcast...</string>
<string name="search_itunes_label">Buscar en iTunes</string>
+ <string name="search_podcastindex_label">Buscar en Podcastindex.org</string>
<string name="search_fyyd_label">Buscar en fyyd</string>
<string name="advanced">Avanzado</string>
- <string name="add_podcast_by_url">Engadir Podcast por URL</string>
+ <string name="add_podcast_by_url">Engadir Podcast polo enderezo RSS</string>
<string name="browse_gpoddernet_label">Buscar en gpodder.net</string>
<string name="discover">Descubrir</string>
+ <string name="discover_hide">Agochar</string>
+ <string name="discover_is_hidden">Elexiches agochar as suxestións.</string>
<string name="discover_more">máis »</string>
- <string name="search_powered_by">Busca xestionada por %1$s</string>
+ <string name="discover_powered_by_itunes">Suxestións de iTunes</string>
+ <string name="search_powered_by">Resultados por %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Engadir cartafol local</string>
+ <string name="local_folder">Cartafol local</string>
+ <string name="reconnect_local_folder">Reconectar cartafol local</string>
+ <string name="reconnect_local_folder_warning">En caso de faltar permisos, podes usar esto para reconectar o exactamente o mesmo cartafol. Non elixas outro cartafol.</string>
+ <string name="local_feed_description">O podcast virtual foi creado ó engadir un cartafol a AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Non foi posible abrir o xestor de ficheiros</string>
<string name="filter">Filtrado</string>
<!--Episodes apply actions-->
<string name="all_label">Todo</string>
<string name="selected_all_label">Seleccionar todos os episodios</string>
- <string name="none_label">Ningún</string>
+ <string name="select_none_label">Nada</string>
<string name="deselected_all_label">Todos os episodios deseleccionados</string>
<string name="played_label">Reproducidos</string>
<string name="selected_played_label">Episodios reproducidos seleccionados</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Episodios descargados seleccionados</string>
<string name="not_downloaded_label">Non descargados</string>
<string name="selected_not_downloaded_label">Episodios non descargados seleccionados</string>
- <string name="queued_label">Na cola</string>
<string name="selected_queued_label">Seleccionados os episodios na cola</string>
- <string name="not_queued_label">Fora da cola</string>
<string name="selected_not_queued_label">Seleccionados os episodios fora da cola</string>
- <string name="has_media">Teñen medios</string>
<string name="selected_has_media_label">Seleccionados episodios que inclúen medios</string>
+ <string name="hide_is_favorite_label">É favorito</string>
+ <string name="not_favorite">Non favorito</string>
+ <string name="hide_downloaded_episodes_label">Descargado</string>
+ <string name="hide_not_downloaded_episodes_label">Non descargado</string>
+ <string name="queued_label">Na cola</string>
+ <string name="not_queued_label">Fora da cola</string>
+ <string name="has_media">Teñen medios</string>
+ <string name="no_media">Sen multimedia</string>
+ <string name="hide_paused_episodes_label">En pausa</string>
+ <string name="not_paused">Non pausado</string>
+ <string name="hide_played_episodes_label">Reproducido</string>
+ <string name="not_played">Non reproducido</string>
<!--Sort-->
<string name="sort_title_a_z">Título (A \u2192 Z)</string>
<string name="sort_title_z_a">Título (Z \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Pasa de min oh!</string>
<string name="rating_later_label">Lembrar máis tarde</string>
<string name="rating_now_label">Trato, fagámolo!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Incluír:</string>
+ <string name="share_playback_position_dialog_label">Posición da reprodución</string>
+ <string name="share_dialog_media_file_url_label">Enderezo do ficheiro multimedia</string>
+ <string name="share_dialog_episode_website_label">Sitio web do episodio</string>
+ <string name="share_dialog_media_file_label">Ficheiro multimedia</string>
<!--Audio controls-->
<string name="audio_controls">Controis de audio</string>
<string name="playback_speed">Velocidade de reprodución</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Soando agora</string>
<string name="notification_channel_playing_description">Permite controlar a reprodución. Esta é a notificación principal que verá mentras reproduce un podcast.</string>
<string name="notification_channel_error">Fallos</string>
- <string name="notification_channel_error_description">Mostrado si algo falla, por exemplo si a descarga ou a sincronización con gpodder fallan.</string>
+ <string name="notification_channel_error_description">Mostrar se algo fallou, por exemplo se a descarga ou a actualización da fonte fallaron.</string>
+ <string name="notification_channel_sync_error">Erros durante a sincronización</string>
+ <string name="notification_channel_sync_error_description">Mostrado cando falla a sincronización con gpodder.</string>
<string name="notification_channel_auto_download">Descargas Automáticas</string>
<string name="notification_channel_episode_auto_download">Mostrado cando os episodios se descargaron automáticamente.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-hu/strings.xml b/core/src/main/res/values-hu/strings.xml
index 55f7a5dbd..5f90546e3 100644
--- a/core/src/main/res/values-hu/strings.xml
+++ b/core/src/main/res/values-hu/strings.xml
@@ -25,17 +25,18 @@
<string name="episode_cache_full_message">Az epizódok tárolására megadott maximális tárhely megtelt. A mérete a beállításokban növelhető meg.</string>
<string name="playback_statistics_label">Lejátszás</string>
<string name="download_statistics_label">Letöltések</string>
+ <string name="notification_pref_fragment">Értesítések</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">A lejátszott podcastok összideje:</string>
+ <string name="total_time_listened_to_podcasts">A lejátszott epizódok összideje:</string>
<string name="statistics_details_dialog">%1$d/%2$d epizód elindítva.\n\n%3$s/%4$s lejátszva.</string>
<string name="statistics_mode">Statisztikai mód</string>
<string name="statistics_mode_normal">A tényleges lejátszási idő számítása. A kétszeri lejátszás kétszer lesz számolva, míg a lejátszottként megjelölés nem számít bele</string>
- <string name="statistics_mode_count_all">Az összes lejátszottnak jelölt podcast összeszámolása</string>
+ <string name="statistics_mode_count_all">Az összes lejátszottnak jelölt epizód összeszámolása</string>
<string name="statistics_speed_not_counted">Megjegyzés: a lejátszási sebesség nem lesz beleszámítva.</string>
<string name="statistics_reset_data">Statisztikai adatok alaphelyzetbe állítása</string>
<string name="statistics_reset_data_msg">Ez törli az összes epizód lejátszási hosszát. Biztos, hogy folytatja?</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">A letöltött podcastok összmérete:</string>
+ <string name="total_size_downloaded_podcasts">Az eszközön lévő epizódok összmérete:</string>
<!--Main activity-->
<string name="drawer_open">Menü megnyitása</string>
<string name="drawer_close">Menü bezárása</string>
@@ -49,6 +50,7 @@
<string name="drawer_feed_counter_unplayed">Nem játszott epizódok száma</string>
<string name="drawer_feed_counter_downloaded">Letöltött epizódok száma</string>
<string name="drawer_feed_counter_none">Nincs</string>
+ <!--Bug report activity-->
<!--Webview actions-->
<string name="open_in_browser_label">Megnyitás böngészőben</string>
<string name="copy_url_label">URL másolása</string>
@@ -124,29 +126,21 @@
<string name="feed_settings_label">Podcast beállítások</string>
<string name="rename_feed_label">Podcast átnevezése</string>
<string name="remove_feed_label">Podcast eltávolítása</string>
- <string name="share_label">Megosztás…</string>
- <string name="share_link_label">Epizód URL megosztása</string>
- <string name="share_link_with_position_label">Epizód URL megosztása pozícióval</string>
+ <string name="share_label">Megosztás</string>
+ <string name="share_label_with_ellipses">Megosztás…</string>
<string name="share_file_label">Fájl megosztása</string>
- <string name="share_website_url_label">Honlap URL megosztása</string>
- <string name="share_feed_url_label">Podcast URL megosztása</string>
- <string name="share_item_url_label">Médiafájl URL megosztása</string>
- <string name="share_item_url_with_position_label">Médiafájl URL megosztása pozícióval</string>
+ <string name="share_website_url_label">Webcím</string>
<string name="feed_delete_confirmation_msg">Erősítse meg, hogy törli a(z) „%1$s” podcastot, és az ÖSSZES epizódját (a letöltött epizódokat is beleértve).</string>
+ <string name="feed_delete_confirmation_local_msg">Erősítse meg, hogy törli a(z) „%1$s” podcastot. A helyi forrásmappában lévő fájlok nem törlődnek.</string>
<string name="feed_remover_msg">Podcast eltávolítása</string>
<string name="load_complete_feed">Teljes podcast frissítése</string>
<string name="multi_select">Több kiválasztása</string>
<string name="select_all_above">Az összes felette lévő kiválasztása</string>
<string name="select_all_below">Az összes alatta lévő kiválasztása</string>
<string name="hide_unplayed_episodes_label">Nem lejátszott</string>
- <string name="hide_paused_episodes_label">Szüneteltetett</string>
- <string name="hide_played_episodes_label">Lejátszott</string>
<string name="hide_queued_episodes_label">Sorbaállított</string>
<string name="hide_not_queued_episodes_label">Nem sorbaállított</string>
- <string name="hide_downloaded_episodes_label">Letöltött</string>
- <string name="hide_not_downloaded_episodes_label">Nem letöltött</string>
<string name="hide_has_media_label">Médiát tartalmaz</string>
- <string name="hide_is_favorite_label">Kedvenc</string>
<string name="filtered_label">Szűrt</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} A legutóbbi frissítés sikertelen</string>
<string name="open_podcast">Podcast megnyitása</string>
@@ -163,10 +157,6 @@
<string name="delete_label">Törlés</string>
<string name="delete_failed">A fájl nem törölhető. Az eszköz újraindítása segíthet a probléma megoldásában.</string>
<string name="delete_episode_label">Epizód törlése</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d epizód törölve. </item>
- <item quantity="other">%d epizód törölve.</item>
- </plurals>
<string name="remove_new_flag_label">Az „új” jelző eltávolítása</string>
<string name="removed_new_flag_label">Az „új” jelző eltávolítva</string>
<string name="mark_read_label">Megjelölés lejátszottként</string>
@@ -238,7 +228,10 @@
</plurals>
<string name="downloads_processing">Letöltések feldolgozása</string>
<string name="download_notification_title">Podcast adatok letöltése</string>
- <string name="download_report_content">%1$d letöltés sikeres, %2$d sikertelen</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d letöltés sikeres, %d sikertelen</item>
+ <item quantity="other">%d letöltés sikeres, %d sikertelen</item>
+ </plurals>
<string name="download_log_title_unknown">Ismeretlen cím</string>
<string name="download_type_feed">Csatorna</string>
<string name="download_type_media">Médiafájl</string>
@@ -251,7 +244,8 @@
<string name="confirm_mobile_download_dialog_message">A mobil adatkapcsolaton történő letöltés ki van kapcsolva a beállításokban.\n\nIdeiglenesen engedélyezi a letöltést?\n\n<small>A választása 10 percig lesz megjegyezve.</small></string>
<string name="confirm_mobile_streaming_notification_title">Mobil adatátvitel megerősítése</string>
<string name="confirm_mobile_streaming_notification_message">A mobil adatkapcsolaton történő adatátvitel ki van kapcsolva a beállításokban. Koppintson ha mindenképp szeretné.</string>
- <string name="confirm_mobile_streaming_button_always">Engedélyezés mindig</string>
+ <string name="confirm_mobile_streaming_button_always">Mindig</string>
+ <string name="confirm_mobile_streaming_button_once">Egyszer</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Sorbaállítás</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Engedélyezés átmenetileg</string>
<!--Mediaplayer messages-->
@@ -297,7 +291,6 @@
<string name="download_plugin_label">Bővítmény letöltése</string>
<string name="no_playback_plugin_title">A bővítmény nincs telepítve</string>
<string name="no_playback_plugin_or_sonic_msg">A változó lejátszási sebesség működéséhez azt javasoljuk, hogy engedélyezze a beépített Sonic médialejátszót.</string>
- <string name="set_playback_speed_label">Lejátszási sebesség</string>
<string name="enable_sonic">Sonic engedélyezése</string>
<!--Empty list labels-->
<string name="no_items_header_label">Nincsenek epizódok a sorban</string>
@@ -371,7 +364,6 @@
<string name="pref_autoUpdateIntervallOrTime_every">minden %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">ekkor: %1$s</string>
<string name="pref_followQueue_title">Folyamatos lejátszás</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Fejhallgató leválasztása</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Fejhallgató újracsatlakoztatása</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth újracsatlakoztatás</string>
<string name="pref_stream_over_download_title">Adatátvitel előnyben részesítése</string>
@@ -384,7 +376,7 @@
<string name="pref_mobileUpdate_episode_download">Epizódletöltés</string>
<string name="pref_mobileUpdate_streaming">Adatátvitel</string>
<string name="user_interface_label">Felhasználói felület</string>
- <string name="user_interface_sum">Megjelenés, feliratkozási sorrend, képernyőzár</string>
+ <string name="user_interface_sum">Megjelenés, feliratkozások, képernyőzár</string>
<string name="pref_set_theme_title">Téma kiválasztása</string>
<string name="pref_nav_drawer_items_title">Navigációs fiók elemeinek beállítása</string>
<string name="pref_nav_drawer_items_sum">A navigációs fiókban megjelenő elemek módosítása.</string>
@@ -423,10 +415,9 @@
<string name="pref_gpodnet_full_sync_title">Teljes szinkronizáció kényszerítése</string>
<string name="pref_gpodnet_full_sync_sum">Az összes feliratkozásának és epizódállapotainak szinkronizálása a gpodder.nettel.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Bejelentkezve mint <i>%1$s</i>, a(z) <i>%2$s</i> eszközzel]]></string>
- <string name="pref_gpodnet_notifications_title">Szinkronizálási hibaértesítések megjelenítése</string>
+ <string name="pref_gpodnet_notifications_title">Szinkronizálás sikertelen</string>
<string name="pref_gpodnet_notifications_sum">Ez a beállítás a hitelesítési hibákra nem érvényes.</string>
- <string name="pref_playback_speed_title">Lejátszási sebességek</string>
- <string name="pref_playback_speed_sum">A változó sebességű hanglejátszáshoz elérhető sebességek testreszabása</string>
+ <string name="pref_playback_speed_sum">A változó sebességű lejátszáshoz elérhető sebességek testreszabása</string>
<string name="pref_feed_playback_speed_sum">A podcast epizódjainak indításakor használandó lejátszási sebesség</string>
<string name="pref_feed_skip">Automatikus kihagyás</string>
<string name="pref_feed_skip_sum">Bevezetők és lezárások kihagyása</string>
@@ -446,15 +437,13 @@
<string name="pref_expandNotify_sum">Ez általában kibővíti az értesítést, hogy megjelenítse a lejátszási gombokat.</string>
<string name="pref_persistNotify_title">Állandó lejátszásvezérlők</string>
<string name="pref_persistNotify_sum">Az értesítés és a zárképernyőn megjelenő vezérlők megtartása a lejátszás szüneteltetésekor.</string>
- <string name="pref_compact_notification_buttons_title">Zárképerny-gombok beállítása</string>
- <string name="pref_compact_notification_buttons_sum">A zárképernyőn megjelenő lejátszási gombok módosítása. A lejátszás/szüneteltetés gombok mindig szerepelnek.</string>
<string name="pref_compact_notification_buttons_dialog_title">Válasszon legfeljebb %1$d elemet</string>
<string name="pref_compact_notification_buttons_dialog_error">Legfeljebb %1$d elemet választhat.</string>
<string name="pref_lockscreen_background_title">Képernyőzár háttérkép beállítása</string>
<string name="pref_lockscreen_background_sum">A képernyőzár háttérképének beállítása a jelenlegi epizód képére. Mellékhatásként, ez a harmadik féltől származó alkalmazásokban is megjeleníti a képet.</string>
- <string name="pref_showDownloadReport_title">Letöltési jelentés megtekintése</string>
+ <string name="pref_showDownloadReport_title">Letöltés sikertelen</string>
<string name="pref_showDownloadReport_sum">Ha a letöltések sikertelenek, előállít egy jelentést, amely részletezi a hibát</string>
- <string name="pref_showAutoDownloadReport_title">Automatikus letöltési jelentés megjelenítése</string>
+ <string name="pref_showAutoDownloadReport_title">Elkészült az automatikus letöltés</string>
<string name="pref_showAutoDownloadReport_sum">Értesítés megjelenítése az automatikusan letöltött epizódokhoz.</string>
<string name="pref_expand_notify_unsupport_toast">A 4.1 előtti Android verziók nem támogatják a bővített értesítéseket.</string>
<string name="pref_enqueue_location_title">Hely sorbaállítása</string>
@@ -484,6 +473,7 @@
<string name="pref_enqueue_downloaded_title">Letöltött elemek sorbaállítása</string>
<string name="pref_enqueue_downloaded_summary">Letöltött epizódok sorhoz adása</string>
<string name="media_player_builtin">Beépített androidos lejátszó</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (javasolt)</string>
<string name="media_player_switch_to_exoplayer">Váltás az ExoPlayerre</string>
<string name="media_player_switched_to_exoplayer">Átváltva az ExoPlayerre.</string>
<string name="pref_skip_silence_title">Csend kihagyása a hangokban</string>
@@ -504,6 +494,8 @@
<string name="back_button_go_to_page_title">Válasszon lapot</string>
<string name="pref_delete_removes_from_queue_title">A törlés eltávolítja a sorból</string>
<string name="pref_delete_removes_from_queue_sum">Törléskor az epizód automatikus eltávolítása a sorból.</string>
+ <string name="auto_downloaded">Automatikusan letöltve</string>
+ <string name="not_auto_downloaded">Nem automatikusan letöltve</string>
<!--About screen-->
<string name="about_pref">Névjegy</string>
<string name="antennapod_version">AntennaPod verzió</string>
@@ -553,7 +545,8 @@
<string name="export_success_sum">Az exportált fájl ide lett kiírva:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">A külső tároló elérése szükséges az OPML fájl olvasásához</string>
<string name="import_select_file">Importálandó fájl kiválasztása</string>
- <string name="import_ok">Importálás sikeres.\n\nNyomja meg az OK gombot az AntennaPod újraindításához</string>
+ <string name="successful_import_label">Importálás sikeres</string>
+ <string name="import_ok">Nyomja meg az OK gombot az AntennaPod újraindításához</string>
<string name="import_no_downgrade">Az adatbázis az AntennaPod egy újabb verziójából lett exportálva. A jelenlegi telepítése még nem tudja, hogyan kezelje ezt a fájlt.</string>
<string name="favorites_export_label">Kedvencek exportálása</string>
<string name="favorites_export_summary">Mentett kedvencek fájlba exportálása</string>
@@ -648,7 +641,6 @@
<string name="decrease_speed">Sebesség csökkentése</string>
<string name="media_type_audio_label">Hang</string>
<string name="media_type_video_label">Videó</string>
- <string name="navigate_upwards_label">Navigálás felfelé</string>
<string name="status_downloading_label">Az epizód letöltés alatt van</string>
<string name="in_queue_label">Az epizód sorba van állítva </string>
<string name="is_favorite_label">Epizód megjelölve kedvencként</string>
@@ -678,16 +670,20 @@
<string name="search_itunes_label">Keresés az iTunes-on</string>
<string name="search_fyyd_label">Keresés a fyyden</string>
<string name="advanced">Speciális</string>
- <string name="add_podcast_by_url">Podcast hozzáadása URL alapján</string>
+ <string name="add_podcast_by_url">Podcast hozzáadása RSS cím alapján</string>
<string name="browse_gpoddernet_label">A gpodder.net böngészése</string>
<string name="discover">Felfedezés</string>
+ <string name="discover_hide">Elrejtés</string>
<string name="discover_more">több »</string>
- <string name="search_powered_by">Keresés a(z) %1$s segítségével</string>
+ <string name="discover_powered_by_itunes">iTunes javaslatok</string>
+ <string name="search_powered_by">%1$s javaslatok</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Helyi mappa hozzáadása</string>
+ <string name="local_folder">Helyi mappa</string>
<string name="filter">Szűrő</string>
<!--Episodes apply actions-->
<string name="all_label">Összes</string>
<string name="selected_all_label">Összes epizód kiválasztva</string>
- <string name="none_label">Egyik sem</string>
<string name="deselected_all_label">Az összes epizód kiválasztásának megszüntetése</string>
<string name="played_label">Lejátszott</string>
<string name="selected_played_label">A lejátszott epizódok kiválasztva</string>
@@ -697,12 +693,17 @@
<string name="selected_downloaded_label">A letöltött epizódok kiválasztása</string>
<string name="not_downloaded_label">Nem letöltött</string>
<string name="selected_not_downloaded_label">A nem letöltött epizódok kiválasztása</string>
- <string name="queued_label">Sorba állított</string>
<string name="selected_queued_label">A sorba állított epizódok kiválasztva</string>
- <string name="not_queued_label">Nem sorba állított</string>
<string name="selected_not_queued_label">A nem sorba állított epizódok kiválasztva</string>
- <string name="has_media">Médiát tartalmaz</string>
<string name="selected_has_media_label">Médiát tartalmazó kiválasztott epizódok</string>
+ <string name="hide_is_favorite_label">Kedvenc</string>
+ <string name="hide_downloaded_episodes_label">Letöltött</string>
+ <string name="hide_not_downloaded_episodes_label">Nem letöltött</string>
+ <string name="queued_label">Sorba állított</string>
+ <string name="not_queued_label">Nem sorba állított</string>
+ <string name="has_media">Médiát tartalmaz</string>
+ <string name="hide_paused_episodes_label">Szüneteltetett</string>
+ <string name="hide_played_episodes_label">Lejátszott</string>
<!--Sort-->
<string name="sort_title_a_z">Cím (A \u2192 Z)</string>
<string name="sort_title_z_a">Cím (Z \u2192 A)</string>
@@ -722,6 +723,7 @@
<string name="rating_never_label">Hagyjon békén</string>
<string name="rating_later_label">Emlékeztessen később</string>
<string name="rating_now_label">Rendben, csináljuk!</string>
+ <!--Share episode dialog-->
<!--Audio controls-->
<string name="audio_controls">Hangvezérlők</string>
<string name="playback_speed">Lejátszási sebesség</string>
@@ -768,7 +770,7 @@
<string name="notification_channel_playing">Most játszott</string>
<string name="notification_channel_playing_description">Lehetővé teszi a lejátszás vezérlését. Ez a fő értesítés, amit a podcast lejátszásakor lát.</string>
<string name="notification_channel_error">Hibák</string>
- <string name="notification_channel_error_description">Akkor látszik, ha hiba történt, például ha a letöltés vagy a gpodder szinkronizálás sikertelen.</string>
+ <string name="notification_channel_sync_error">Szinkronizálási hibák</string>
<string name="notification_channel_auto_download">Automatikus letöltések</string>
<string name="notification_channel_episode_auto_download">Akkor jelenik meg, ha az epizódok automatikusan letöltésre kerültek.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-it/strings.xml b/core/src/main/res/values-it/strings.xml
index abd08d2cc..65ad90f28 100644
--- a/core/src/main/res/values-it/strings.xml
+++ b/core/src/main/res/values-it/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Il limite della cache degli episodi è stato raggiunto. Puoi aumentare la dimensione della cache nelle Impostazioni.</string>
<string name="playback_statistics_label">Riproduzione</string>
<string name="download_statistics_label">Download</string>
+ <string name="notification_pref_fragment">Notifiche</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Tempo totale di riproduzione:</string>
+ <string name="total_time_listened_to_podcasts">Tempo totale episodi riprodotti:</string>
<string name="statistics_details_dialog">%1$d di %2$d episodi iniziati.\n\nRiprodotti %3$s di %4$s.</string>
<string name="statistics_mode">Modalità di calcolo</string>
<string name="statistics_mode_normal">Tempo di riproduzione reale. Riprodurre due volte un episodio verrà contato doppio, segnarlo come riprodotto no</string>
- <string name="statistics_mode_count_all">Somma il tempo di riproduzione di tutti i podcast segnati come riprodotti</string>
+ <string name="statistics_mode_count_all">Somma tutti gli episodi segnati come riprodotti</string>
<string name="statistics_speed_not_counted">Avviso: la velocità di riproduzione non viene considerata.</string>
<string name="statistics_reset_data">Resetta statistiche</string>
<string name="statistics_reset_data_msg">Verranno eliminate le statistiche sul tempo di riproduzione di tutti gli episodi. Procedo?</string>
+ <string name="statistics_counting_since">Dal %s,\nhai riprodotto</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Dimensione totale podcast scaricati:</string>
+ <string name="total_size_downloaded_podcasts">Dimensione totale degli episodi sul dispositivo:</string>
<!--Main activity-->
<string name="drawer_open">Apri il menù</string>
<string name="drawer_close">Chiudi il menù</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Numero di episodi non riprodotti</string>
<string name="drawer_feed_counter_downloaded">Numero di episodi scaricati</string>
<string name="drawer_feed_counter_none">Nessuno</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Nessuna applicazione compatibile trovata</string>
<!--Webview actions-->
<string name="open_in_browser_label">Apri nel browser</string>
<string name="copy_url_label">Copia URL</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Impostazioni podcast</string>
<string name="rename_feed_label">Rinomina podcast</string>
<string name="remove_feed_label">Rimuovi podcast</string>
- <string name="share_label">Condividi...</string>
- <string name="share_link_label">Condividi URL episodio</string>
- <string name="share_link_with_position_label">Condividi URL episodio con posizione</string>
+ <string name="share_label">Condividi</string>
+ <string name="share_label_with_ellipses">Condividi...</string>
<string name="share_file_label">Condividi il file</string>
- <string name="share_website_url_label">Condividi URL del sito</string>
- <string name="share_feed_url_label">Condividi URL del podcast</string>
- <string name="share_item_url_label">Condividi URL del media</string>
- <string name="share_item_url_with_position_label">Condividi URL del media con posizione</string>
+ <string name="share_website_url_label">Indirizzo del sito internet</string>
+ <string name="share_feed_url_label">URL feed del podcast</string>
<string name="feed_delete_confirmation_msg">Conferma di voler eliminare il podcast \"%1$s\" e TUTTI i suoi episodi (compresi quelli scaricati).</string>
+ <string name="feed_delete_confirmation_local_msg">Conferma se desideri rimuovere il podcast \"%1$s\". I file nella cartella di origine locale non verranno cancellati.</string>
<string name="feed_remover_msg">Rimozione podcast in corso</string>
<string name="load_complete_feed">Aggiorna podcast completo</string>
<string name="multi_select">Selezione multipla</string>
<string name="select_all_above">Seleziona tutti in su</string>
<string name="select_all_below">Seleziona tutti in giù</string>
<string name="hide_unplayed_episodes_label">Non riprodotti</string>
- <string name="hide_paused_episodes_label">In pausa</string>
- <string name="hide_played_episodes_label">Riprodotti</string>
<string name="hide_queued_episodes_label">In coda</string>
<string name="hide_not_queued_episodes_label">Non in coda</string>
- <string name="hide_downloaded_episodes_label">Scaricati</string>
- <string name="hide_not_downloaded_episodes_label">Non scaricati</string>
<string name="hide_has_media_label">Con media</string>
- <string name="hide_is_favorite_label">Preferiti</string>
<string name="filtered_label">Filtrati</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Ultimo aggiornamento fallito</string>
<string name="open_podcast">Apri podcast</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Elimina</string>
<string name="delete_failed">Impossibile eliminare il file. Prova a riavviare il dispositivo.</string>
<string name="delete_episode_label">Elimina episodio</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d episodio eliminato.</item>
- <item quantity="other">%d episodi eliminati.</item>
- </plurals>
<string name="remove_new_flag_label">Rimuovi flag \"nuovo\"</string>
<string name="removed_new_flag_label">Flag \"nuovo\" rimosso</string>
<string name="mark_read_label">Segna come riprodotto</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Elaborazione dei download in corso</string>
<string name="download_notification_title">Scaricamento podcast in corso</string>
- <string name="download_report_content">%1$d download con successo, %2$d falliti</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d scaricamento completato, %d non riuscito.</item>
+ <item quantity="other">%d scaricamenti completati, %d non riusciti.</item>
+ </plurals>
<string name="download_log_title_unknown">Titolo sconosciuto</string>
<string name="download_type_feed">Feed</string>
<string name="download_type_media">File multimediali</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Il download tramite rete mobile è disattivato nelle impostazioni.\n\nVuoi abilitare temporaneamente il download?\n\n<small>La scelta sarà valida per 10 minuti.</small></string>
<string name="confirm_mobile_streaming_notification_title">Conferma streaming su rete mobile</string>
<string name="confirm_mobile_streaming_notification_message">Lo streaming su rete mobile è disattivato nelle impostazioni. Tocca per avviare comunque.</string>
- <string name="confirm_mobile_streaming_button_always">Consenti sempre</string>
+ <string name="confirm_mobile_streaming_button_always">Sempre</string>
+ <string name="confirm_mobile_streaming_button_once">Una volta</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Aggiungi alla coda</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Consenti temporaneamente</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Scarica plugin</string>
<string name="no_playback_plugin_title">Plugin non installato</string>
<string name="no_playback_plugin_or_sonic_msg">Per la velocità di riproduzione variabile, raccomandiamo di usare il riproduttore Sonic integrato.</string>
- <string name="set_playback_speed_label">Velocità di riproduzione</string>
<string name="enable_sonic">Abilita Sonic</string>
+ <string name="speed_presets">Preimpostazioni</string>
+ <string name="preset_already_exists">%1$.2fx è già stato selezionato.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Nessun episodio in coda</string>
<string name="no_items_label">Aggiungine uno scaricandolo o selezionando \"Aggiungi alla coda\" dopo aver tenuto premuto su di esso.</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">ogni %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">alle %1$s</string>
<string name="pref_followQueue_title">Riproduzione continua</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Disconnessione cuffie</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Disconnessione cuffie o Bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Riconnessione cuffie</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Riconnessione Bluetooth</string>
<string name="pref_stream_over_download_title">Preferisci streaming</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Download episodi</string>
<string name="pref_mobileUpdate_streaming">Streaming</string>
<string name="user_interface_label">Interfaccia utente</string>
- <string name="user_interface_sum">Aspetto, ordine delle iscrizioni, schermata di blocco</string>
+ <string name="user_interface_sum">Aspetto, sottoscrizioni, schermata di blocco</string>
<string name="pref_set_theme_title">Seleziona un tema</string>
<string name="pref_nav_drawer_items_title">Seleziona elementi del menù</string>
<string name="pref_nav_drawer_items_sum">Aggiungi o rimuovi gli elementi che appaiono nel menù laterale.</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Forza sincronizzazione completa</string>
<string name="pref_gpodnet_full_sync_sum">Sincronizza le iscrizioni e lo stato di tutti gli episodi con gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Accesso come <i>%1$s</i> con il dispositivo <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Notifica gli errori di sincronizzazione</string>
+ <string name="pref_gpodnet_notifications_title">Sincronizzazione fallita</string>
<string name="pref_gpodnet_notifications_sum">Non si applica agli errori di autenticazione.</string>
- <string name="pref_playback_speed_title">Velocità di riproduzione</string>
- <string name="pref_playback_speed_sum">Personalizza le velocità disponibili per la riproduzione audio a velocità variabile</string>
+ <string name="pref_playback_speed_sum">Personalizzare le velocità disponibili per le varie velocità di riproduzione.</string>
<string name="pref_feed_playback_speed_sum">Velocità da usare per la riproduzione degli episodi di questo podcast</string>
<string name="pref_feed_skip">Salta automaticamente</string>
<string name="pref_feed_skip_sum">Salta alcuni secondi all\'inizio o alla fine.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Di solito espande la notifica per mostrare i tasti di riproduzione.</string>
<string name="pref_persistNotify_title">Controlli di riproduzione persistenti</string>
<string name="pref_persistNotify_sum">Mantiene le notifiche e i controlli del blocco schermo anche quando la riproduzione è in pausa.</string>
- <string name="pref_compact_notification_buttons_title">Pulsanti schermata di blocco</string>
- <string name="pref_compact_notification_buttons_sum">Modifica i pulsanti di riproduzione mostrati nella schermata di blocco. Play/Pausa è sempre presente.</string>
+ <string name="pref_compact_notification_buttons_title">Imposta tasti notifica compatti</string>
+ <string name="pref_compact_notification_buttons_sum">Modifica i tasti di riproduzione quando la notifica è compressa. Il tasto play/pausa è sempre incluso.</string>
<string name="pref_compact_notification_buttons_dialog_title">Seleziona al massimo %1$d voci</string>
<string name="pref_compact_notification_buttons_dialog_error">Puoi selezionare al massimo %1$d voci.</string>
<string name="pref_lockscreen_background_title">Cambia sfondo della schermata di blocco</string>
<string name="pref_lockscreen_background_sum">Sostituisce l\'immagine della schermata di blocco con quella dell\'episodio in riproduzione. Mostrerà l\'immagine anche in app di terze parti.</string>
- <string name="pref_showDownloadReport_title">Mostra il rapporto del download</string>
+ <string name="pref_showDownloadReport_title">Download fallito</string>
<string name="pref_showDownloadReport_sum">Se il download fallisce, genera un report che mostra i dettagli dell\'errore.</string>
- <string name="pref_showAutoDownloadReport_title">Mostra report download automatici</string>
+ <string name="pref_showAutoDownloadReport_title">Download automatico completato</string>
<string name="pref_showAutoDownloadReport_sum">Mostra una notifica per gli episodi scaricati automaticamente.</string>
<string name="pref_expand_notify_unsupport_toast">Le versioni Android precedenti alla 4.1 non supportano le notifiche estese.</string>
<string name="pref_enqueue_location_title">Posizione in coda</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Aggiungi i download alla coda</string>
<string name="pref_enqueue_downloaded_summary">Aggiunge gli episodi alla coda quando vengono scaricati</string>
<string name="media_player_builtin">Player Android integrato</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (consigliato)</string>
<string name="media_player_switch_to_exoplayer">Passa ad ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Passaggio ad ExoPlayer eseguito.</string>
<string name="pref_skip_silence_title">Salta il silenzio audio</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Seleziona schermata</string>
<string name="pref_delete_removes_from_queue_title">Rimuovi dalla coda gli eliminati</string>
<string name="pref_delete_removes_from_queue_sum">Quando un episodio viene eliminato lo rimuove automaticamente dalla coda.</string>
+ <string name="pref_filter_feed_title">Filtro iscrizioni</string>
+ <string name="pref_filter_feed_sum">Filtra le iscrizioni nella barra laterale e nella schermata Iscrizioni.</string>
+ <string name="no_filter_label">Nessuno</string>
+ <string name="subscriptions_are_filtered">Iscrizioni filtrate.</string>
+ <string name="subscriptions_counter_greater_zero">Contatore maggiore di zero</string>
+ <string name="auto_downloaded">Con download automatico</string>
+ <string name="not_auto_downloaded">Senza download automatico</string>
+ <string name="kept_updated">Mantenute aggiornate</string>
+ <string name="not_kept_updated">Non mantenute aggiornate</string>
<!--About screen-->
<string name="about_pref">Informazioni</string>
<string name="antennapod_version">Versione di AntennaPod</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Sposta le iscrizioni, gli episodi ascoltati e la coda su AntennaPod di un altro dispositivo</string>
<string name="database_import_summary">Importa il database di AntennaPod da un altro dispositivo</string>
<string name="opml_import_label">Importa da OPML</string>
+ <string name="opml_add_podcast_label">Importa lista podcast (OPML)</string>
<string name="opml_reader_error">Errore in fase di lettura del documento OPML:</string>
<string name="opml_import_error_no_file">Nessun file selezionato!</string>
<string name="select_all_label">Seleziona tutti</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">Il file esportato è stato salvato in:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">E\' richiesto l\'accesso alla memoria esterna per leggere il file OPML</string>
<string name="import_select_file">Scegli file da importare</string>
- <string name="import_ok">Importazione eseguita.\n\nPremi OK per riavviare AntennaPod</string>
+ <string name="successful_import_label">Importazione eseguita</string>
+ <string name="import_ok">Premi OK per riavviare AntennaPod</string>
<string name="import_no_downgrade">Questo database è stato esportato da una versione più recente di AntennaPod. La tua applicazione attuale non sa ancora come gestire questo file.</string>
<string name="favorites_export_label">Esporta preferiti</string>
<string name="favorites_export_summary">Esporta preferiti su file</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Riduci velocità</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Naviga verso l\'alto</string>
<string name="status_downloading_label">L\'episodio sta venendo scaricato</string>
<string name="in_queue_label">L\'episodio è in coda</string>
<string name="is_favorite_label">Episodio contrassegnato come preferito</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Mantieni aggiornato</string>
<string name="keep_updated_summary">Includi questo podcast nell\'auto-aggiornamento generale</string>
<string name="auto_download_disabled_globally">Il download automatico è disabilitato nelle impostazioni generali.</string>
+ <string name="statistics_listened_for">Ascoltato per:</string>
+ <string name="statistics_episodes_on_device">Episodi sul dispositivo:</string>
+ <string name="statistics_space_used">Spazio utilizzato:</string>
+ <string name="statistics_view_all">Vedi per tutti i podcast »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Aggiornamento del database</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Cerca podcast...</string>
<string name="search_itunes_label">Cerca su iTunes</string>
+ <string name="search_podcastindex_label">Cerca su podcastindex.org</string>
<string name="search_fyyd_label">Cerca su fyyd</string>
<string name="advanced">Avanzate</string>
- <string name="add_podcast_by_url">Aggiungi podcast da URL</string>
+ <string name="add_podcast_by_url">Aggiungi podcast da indirizzo RSS</string>
<string name="browse_gpoddernet_label">Esplora gpodder.net</string>
<string name="discover">Scopri</string>
+ <string name="discover_hide">Nascondi</string>
+ <string name="discover_is_hidden">Hai scelto di nascondere i suggerimenti</string>
<string name="discover_more">altro »</string>
- <string name="search_powered_by">Ricerca fornita da %1$s</string>
+ <string name="discover_powered_by_itunes">Suggerimenti di iTunes</string>
+ <string name="search_powered_by">Risultati da %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Aggiungi cartella locale</string>
+ <string name="local_folder">Cartella locale</string>
+ <string name="reconnect_local_folder">Riconnetti cartella locale</string>
+ <string name="reconnect_local_folder_warning">In caso di rifiuto dell\'autorizzazione, puoi usare questa opzione per riconnetterti alla stessa cartella. Non selezionare un\'altra cartella.</string>
+ <string name="local_feed_description">Questo podcast virtuale è generato dall\'aggiunta di una cartella ad AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Impossibile avviare il gestore file di sistema</string>
<string name="filter">Filtra</string>
<!--Episodes apply actions-->
<string name="all_label">Tutto</string>
<string name="selected_all_label">Seleziona tutti gli episodi</string>
- <string name="none_label">Nessuno</string>
+ <string name="select_none_label">Nessuno</string>
<string name="deselected_all_label">Deseleziona tutti gli episodi</string>
<string name="played_label">Riprodotti</string>
<string name="selected_played_label">Episodi riprodotti selezionati</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Episodi scaricati selezionati</string>
<string name="not_downloaded_label">Non scaricati</string>
<string name="selected_not_downloaded_label">Episodi non scaricati selezionati</string>
- <string name="queued_label">In coda</string>
<string name="selected_queued_label">Episodi in coda selezionati</string>
- <string name="not_queued_label">Non in coda</string>
<string name="selected_not_queued_label">Episodi non in coda selezionati</string>
- <string name="has_media">Con media</string>
<string name="selected_has_media_label">Episodi con elementi multimediali selezionati</string>
+ <string name="hide_is_favorite_label">Preferiti</string>
+ <string name="not_favorite">Non preferito</string>
+ <string name="hide_downloaded_episodes_label">Scaricati</string>
+ <string name="hide_not_downloaded_episodes_label">Non scaricati</string>
+ <string name="queued_label">In coda</string>
+ <string name="not_queued_label">Non in coda</string>
+ <string name="has_media">Con media</string>
+ <string name="no_media">Nessun media</string>
+ <string name="hide_paused_episodes_label">In pausa</string>
+ <string name="not_paused">Non in pausa</string>
+ <string name="hide_played_episodes_label">Riprodotti</string>
+ <string name="not_played">Non riprodotto</string>
<!--Sort-->
<string name="sort_title_a_z">Titolo (A \u2192 Z)</string>
<string name="sort_title_z_a">Titolo (Z \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Lasciatemi in pace</string>
<string name="rating_later_label">Ricordamelo più tardi</string>
<string name="rating_now_label">Certo, facciamolo!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Includi:</string>
+ <string name="share_playback_position_dialog_label">Posizione riproduzione</string>
+ <string name="share_dialog_media_file_url_label">Indirizzo file multimediale</string>
+ <string name="share_dialog_episode_website_label">Pagina web episodio</string>
+ <string name="share_dialog_media_file_label">File multimediale</string>
<!--Audio controls-->
<string name="audio_controls">Controlli audio</string>
<string name="playback_speed">Velocità di riproduzione</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">In riproduzione</string>
<string name="notification_channel_playing_description">Permette di controllare la riproduzione. E\' la principale notifica visualizzata quando un podcast è in riproduzione.</string>
<string name="notification_channel_error">Errori</string>
- <string name="notification_channel_error_description">Viene mostrato se qualcosa fallisce, ad esempio il download o la sincronizzazione di gpodder.</string>
+ <string name="notification_channel_error_description">Viene mostrato se qualcosa fallisce, ad esempio il download o l\'aggiornamento del feed.</string>
+ <string name="notification_channel_sync_error">Errori di sincronizzazione</string>
+ <string name="notification_channel_sync_error_description">Mostrati quando la sincronizzazione con gpodder fallisce.</string>
<string name="notification_channel_auto_download">Download automatici</string>
<string name="notification_channel_episode_auto_download">Viene mostrato quando un episodio è stato scaricato automaticamente.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-iw/strings.xml b/core/src/main/res/values-iw/strings.xml
index 1e9f3f246..f9016ec3f 100644
--- a/core/src/main/res/values-iw/strings.xml
+++ b/core/src/main/res/values-iw/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">מטמון הפרקים התמלא. ניתן להגדיל את גודל המטמון בהגדרות.</string>
<string name="playback_statistics_label">נגינה</string>
<string name="download_statistics_label">הורדות</string>
+ <string name="notification_pref_fragment">התראות</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">זמן ניגון הפודקאסטים הכולל:</string>
+ <string name="total_time_listened_to_podcasts">זמן הנגינה הכולל של הפרקים:</string>
<string name="statistics_details_dialog">%1$d מתוך %2$d פרקים החלו.\n\nנוגנו %3$s מתוך %4$s.</string>
<string name="statistics_mode">מצב סטטיסטיקה</string>
<string name="statistics_mode_normal">חישוב זמן שנוגן בפועל. נגינה כפולה נספרת פעמיים, בעוד שסימון כנוגן לא נחשב.</string>
- <string name="statistics_mode_count_all">סיכום כל הפודקאסטים שסומנו כנוגנו</string>
+ <string name="statistics_mode_count_all">סכימת כל הפרקים שסומנו שהושמעו</string>
<string name="statistics_speed_not_counted">לתשומת לבך: אין התייחסות למהירות הנגינה.</string>
<string name="statistics_reset_data">איפוס נתונים סטטיסטיים</string>
<string name="statistics_reset_data_msg">פעולה זו תמחק את משך הנגינה של כל הפרקים. להמשיך?</string>
+ <string name="statistics_counting_since">מאז %s,\nניגנת</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">סך גודל הפודקאסטים שהתקבלו:</string>
+ <string name="total_size_downloaded_podcasts">סך גודל כל הפרקים שבמכשיר:</string>
<!--Main activity-->
<string name="drawer_open">פתיחת תפריט</string>
<string name="drawer_close">סגירת תפריט</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">מספר פרקים שעוד לא התנגנו</string>
<string name="drawer_feed_counter_downloaded">מספר פרקים שהתקבלו</string>
<string name="drawer_feed_counter_none">ללא</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">לא נמצאו יישומונים תואמים</string>
<!--Webview actions-->
<string name="open_in_browser_label">פתיחה בדפדפן</string>
<string name="copy_url_label">העתקת כתובת</string>
@@ -130,29 +134,22 @@
<string name="feed_settings_label">הגדרות פודקאסט</string>
<string name="rename_feed_label">שינוי שם פודקאסט</string>
<string name="remove_feed_label">הסרת פודקאסט</string>
- <string name="share_label">שיתוף…</string>
- <string name="share_link_label">שיתוף כתובת פרק</string>
- <string name="share_link_with_position_label">שיתוף כתובת הפרק עם מיקום</string>
+ <string name="share_label">שיתוף</string>
+ <string name="share_label_with_ellipses">שיתוף…</string>
<string name="share_file_label">שיתוף כתובת</string>
- <string name="share_website_url_label">שיתוף כתובת אתר</string>
- <string name="share_feed_url_label">שיתוף כתובת הפודקאסט</string>
- <string name="share_item_url_label">שיתוף כתובת קובץ המדיה</string>
- <string name="share_item_url_with_position_label">שיתוף כתובת קובץ המדיה עם מיקום</string>
+ <string name="share_website_url_label">כתובת אתר</string>
+ <string name="share_feed_url_label">כתובת הזנת פודקאסט</string>
<string name="feed_delete_confirmation_msg">נא לאשר שרצונך הוא למחוק את הפודקאסט „%1$s” על כל פרקיו (לרבות הפרקים שכבר הורדת).</string>
+ <string name="feed_delete_confirmation_local_msg">נא לאשר כדי להסיר את הפודקאסט „%1$s”. הקבצים בתיקייה המקור המקומית לא יימחקו.</string>
<string name="feed_remover_msg">הפודקאסט מוסר</string>
<string name="load_complete_feed">רענון מלא של הפודקאסט</string>
<string name="multi_select">לבחור מגוון</string>
<string name="select_all_above">בחירת כל אלו שלעיל</string>
<string name="select_all_below">בחירת כל אלו שלהלן</string>
<string name="hide_unplayed_episodes_label">לא נוגן</string>
- <string name="hide_paused_episodes_label">מושהה</string>
- <string name="hide_played_episodes_label">נוגן</string>
<string name="hide_queued_episodes_label">בתור</string>
<string name="hide_not_queued_episodes_label">לא בתור</string>
- <string name="hide_downloaded_episodes_label">הורד</string>
- <string name="hide_not_downloaded_episodes_label">לא הורד</string>
<string name="hide_has_media_label">יש מדיה</string>
- <string name="hide_is_favorite_label">עם סימון מועדף</string>
<string name="filtered_label">מסונן</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} הרענון האחרון נכשל</string>
<string name="open_podcast">פתיחת פודקאסט</string>
@@ -171,12 +168,6 @@
<string name="delete_label">מחיקה</string>
<string name="delete_failed">לא ניתן למחוק קובץ. הפעלת המכשיר מחדש עשויה לסייע.</string>
<string name="delete_episode_label">מחיקת פרק</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">פרק אחד נמחק.</item>
- <item quantity="two">%d פרקים נמחקו.</item>
- <item quantity="many">%d פרקים נמחקו.</item>
- <item quantity="other">%d פרקים נמחקו.</item>
- </plurals>
<string name="remove_new_flag_label">הסרת הסימון „חדש”</string>
<string name="removed_new_flag_label">הוסר הסימון „חדש”</string>
<string name="mark_read_label">סימון כנצפה</string>
@@ -258,7 +249,12 @@
</plurals>
<string name="downloads_processing">ההורדות בהליכי עיבוד</string>
<string name="download_notification_title">נתוני הפודקאסט מתקבלים</string>
- <string name="download_report_content">%1$d הורדות הצליחו, %2$d נכשלו</string>
+ <plurals name="download_report_content">
+ <item quantity="one">הורדה %d הצליחה, %d נכשלו</item>
+ <item quantity="two">%d הורדות הצליחו, %d נכשלו</item>
+ <item quantity="many">%d הורדות הצליחו, %d נכשלו</item>
+ <item quantity="other">%d הורדות הצליחו, %d נכשלו</item>
+ </plurals>
<string name="download_log_title_unknown">כותרת לא ידועה</string>
<string name="download_type_feed">הזנה</string>
<string name="download_type_media">קובץ מדיה</string>
@@ -271,7 +267,8 @@
<string name="confirm_mobile_download_dialog_message">הורדה דרך חיבור נתונים של רשת סלולרית מושבת דרך ההגדרות.\n\nלאפשר את ההורדה באופן זמני?\n\n<small>הבחירה שלך תישמר למשך 10 דקות.</small></string>
<string name="confirm_mobile_streaming_notification_title">אישור הזרמה דרך רשת סלולרית</string>
<string name="confirm_mobile_streaming_notification_message">הזרמה דרך חיבור רשת סלולרית מושבתת בהגדרות. ניתן לגעת כדי להזרים בכל זאת.</string>
- <string name="confirm_mobile_streaming_button_always">לאפשר תמיד</string>
+ <string name="confirm_mobile_streaming_button_always">תמיד</string>
+ <string name="confirm_mobile_streaming_button_once">פעם אחת</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">הוספה לתור</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">לאפשר לבינתיים</string>
<!--Mediaplayer messages-->
@@ -317,8 +314,9 @@
<string name="download_plugin_label">הורדת תוסף</string>
<string name="no_playback_plugin_title">תוסף לא מותקן</string>
<string name="no_playback_plugin_or_sonic_msg">כדי שתהיה לך אפשרות להשתמש במהירות נגינה משתנה אנו ממליצים להפעיל את נגן המדיה המובנה Sonic.</string>
- <string name="set_playback_speed_label">מהירויות ניגון</string>
<string name="enable_sonic">הפעלת Sonic</string>
+ <string name="speed_presets">ערכות מוגדרות</string>
+ <string name="preset_already_exists">%1$.2fx כבר נשמרה כערכה מוגדרת.</string>
<!--Empty list labels-->
<string name="no_items_header_label">אין פרקים בתור</string>
<string name="no_items_label">ניתן להוסיף פרק על ידי הורדתו או ללחוץ על פרק לחיצה ארוכה ולבחור ב־„הוספה לתור”.</string>
@@ -391,7 +389,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">כל %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">ב־%1$s</string>
<string name="pref_followQueue_title">ניגון מתמשך</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">ניתוק אוזניות</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">ניתוק אוזניות או Bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_title">חיבור אוזניות מחדש</string>
<string name="pref_unpauseOnBluetoothReconnect_title">חיבור Bluetooth מחדש</string>
<string name="pref_stream_over_download_title">הזרמה עדיפה</string>
@@ -404,7 +402,7 @@
<string name="pref_mobileUpdate_episode_download">הורדת פרקים</string>
<string name="pref_mobileUpdate_streaming">הזרמה</string>
<string name="user_interface_label">מנשק משתמש</string>
- <string name="user_interface_sum">מראה, סדר מינויים, מסך נעילה</string>
+ <string name="user_interface_sum">מראה, מינויים, מסך נעילה</string>
<string name="pref_set_theme_title">בחירת ערכת עיצוב</string>
<string name="pref_nav_drawer_items_title">הגדרת פריטי מגירת ניווט</string>
<string name="pref_nav_drawer_items_sum">החלפת הפריטים שמופיעים במגירת הניווט.</string>
@@ -443,10 +441,9 @@
<string name="pref_gpodnet_full_sync_title">לכפות סנכרון מלא</string>
<string name="pref_gpodnet_full_sync_sum">סנכרון כל המינויים ומצבי הפרקים עם gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[נכנסת בשם <i>%1$s</i> עם ההתקן <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">הצגת התרעות שגיאות סנכרון</string>
+ <string name="pref_gpodnet_notifications_title">הסנכרון נכשל</string>
<string name="pref_gpodnet_notifications_sum">הגדרה זו אינה חלה על שגיאות אימות.</string>
- <string name="pref_playback_speed_title">מהירויות ניגון</string>
- <string name="pref_playback_speed_sum">בחירת המהירויות הזמינות למהירות נגינה משתנה</string>
+ <string name="pref_playback_speed_sum">התאמת המהירויות הזמינות למהירות נגינה משתנה</string>
<string name="pref_feed_playback_speed_sum">המהירות שתחול על פרקים בפודקאסט זה כשאלו מתחילים להתנגן</string>
<string name="pref_feed_skip">לדלג אוטומטית</string>
<string name="pref_feed_skip_sum">לדלג על הקדמה ותודות בסיום.</string>
@@ -466,15 +463,15 @@
<string name="pref_expandNotify_sum">הגדרה זו מרחיבה את ההתראה כדי שתציג גם כפתורי נגינה.</string>
<string name="pref_persistNotify_title">פקדי נגינה קבועים</string>
<string name="pref_persistNotify_sum">להשאיר את פקדי ההתרעות ומסך הנעילה גם כשהנגינה מושהית.</string>
- <string name="pref_compact_notification_buttons_title">הגדרת כפתורים במסך נעילה</string>
- <string name="pref_compact_notification_buttons_sum">החלפת כפתור הנגינה במסך הנעילה. הכפתורים נגינה/השהיה תמיד נכללים.</string>
+ <string name="pref_compact_notification_buttons_title">הגדרת כפתורי התראה מוקטנים</string>
+ <string name="pref_compact_notification_buttons_sum">להחליף את כפתורי הנגינה כאשר ההתראה מצומצמת. כפתור נגינה/השהיה תמיד יופיע.</string>
<string name="pref_compact_notification_buttons_dialog_title">בחירה עד %1$d פריטים</string>
<string name="pref_compact_notification_buttons_dialog_error">ניתן לבחור עד %1$d פריטים.</string>
<string name="pref_lockscreen_background_title">הגדרת רקע מסך הנעילה</string>
<string name="pref_lockscreen_background_sum">הגדרת רקע מסך הנעילה לתמונה של הפרק שמתנגן כעת. כתופעת לוואי, התמונה תופיע גם ביישומי צד שלישי.</string>
- <string name="pref_showDownloadReport_title">הצגת דוח הורדה</string>
+ <string name="pref_showDownloadReport_title">ההורדה נכשלה</string>
<string name="pref_showDownloadReport_sum">אם ההורדה נכשלת, יש ליצר דוח שמציג את פרטי הכשל.</string>
- <string name="pref_showAutoDownloadReport_title">הצגת דוח הורדה אוטומטית</string>
+ <string name="pref_showAutoDownloadReport_title">הורדה אוטומטית הושלמה</string>
<string name="pref_showAutoDownloadReport_sum">להציג הודעה לפרקים שהתקבלו אוטומטית.</string>
<string name="pref_expand_notify_unsupport_toast">גרסאות Android שקדמו ל־4.1 אינן תומכות בהתרעות מתרחבות.</string>
<string name="pref_enqueue_location_title">הוספת המיקום לתור</string>
@@ -504,6 +501,7 @@
<string name="pref_enqueue_downloaded_title">הוספת הורדות לתור</string>
<string name="pref_enqueue_downloaded_summary">הוספת פרקים שהתקבלו לתור</string>
<string name="media_player_builtin">הנגן המובנה ב־Android</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (מומלץ)</string>
<string name="media_player_switch_to_exoplayer">מעבר ל־ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">הועבר ל־ExoPlayer.</string>
<string name="pref_skip_silence_title">דילוג על שקט בקטעי ההאזנה</string>
@@ -524,6 +522,15 @@
<string name="back_button_go_to_page_title">בחירת עמוד</string>
<string name="pref_delete_removes_from_queue_title">מחיקה מסירה מהתור</string>
<string name="pref_delete_removes_from_queue_sum">הסרת פרק מהתור אוטומטית עם מחיקתו.</string>
+ <string name="pref_filter_feed_title">מסנן מינויים</string>
+ <string name="pref_filter_feed_sum">סינון המינויים שלך במגירת הניווט ובמסך המינויים.</string>
+ <string name="no_filter_label">ללא</string>
+ <string name="subscriptions_are_filtered">המינויים מסוננים.</string>
+ <string name="subscriptions_counter_greater_zero">המונה גדול מאפס</string>
+ <string name="auto_downloaded">התקבלו אוטומטית</string>
+ <string name="not_auto_downloaded">לא התקבלו אוטומטית</string>
+ <string name="kept_updated">נשאר עדכני</string>
+ <string name="not_kept_updated">לא נשאר עדכני</string>
<!--About screen-->
<string name="about_pref">על אודות</string>
<string name="antennapod_version">גרסת אנטנה־פּוֹד</string>
@@ -558,6 +565,7 @@
<string name="database_export_summary">העברת מינויים, פרקים להם האזנת ותור נגינה לאנטנה־פ‎וֹד במכשיר אחר</string>
<string name="database_import_summary">ייבוא מסד הנתונים של אנטנה־פ‎וֹד ממכשיר אחר</string>
<string name="opml_import_label">ייבוא OPML</string>
+ <string name="opml_add_podcast_label">לייבא רשימת פודקאסטים (OPML)</string>
<string name="opml_reader_error">אירעה שגיאה בעת קריאת מסמך ה־OPML:</string>
<string name="opml_import_error_no_file">לא נבחר קובץ!</string>
<string name="select_all_label">בחירת הכול</string>
@@ -573,7 +581,8 @@
<string name="export_success_sum">הקובץ שייוצא נכתב אל:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">נדרשת גישה לאחסון חיצוני כדי לקרוא את קובץ ה־OPML</string>
<string name="import_select_file">בחירת קובץ לייבוא</string>
- <string name="import_ok">הייבוא הצליח.\n\nנא ללחוץ על אישור כדי להפעיל את אנטנה־פּוֹד מחדש</string>
+ <string name="successful_import_label">הייבוא הצליח</string>
+ <string name="import_ok">נא ללחוץ על אישור כדי להפעיל את אנטנה־פּוֹד מחדש</string>
<string name="import_no_downgrade">מסד נתונים זה ייוצא עם גרסה עדכנית יותר של אנטנה־פ‎וֹד</string>
<string name="favorites_export_label">ייצוא מועדפים</string>
<string name="favorites_export_summary">ייצור המועדפים השמורים לקובץ</string>
@@ -674,7 +683,6 @@
<string name="decrease_speed">האטה</string>
<string name="media_type_audio_label">שמע</string>
<string name="media_type_video_label">וידאו</string>
- <string name="navigate_upwards_label">ניווט כלפי מעלה</string>
<string name="status_downloading_label">הפרק יורד</string>
<string name="in_queue_label">הפרק בתור</string>
<string name="is_favorite_label">הפרק מסומן כמועדף</string>
@@ -695,6 +703,10 @@
<string name="keep_updated">לשמור על עדכניות</string>
<string name="keep_updated_summary">לכלול את הפודקאסט בעת רענון (אוטומטי) של כל הפודקאסטים</string>
<string name="auto_download_disabled_globally">הורדה אוטומטית מושבתת בהגדרות הראשיות של אנטנה־פּוֹד</string>
+ <string name="statistics_listened_for">הואזן למשך:</string>
+ <string name="statistics_episodes_on_device">פרקים על המכשיר הזה:</string>
+ <string name="statistics_space_used">מקום תפוס:</string>
+ <string name="statistics_view_all">להציג לכל הפודקאסטים »</string>
<!--Progress information-->
<string name="progress_upgrading_database">מסד הנתונים משתדרג</string>
<!--AntennaPodSP-->
@@ -702,18 +714,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">חיפוש פודקאסט…</string>
<string name="search_itunes_label">חיפוש ב־iTunes</string>
+ <string name="search_podcastindex_label">חיפוש ב־Podcastindex.org</string>
<string name="search_fyyd_label">בחיפוש ב־fyyd</string>
<string name="advanced">מתקדם</string>
- <string name="add_podcast_by_url">הוספת פודקאסט לפי כתובת</string>
+ <string name="add_podcast_by_url">הוספת פודקאסט לפי כתובת RSS</string>
<string name="browse_gpoddernet_label">עיון ב־gpodder.net</string>
<string name="discover">עיון</string>
+ <string name="discover_hide">הסתרה</string>
+ <string name="discover_is_hidden">בחרת להסתיר הצעות.</string>
<string name="discover_more">עוד »</string>
- <string name="search_powered_by">החיפוש מופעל על ידי %1$s</string>
+ <string name="discover_powered_by_itunes">הצעות מ־iTunes</string>
+ <string name="search_powered_by">תוצאות מאת %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">הוספת תיקייה מקומית</string>
+ <string name="local_folder">תיקייה מקומית</string>
+ <string name="reconnect_local_folder">חיבור מחדש לתיקייה מקומית</string>
+ <string name="reconnect_local_folder_warning">במקרה של דחיית הרשה, ניתן להשתמש בזה כדי לחבר את אותה התיקייה בדיוק מחדש. אין לבחור בתיקייה אחרת.</string>
+ <string name="local_feed_description">הפודקאסט הווירטואלי הזה נוצר על ידי הוספת תיקייה לאנטנה־פּוֹד.</string>
+ <string name="unable_to_start_system_file_manager">לא ניתן להפעיל את מנהל הקבצים של המערכת</string>
<string name="filter">מסנן</string>
<!--Episodes apply actions-->
<string name="all_label">הכול</string>
<string name="selected_all_label">בחירת כל הפרקים</string>
- <string name="none_label">ללא</string>
+ <string name="select_none_label">ללא</string>
<string name="deselected_all_label">אף פרק לא נבחר</string>
<string name="played_label">נוגנו</string>
<string name="selected_played_label">בחירת פרקים שנוגנו</string>
@@ -723,12 +746,21 @@
<string name="selected_downloaded_label">בחירת פרקים שהורדו</string>
<string name="not_downloaded_label">לא הורדו</string>
<string name="selected_not_downloaded_label">בחירת פרקים שלא הורדו</string>
- <string name="queued_label">בתור</string>
<string name="selected_queued_label">בחירת פרקים בתור</string>
- <string name="not_queued_label">לא בתור</string>
<string name="selected_not_queued_label">בחירת פרטים שאינם בתור</string>
- <string name="has_media">יש מדיה</string>
<string name="selected_has_media_label">בחירת פרקים עם מדיה</string>
+ <string name="hide_is_favorite_label">עם סימון מועדף</string>
+ <string name="not_favorite">לא במועדפים</string>
+ <string name="hide_downloaded_episodes_label">הורד</string>
+ <string name="hide_not_downloaded_episodes_label">לא הורד</string>
+ <string name="queued_label">בתור</string>
+ <string name="not_queued_label">לא בתור</string>
+ <string name="has_media">יש מדיה</string>
+ <string name="no_media">אין מדיה</string>
+ <string name="hide_paused_episodes_label">מושהה</string>
+ <string name="not_paused">לא מושהים</string>
+ <string name="hide_played_episodes_label">נוגן</string>
+ <string name="not_played">לא נוגנו</string>
<!--Sort-->
<string name="sort_title_a_z">כותרת (א \u2192 ת)</string>
<string name="sort_title_z_a">כותרת (ת \u2192 א)</string>
@@ -748,6 +780,12 @@
<string name="rating_never_label">לא תודה</string>
<string name="rating_later_label">פעם אחרת</string>
<string name="rating_now_label">בטח, נלך על זה!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">כולל:</string>
+ <string name="share_playback_position_dialog_label">מיקום הנגינה</string>
+ <string name="share_dialog_media_file_url_label">כתובת קובץ מדיה</string>
+ <string name="share_dialog_episode_website_label">עמוד הפרק</string>
+ <string name="share_dialog_media_file_label">קובץ מדיה</string>
<!--Audio controls-->
<string name="audio_controls">פקדי שמע</string>
<string name="playback_speed">מהירות נגינה</string>
@@ -794,7 +832,9 @@
<string name="notification_channel_playing">מתנגן כעת</string>
<string name="notification_channel_playing_description">מאשר לשלוט בנגינה. זאת ההתראה הראשית שמופיעה בעת נגינת פודקאסט.</string>
<string name="notification_channel_error">שגיאות</string>
- <string name="notification_channel_error_description">מופיעות אם משהו משתבש, למשל אם הורדה או סנכרון מול gpodder נכשלים.</string>
+ <string name="notification_channel_error_description">מופיע אם משהו משתבש, למשל אם הורדה או עדכון הזנה נכשלים.</string>
+ <string name="notification_channel_sync_error">שגיאות סנכרון</string>
+ <string name="notification_channel_sync_error_description">מופיע כאשר הסנכרון מול gpodder נכשל.</string>
<string name="notification_channel_auto_download">הורדות אוטומטיות</string>
<string name="notification_channel_episode_auto_download">מופיע כאשר פרקים התקבלו אוטומטית.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-ja/strings.xml b/core/src/main/res/values-ja/strings.xml
index ac9c49a2e..7a38857a2 100644
--- a/core/src/main/res/values-ja/strings.xml
+++ b/core/src/main/res/values-ja/strings.xml
@@ -26,16 +26,13 @@
<string name="playback_statistics_label">再生</string>
<string name="download_statistics_label">ダウンロード</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">ポッドキャストを再生した合計時間:</string>
<string name="statistics_details_dialog">%2$d から %1$d のエピソードが開始しました。\n\n%4$s から%3$s を再生しました。</string>
<string name="statistics_mode">統計情報モード</string>
<string name="statistics_mode_normal">実際に再生された時間を計算します。 2回再生すると2回カウントされ、再生済のマークはカウントされません</string>
- <string name="statistics_mode_count_all">再生済みとマークされたすべてのポッドキャストを集計する</string>
<string name="statistics_speed_not_counted">注意: 再生速度は考慮されません。</string>
<string name="statistics_reset_data">統計情報のデータをリセット</string>
<string name="statistics_reset_data_msg">これにより、すべてのエピソードを再生した期間の履歴が消去されます。 続行しますか?</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">ダウンロード済のポッドキャストのサイズ合計:</string>
<!--Main activity-->
<string name="drawer_open">メニューを開く</string>
<string name="drawer_close">メニューを閉じる</string>
@@ -49,6 +46,7 @@
<string name="drawer_feed_counter_unplayed">未再生のエピソードの数</string>
<string name="drawer_feed_counter_downloaded">ダウンロード済のエピソードの数</string>
<string name="drawer_feed_counter_none">なし</string>
+ <!--Bug report activity-->
<!--Webview actions-->
<string name="open_in_browser_label">ブラウザーで開く</string>
<string name="copy_url_label">URLをコピー</string>
@@ -117,14 +115,7 @@
<string name="feed_settings_label">ポッドキャスト設定</string>
<string name="rename_feed_label">ポッドキャストの名前を変更</string>
<string name="remove_feed_label">ポッドキャストを削除</string>
- <string name="share_label">共有…</string>
- <string name="share_link_label">エピソード URLを共有</string>
- <string name="share_link_with_position_label">エピソード URL を位置と共に共有</string>
<string name="share_file_label">ファイルを共有</string>
- <string name="share_website_url_label">ウェブサイト URLを共有</string>
- <string name="share_feed_url_label">ポッドキャスト URL を共有</string>
- <string name="share_item_url_label">メディアファイル URLを共有</string>
- <string name="share_item_url_with_position_label">メディアファイル URL を位置と共に共有</string>
<string name="feed_delete_confirmation_msg">ポッドキャスト \"%1$s\" とすべての(ダウンロード済を含む)エピソードを削除することを確認してください。</string>
<string name="feed_remover_msg">ポッドキャストを削除しています</string>
<string name="load_complete_feed">ポッドキャストをすべて更新</string>
@@ -132,14 +123,9 @@
<string name="select_all_above">上のすべてを選択</string>
<string name="select_all_below">下のすべてを選択</string>
<string name="hide_unplayed_episodes_label">未再生</string>
- <string name="hide_paused_episodes_label">一時停止中</string>
- <string name="hide_played_episodes_label">再生済み</string>
<string name="hide_queued_episodes_label">キューに追加済</string>
<string name="hide_not_queued_episodes_label">キューに未追加</string>
- <string name="hide_downloaded_episodes_label">ダウンロード済</string>
- <string name="hide_not_downloaded_episodes_label">未ダウンロード</string>
<string name="hide_has_media_label">メディアあり</string>
- <string name="hide_is_favorite_label">お気に入り</string>
<string name="filtered_label">フィルターしました</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} 前回更新に失敗しました</string>
<string name="open_podcast">ポッドキャストを開く</string>
@@ -155,9 +141,6 @@
<string name="delete_label">削除</string>
<string name="delete_failed">ファイルを削除できません。デバイスを再起動してみてください。</string>
<string name="delete_episode_label">エピソードを削除</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="other">%d エピソードを削除しました。</item>
- </plurals>
<string name="remove_new_flag_label">\"新規\" フラグを削除</string>
<string name="removed_new_flag_label">\"新規\" フラグを削除しました</string>
<string name="mark_read_label">再生済としてマーク</string>
@@ -223,7 +206,6 @@
</plurals>
<string name="downloads_processing">ダウンロード処理中</string>
<string name="download_notification_title">ポッドキャストデータをダウンロード中</string>
- <string name="download_report_content">%1$d ダウンロード成功, %2$d 失敗</string>
<string name="download_log_title_unknown">タイトル不明</string>
<string name="download_type_feed">フィード</string>
<string name="download_type_media">メディアファイル</string>
@@ -236,7 +218,6 @@
<string name="confirm_mobile_download_dialog_message">モバイルデータ接続でのダウンロードは設定で無効になっています。\n\n一時的に有効にしますか?\n\n<small>選択は 10 分間記憶されます。</small></string>
<string name="confirm_mobile_streaming_notification_title">モバイルストリーミングの確認</string>
<string name="confirm_mobile_streaming_notification_message">モバイルデータ接続を介したストリーミングは設定で無効になっています。 タップするととにかくストリーミングします。</string>
- <string name="confirm_mobile_streaming_button_always">常に許可</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">キューに追加するだけ</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">一時的に有効にする</string>
<!--Mediaplayer messages-->
@@ -282,7 +263,6 @@
<string name="download_plugin_label">プラグインをダウンロード</string>
<string name="no_playback_plugin_title">プラグイン はインストールされていません</string>
<string name="no_playback_plugin_or_sonic_msg">可変速再生を機能させるには、内蔵のSonicメディアプレーヤーを有効にすることをお勧めします。</string>
- <string name="set_playback_speed_label">再生速度</string>
<string name="enable_sonic">Sonic を有効にする</string>
<!--Empty list labels-->
<string name="no_items_header_label">エピソードはキューにありません</string>
@@ -354,7 +334,6 @@
<string name="pref_autoUpdateIntervallOrTime_every">%1$s ごと</string>
<string name="pref_autoUpdateIntervallOrTime_at">%1$s に</string>
<string name="pref_followQueue_title">連続再生</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">ヘッドフォン切断</string>
<string name="pref_unpauseOnHeadsetReconnect_title">ヘッドフォン再接続</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth再接続</string>
<string name="pref_stream_over_download_title">ストリーミングを優先する</string>
@@ -367,7 +346,6 @@
<string name="pref_mobileUpdate_episode_download">エピソードのダウンロード</string>
<string name="pref_mobileUpdate_streaming">ストリーミング</string>
<string name="user_interface_label">インターフェース</string>
- <string name="user_interface_sum">外観、購読注文、ロック画面</string>
<string name="pref_set_theme_title">テーマを選択</string>
<string name="pref_nav_drawer_items_title">ナビゲーションドロワーを変更</string>
<string name="pref_nav_drawer_items_sum">ナビゲーションドロワーに表示するアイテムを変更します。</string>
@@ -404,10 +382,7 @@
<string name="pref_gpodnet_sync_changes_sum">購読とエピソードの状態の変更を gpodder.net で同期します。</string>
<string name="pref_gpodnet_full_sync_sum">すべての購読とエピソードの状態を gpodder.net で同期します。</string>
<string name="pref_gpodnet_login_status"><![CDATA[<i>%1$s</i> としてデバイス <i>%2$s</i> でログインしました]]></string>
- <string name="pref_gpodnet_notifications_title">同期エラーの通知を表示</string>
<string name="pref_gpodnet_notifications_sum">この設定は、認証エラーには適用されません。</string>
- <string name="pref_playback_speed_title">再生速度</string>
- <string name="pref_playback_speed_sum">可変速度音声再生に使用可能な速度をカスタマイズします</string>
<string name="pref_feed_playback_speed_sum">このポッドキャストでエピソードのオーディオ再生を開始するときに使用する速度</string>
<string name="pref_playback_time_respects_speed_title">メディア情報を再生速度に調整</string>
<string name="pref_playback_time_respects_speed_sum">表示される位置と時間が再生速度に調整されます</string>
@@ -421,15 +396,11 @@
<string name="pref_expandNotify_sum">これは通常再生ボタンを表示するように通知を展開します。</string>
<string name="pref_persistNotify_title">永続再生コントロール</string>
<string name="pref_persistNotify_sum">再生が一時停止された時に、通知およびロック画面のコントロールを保持します。</string>
- <string name="pref_compact_notification_buttons_title">ロック画面ボタンを設定</string>
- <string name="pref_compact_notification_buttons_sum">ロック画面の再生ボタンを変更します。再生/一時停止ボタンを常に含みます。</string>
<string name="pref_compact_notification_buttons_dialog_title">最大 %1$d のアイテムを選択</string>
<string name="pref_compact_notification_buttons_dialog_error">最大 %1$d のアイテムのみを選択できます。</string>
<string name="pref_lockscreen_background_title">ロック画面の背景を設定</string>
<string name="pref_lockscreen_background_sum">ロック画面の背景を、現在のエピソードの画像に設定します。副作用として、これはサードパーティのアプリケーションでも画像を表示します。</string>
- <string name="pref_showDownloadReport_title">ダウンロード レポートを表示</string>
<string name="pref_showDownloadReport_sum">ダウンロードが失敗した場合、失敗の詳細を表示するレポートを生成します。</string>
- <string name="pref_showAutoDownloadReport_title">自動ダウンロード レポートを表示</string>
<string name="pref_showAutoDownloadReport_sum">自動ダウンロードされたエピソードの通知を表示します。</string>
<string name="pref_expand_notify_unsupport_toast">Androidバージョン4.1以前では、拡張通知をサポートしていません。</string>
<string name="pref_enqueue_location_title">キューに入れる場所</string>
@@ -515,7 +486,6 @@
<string name="export_success_sum">エクスポートしたファイルを書き込みました:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">OPML ファイルを読み込むために、外部ストレージへのアクセスが必要です</string>
<string name="import_select_file">インポートするファイルを選択してください</string>
- <string name="import_ok">インポートが成功しました。\n\nOKを押してAntennaPodを再起動してください。</string>
<string name="import_no_downgrade">このデータベースは、AntennaPodの新しいバージョンでエクスポートされました。 現在インストールされたアプリでは、このファイルの処理方法がまだわかりません。</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">スリープタイマーをセット</string>
@@ -602,7 +572,6 @@
<string name="fast_forward_label">早送り</string>
<string name="media_type_audio_label">音声</string>
<string name="media_type_video_label">動画</string>
- <string name="navigate_upwards_label">上に移動</string>
<string name="status_downloading_label">エピソードをダウンロード中</string>
<string name="in_queue_label">エピソードはキューの中にあります</string>
<string name="drag_handle_content_description">このアイテムの場所を変更するにはドラッグしてください</string>
@@ -628,15 +597,14 @@
<string name="search_itunes_label">iTunes を検索</string>
<string name="search_fyyd_label">fyydを検索</string>
<string name="advanced">詳細</string>
- <string name="add_podcast_by_url">URLでポッドキャストを追加</string>
<string name="browse_gpoddernet_label">gpodder.netを参照</string>
<string name="discover">発見</string>
<string name="discover_more">さらに »</string>
+ <!--Local feeds-->
<string name="filter">フィルター</string>
<!--Episodes apply actions-->
<string name="all_label">すべて</string>
<string name="selected_all_label">すべてのエピソードを選択しました</string>
- <string name="none_label">なし</string>
<string name="deselected_all_label">すべてのエピソードの選択を解除しました</string>
<string name="played_label">再生しました</string>
<string name="selected_played_label">再生済のエピソードを選択しました</string>
@@ -646,12 +614,17 @@
<string name="selected_downloaded_label">ダウンロード済のエピソードを選択しました</string>
<string name="not_downloaded_label">ダウンロードしていません</string>
<string name="selected_not_downloaded_label">ダウンロードしていないエピソードを選択しました</string>
- <string name="queued_label">キューに入れました</string>
<string name="selected_queued_label">キューに入ったエピソードを選択しました</string>
- <string name="not_queued_label">キューに入っていません</string>
<string name="selected_not_queued_label">キューに入っていないエピソードを選択しました</string>
- <string name="has_media">メディアあり</string>
<string name="selected_has_media_label">メディアのあるエピソードを選択しました</string>
+ <string name="hide_is_favorite_label">お気に入り</string>
+ <string name="hide_downloaded_episodes_label">ダウンロード済</string>
+ <string name="hide_not_downloaded_episodes_label">未ダウンロード</string>
+ <string name="queued_label">キューに入れました</string>
+ <string name="not_queued_label">キューに入っていません</string>
+ <string name="has_media">メディアあり</string>
+ <string name="hide_paused_episodes_label">一時停止中</string>
+ <string name="hide_played_episodes_label">再生済み</string>
<!--Sort-->
<string name="sort_title_a_z">タイトル (A \u2192 Z)</string>
<string name="sort_title_z_a">タイトル (Z \u2192 A)</string>
@@ -665,6 +638,7 @@
<string name="rating_never_label">構わないで</string>
<string name="rating_later_label">後で確認する</string>
<string name="rating_now_label">もちろん、します!</string>
+ <!--Share episode dialog-->
<!--Audio controls-->
<string name="audio_controls">オーディオコントロール</string>
<string name="playback_speed">再生速度</string>
@@ -711,7 +685,6 @@
<string name="notification_channel_playing">現在再生中</string>
<string name="notification_channel_playing_description">再生をコントロールできます。これはポッドキャスト再生中のメイン通知です。</string>
<string name="notification_channel_error">エラー</string>
- <string name="notification_channel_error_description">ダウンロードや gpodder の同期に失敗した場合など、何か問題が発生した場合に表示されます。</string>
<string name="notification_channel_auto_download">自動ダウンロード</string>
<string name="notification_channel_episode_auto_download">エピソードが自動ダウンロードされた時に表示します。</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-ko/strings.xml b/core/src/main/res/values-ko/strings.xml
index 28f79aca7..538aa2629 100644
--- a/core/src/main/res/values-ko/strings.xml
+++ b/core/src/main/res/values-ko/strings.xml
@@ -26,16 +26,13 @@
<string name="playback_statistics_label">재생</string>
<string name="download_statistics_label">다운로드</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">재생한 팟캐스트의 전체 시간</string>
<string name="statistics_details_dialog">에피소드 %1$d개 (전체 %2$d개) 시작.\n\n%3$s개 재생 (전체 %4$s개).</string>
<string name="statistics_mode">통계 모드</string>
<string name="statistics_mode_normal">실제 재생한 시간을 계산합니다. 두 번 재생하면 두 번 계산되고, 재생한 것으로 표시하면 계산에 안 들어갑니다.</string>
- <string name="statistics_mode_count_all">재생한 것으로 표시한 모든 팟캐스트 합계</string>
<string name="statistics_speed_not_counted">주의: 재생 속도는 고려하지 않습니다</string>
<string name="statistics_reset_data">통계 데이터 초기화</string>
<string name="statistics_reset_data_msg">모든 에피소드의 재생 시간 기록을 지웁니다. 정말로 계속 하시겠습니까?</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">다운로드한 팟캐스트의 전체 크기:</string>
<!--Main activity-->
<string name="drawer_open">메뉴 열기</string>
<string name="drawer_close">메뉴 닫기</string>
@@ -49,6 +46,7 @@
<string name="drawer_feed_counter_unplayed">재생하지 않은 에피소드 수</string>
<string name="drawer_feed_counter_downloaded">다운로드한 에피소드 수</string>
<string name="drawer_feed_counter_none">없음</string>
+ <!--Bug report activity-->
<!--Webview actions-->
<string name="open_in_browser_label">브라우저에서 열기</string>
<string name="copy_url_label">URL 복사</string>
@@ -121,14 +119,7 @@
<string name="feed_settings_label">팟캐스트 설정</string>
<string name="rename_feed_label">팟캐스트 이름 바꾸기</string>
<string name="remove_feed_label">팟캐스트 제거</string>
- <string name="share_label">공유…</string>
- <string name="share_link_label">에피소드 URL 공유</string>
- <string name="share_link_with_position_label">에피소드 URL 및 재생 위치 공유</string>
<string name="share_file_label">파일 공유</string>
- <string name="share_website_url_label">홈페이지 URL 공유</string>
- <string name="share_feed_url_label">팟캐스트 URL 공유</string>
- <string name="share_item_url_label">미디어 파일 URL 공유</string>
- <string name="share_item_url_with_position_label">미디어 파일 URL과 재생 위치 공유</string>
<string name="feed_delete_confirmation_msg">확인하면 \"%1$s\" 피드를 삭제하고 이 피드에서 다운로드한 모든 에피소드를 삭제합니다.</string>
<string name="feed_remover_msg">팟캐스트 삭제하는 중</string>
<string name="load_complete_feed">전체 팟캐스트 새로 고침</string>
@@ -136,14 +127,9 @@
<string name="select_all_above">위 모두 선택</string>
<string name="select_all_below">아래 모두 선택</string>
<string name="hide_unplayed_episodes_label">재생 안 함</string>
- <string name="hide_paused_episodes_label">일시 중지함</string>
- <string name="hide_played_episodes_label">재생함</string>
<string name="hide_queued_episodes_label">대기열 추가함</string>
<string name="hide_not_queued_episodes_label">대기열 추가 안 함</string>
- <string name="hide_downloaded_episodes_label">다운로드함</string>
- <string name="hide_not_downloaded_episodes_label">다운로드 안 함</string>
<string name="hide_has_media_label">미디어 있음</string>
- <string name="hide_is_favorite_label">즐겨찾기 포함</string>
<string name="filtered_label">필터링함</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} 최근 새로 고침 실패</string>
<string name="open_podcast">팟캐스트 열기</string>
@@ -159,9 +145,6 @@
<string name="delete_label">삭제</string>
<string name="delete_failed">파일을 삭제할 수 없습니다. 장치를 재부팅하면 동작할 수도 있습니다.</string>
<string name="delete_episode_label">에피소드 삭제</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="other">%d개 에피소드 삭제함.</item>
- </plurals>
<string name="remove_new_flag_label">\"신규\" 플래그 제거</string>
<string name="removed_new_flag_label">\"신규\" 플래그 제거함</string>
<string name="mark_read_label">재생했다고 표시</string>
@@ -228,7 +211,6 @@
</plurals>
<string name="downloads_processing">다운로드 처리 중</string>
<string name="download_notification_title">팟캐스트 데이터 다운로드 중</string>
- <string name="download_report_content">다운로드 %1$d개 성공, %2$d개 실패</string>
<string name="download_log_title_unknown">알 수 없는 제목</string>
<string name="download_type_feed">피드</string>
<string name="download_type_media">미디어 파일</string>
@@ -241,7 +223,6 @@
<string name="confirm_mobile_download_dialog_message">휴대전화망 데이터 연결을 통한 다운로드는 설정에서 막혀 있습니다.\n\n임시로 다운로드를 열 수 있습니다\n\n<small>여기서 선택한 사항은 10분 동안 유지됩니다.</small></string>
<string name="confirm_mobile_streaming_notification_title">휴대전화망 스트리밍 확인</string>
<string name="confirm_mobile_streaming_notification_message">휴대전화 데이터 연결을 통한 스트리밍은 사용하지 않게 설정되어 있습니다. 그래도 스트리밍을 하려면 누르십시오.</string>
- <string name="confirm_mobile_streaming_button_always">항상 허용</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">대기열에 추가</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">임시로 허용</string>
<!--Mediaplayer messages-->
@@ -287,7 +268,6 @@
<string name="download_plugin_label">플러그인 다운로드</string>
<string name="no_playback_plugin_title">플러그인을 설치하지 않았습니다</string>
<string name="no_playback_plugin_or_sonic_msg">여러가지 속도로 재생이 동작하려면 내부의 소닉 미디어 플레이어 사용을 추천합니다.</string>
- <string name="set_playback_speed_label">재생 속도</string>
<string name="enable_sonic">소닉 사용</string>
<!--Empty list labels-->
<string name="no_items_header_label">대기열의 에피소드 없음</string>
@@ -361,7 +341,6 @@
<string name="pref_autoUpdateIntervallOrTime_every">매 %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">%1$s에서</string>
<string name="pref_followQueue_title">연속 재생</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">헤드폰 연결 끊김</string>
<string name="pref_unpauseOnHeadsetReconnect_title">헤드폰 다시 연결</string>
<string name="pref_unpauseOnBluetoothReconnect_title">블루투스 다시 연결</string>
<string name="pref_stream_over_download_title">스트리밍 우선</string>
@@ -374,7 +353,6 @@
<string name="pref_mobileUpdate_episode_download">에피소드 다운로드</string>
<string name="pref_mobileUpdate_streaming">스트리밍</string>
<string name="user_interface_label">사용자 인터페이스</string>
- <string name="user_interface_sum">모양, 구독 순서, 잠금 화면</string>
<string name="pref_set_theme_title">테마 선택</string>
<string name="pref_nav_drawer_items_title">네비게이션 드로어 항목 설정</string>
<string name="pref_nav_drawer_items_sum">네비게이션 드로어에 어떤 항목을 표시할지 바꿉니다.</string>
@@ -413,10 +391,7 @@
<string name="pref_gpodnet_full_sync_title">전체 동기화 강제</string>
<string name="pref_gpodnet_full_sync_sum">gpodder.net의 모든 구독과 에피소드 상태를 동기화합니다.</string>
<string name="pref_gpodnet_login_status"><![CDATA[<i>%1$s</i> 사용자로 로그인, <i>%2$s</i> 장치]]></string>
- <string name="pref_gpodnet_notifications_title">동기화 오류 알림 표시</string>
<string name="pref_gpodnet_notifications_sum">이 설정은 인증 오류에는 적용되지 않습니다.</string>
- <string name="pref_playback_speed_title">재생 속도</string>
- <string name="pref_playback_speed_sum">여러가지 오디오 재생 속도 직접 설정</string>
<string name="pref_feed_playback_speed_sum">이 팟캐스트의 에피소드를 재생할 때 사용할 오디오 재생 속도</string>
<string name="pref_feed_skip">자동 건너뛰기</string>
<string name="pref_feed_skip_sum">소개 및 마지막 크레디트 건너뛰기</string>
@@ -436,15 +411,11 @@
<string name="pref_expandNotify_sum">알림에서 재생 버튼이 표시되도록 확장합니다.</string>
<string name="pref_persistNotify_title">재생 조작 항상 표시</string>
<string name="pref_persistNotify_sum">재생이 일시 중지했을 때에도 알림과 잠금 화면의 조작 기능을 유지합니다.</string>
- <string name="pref_compact_notification_buttons_title">화면잠금 버튼 설정</string>
- <string name="pref_compact_notification_buttons_sum">잠금화면의 조작 버튼을 바꿉니다. 재생/일시중지 버튼은 항상 포함됩니다.</string>
<string name="pref_compact_notification_buttons_dialog_title">최대 %1$d개 항목 선택</string>
<string name="pref_compact_notification_buttons_dialog_error">최대 %1$d개 항목만 선택할 수 있습니다.</string>
<string name="pref_lockscreen_background_title">잠금 화면 배경 설정</string>
<string name="pref_lockscreen_background_sum">현재 에피소드의 이미지를 잠금 화면의 배경으로 설정합니다. 대신 이는 제3자 앱의 이미지도 표시하게 됩니다.</string>
- <string name="pref_showDownloadReport_title">다운로드 보고서 보기</string>
<string name="pref_showDownloadReport_sum">다운로드가 실패하면, 실패 이유를 자세히 표시하는 보고서를 만듭니다.</string>
- <string name="pref_showAutoDownloadReport_title">자동 다운로드 보고서 표시</string>
<string name="pref_showAutoDownloadReport_sum">자동 다운로드 에피소드 에 대해 알림을 표시합니다.</string>
<string name="pref_expand_notify_unsupport_toast">안드로이드 4.1 미만의 버전에서는 확장 알림을 지원하지 않습니다.</string>
<string name="pref_enqueue_location_title">대기열 추가 위치</string>
@@ -543,7 +514,6 @@
<string name="export_success_sum">내보낸 파일을 다음에 저장했습니다:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">OPML 파일을 읽으려면 외부 저장소 접근이 필요합니다</string>
<string name="import_select_file">가져올 파일을 선택하십시오</string>
- <string name="import_ok">내보내기 성공.\n\n안테나팟을 다시 시작하려면 확인을 누르십시오</string>
<string name="import_no_downgrade">이 데이터베이스는 더 새로운 버전의 안테나팟에서 내보낸 데이터베이스입니다. 현재 설치된 버전의 안테나팟에서는 이 파일을 제대로 처리하지 못할 수도 있습니다.</string>
<string name="favorites_export_label">즐겨찾기 내보내기</string>
<string name="favorites_export_summary">저장한 즐겨찾기를 파일로 내보내기</string>
@@ -635,7 +605,6 @@
<string name="decrease_speed">속도 감소</string>
<string name="media_type_audio_label">오디오</string>
<string name="media_type_video_label">비디오</string>
- <string name="navigate_upwards_label">위 단계로 이동</string>
<string name="status_downloading_label">에피소드를 다운로드하는 중입니다</string>
<string name="in_queue_label">에피소드가 대기열에 들어 있습니다</string>
<string name="is_favorite_label">에피소드를 좋아한다고 표시되었습니다</string>
@@ -665,16 +634,14 @@
<string name="search_itunes_label">iTunes 검색</string>
<string name="search_fyyd_label">fyyd 검색</string>
<string name="advanced">고급</string>
- <string name="add_podcast_by_url">URL로 팟캐스트 추가</string>
<string name="browse_gpoddernet_label">gpodder.net 둘러보기</string>
<string name="discover">발견</string>
<string name="discover_more">더 보기 »</string>
- <string name="search_powered_by">검색 기능 제공 %1$s</string>
+ <!--Local feeds-->
<string name="filter">필터</string>
<!--Episodes apply actions-->
<string name="all_label">모두</string>
<string name="selected_all_label">모든 에피소드 선택함</string>
- <string name="none_label">없음</string>
<string name="deselected_all_label">모든 에피소드 선택 해제함</string>
<string name="played_label">재생함</string>
<string name="selected_played_label">재생한 에피소드 선택함</string>
@@ -684,12 +651,17 @@
<string name="selected_downloaded_label">다운로드한 에피소드 선택함</string>
<string name="not_downloaded_label">다운로드 안 함</string>
<string name="selected_not_downloaded_label">다운로드 안 한 에피소드 선택함</string>
- <string name="queued_label">대기열에 있음</string>
<string name="selected_queued_label">대기열의 에피소드 선택함</string>
- <string name="not_queued_label">대기열에 없음</string>
<string name="selected_not_queued_label">대기열에 없는 에피소드 선택함</string>
- <string name="has_media">미디어 있음</string>
<string name="selected_has_media_label">미디어가 있는 에피소드 선택함</string>
+ <string name="hide_is_favorite_label">즐겨찾기 포함</string>
+ <string name="hide_downloaded_episodes_label">다운로드함</string>
+ <string name="hide_not_downloaded_episodes_label">다운로드 안 함</string>
+ <string name="queued_label">대기열에 있음</string>
+ <string name="not_queued_label">대기열에 없음</string>
+ <string name="has_media">미디어 있음</string>
+ <string name="hide_paused_episodes_label">일시 중지함</string>
+ <string name="hide_played_episodes_label">재생함</string>
<!--Sort-->
<string name="sort_title_a_z">제목 (A \u2192 Z)</string>
<string name="sort_title_z_a">제목 (Z \u2192 A)</string>
@@ -709,6 +681,7 @@
<string name="rating_never_label">관심 없음</string>
<string name="rating_later_label">나중에 알림</string>
<string name="rating_now_label">해봅시다!</string>
+ <!--Share episode dialog-->
<!--Audio controls-->
<string name="audio_controls">오디오 조작</string>
<string name="playback_speed">재생 속도</string>
@@ -755,7 +728,6 @@
<string name="notification_channel_playing">현재 재생 중</string>
<string name="notification_channel_playing_description">재생을 조작할 수 있습니다 .팟캐스트를 재생할 때 볼 수 있는 메인 알림입니다.</string>
<string name="notification_channel_error">오류</string>
- <string name="notification_channel_error_description">뭔가 잘못될 때 표시됩니다. 예를 들어 다운로드나 gpodder 동기화가 실패했을 경우.</string>
<string name="notification_channel_auto_download">자동 다운로드</string>
<string name="notification_channel_episode_auto_download">에피소드를 자동으로 다운로드했을 때 표시됩니다.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-lt/strings.xml b/core/src/main/res/values-lt/strings.xml
index 380a68120..fac693b25 100644
--- a/core/src/main/res/values-lt/strings.xml
+++ b/core/src/main/res/values-lt/strings.xml
@@ -26,16 +26,13 @@
<string name="playback_statistics_label">Atkūrimas</string>
<string name="download_statistics_label">Atsiuntimai</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Bendra perklausytų tinklalaidžių trukmė:</string>
<string name="statistics_details_dialog">Paleisti %1$d iš %2$d epizodų.\n\nPerklausyta %3$s iš %4$s.</string>
<string name="statistics_mode">Statistikos režimas</string>
<string name="statistics_mode_normal">Apskaičiuoti tikrąją atkūrimo trukmę. Perklausa dukart skaičiuojama dvigubai, o pažymėjimas perklausytu neskaičiuojamas</string>
- <string name="statistics_mode_count_all">Sumuoti visas tinklalaides, pažymėtas kaip perklausytas</string>
<string name="statistics_speed_not_counted">Atkreipkite dėmesį: į atkūrimo spartą neatsižvelgiama.</string>
<string name="statistics_reset_data">Nustatyti statistikos duomenis iš naujo</string>
<string name="statistics_reset_data_msg">Bus išvalyta visų epizodų perklausytos trukmės istorija. Ar tikrai norite tęsti?</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Bendras atsiųstų tinklalaidžių dydis:</string>
<!--Main activity-->
<string name="drawer_open">Atverti meniu</string>
<string name="drawer_close">Užverti meniu</string>
@@ -49,6 +46,7 @@
<string name="drawer_feed_counter_unplayed">Neperklausytų epizodų skaičius</string>
<string name="drawer_feed_counter_downloaded">Atsisiųstų epizodų skaičius</string>
<string name="drawer_feed_counter_none">Nieko</string>
+ <!--Bug report activity-->
<!--Webview actions-->
<string name="open_in_browser_label">Atverti naršyklėje</string>
<string name="copy_url_label">Kopijuoti URL</string>
@@ -130,14 +128,7 @@
<string name="feed_settings_label">Tinklalaidės nustatymai</string>
<string name="rename_feed_label">Pervadinti tinklalaidę</string>
<string name="remove_feed_label">Pašalinti tinklalaidę</string>
- <string name="share_label">Dalintis...</string>
- <string name="share_link_label">Dalintis epizodo URL</string>
- <string name="share_link_with_position_label">Dalintis epizodo URL su pozicija</string>
<string name="share_file_label">Dalintis failu</string>
- <string name="share_website_url_label">Dalintis svetainės URL</string>
- <string name="share_feed_url_label">Dalintis tinklalaidės URL</string>
- <string name="share_item_url_label">Dalintis medijos failo URL</string>
- <string name="share_item_url_with_position_label">Dalintis medijos failo adresu su pozicija</string>
<string name="feed_delete_confirmation_msg">Patvirtinkite, jog norite ištrinti tinklalaidę „%1$s“ ir VISUS jos epizodus (įskaitant atsiųstus epizodus).</string>
<string name="feed_remover_msg">Tinklalaidė šalinama</string>
<string name="load_complete_feed">Atnaujinti visą tinklalaidę</string>
@@ -145,14 +136,9 @@
<string name="select_all_above">Pažymėti visus aukščiau</string>
<string name="select_all_below">Pažymėti visus žemiau</string>
<string name="hide_unplayed_episodes_label">Neperklausyti</string>
- <string name="hide_paused_episodes_label">Pristabdyti</string>
- <string name="hide_played_episodes_label">Perklausyti</string>
<string name="hide_queued_episodes_label">Esantys eilėje</string>
<string name="hide_not_queued_episodes_label">Nesantys eilėje</string>
- <string name="hide_downloaded_episodes_label">Atsiųsti</string>
- <string name="hide_not_downloaded_episodes_label">Neatsiųsti</string>
<string name="hide_has_media_label">Turintys medijos failų</string>
- <string name="hide_is_favorite_label">Mėgstami</string>
<string name="filtered_label">Filtruota</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Paskutinis atnaujinimas nepavyko</string>
<string name="open_podcast">Atverti tinklalaidę</string>
@@ -171,12 +157,6 @@
<string name="delete_label">Ištrinti</string>
<string name="delete_failed">Nepavyksta ištrinti failo. Įrenginio paleidimas iš naujo gali padėti.</string>
<string name="delete_episode_label">Ištrinti epizodą</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d epizodas ištrintas.</item>
- <item quantity="few">%d epizodai ištrinti.</item>
- <item quantity="many">%d epizodai ištrinti.</item>
- <item quantity="other">%d epizodai ištrinti.</item>
- </plurals>
<string name="remove_new_flag_label">Pašalinti „naujas“ gairelę</string>
<string name="removed_new_flag_label">„naujas“ gairelė pašalinta</string>
<string name="mark_read_label">Pažymėti kaip perklausytą</string>
@@ -258,7 +238,6 @@
</plurals>
<string name="downloads_processing">Apdorojami atsiuntimai</string>
<string name="download_notification_title">Atsiunčiami tinklalaidės duomenys</string>
- <string name="download_report_content">%1$d atsiuntimai sėkmingi, %2$d nepavyko</string>
<string name="download_log_title_unknown">Nežinomas pavadinimas</string>
<string name="download_type_feed">Sklaidos kanalas</string>
<string name="download_type_media">Medijos failas</string>
@@ -271,7 +250,6 @@
<string name="confirm_mobile_download_dialog_message">Atsiuntimas mobiliuoju internetu išjungtas nustatymuose.\n\nAr norite laikinai leisti atsiuntimą?\n\n<small>Jūsų pasirinkimas bus prisimenamas 10 minučių.</small></string>
<string name="confirm_mobile_streaming_notification_title">Patvirtinkite tiesioginį klausymąsi mobiliuoju internetu</string>
<string name="confirm_mobile_streaming_notification_message">Tiesioginis klausymasis mobiliuoju internetu išjungtas nustatymuose. Spustelėkite, jei vis tiek norite klausytis tiesiogiai.</string>
- <string name="confirm_mobile_streaming_button_always">Leisti visada</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Pridėti į eilę</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Laikinai leisti</string>
<!--Mediaplayer messages-->
@@ -317,7 +295,6 @@
<string name="download_plugin_label">Atsiųsti įskiepį</string>
<string name="no_playback_plugin_title">Įskiepis neįdiegtas</string>
<string name="no_playback_plugin_or_sonic_msg">Tinkamam kintamos atkūrimo spartos veikimui rekomenduojame įjungti įtaisytąją „Sonic“ medijos leistuvę.</string>
- <string name="set_playback_speed_label">Atkūrimo spartos</string>
<string name="enable_sonic">Įjungti „Sonic“</string>
<!--Empty list labels-->
<string name="no_items_header_label">Epizodų eilėje nėra</string>
@@ -391,7 +368,6 @@
<string name="pref_autoUpdateIntervallOrTime_every">kas %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">lygiai %1$s</string>
<string name="pref_followQueue_title">Nenutrūkstamas atkūrimas</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Ausinių atjungimas</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Pakartotinai prijungus ausines</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Pakartotinai prisijungus prie „Bluetooth“</string>
<string name="pref_stream_over_download_title">Teikti pirmenybę klausymuisi tiesiogiai</string>
@@ -404,7 +380,6 @@
<string name="pref_mobileUpdate_episode_download">Epizodų atsiuntimas</string>
<string name="pref_mobileUpdate_streaming">Klausymasis tiesiogiai</string>
<string name="user_interface_label">Vartotojo sąsaja</string>
- <string name="user_interface_sum">Išvaizda, prenumeratų tvarka, ekrano užraktas</string>
<string name="pref_set_theme_title">Pasirinkti temą</string>
<string name="pref_nav_drawer_items_title">Nustatyti naršymo stalčiaus elementus</string>
<string name="pref_nav_drawer_items_sum">Keisti naršymo stalčiuje rodomus elementus.</string>
@@ -443,10 +418,7 @@
<string name="pref_gpodnet_full_sync_title">Priverstinis pilnas sinchronizavimas</string>
<string name="pref_gpodnet_full_sync_sum">Sinchronizuoti visas prenumeratas bei epizodų būsenas su „gpodder.net“.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Prisijungta kaip <i>%1$s</i> naudojant įrenginį <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Rodyti sinchronizavimo klaidų pranešimus</string>
<string name="pref_gpodnet_notifications_sum">Šis nustatymas negalioja tapatumo nustatymo klaidoms.</string>
- <string name="pref_playback_speed_title">Atkūrimo sparta</string>
- <string name="pref_playback_speed_sum">Derinkite prieinamas garso atkūrimo spartas</string>
<string name="pref_feed_playback_speed_sum">Atkūrimo sparta, naudojama pradedant šios tinklalaidės epizodų atkūrimą</string>
<string name="pref_feed_skip">Automatinis praleidimas</string>
<string name="pref_feed_skip_sum">Praleisti įvadą ir pabaigos žodį.</string>
@@ -466,15 +438,11 @@
<string name="pref_expandNotify_sum">Tai dažniausiai išskleidžia pranešimą, kad būtų rodomi atkūrimo valdymo mygtukai.</string>
<string name="pref_persistNotify_title">Pastovūs atkūrimo valdikliai</string>
<string name="pref_persistNotify_sum">Pristabdžius atkūrimą palikti valdiklius ekrano užrakte bei programų pranešimuose. </string>
- <string name="pref_compact_notification_buttons_title">Nustatyti ekrano užrakto mygtukus</string>
- <string name="pref_compact_notification_buttons_sum">Keisti ekrano užrakte matomus atkūrimo valdymo mygtukus. Atkūrimo/pristabdymo mygtukas matomas visada.</string>
<string name="pref_compact_notification_buttons_dialog_title">Pasirinkite daugiausiai %1$d elementus</string>
<string name="pref_compact_notification_buttons_dialog_error">Galite pasirinkti daugiausiai %1$d elementus.</string>
<string name="pref_lockscreen_background_title">Nustatyti ekrano užrakto foną</string>
<string name="pref_lockscreen_background_sum">Atkuriamo epizodo paveikslėlį naudoti kaip ekrano užrakto foną. Paveikslėlis taip pat bus matomas trečiųjų šalių programėlėse.</string>
- <string name="pref_showDownloadReport_title">Rodyti atsiuntimų ataskaitą</string>
<string name="pref_showDownloadReport_sum">Atsiuntimui nepavykus, sukurti ataskaitą su išsamiu klaidų aprašymu.</string>
- <string name="pref_showAutoDownloadReport_title">Rodyti automatinių atsiuntimų ataskaitą</string>
<string name="pref_showAutoDownloadReport_sum">Rodyti pranešimą automatiškai atsiuntus epizodus.</string>
<string name="pref_expand_notify_unsupport_toast">Ankstesnės nei 4.1 „Android“ versijos nepalaiko išplėstų programos pranešimų.</string>
<string name="pref_enqueue_location_title">Pridėjimo į eilę vieta</string>
@@ -573,9 +541,6 @@
<string name="export_success_sum">Eksporto failas išsaugotas:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Norint nuskaityti OPML failą reikalinga prieiga prie išorinės laikmenos</string>
<string name="import_select_file">Pasirinkite failą, kurį norite importuoti</string>
- <string name="import_ok">Importuota sėkmingai.
-
-Spauskite „OK“, kad paleisti „AntennaPod“ iš naujo.</string>
<string name="import_no_downgrade">Ši duomenų bazė buvo eksportuota naudojant naujesnę „AntennaPod“ versija. Dabartinė įdiegtis nežino, kaip apdorotį šį failą.</string>
<string name="favorites_export_label">Mėgstamųjų eksportas</string>
<string name="favorites_export_summary">Mėgstamieji išsaugoti faile</string>
@@ -676,7 +641,6 @@ Spauskite „OK“, kad paleisti „AntennaPod“ iš naujo.</string>
<string name="decrease_speed">Sumažinti spartą</string>
<string name="media_type_audio_label">Garsas</string>
<string name="media_type_video_label">Vaizdas</string>
- <string name="navigate_upwards_label">Eiti aukštyn</string>
<string name="status_downloading_label">Epizodas atsiunčiamas</string>
<string name="in_queue_label">Epizodas yra eilėje</string>
<string name="is_favorite_label">Epizodas pažymėtas kaip mėgstamas</string>
@@ -706,16 +670,14 @@ Spauskite „OK“, kad paleisti „AntennaPod“ iš naujo.</string>
<string name="search_itunes_label">Ieškoti „iTunes“</string>
<string name="search_fyyd_label">Ieškoti „fyyd“</string>
<string name="advanced">Išplėstinis</string>
- <string name="add_podcast_by_url">Pridėti tinklalaidę pagal URL adresą</string>
<string name="browse_gpoddernet_label">Naršyti gpodder.net svetainėje</string>
<string name="discover">Atraskite</string>
<string name="discover_more">daugiau »</string>
- <string name="search_powered_by">Paiešką įgalina %1$s</string>
+ <!--Local feeds-->
<string name="filter">Filtruoti</string>
<!--Episodes apply actions-->
<string name="all_label">Visi</string>
<string name="selected_all_label">Pažymėti visi epizodai</string>
- <string name="none_label">Jokie</string>
<string name="deselected_all_label">Panaikintas visų epizodų žymėjimas</string>
<string name="played_label">Perklausyti</string>
<string name="selected_played_label">Pažymėti perklausyti epizodai</string>
@@ -725,12 +687,17 @@ Spauskite „OK“, kad paleisti „AntennaPod“ iš naujo.</string>
<string name="selected_downloaded_label">Pažymėti atsiųsti epizodai</string>
<string name="not_downloaded_label">Neatsiųsti</string>
<string name="selected_not_downloaded_label">Pažymėti neatsiųsti epizodai</string>
- <string name="queued_label">Eilėje</string>
<string name="selected_queued_label">Pažymėti epizodai, esantys eilėje</string>
- <string name="not_queued_label">Ne eilėje</string>
<string name="selected_not_queued_label">Pažymėti epizodai, nesantys eilėje</string>
- <string name="has_media">Turintys medijos failų</string>
<string name="selected_has_media_label">Pažymėti epizodai, turintys medijos failų</string>
+ <string name="hide_is_favorite_label">Mėgstami</string>
+ <string name="hide_downloaded_episodes_label">Atsiųsti</string>
+ <string name="hide_not_downloaded_episodes_label">Neatsiųsti</string>
+ <string name="queued_label">Eilėje</string>
+ <string name="not_queued_label">Ne eilėje</string>
+ <string name="has_media">Turintys medijos failų</string>
+ <string name="hide_paused_episodes_label">Pristabdyti</string>
+ <string name="hide_played_episodes_label">Perklausyti</string>
<!--Sort-->
<string name="sort_title_a_z">Pavadinimas (A \u2192 Z)</string>
<string name="sort_title_z_a">Pavadinimas (Z \u2192 A)</string>
@@ -750,6 +717,7 @@ Spauskite „OK“, kad paleisti „AntennaPod“ iš naujo.</string>
<string name="rating_never_label">Palikite mane ramybėje</string>
<string name="rating_later_label">Priminti vėliau</string>
<string name="rating_now_label">Žinoma, padarykime tai!</string>
+ <!--Share episode dialog-->
<!--Audio controls-->
<string name="audio_controls">Garso valdikliai</string>
<string name="playback_speed">Atkūrimo sparta</string>
@@ -796,7 +764,6 @@ Spauskite „OK“, kad paleisti „AntennaPod“ iš naujo.</string>
<string name="notification_channel_playing">Šiuo metu atkuriama</string>
<string name="notification_channel_playing_description">Leidžia valdyti atkūrimą. Tai pagrindinis pranešimas matomas tinklalaidės atkūrimo metu.</string>
<string name="notification_channel_error">Klaidos</string>
- <string name="notification_channel_error_description">Rodomas, kai įvykstą kažkas nenumatyto, pavyzdžiui, nepavykus atsiuntimui ar „gpodder“ sinchronizavimui.</string>
<string name="notification_channel_auto_download">Automatiniai atsiuntimai</string>
<string name="notification_channel_episode_auto_download">Rodomas automatiškai atsiuntus epizodus.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-nb/strings.xml b/core/src/main/res/values-nb/strings.xml
index ccdc9a28c..eb653afd2 100644
--- a/core/src/main/res/values-nb/strings.xml
+++ b/core/src/main/res/values-nb/strings.xml
@@ -9,7 +9,7 @@
<string name="all_episodes_short_label">Alle</string>
<string name="new_episodes_label">Nye</string>
<string name="favorite_episodes_label">Favoritter</string>
- <string name="new_label">Nye</string>
+ <string name="new_label">Ny</string>
<string name="settings_label">Innstillinger</string>
<string name="downloads_label">Nedlastninger</string>
<string name="downloads_running_label">Kjører</string>
@@ -25,8 +25,9 @@
<string name="episode_cache_full_message">Grensen for størrelse på hurtigbuffer er nådd. Du kan øke størrelsen på hurtigbuffer i innstillingene.</string>
<string name="playback_statistics_label">Avspilling</string>
<string name="download_statistics_label">Nedlastinger</string>
+ <string name="notification_pref_fragment">Varslinger</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Sum av tid i avspilte podkaster:</string>
+ <string name="total_time_listened_to_podcasts">Total tid, avspilte episoder</string>
<string name="statistics_details_dialog">Startet %1$d av %2$d episoder.\n\nAvspilt %3$s av %4$s.</string>
<string name="statistics_mode">Statistikkmodus</string>
<string name="statistics_mode_normal">Beregn faktisk avspilt varighet. Dobbel avspilling telles to ganger, mens markering som avspilt telles ikke</string>
@@ -34,6 +35,7 @@
<string name="statistics_speed_not_counted">Merk: Avspillingshastighet tas aldri med i betraktningen.</string>
<string name="statistics_reset_data">Tilbakestill statistikkdata</string>
<string name="statistics_reset_data_msg">Dette vil slette historikk om varighet som er spilt for alle episoder. Er du sikker på at du vil fortsette?</string>
+ <string name="statistics_counting_since">Siden %s,\nhar du spilt</string>
<!--Download Statistics fragment-->
<string name="total_size_downloaded_podcasts">Total størrelse på nedlastede podkaster:</string>
<!--Main activity-->
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Antall uavspilte episoder</string>
<string name="drawer_feed_counter_downloaded">Antall nedlastede episoder</string>
<string name="drawer_feed_counter_none">Ingen</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Fant ingen kompatible apper</string>
<!--Webview actions-->
<string name="open_in_browser_label">Åpne i nettleser</string>
<string name="copy_url_label">Kopier URL</string>
@@ -85,6 +89,7 @@
<string name="auto_download_apply_to_items_message">Den nye <i>Automatisk nedlasting</i>-innstillingen vil automatisk aktiveres for nye episoder.\nØnsker du å aktivere den for tidligere utgitte episoder også?</string>
<string name="auto_delete_label">Slett episode automatisk</string>
<string name="feed_volume_reduction">Volumreduksjon</string>
+ <string name="feed_volume_reduction_summary">Demp volumet for episoder i denne strømmen: %1$s</string>
<string name="feed_volume_reduction_off">Av</string>
<string name="feed_volume_reduction_light">Lett</string>
<string name="feed_volume_reduction_heavy">Tung</string>
@@ -119,14 +124,11 @@
<string name="feed_settings_label">Podkastinnstillinger</string>
<string name="rename_feed_label">Gi nytt navn til podkast</string>
<string name="remove_feed_label">Fjern podkast</string>
- <string name="share_label">Del ...</string>
- <string name="share_link_label">Del episodens URL</string>
- <string name="share_link_with_position_label">Del episodens URL med posisjon</string>
+ <string name="share_label">Del</string>
+ <string name="share_label_with_ellipses">Del…</string>
<string name="share_file_label">Del fil</string>
- <string name="share_website_url_label">Del nettsidens URL</string>
- <string name="share_feed_url_label">Del podkastens URL</string>
- <string name="share_item_url_label">Del mediafilens URL</string>
- <string name="share_item_url_with_position_label">Del mediafilens URL med posisjon</string>
+ <string name="share_website_url_label">Nettsidens adresse</string>
+ <string name="share_feed_url_label">Podcaststrøm-URL</string>
<string name="feed_delete_confirmation_msg">Bekreft at du ønsker å slette podkasten \"%1$s\" og ALLE episodene dens (inkludert nedlastede episoder).</string>
<string name="feed_remover_msg">Fjerner podkast</string>
<string name="load_complete_feed">Last hele podkasten på nytt</string>
@@ -134,14 +136,9 @@
<string name="select_all_above">Velg alle over</string>
<string name="select_all_below">Velg alle under</string>
<string name="hide_unplayed_episodes_label">Ikke avspilt</string>
- <string name="hide_paused_episodes_label">Pauset</string>
- <string name="hide_played_episodes_label">Avspilt</string>
<string name="hide_queued_episodes_label">I kø</string>
<string name="hide_not_queued_episodes_label">Ikke i kø</string>
- <string name="hide_downloaded_episodes_label">Nedlastet</string>
- <string name="hide_not_downloaded_episodes_label">Ikke nedlastet</string>
<string name="hide_has_media_label">Har medier</string>
- <string name="hide_is_favorite_label">Er favoritt</string>
<string name="filtered_label">Filtrert</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Siste oppdatering mislyktes</string>
<string name="open_podcast">Åpne podkast</string>
@@ -158,10 +155,6 @@
<string name="delete_label">Slett</string>
<string name="delete_failed">Kan ikke slette filen. Omstart av enheten kan hjelpe.</string>
<string name="delete_episode_label">Slett episode</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d episode slettet.</item>
- <item quantity="other">%d episode slettet.</item>
- </plurals>
<string name="remove_new_flag_label">Fjern \"Ny\"-markering</string>
<string name="removed_new_flag_label">Fjernet \"Ny\"-markering</string>
<string name="mark_read_label">Marker som avspilt</string>
@@ -200,6 +193,7 @@
<string name="deactivate_auto_download">Deaktiver automatisk nedlasting</string>
<string name="reset_position">Tilbakestill avspillingsposisjon</string>
<string name="removed_item">Element fjernet</string>
+ <string name="no_items_selected">Ingen ting er valgt</string>
<!--Download messages and labels-->
<string name="download_successful">vellykket</string>
<string name="download_pending">Nedlastning venter</string>
@@ -232,7 +226,10 @@
</plurals>
<string name="downloads_processing">Behandler nedlastninger</string>
<string name="download_notification_title">Laster ned data til podkast</string>
- <string name="download_report_content">%1$d nedlastninger lyktes, %2$d mislyktes</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%1$d nedlastninger lyktes, %2$d mislyktes</item>
+ <item quantity="other">%d nedlastinger lyktes, %d mislyktes</item>
+ </plurals>
<string name="download_log_title_unknown">Ukjent tittel</string>
<string name="download_type_feed">Strøm</string>
<string name="download_type_media">Mediafil</string>
@@ -245,7 +242,8 @@
<string name="confirm_mobile_download_dialog_message">Nedlasting over mobildata er deaktivert i innstillingene.\n\nVil du tillate nedlasting over mobildata midlertidig?\n\n<small>Valget ditt vil gjelde i 10 minutter.</small></string>
<string name="confirm_mobile_streaming_notification_title">Bekreft mobil strømming</string>
<string name="confirm_mobile_streaming_notification_message">Strømming over mobildata er deaktivert i innstillingene. Trykk for å strømme likevel.</string>
- <string name="confirm_mobile_streaming_button_always">Tillat alltid</string>
+ <string name="confirm_mobile_streaming_button_always">Alltid</string>
+ <string name="confirm_mobile_streaming_button_once">Én gang</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Legg til i kø</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Tillat midlertidig</string>
<!--Mediaplayer messages-->
@@ -291,8 +289,9 @@
<string name="download_plugin_label">Last ned programtillegg</string>
<string name="no_playback_plugin_title">Programtillegg er ikke installert</string>
<string name="no_playback_plugin_or_sonic_msg">For at avspilling med varierende hastighet skal virke, anbefaler vi å bruke den innebygde Sonic-mediespilleren.</string>
- <string name="set_playback_speed_label">Avspillingshastigheter</string>
<string name="enable_sonic">Skru på Sonic</string>
+ <string name="speed_presets">Ferdiginstillinger</string>
+ <string name="preset_already_exists">%1$.2fx er allerede lagret som en ferdiginstilling.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Ingen episoder i kø</string>
<string name="no_items_label">Legg til en episode ved å laste den ned, eller trykk og hold på en episode og velg \"Legg til i køen\".</string>
@@ -321,6 +320,7 @@
<string name="project_pref">Prosjekt</string>
<string name="queue_label">Kø</string>
<string name="synchronization_pref">Synkronisering</string>
+ <string name="synchronization_sum">Synkroniser med andre enheter over gpodder.net</string>
<string name="automation">Automasjon</string>
<string name="download_pref_details">Detaljer</string>
<string name="import_export_pref">Importer/Eksporter</string>
@@ -338,10 +338,10 @@
<string name="pref_pauseOnDisconnect_sum">Sett playback på pause når hodetelefoner eller bluetooth er frakoblet</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Gjenoppta avspilling når hodetelefoner gjeninnkoples</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Fortsett avspilling når bluetooth er tilkoblet igjen</string>
- <string name="pref_hardwareForwardButtonSkips_title">\"Forover\"-knapp hopper over</string>
- <string name="pref_hardwareForwardButtonSkips_sum">Hopp til neste episode i stedet for å spole når \"Fremover\"-knapp trykkes</string>
+ <string name="pref_hardwareForwardButtonSkips_title">\"Fremover\" hopper over</string>
+ <string name="pref_hardwareForwardButtonSkips_sum">Hopp til neste episode i stedet for å spole når du trykker på \"Fremover\"-knappen</string>
<string name="pref_hardwarePreviousButtonRestarts_title">Forriv</string>
- <string name="pref_hardwarePreviousButtonRestarts_sum">Start episoden på nytt i stedet for å spole når \"Tilbake\"-knapp trykkes</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Start episoden på nytt i stedet for å spole når du trykker på \"Tilbake\"-knappen</string>
<string name="pref_followQueue_sum">Hopp til neste element i køen når avspillingen er ferdig</string>
<string name="pref_auto_delete_sum">Slett episode når avspillingen er ferdig</string>
<string name="pref_auto_delete_title">Automatisk sletting</string>
@@ -364,11 +364,11 @@
<string name="pref_autoUpdateIntervallOrTime_every">hver %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">ved %1$s</string>
<string name="pref_followQueue_title">Kontinuerlig avspilling</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Frakobling av hodetelefoner</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Koblet fra hodetelefoner eller Bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Gjeninnkopling av hodetelefoner</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Blutetooth tilkoblet igjen</string>
<string name="pref_stream_over_download_title">Foretrekk strømming</string>
- <string name="pref_stream_over_download_sum">Vis strømmeknapp i stedet for nedlastingsknapp i lister.</string>
+ <string name="pref_stream_over_download_sum">Vis knapp for å strømme i stedet for for nedlasting i lister.</string>
<string name="pref_mobileUpdate_title">Mobiloppdateringer</string>
<string name="pref_mobileUpdate_sum">Velg hva som skal tillates over mobildata</string>
<string name="pref_mobileUpdate_refresh">Last podkast på nytt</string>
@@ -377,7 +377,7 @@
<string name="pref_mobileUpdate_episode_download">Nedlasting av episoder</string>
<string name="pref_mobileUpdate_streaming">Strømming</string>
<string name="user_interface_label">Brukergrensesnitt</string>
- <string name="user_interface_sum">Utseende, rekkefølge på abonnementer, låseskjerm</string>
+ <string name="user_interface_sum">Utseende, Abonnementer, Låsskjerm</string>
<string name="pref_set_theme_title">Velg tema</string>
<string name="pref_nav_drawer_items_title">Velg elementer i navigasjonsskuffen</string>
<string name="pref_nav_drawer_items_sum">Endre hvilke elementer som vises i navigeringsfanen.</string>
@@ -411,18 +411,24 @@
<string name="pref_gpodnet_logout_toast">Utloggelse lyktes</string>
<string name="pref_gpodnet_setlogin_information_title">Endre innloggingsinformasjon</string>
<string name="pref_gpodnet_setlogin_information_sum">Endre innlogginsinformasjonen til din gpodder.net konto</string>
+ <string name="pref_gpodnet_sync_changes_title">Synkroniser nå</string>
<string name="pref_gpodnet_sync_changes_sum">Synkroniser abonnement og episoder med gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Tving fram full synkronisering</string>
<string name="pref_gpodnet_full_sync_sum">Synkroniser alle abonnement og episoder med gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Logget inn som <i>%1$s</i> med enhet <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Vis synkroniseringsfeil varsler</string>
+ <string name="pref_gpodnet_notifications_title">Synkronisering feilet</string>
<string name="pref_gpodnet_notifications_sum">Denne instillingen gjelder ikke autentiseringfeil.</string>
- <string name="pref_playback_speed_title">Avspillingshastigheter</string>
- <string name="pref_playback_speed_sum">Egendefiner hastighetene tilgjengelig for variabel avspillingshastighet</string>
<string name="pref_feed_playback_speed_sum">Hastigheten som brukes når episoder av denne podkasten spilles av</string>
+ <string name="pref_feed_skip">Automatisk hopp</string>
+ <string name="pref_feed_skip_sum">Hopp over introer og \"rulletekster\"</string>
+ <string name="pref_feed_skip_ending">Hopp over siste</string>
+ <string name="pref_feed_skip_intro">Hopp over første</string>
+ <string name="pref_feed_skip_ending_toast">Hoppet over siste %d sekunder</string>
+ <string name="pref_feed_skip_intro_toast">Hoppet over første %d sekunder</string>
<string name="pref_playback_time_respects_speed_title">Juster media-info til avspillingshastighet</string>
<string name="pref_playback_time_respects_speed_sum">Vist posisjon og varighet tilpasses avspillingshastighet</string>
<string name="pref_fast_forward">Hopp fremover</string>
- <string name="pref_fast_forward_sum">Velg hvor mange sekunder som skal hoppes når \"Spol fremover\"-knappen trykkes</string>
+ <string name="pref_fast_forward_sum">Velg hvor mange sekunder som skal hoppes når du trykker på \"Spol fremover\"-knappen</string>
<string name="pref_rewind">Hopp tilbake</string>
<string name="pref_rewind_sum">Velg hvor mange sekunder som skal hoppes tilbake når \"Spol tilbake\"-knappen trykkes</string>
<string name="pref_gpodnet_sethostname_title">Sett vertsnavn</string>
@@ -431,15 +437,13 @@
<string name="pref_expandNotify_sum">Dette utvider som regel varslingen for å vise kontroller.</string>
<string name="pref_persistNotify_title">Vedvarende avspillingskontroller</string>
<string name="pref_persistNotify_sum">Behold varsel- og låseskjermkontroller når avspilling er satt på pause.</string>
- <string name="pref_compact_notification_buttons_title">Velg låseskjermsknapper</string>
- <string name="pref_compact_notification_buttons_sum">Endre kontrollene på låseskjermen. Spill/pause-knappen er alltid inkludert.</string>
+ <string name="pref_compact_notification_buttons_title">Set kompakte notifikasjonsknapper</string>
<string name="pref_compact_notification_buttons_dialog_title">Velg opp til %1$d ting</string>
<string name="pref_compact_notification_buttons_dialog_error">Du kan kun velge opp til %1$d ting.</string>
<string name="pref_lockscreen_background_title">Angi som bakgrunn på låseskjermen</string>
<string name="pref_lockscreen_background_sum">Angir låseskjermbakgrunnsbildet til å være den nåværende episodens bilde. Som en sideeffekt vil dette også vise bildet i tredjepartsapper.</string>
- <string name="pref_showDownloadReport_title">Vis nedlastingsrapport</string>
<string name="pref_showDownloadReport_sum">Generer en rapport som viser detaljer dersom nedlastinger feiler.</string>
- <string name="pref_showAutoDownloadReport_title">Vis rapport fra auto-nedlasting</string>
+ <string name="pref_showAutoDownloadReport_title">Automatisk nedlasting fullført</string>
<string name="pref_showAutoDownloadReport_sum">Vis en varsling for automatisk nedlastede episoder</string>
<string name="pref_expand_notify_unsupport_toast">Android-versjoner tidligere enn 4.1 støtter ikke utvidede varsler.</string>
<string name="pref_enqueue_location_title">Plassering i køen</string>
@@ -469,6 +473,8 @@
<string name="pref_enqueue_downloaded_title">Legg til nedlastede i køen</string>
<string name="pref_enqueue_downloaded_summary">Legg til nedlastede episoder i køen</string>
<string name="media_player_builtin">Innebygd Android-spiller</string>
+ <string name="media_player_switch_to_exoplayer">Bytt til ExoPlayer</string>
+ <string name="media_player_switched_to_exoplayer">Byttet til ExoPlayer</string>
<string name="pref_skip_silence_title">Hopp over stillhet</string>
<string name="pref_videoBehavior_title">Når video lukkes</string>
<string name="pref_videoBehavior_sum">Oppførsel når video-avspilling lukkes</string>
@@ -490,8 +496,10 @@
<!--About screen-->
<string name="about_pref">Om</string>
<string name="antennapod_version">AntennaPod versjon</string>
+ <string name="contributors">Bidragsytere</string>
<string name="developers">Utviklere</string>
<string name="translators">Oversettere</string>
+ <string name="special_thanks">Spesiell takk til</string>
<string name="privacy_policy">Personvern</string>
<string name="licenses">Lisenser</string>
<string name="licenses_summary">AntennaPod bruker annen flott programvare</string>
@@ -525,7 +533,7 @@
<string name="export_success_sum">Den eksporterte filen ble skrevet til:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Tilgang til ekstern lagring er nødvendig for å lese OPML filen</string>
<string name="import_select_file">Velg fil å importere</string>
- <string name="import_ok">Importering vellykket!\n\nTrykk OK for å starte AntennaPod på nytt</string>
+ <string name="successful_import_label">Eksportering vellykket</string>
<string name="import_no_downgrade">Denne databasen ble eksportert fra en nyere versjon av AntennaPod. Din versjon av AntennaPod kan ikke lese denne filen enda.</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Sett opp sovetimer</string>
@@ -610,19 +618,21 @@
<string name="subscribe_label">Abonner</string>
<string name="subscribing_label">Abonnerer...</string>
<string name="preview_episode">Forhåndsvisning</string>
+ <string name="stop_preview">Stopp forhåndsvisning</string>
<!--Content descriptions for image buttons-->
<string name="rewind_label">Spol tilbake</string>
<string name="fast_forward_label">Spol fremover</string>
+ <string name="increase_speed">Øk hastighet</string>
+ <string name="decrease_speed">Reduser hastigheten</string>
<string name="media_type_audio_label">Lyd</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Naviger oppover</string>
<string name="status_downloading_label">Episode lastes ned nå</string>
<string name="in_queue_label">Episoden er i køen</string>
<string name="drag_handle_content_description">Dra for å endre posisjonen til dette objektet</string>
<string name="load_next_page_label">Last inn neste side</string>
<!--Feed information screen-->
<string name="authentication_label">Autentisering</string>
- <string name="authentication_descr">Endre brukernavnet og passordet for denne podkasten og dens episoder.</string>
+ <string name="authentication_descr">Endre brukernavnet og passordet for denne podkasten og dens episoder</string>
<string name="auto_download_settings_label">Innstillinger for automatisk nedlastning</string>
<string name="episode_filters_label">Episodefilter</string>
<string name="episode_filters_description">Nøkkelord som skal brukes for å avgjøre om en episode skal nedlastes automatisk eller ikke</string>
@@ -639,17 +649,22 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Søk etter podkast...</string>
<string name="search_itunes_label">Søk på iTunes</string>
+ <string name="search_podcastindex_label">Søk i Podcastindex.org</string>
<string name="search_fyyd_label">Søk med fyyd</string>
<string name="advanced">Avansert</string>
- <string name="add_podcast_by_url">Legg til podkast med URL</string>
<string name="browse_gpoddernet_label">Bla gjennom gpodder.net</string>
<string name="discover">Oppdage</string>
+ <string name="discover_hide">Skjul</string>
+ <string name="discover_is_hidden">Du valgte å skjule forslag</string>
<string name="discover_more">mer »</string>
+ <string name="discover_powered_by_itunes">Foreslått av iTunes</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Legg til lokal mappe</string>
+ <string name="local_feed_description">Denne virtuelle podkasten ble laget ved å legge en mappe til i AntennaPod.</string>
<string name="filter">Filter</string>
<!--Episodes apply actions-->
<string name="all_label">Alle</string>
<string name="selected_all_label">Valgte alle episoder</string>
- <string name="none_label">Ingen</string>
<string name="deselected_all_label">Fjernet valg av alle episoder</string>
<string name="played_label">Avspilt</string>
<string name="selected_played_label">Valgte avspilte episoder</string>
@@ -659,12 +674,17 @@
<string name="selected_downloaded_label">Valgte nedlastede episoder</string>
<string name="not_downloaded_label">Ikke nedlastet</string>
<string name="selected_not_downloaded_label">Valgte ikke-nedlastede episoder</string>
- <string name="queued_label">I kø</string>
<string name="selected_queued_label">Valgte episoder i køen</string>
- <string name="not_queued_label">Ikke i kø</string>
<string name="selected_not_queued_label">Valgte episoder som ikke er i kø</string>
- <string name="has_media">Har media</string>
<string name="selected_has_media_label">Valgte episoder med media</string>
+ <string name="hide_is_favorite_label">Er favoritt</string>
+ <string name="hide_downloaded_episodes_label">Nedlastet</string>
+ <string name="hide_not_downloaded_episodes_label">Ikke nedlastet</string>
+ <string name="queued_label">I kø</string>
+ <string name="not_queued_label">Ikke i kø</string>
+ <string name="has_media">Har media</string>
+ <string name="hide_paused_episodes_label">Pauset</string>
+ <string name="hide_played_episodes_label">Avspilt</string>
<!--Sort-->
<string name="sort_title_a_z">Tittel (A \u2192 Z)</string>
<string name="sort_title_z_a">Tittel (Z \u2192 A)</string>
@@ -672,12 +692,20 @@
<string name="sort_date_old_new">Dato (Gammel \u2192 Ny)</string>
<string name="sort_duration_short_long">Lengde (Kort \u2192 Lang)</string>
<string name="sort_duration_long_short">Lengde (Lang \u2192 Kort)</string>
+ <string name="sort_a_z">A \u2192 Å</string>
+ <string name="sort_z_a">Å \u2192 A</string>
+ <string name="sort_new_old">Ny \u2192 Gammel</string>
+ <string name="sort_old_new">Gammel \u2192 Ny</string>
+ <string name="sort_short_long">Kort \u2192 Lang</string>
+ <string name="sort_long_short">Lang \u2192 Kort</string>
<!--Rating dialog-->
<string name="rating_title">Liker du AntennaPod?</string>
<string name="rating_message">Vi ville satt pris på om du tok deg tid til å vurdere AntennaPod.</string>
<string name="rating_never_label">La meg være i fred</string>
<string name="rating_later_label">Minn meg på dette senere</string>
<string name="rating_now_label">Naturligvis, kom igjen!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Inkluder:</string>
<!--Audio controls-->
<string name="audio_controls">Lyd-kontroller</string>
<string name="playback_speed">Avspillingshastighet</string>
@@ -724,7 +752,8 @@
<string name="notification_channel_playing">Spilles nå</string>
<string name="notification_channel_playing_description">Kan styrre avspilling. Dette er hoved-varslingen du vil se mens en podkast spilles.</string>
<string name="notification_channel_error">Feil</string>
- <string name="notification_channel_error_description">Vises hvis noe gikk galt, for eksempel hvis en nedlasting eller gpodder-synkronisering ikke kunne fullføres.</string>
+ <string name="notification_channel_sync_error">Feil ved synkronisering</string>
+ <string name="notification_channel_sync_error_description">Vises når synkronisering mot gpodder feiler</string>
<string name="notification_channel_auto_download">Automatiske nedlastinger</string>
<string name="notification_channel_episode_auto_download">Vises når episoder har blitt lastet ned automatisk</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-nl/strings.xml b/core/src/main/res/values-nl/strings.xml
index 6e7f08ddf..6cdd59e77 100644
--- a/core/src/main/res/values-nl/strings.xml
+++ b/core/src/main/res/values-nl/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Het maximum aantal gecachete afleveringen is bereikt. Je kunt dit aantal verhogen in de instellingen.</string>
<string name="playback_statistics_label">Afspelen</string>
<string name="download_statistics_label">Downloads</string>
+ <string name="notification_pref_fragment">Meldingen</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Totale duur van afgespeelde podcasts:</string>
+ <string name="total_time_listened_to_podcasts">Totaalduur van afgespeelde afleveringen:</string>
<string name="statistics_details_dialog">%1$d van %2$d afleveringen gestart.\n\n%3$s van %4$s afgespeeld.</string>
<string name="statistics_mode">Rekenmethode</string>
<string name="statistics_mode_normal">Bereken de daadwerkelijke speeltijd. Tweemaal afspelen wordt twee keer gerekend; gemarkeerd als \'afgespeeld\' wordt niet meegeteld.</string>
- <string name="statistics_mode_count_all">Duur van de podcasts optellen die als \'afgespeeld\' gemarkeerd zijn</string>
+ <string name="statistics_mode_count_all">Alle afgespeelde afleveringen opsommen</string>
<string name="statistics_speed_not_counted">Let op: er wordt geen rekening gehouden met de afspeelsnelheid.</string>
<string name="statistics_reset_data">Statistieken op nul zetten</string>
<string name="statistics_reset_data_msg">Dit wist alle luistertijden van alle afleveringen. Weet je zeker dat je wilt doorgaan?</string>
+ <string name="statistics_counting_since">Sinds %s\nheb je geluisterd:</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Totale grootte van gedownloade podcasts:</string>
+ <string name="total_size_downloaded_podcasts">Totaalgrootte van afleveringen op apparaat:</string>
<!--Main activity-->
<string name="drawer_open">Menu openen</string>
<string name="drawer_close">Menu sluiten</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Aantal onbeluisterde afleveringen</string>
<string name="drawer_feed_counter_downloaded">Aantal gedownloade afleveringen</string>
<string name="drawer_feed_counter_none">Geen</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Geen compatibele apps aangetroffen</string>
<!--Webview actions-->
<string name="open_in_browser_label">Openen in browser</string>
<string name="copy_url_label">URL kopiëren</string>
@@ -69,7 +73,7 @@
<string name="cover_label">Beeld</string>
<string name="error_label">Fout</string>
<string name="error_msg_prefix">Er is een fout opgetreden:</string>
- <string name="needs_storage_permission">Machtiging vereist voor gebruik van opslag</string>
+ <string name="needs_storage_permission">Recht vereist voor gebruik van opslag</string>
<string name="refresh_label">Verversen</string>
<string name="external_storage_error_msg">Geen externe opslag beschikbaar. Zorg ervoor dat de externe opslag gekoppeld is zodat de app juist kan functioneren.</string>
<string name="chapters_label">Hoofdstukken</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Podcastinstellingen</string>
<string name="rename_feed_label">Podcastnaam wijzigen</string>
<string name="remove_feed_label">Podcast verwijderen</string>
- <string name="share_label">Delen...</string>
- <string name="share_link_label">URL van aflevering delen</string>
- <string name="share_link_with_position_label">URL van aflevering, incl. afspeelpositie, delen</string>
+ <string name="share_label">Delen</string>
+ <string name="share_label_with_ellipses">Delen…</string>
<string name="share_file_label">Bestand delen</string>
- <string name="share_website_url_label">Website-url delen</string>
- <string name="share_feed_url_label">Podcast-url delen</string>
- <string name="share_item_url_label">URL van mediabestand delen</string>
- <string name="share_item_url_with_position_label">URL van mediabestand, incl. afspeelpositie, delen</string>
+ <string name="share_website_url_label">Website-adres</string>
+ <string name="share_feed_url_label">Podcast-feedurl</string>
<string name="feed_delete_confirmation_msg">Bevestig dat je de podcast \'%1$s\' en ALLE bijbehorende (gedownloade) afleveringen wilt verwijderen.</string>
+ <string name="feed_delete_confirmation_local_msg">Bevestig dat je de podcast \'%1$s\' wilt verwijderen. De bestanden in de lokale bronmap worden bewaard.</string>
<string name="feed_remover_msg">Podcast verwijderen</string>
<string name="load_complete_feed">Gehele podcast verversen</string>
<string name="multi_select">Meerdere selecteren</string>
<string name="select_all_above">Alles hierboven selecteren</string>
<string name="select_all_below">Alles hieronder selecteren</string>
<string name="hide_unplayed_episodes_label">Niet afgespeeld</string>
- <string name="hide_paused_episodes_label">Gepauzeerd</string>
- <string name="hide_played_episodes_label">Afgespeeld</string>
<string name="hide_queued_episodes_label">In de wachtrij</string>
<string name="hide_not_queued_episodes_label">Niet in de wachtrij</string>
- <string name="hide_downloaded_episodes_label">Gedownload</string>
- <string name="hide_not_downloaded_episodes_label">Niet gedownload</string>
<string name="hide_has_media_label">Bevat media</string>
- <string name="hide_is_favorite_label">Gemarkeerd als favoriet</string>
<string name="filtered_label">Gefilterd</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Vorige verversing mislukt</string>
<string name="open_podcast">Podcast openen</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Verwijderen</string>
<string name="delete_failed">Kan bestand niet verwijderen; start je apparaat opnieuw op.</string>
<string name="delete_episode_label">Aflevering verwijderen</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d aflevering verwijderd.</item>
- <item quantity="other">%d afleveringen verwijderd.</item>
- </plurals>
<string name="remove_new_flag_label">\'Nieuw\'-label verwijderen</string>
<string name="removed_new_flag_label">\'Nieuw\'-label is verwijderd</string>
<string name="mark_read_label">Als afgespeeld markeren</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Bezig met verwerken van downloads</string>
<string name="download_notification_title">Bezig met downloaden van podcastgegevens</string>
- <string name="download_report_content">%1$d downloads voltooid; %2$d mislukt</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d download voltooid; %d mislukt</item>
+ <item quantity="other">%d downloads voltooid; %d mislukt</item>
+ </plurals>
<string name="download_log_title_unknown">Onbekende titel</string>
<string name="download_type_feed">Feed</string>
<string name="download_type_media">Mediabestand</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Downloaden via mobiel internet is uitgeschakeld in de instellingen.\n\nWil je dit tijdelijk toestaan?\n<small>Je keuze wordt 10 minuten onthouden.</small></string>
<string name="confirm_mobile_streaming_notification_title">Bevestig streamen via mobiel internet</string>
<string name="confirm_mobile_streaming_notification_message">Streamen via mobiel internet is uitgeschakeld in de instellingen. Druk om tóch te streamen.</string>
- <string name="confirm_mobile_streaming_button_always">Altijd toestaan</string>
+ <string name="confirm_mobile_streaming_button_always">Altijd</string>
+ <string name="confirm_mobile_streaming_button_once">Eenmalig</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Toevoegen aan wachtrij</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Tijdelijk toestaan</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Plug-in downloaden</string>
<string name="no_playback_plugin_title">Plug-in niet geïnstalleerd</string>
<string name="no_playback_plugin_or_sonic_msg">Als je variabele afspeelsnelheden aan de praat wilt krijgen, dan raden we aan om de ingebouwde Sonic-mediaspeler te gebruiken.</string>
- <string name="set_playback_speed_label">Afspeelsnelheden</string>
<string name="enable_sonic">Sonic inschakelen</string>
+ <string name="speed_presets">Voorinstellingen</string>
+ <string name="preset_already_exists">%1$.2fx is al opgeslagen als voorinstelling.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Geen afleveringen in wachtrij</string>
<string name="no_items_label">Voeg een aflevering toe door deze te downloaden of houd een aflevering lang ingedrukt en kies \'Toevoegen aan wachtrij\'.</string>
@@ -342,11 +340,11 @@
<string name="media_player">Mediaspeler</string>
<string name="pref_episode_cleanup_title">Automatisch opschonen</string>
<string name="pref_episode_cleanup_summary">Afleveringen die niet in de wachtrij staan én geen favoriet zijn, mogen verwijderd worden als \'Automatisch downloaden\' ruimte nodig heeft voor nieuwe afleveringen</string>
- <string name="pref_pauseOnDisconnect_sum">Afspelen pauzeren als de koptelefoon wordt losgekoppeld of de Bluetooth-verbinding verbroken</string>
+ <string name="pref_pauseOnDisconnect_sum">Afspelen pauzeren als de koptelefoon wordt losgekoppeld of de bluetoothverbinding verbroken</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Afspelen hervatten als de koptelefoon weer wordt aangesloten</string>
- <string name="pref_unpauseOnBluetoothReconnect_sum">Afspelen hervatten als de Bluetooth-verbinding hervat</string>
+ <string name="pref_unpauseOnBluetoothReconnect_sum">Afspelen hervatten als de bluetoothverbinding hersteld is</string>
<string name="pref_hardwareForwardButtonSkips_title">\'Vooruit\' gebruiken voor overslaan</string>
- <string name="pref_hardwareForwardButtonSkips_sum">Als je op de vooruitknop van een via Bluetooth verbonden apparaat drukt, wordt de volgende aflevering geladen i.p.v. doorgespoeld</string>
+ <string name="pref_hardwareForwardButtonSkips_sum">Als je op de vooruitknop van een via bluetooth verbonden apparaat drukt, wordt de volgende aflevering geladen i.p.v. doorgespoeld</string>
<string name="pref_hardwarePreviousButtonRestarts_title">\'Vorige\' gebruiken voor opnieuw afspelen</string>
<string name="pref_hardwarePreviousButtonRestarts_sum">Aflevering afspelen vanaf het begin i.p.v. terugspoelen als er op een fysieke \'vorige\'-knop wordt gedrukt</string>
<string name="pref_followQueue_sum">Volgende item in de wachtrij afspelen als de aflevering voltooid is</string>
@@ -371,9 +369,9 @@
<string name="pref_autoUpdateIntervallOrTime_every">elke %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">om %1$s</string>
<string name="pref_followQueue_title">Doorlopend afspelen</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Loskoppelen van hoofdtelefoon</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Koptelefoon- of bluetoothverbinding verbroken</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Opnieuw aansluiten van hoofdtelefoon</string>
- <string name="pref_unpauseOnBluetoothReconnect_title">Opnieuw verbinden met Bluetooth</string>
+ <string name="pref_unpauseOnBluetoothReconnect_title">Opnieuw verbinden met bluetooth</string>
<string name="pref_stream_over_download_title">Voorkeur geven aan streaming</string>
<string name="pref_stream_over_download_sum">Toon een stream- i.p.v. downloadknop in lijsten.</string>
<string name="pref_mobileUpdate_title">Bijwerken via mobiel internet</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Hoofdstuk downloaden</string>
<string name="pref_mobileUpdate_streaming">Streamen</string>
<string name="user_interface_label">Uiterlijk</string>
- <string name="user_interface_sum">Uiterlijk, abonnementsortering, vergrendelscherm</string>
+ <string name="user_interface_sum">Uiterlijk, abonnementen, vergrendelscherm</string>
<string name="pref_set_theme_title">Thema kiezen</string>
<string name="pref_nav_drawer_items_title">Menu-items kiezen</string>
<string name="pref_nav_drawer_items_sum">Kies welke items moeten worden getoond in het navigatiemenu.</string>
@@ -395,8 +393,8 @@
<string name="pref_set_theme_sum">Pas het uiterlijk van AntennaPod aan.</string>
<string name="pref_automatic_download_title">Automatisch downloaden</string>
<string name="pref_automatic_download_sum">Stel het automatisch downloaden van afleveringen in.</string>
- <string name="pref_autodl_wifi_filter_title">Wi-Fi-filter inschakelen</string>
- <string name="pref_autodl_wifi_filter_sum">Automatisch downloaden alleen toestaan via gekozen Wi-Fi-netwerken.</string>
+ <string name="pref_autodl_wifi_filter_title">Wifi-filter inschakelen</string>
+ <string name="pref_autodl_wifi_filter_sum">Automatisch downloaden alleen toestaan via gekozen wifi-netwerken.</string>
<string name="pref_automatic_download_on_battery_title">Downloaden als het apparaat niet wordt opgeladen</string>
<string name="pref_automatic_download_on_battery_sum">Downloaden toestaan als het apparaat niet wordt opgeladen</string>
<string name="pref_parallel_downloads_title">Gelijktijdige downloads</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Volledige synchronisatie afdwingen</string>
<string name="pref_gpodnet_full_sync_sum">Synchroniseer alle abonnementen en afleveringsstatussen met gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Ingelogd als <i>%1$s</i> met apparaat <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Melding tonen bij synchronisatiefouten</string>
+ <string name="pref_gpodnet_notifications_title">Synchronisatie mislukt</string>
<string name="pref_gpodnet_notifications_sum">Deze instelling is niet van toepassing op inlogfouten.</string>
- <string name="pref_playback_speed_title">Afspeelsnelheden</string>
- <string name="pref_playback_speed_sum">Pas de beschikbare snelheden aan voor de variabele audio-afspeelsnelheid</string>
+ <string name="pref_playback_speed_sum">Pas de beschikbare snelheden aan voor de variabele afspeelsnelheid</string>
<string name="pref_feed_playback_speed_sum">De te gebruiken snelheid bij het afspelen van afleveringen in deze podcast</string>
<string name="pref_feed_skip">Automatisch overslaan</string>
<string name="pref_feed_skip_sum">Sla introducties en aftitelingen over.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Dit klapt meestal de melding uit zodat de bedieningsknoppen kunnen worden getoond.</string>
<string name="pref_persistNotify_title">Bedieningsknoppen behouden</string>
<string name="pref_persistNotify_sum">Ook bedieningsknoppen op het meldings- en vergrendelscherm behouden als het afspelen gepauzeerd wordt.</string>
- <string name="pref_compact_notification_buttons_title">Bedieningsknoppen vergrendelscherm</string>
- <string name="pref_compact_notification_buttons_sum">Kies de bedieningsknoppen voor het vergrendelscherm. De knop afspelen/pauzeren wordt altijd getoond.</string>
+ <string name="pref_compact_notification_buttons_title">Kleine meldingsknoppen gebruiken</string>
+ <string name="pref_compact_notification_buttons_sum">Kies de bedieningsknoppen voor als de melding is ingeklapt. De knop afspelen/pauzeren wordt altijd getoond.</string>
<string name="pref_compact_notification_buttons_dialog_title">Kies maximaal %1$d knoppen</string>
<string name="pref_compact_notification_buttons_dialog_error">Je kunt maximaal %1$d knoppen kiezen.</string>
<string name="pref_lockscreen_background_title">Achtergrondafbeelding vergrendelscherm</string>
<string name="pref_lockscreen_background_sum">Toon de afbeelding van de huidige aflevering op het vergrendelscherm. Hierdoor is de afbeelding ook beschikbaar voor andere apps.</string>
- <string name="pref_showDownloadReport_title">Toon downloadverslag</string>
+ <string name="pref_showDownloadReport_title">Downloaden mislukt</string>
<string name="pref_showDownloadReport_sum">Stel een verslag op met foutdetails als downloads mislukken.</string>
- <string name="pref_showAutoDownloadReport_title">Toon verslag automatische downloads</string>
+ <string name="pref_showAutoDownloadReport_title">Automatisch downloaden voltooid</string>
<string name="pref_showAutoDownloadReport_sum">Toon een melding bij automatisch gedownloade afleveringen.</string>
<string name="pref_expand_notify_unsupport_toast">Android-versies lager dan 4.1 ondersteunen geen knoppen op meldingen.</string>
<string name="pref_enqueue_location_title">Wachtrijlocatie</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Gedownloade afleveringen in wachtrij</string>
<string name="pref_enqueue_downloaded_summary">Voeg gedownloade afleveringen toe aan de wachtrij</string>
<string name="media_player_builtin">Ingebouwde Android-speler</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (aanbevolen)</string>
<string name="media_player_switch_to_exoplayer">ExoPlayer gebruiken</string>
<string name="media_player_switched_to_exoplayer">Overgeschakeld naar ExoPlayer.</string>
<string name="pref_skip_silence_title">Audiostiltes overslaan</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Kies een pagina</string>
<string name="pref_delete_removes_from_queue_title">Afleveringen verwijderen uit wachtrij na wissen</string>
<string name="pref_delete_removes_from_queue_sum">Verwijder een aflevering uit de wachtrij als de aflevering in kwestie is verwijderd.</string>
+ <string name="pref_filter_feed_title">Abonnementsfilter</string>
+ <string name="pref_filter_feed_sum">Filter je abonnementen in het navigatiemenu en op het abonnementenscherm.</string>
+ <string name="no_filter_label">Geen</string>
+ <string name="subscriptions_are_filtered">De abonnementen zijn gefilterd.</string>
+ <string name="subscriptions_counter_greater_zero">Teller hoger dan nul</string>
+ <string name="auto_downloaded">Automatisch gedownload</string>
+ <string name="not_auto_downloaded">Niet automatisch gedownload</string>
+ <string name="kept_updated">Bijgehouden</string>
+ <string name="not_kept_updated">Niet bijgehouden</string>
<!--About screen-->
<string name="about_pref">Over AntennaPod</string>
<string name="antennapod_version">AntennaPod-versie</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Zet je abonnementen, beluisterde afleveringen en wachtrij over naar Antennapod op een ander apparaat</string>
<string name="database_import_summary">Antennapod-databank importeren van ander apparaat</string>
<string name="opml_import_label">OPML importeren</string>
+ <string name="opml_add_podcast_label">Podcastlijst (opml) importeren</string>
<string name="opml_reader_error">Er is iets misgegaan tijdens het lezen van het OPML-bestand:</string>
<string name="opml_import_error_no_file">Geen bestand gekozen!</string>
<string name="select_all_label">Alles selecteren</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">Het geëxporteerde bestand is opgeslagen in:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Toegang tot externe locaties is nodig om het OPML-bestand te kunnen lezen</string>
<string name="import_select_file">Kies een te importeren bestand</string>
- <string name="import_ok">Geïmporteerd.\n\nDruk op Oké om AntennaPod opnieuw te starten.</string>
+ <string name="successful_import_label">Importeren voltooid</string>
+ <string name="import_ok">Druk op \'Oké\' om AntennaPod opnieuw te starten.</string>
<string name="import_no_downgrade">Deze databank is geëxporteerd door een nieuwere versie van Antennapod. Je huidige versie weet nog niet hoe daar mee om te gaan.</string>
<string name="favorites_export_label">Favorieten exporteren</string>
<string name="favorites_export_summary">Exporteer opgeslagen favorieten naar een bestand</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Verlaag snelheid</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Navigeer naar boven</string>
<string name="status_downloading_label">Aflevering wordt gedownload</string>
<string name="in_queue_label">Aflevering staat in de wachtrij</string>
<string name="is_favorite_label">Aflevering als favoriet gemarkeerd</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Bijgewerkt houden</string>
<string name="keep_updated_summary">Deze podcast meenemen bij het (automatisch) verversen van alle podcasts</string>
<string name="auto_download_disabled_globally">Automatisch downloaden is uitgeschakeld in de AntennaPod-instellingen</string>
+ <string name="statistics_listened_for">Luisterduur:</string>
+ <string name="statistics_episodes_on_device">Afleveringen op apparaat:</string>
+ <string name="statistics_space_used">Gebruikte ruimte:</string>
+ <string name="statistics_view_all">Alle podcasts tonen »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Bezig met upgraden van databank...</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Podcast zoeken...</string>
<string name="search_itunes_label">iTunes doorzoeken</string>
+ <string name="search_podcastindex_label">Podcastindex.org doorzoeken</string>
<string name="search_fyyd_label">Fyyd doorzoeken</string>
<string name="advanced">Geavanceerd</string>
- <string name="add_podcast_by_url">Podcast toevoegen middels url</string>
+ <string name="add_podcast_by_url">Podcast toevoegen middels rss-adres</string>
<string name="browse_gpoddernet_label">Verken gpodder.net</string>
<string name="discover">Ontdekken</string>
+ <string name="discover_hide">Verbergen</string>
+ <string name="discover_is_hidden">Je hebt er voor gekozen om aanbevelingen te verbergen.</string>
<string name="discover_more">meer »</string>
- <string name="search_powered_by">Zoeken via %1$s</string>
+ <string name="discover_powered_by_itunes">Aanbevelingen van iTunes</string>
+ <string name="search_powered_by">Resultaten van %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Lokale map toevoegen</string>
+ <string name="local_folder">Lokale map</string>
+ <string name="reconnect_local_folder">Lokale map opnieuw koppelen</string>
+ <string name="reconnect_local_folder_warning">Als je geen rechten hebt, gebruik dan dit om de map opnieuw te koppelen. Kies geen andere map.</string>
+ <string name="local_feed_description">De virtuele podcast is aangemaakt door een aan AntennaPod toegevoegde map.</string>
+ <string name="unable_to_start_system_file_manager">De bestandsbeheerder-app kan niet worden geopend</string>
<string name="filter">Filter</string>
<!--Episodes apply actions-->
<string name="all_label">Alle</string>
<string name="selected_all_label">Alle afleveringen geselecteerd</string>
- <string name="none_label">Geen</string>
+ <string name="select_none_label">Geen</string>
<string name="deselected_all_label">Alle afleveringen gede-selecteerd</string>
<string name="played_label">Afgespeeld</string>
<string name="selected_played_label">Alle afgespeelde afleveringen geselecteerd</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Gedownloade afleveringen geselecteerd</string>
<string name="not_downloaded_label">Niet gedownload</string>
<string name="selected_not_downloaded_label">Niet-gedownloade afleveringen geselecteerd</string>
- <string name="queued_label">In de wachtrij</string>
<string name="selected_queued_label">Afleveringen in de wachtrij geselecteerd</string>
- <string name="not_queued_label">Niet in de wachtrij</string>
<string name="selected_not_queued_label">Afleveringen geselecteerd die niet in de wachtrij staan</string>
- <string name="has_media">Bevat media</string>
<string name="selected_has_media_label">Afleveringen met media geselecteerd</string>
+ <string name="hide_is_favorite_label">Gemarkeerd als favoriet</string>
+ <string name="not_favorite">Geen favoriet</string>
+ <string name="hide_downloaded_episodes_label">Gedownload</string>
+ <string name="hide_not_downloaded_episodes_label">Niet gedownload</string>
+ <string name="queued_label">In de wachtrij</string>
+ <string name="not_queued_label">Niet in de wachtrij</string>
+ <string name="has_media">Bevat media</string>
+ <string name="no_media">Geen media</string>
+ <string name="hide_paused_episodes_label">Gepauzeerd</string>
+ <string name="not_paused">Niet gepauzeerd</string>
+ <string name="hide_played_episodes_label">Afgespeeld</string>
+ <string name="not_played">Niet afgespeeld</string>
<!--Sort-->
<string name="sort_title_a_z">Titel (A \u2192 Z)</string>
<string name="sort_title_z_a">Titel (A \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Nee, bedankt</string>
<string name="rating_later_label">Herinner me later</string>
<string name="rating_now_label">Ja, doen we!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Opnemen:</string>
+ <string name="share_playback_position_dialog_label">Afspeelpositie</string>
+ <string name="share_dialog_media_file_url_label">Adres van mediabestand</string>
+ <string name="share_dialog_episode_website_label">Website van aflevering</string>
+ <string name="share_dialog_media_file_label">Mediabestand</string>
<!--Audio controls-->
<string name="audio_controls">Audio-instellingen</string>
<string name="playback_speed">Afspeelsnelheid</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Nu aan het afspelen</string>
<string name="notification_channel_playing_description">Hiermee kun je het afspelen bedienen. Dit is de voornaamste melding tijdens het afspelen van een podcast.</string>
<string name="notification_channel_error">Foutmeldingen</string>
- <string name="notification_channel_error_description">Wordt getoond als er iets is misgegaan, bijvoorbeeld bij het downloaden of synchroniseren.</string>
+ <string name="notification_channel_error_description">Wordt getoond als er iets misgaat, zoals downloaden of het bijwerken van de feed.</string>
+ <string name="notification_channel_sync_error">Syschronisatiefouten</string>
+ <string name="notification_channel_sync_error_description">Worden getoond als gpodder-synchronisatie mislukt.</string>
<string name="notification_channel_auto_download">Automatisch downloaden</string>
<string name="notification_channel_episode_auto_download">Wordt getoond als afleveringen automatisch zijn gedownload.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-pl/strings.xml b/core/src/main/res/values-pl/strings.xml
index f5fa5e310..c2b977382 100644
--- a/core/src/main/res/values-pl/strings.xml
+++ b/core/src/main/res/values-pl/strings.xml
@@ -25,30 +25,34 @@
<string name="episode_cache_full_message">Limit pamięci cache został osiągnięty. Możesz zwiększyć pojemność cache w ustawieniach aplikacji.</string>
<string name="playback_statistics_label">Odtwarzanie</string>
<string name="download_statistics_label">Pobrane</string>
+ <string name="notification_pref_fragment">Powiadomienia</string>
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">Całkowity czas odtwarzania podcastów:</string>
<string name="statistics_details_dialog">%1$d z %2$d odcinków rozpoczęto.\n\nOdtworzono %3$s z %4$s.</string>
<string name="statistics_mode">Tryb statystyk</string>
<string name="statistics_mode_normal">Oblicz łączny czas rzeczywistego odtwarzania. Dwukrotne odtworzenie będzie policzone ale zaznaczenie jako odtworzone nie będzie policzone.</string>
- <string name="statistics_mode_count_all">Podsumuj wszystkie podcasty oznaczone jako odtworzone</string>
+ <string name="statistics_mode_count_all">Podsumuj wszystkie odcinki oznaczone jako odtworzone</string>
<string name="statistics_speed_not_counted">Powiadomienie: Prędkość odtwarzania nigdy nie jest uwzględniana.</string>
<string name="statistics_reset_data">Resetuj statystyki</string>
<string name="statistics_reset_data_msg">Operacja skasuje historię długości odtwarzania wszystkich odcinków. Czy na pewno chcesz kontynuować?</string>
+ <string name="statistics_counting_since">Od %s odtworzono</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Całkowita wielkość pobranych podcastów:</string>
+ <string name="total_size_downloaded_podcasts">Całkowity rozmiar odcinków na urządzeniu:</string>
<!--Main activity-->
<string name="drawer_open">Otwórz menu</string>
<string name="drawer_close">Zamknij menu</string>
- <string name="drawer_preferences">Ustawienia panelu</string>
- <string name="drawer_feed_order_unplayed_episodes">Sortuj wg liczby</string>
+ <string name="drawer_preferences">Ustawienia panelu nawigacyjnego</string>
+ <string name="drawer_feed_order_unplayed_episodes">Sortuj wg licznika</string>
<string name="drawer_feed_order_alphabetical">Sortuj alfabetycznie</string>
<string name="drawer_feed_order_last_update">Sortuj wg daty publikacji</string>
- <string name="drawer_feed_order_most_played">Sortuj po liczbie odtworzonych odcinków</string>
+ <string name="drawer_feed_order_most_played">Sortuj wg liczby odtworzonych odcinków</string>
<string name="drawer_feed_counter_new_unplayed">Liczba nowych i nieodtworzonych odcinków</string>
<string name="drawer_feed_counter_new">Liczba nowych odcinków</string>
<string name="drawer_feed_counter_unplayed">Liczba nieodtworzonych odcinków</string>
<string name="drawer_feed_counter_downloaded">Liczba pobranych odcinków</string>
<string name="drawer_feed_counter_none">Brak</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Nie znaleziono kompatybilnych aplikacji</string>
<!--Webview actions-->
<string name="open_in_browser_label">Otwórz w przeglądarce</string>
<string name="copy_url_label">Kopiuj adres</string>
@@ -63,7 +67,7 @@
<string name="yes">Tak</string>
<string name="no">Nie</string>
<string name="reset">Reset</string>
- <string name="author_label">Autor(rzy)</string>
+ <string name="author_label">Autorzy</string>
<string name="language_label">Język</string>
<string name="url_label">URL</string>
<string name="cover_label">Obraz</string>
@@ -75,7 +79,7 @@
<string name="chapters_label">Rozdziały</string>
<string name="chapter_duration">Czas trwania: %1$s</string>
<string name="description_label">Opis</string>
- <string name="episodes_suffix">:\u0020odcinków</string>
+ <string name="episodes_suffix">\u0020odcinków</string>
<string name="processing_label">Przetwarzanie</string>
<string name="save_username_password_label">Zapisz nazwę użytkownika i hasło</string>
<string name="close_label">Zamknij</string>
@@ -130,29 +134,22 @@
<string name="feed_settings_label">Ustawienia podcastu</string>
<string name="rename_feed_label">Zmień nazwę podcastu</string>
<string name="remove_feed_label">Usuń podcast</string>
- <string name="share_label">Udostępnij...</string>
- <string name="share_link_label">Udostępnij adres URL odcinka</string>
- <string name="share_link_with_position_label">Udostępnij adres URL odcinka z aktualną pozycją</string>
+ <string name="share_label">Udostępnij</string>
+ <string name="share_label_with_ellipses">Udostępnij...</string>
<string name="share_file_label">Udostępnij plik</string>
- <string name="share_website_url_label">Udostępnij adres URL</string>
- <string name="share_feed_url_label">Udostępnij adres URL podcastu</string>
- <string name="share_item_url_label">Udostępnij adres URL odcinka</string>
- <string name="share_item_url_with_position_label">Udostępnij adres URL odcinka z pozycją</string>
+ <string name="share_website_url_label">Adres stony</string>
+ <string name="share_feed_url_label">Adres URL podcastu</string>
<string name="feed_delete_confirmation_msg">Potwierdź, że chcesz usunąć kanał \"%1$s\" oraz WSZYSTKIE jego odcinki (również te pobrane).</string>
+ <string name="feed_delete_confirmation_local_msg">Proszę potwierdzić usunięcie podcastu \"%1$s\". Pliki w lokalnym folderze źródłowym nie zostaną usunięte.</string>
<string name="feed_remover_msg">Usuwanie podcastu</string>
<string name="load_complete_feed">Odśwież cały podcast</string>
<string name="multi_select">Wybierz wiele</string>
<string name="select_all_above">Zaznacz wszystkie powyżej</string>
<string name="select_all_below">Zaznacz wszystkie poniżej</string>
<string name="hide_unplayed_episodes_label">Nieodtworzone</string>
- <string name="hide_paused_episodes_label">Zatrzymane</string>
- <string name="hide_played_episodes_label">Odtworzone</string>
<string name="hide_queued_episodes_label">W kolejce</string>
<string name="hide_not_queued_episodes_label">Nie w kolejce</string>
- <string name="hide_downloaded_episodes_label">Pobrane</string>
- <string name="hide_not_downloaded_episodes_label">Nie pobrane</string>
<string name="hide_has_media_label">Ma media</string>
- <string name="hide_is_favorite_label">Ulubione</string>
<string name="filtered_label">Przefiltrowany</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Ostatnie odświerzanie nie powiodło się</string>
<string name="open_podcast">Otwórz Podcast</string>
@@ -167,16 +164,10 @@
</plurals>
<string name="play_label">Odtwórz</string>
<string name="pause_label">Pauza</string>
- <string name="stream_label">Strumień</string>
+ <string name="stream_label">Streamuj</string>
<string name="delete_label">Usuń</string>
<string name="delete_failed">Nie można usunąć pliku. Restart urządzenia może w tym pomóc.</string>
<string name="delete_episode_label">Usuń odcinek</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">Usunięto %d odcinek. </item>
- <item quantity="few">Usunięto %d odcinki(ów). </item>
- <item quantity="many">Usunięto %d odcinki(ów). </item>
- <item quantity="other">Usunięto %d odcinki(ów). </item>
- </plurals>
<string name="remove_new_flag_label">Usuń flagę \"nowy\"</string>
<string name="removed_new_flag_label">Usunięto flagę \"nowy\"</string>
<string name="mark_read_label">Oznacz jako odtworzone</string>
@@ -259,7 +250,12 @@
</plurals>
<string name="downloads_processing">Przetwarzanie pobranych</string>
<string name="download_notification_title">Pobieranie danych podcastu</string>
- <string name="download_report_content">%1$d pobierania poprawne, %2$d nieudane</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d pobranie udane, %d błędne</item>
+ <item quantity="few">%d pobrań udanych, %d błędnych</item>
+ <item quantity="many">%d pobrań udanych, %d błędnych</item>
+ <item quantity="other">%d pobrań udanych, %d błędnych</item>
+ </plurals>
<string name="download_log_title_unknown">Nieznany tytuł</string>
<string name="download_type_feed">Kanał</string>
<string name="download_type_media">Plik multimedialny</string>
@@ -272,7 +268,8 @@
<string name="confirm_mobile_download_dialog_message">Pobieranie przez sieć komórkową jest wyłączone w ustawieniach.\n\nCzy chcesz tymczasowo zezwolić na pobieranie?\n\n<small>Twój wybór zostanie zapamiętany na 10 minut.</small></string>
<string name="confirm_mobile_streaming_notification_title">Potwierdź streamowanie przy użyciu danych komórkowych</string>
<string name="confirm_mobile_streaming_notification_message">Streamowanie przy użyciu danych komórkowych jest wyłączone w ustawieniach. Naciśnij aby streamować mimo to.</string>
- <string name="confirm_mobile_streaming_button_always">Pozwalaj zawsze</string>
+ <string name="confirm_mobile_streaming_button_always">Zawsze</string>
+ <string name="confirm_mobile_streaming_button_once">Tylko tym razem</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Dodaj do kolejki</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Zezwól tymczasowo</string>
<!--Mediaplayer messages-->
@@ -318,8 +315,9 @@
<string name="download_plugin_label">Pobierz wtyczkę</string>
<string name="no_playback_plugin_title">Wtyczka nie zainstalowana</string>
<string name="no_playback_plugin_or_sonic_msg">Aby używać zmiennej prędkości odtwarzania, zalecamy używanie wbudowanego odtwarzacza Sonic.</string>
- <string name="set_playback_speed_label">Prędkość odtwarzania</string>
<string name="enable_sonic">Włącz Sonic</string>
+ <string name="speed_presets">Nastawy</string>
+ <string name="preset_already_exists">%1$.2fx już istnieje jako nastawa.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Brak odcinków w kolejce</string>
<string name="no_items_label">Dodaj odcinek, pobierając go, lub przytrzymaj dłużej na odcinku i wybierz \"Dodaj do kolejki\".</string>
@@ -392,7 +390,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">co %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">o %1$s</string>
<string name="pref_followQueue_title">Odtwarzanie ciągłe</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Słuchawki odłączone</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Rozłączenie słuchawek lub Bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Słuchawki podłączone ponownie</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth podłączony ponownie</string>
<string name="pref_stream_over_download_title">Preferuj streamowanie</string>
@@ -403,16 +401,16 @@
<string name="pref_mobileUpdate_images">Okładki</string>
<string name="pref_mobileUpdate_auto_download">Automatyczne pobieranie</string>
<string name="pref_mobileUpdate_episode_download">Pobieranie odcinków</string>
- <string name="pref_mobileUpdate_streaming">Streaming</string>
+ <string name="pref_mobileUpdate_streaming">Streamowanie</string>
<string name="user_interface_label">Interfejs użytkownika</string>
- <string name="user_interface_sum">Wygląd, Kolejność subskrypcji, Ekran blokady</string>
+ <string name="user_interface_sum">Wygląd, Subskrypcje, Ekran blokady</string>
<string name="pref_set_theme_title">Wybierz motyw</string>
<string name="pref_nav_drawer_items_title">Wybierz pozycje panelu nawigacyjnego</string>
<string name="pref_nav_drawer_items_sum">Zmienia pozycje widoczne w panelu nawigacyjnym.</string>
<string name="pref_nav_drawer_feed_order_title">Ustaw kolejność subskrypcji</string>
<string name="pref_nav_drawer_feed_order_sum">Zmień kolejność subskrybowanych kanałów</string>
<string name="pref_nav_drawer_feed_counter_title">Ustaw licznik subskrypcji</string>
- <string name="pref_nav_drawer_feed_counter_sum">Zmień informacje wyświetlane przez licznik subskrypcji. Zmienia również sortowanie subskrypcji, jeśli kolejność ustawiona jest na \'Sortuj wg liczby\'</string>
+ <string name="pref_nav_drawer_feed_counter_sum">Zmień informacje wyświetlane przez licznik subskrypcji. Zmienia również sortowanie subskrypcji, jeśli kolejność ustawiona jest na \'Sortuj wg licznika\'</string>
<string name="pref_set_theme_sum">Zmień wygląd AntennaPod.</string>
<string name="pref_automatic_download_title">Automatyczne pobieranie</string>
<string name="pref_automatic_download_sum">Skonfiguruj automatyczne pobieranie odcinków.</string>
@@ -444,10 +442,9 @@
<string name="pref_gpodnet_full_sync_title">Wymuś pełną synchronizację</string>
<string name="pref_gpodnet_full_sync_sum">Synchronizuj wszystkie subskrypcje oraz stan odcinków z pomocą gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Zalogowano jako <i>%1$s</i> na urządzeniu <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Pokaż powiadomienia błędów synchronizacji</string>
+ <string name="pref_gpodnet_notifications_title">Błąd synchronizacji</string>
<string name="pref_gpodnet_notifications_sum">To ustawienie nie dotyczy błędów autoryzacji.</string>
- <string name="pref_playback_speed_title">Prędkość odtwarzania</string>
- <string name="pref_playback_speed_sum">Dostosuj prędkości dostępne dla odtwarzania audio o zmiennej prędkości</string>
+ <string name="pref_playback_speed_sum">Dostosuj prędkości dostępne dla odtwarzania o zmiennej prędkości</string>
<string name="pref_feed_playback_speed_sum">Prędkość używana podczas odtwarzania odcinków z tego kanału</string>
<string name="pref_feed_skip">Automatyczne pomijanie</string>
<string name="pref_feed_skip_sum">Pomijaj wstęp i napisy końcowe</string>
@@ -467,15 +464,15 @@
<string name="pref_expandNotify_sum">Rozwija powiadomienie, aby pokazać przyciski odtwarzania</string>
<string name="pref_persistNotify_title">Stałe przyciski odtwarzacza</string>
<string name="pref_persistNotify_sum">Utrzymuj powiadomienie i przyciski odtwarzania na ekranie blokady gdy odtwarzanie jest wstrzymane.</string>
- <string name="pref_compact_notification_buttons_title">Ustaw przyciski ekranu blokowania</string>
- <string name="pref_compact_notification_buttons_sum">Zmień przyciski odtwarzania na ekranie blokowania. Przyciski odtwórz/zatrzymaj są zawsze uwzględnione.</string>
+ <string name="pref_compact_notification_buttons_title">Ustaw kompaktowe przyciski w powiadomieniach</string>
+ <string name="pref_compact_notification_buttons_sum">Zmień przyciski odtwarzania, gdy powiadomienia są zwinięte. Przycisk odtwórz/pauza jest zawsze uwzględniony.</string>
<string name="pref_compact_notification_buttons_dialog_title">Wybierz maksimum z %1$d przedmiotów</string>
<string name="pref_compact_notification_buttons_dialog_error">Możesz tylko wybrać maksimum z %1$d przedmiotów.</string>
<string name="pref_lockscreen_background_title">Ustaw tło ekranu blokady</string>
<string name="pref_lockscreen_background_sum">Ustaw tło ekranu blokowania na aktualny obraz odcinka. W efekcie będzie zawsze pokazywał obraz w innych aplikacjach.</string>
- <string name="pref_showDownloadReport_title">Pokaż raport z pobierania</string>
+ <string name="pref_showDownloadReport_title">Błąd pobierania</string>
<string name="pref_showDownloadReport_sum">Jeżeli pobieranie się nie powiedzie, pokaż raport ze szczegółami błędu.</string>
- <string name="pref_showAutoDownloadReport_title">Pokazuj raport z automatycznego pobierania</string>
+ <string name="pref_showAutoDownloadReport_title">Automatyczne pobieranie zakończone</string>
<string name="pref_showAutoDownloadReport_sum">Pokazuj powiadomienie dla odcinków pobranych automatycznie</string>
<string name="pref_expand_notify_unsupport_toast">Android starszy niż 4.1 nie wspiera rozszerzonych powiadomień.</string>
<string name="pref_enqueue_location_title">Pozycja w kolejce</string>
@@ -505,6 +502,7 @@
<string name="pref_enqueue_downloaded_title">Kolejkuj pobrane</string>
<string name="pref_enqueue_downloaded_summary">Dodaj pobrane odcinki do kolejki</string>
<string name="media_player_builtin">Wbudowany odtwarzacz Androida</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (rekomendowany)</string>
<string name="media_player_switch_to_exoplayer">Zmień na ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Zmieniono na ExoPlayer</string>
<string name="pref_skip_silence_title">Pomiń ciszę w plikach audio</string>
@@ -525,10 +523,20 @@
<string name="back_button_go_to_page_title">Wybierz stronę</string>
<string name="pref_delete_removes_from_queue_title">Kasowanie usuwa z kolejki</string>
<string name="pref_delete_removes_from_queue_sum">Automatycznie usuwaj odcinek z kolejki gdy go kasujesz.</string>
+ <string name="pref_filter_feed_title">Filtr subskrypcji</string>
+ <string name="pref_filter_feed_sum">Filtruj subskrypcje w panelu nawigacyjnym i na ekranie subskrypcji.</string>
+ <string name="no_filter_label">Brak</string>
+ <string name="subscriptions_are_filtered">Subskrypcje są wyfiltrowane.</string>
+ <string name="subscriptions_counter_greater_zero">Licznik większy niż zero</string>
+ <string name="auto_downloaded">Pobrane automatycznie</string>
+ <string name="not_auto_downloaded">Nie pobrane automatycznie</string>
+ <string name="kept_updated">Kanały automatycznie aktualizowane</string>
+ <string name="not_kept_updated">Kanały nie będące automatycznie aktualizowane</string>
<!--About screen-->
<string name="about_pref">O...</string>
<string name="antennapod_version">Wersja AntennaPod</string>
<string name="contributors">Kontrybutorzy</string>
+ <string name="contributors_summary">Każdy może pomóc ulepszyć AntennaPod - pisząc kod, tłumacząc lub pomagając użytkownikom na forum.</string>
<string name="developers">Twórcy</string>
<string name="translators">Tłumacze</string>
<string name="special_thanks">Specjalne podziękowania</string>
@@ -558,6 +566,7 @@
<string name="database_export_summary">Przenieś subskrypcje, listę odsłuchanych odcinków i kolejkę do AntennaPod na innym urządzeniu</string>
<string name="database_import_summary">Importuj bazę danych AntennaPod z innego urządzenia</string>
<string name="opml_import_label">Import OPML</string>
+ <string name="opml_add_podcast_label">Importuj listę podcastów (OPML)</string>
<string name="opml_reader_error">Wystąpił błąd podczas odczytywania pliku OPML:</string>
<string name="opml_import_error_no_file">Nie wbrano pliku!</string>
<string name="select_all_label">Zaznacz wszystko</string>
@@ -573,10 +582,11 @@
<string name="export_success_sum">Wyeksportowany plik został zapisany w:\n\n %1$s</string>
<string name="opml_import_ask_read_permission">Dostęp do zewnętrznej pamięci jest potrzebny do odczytywania plików OPML</string>
<string name="import_select_file">Wybierz plik do Importowania</string>
- <string name="import_ok">Import zakończony powodzeniem.\n\nNaciśnij OK aby zrestartować AntennaPod</string>
+ <string name="successful_import_label">Import udany</string>
+ <string name="import_ok">Naciśnij OK, aby zrestartować AntennaPod</string>
<string name="import_no_downgrade">Baza danych została eksportowana z nowszej wersji AntennaPod. Twoja wersja nie potrafi obsłużyć tego pliku. </string>
<string name="favorites_export_label">Eksport ulubionych</string>
- <string name="favorites_export_summary">Ulubione wyeksportowano do pliku</string>
+ <string name="favorites_export_summary">Wyeksportuj ulubione do pliku</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Ustaw czas do wyłączenia</string>
<string name="disable_sleeptimer_label">Wyłącz wyłącznik czasowy</string>
@@ -675,7 +685,6 @@ https://gpodder.net/register/</string>
<string name="decrease_speed">Zmniejsz prędkość</string>
<string name="media_type_audio_label">Audio</string>
<string name="media_type_video_label">Wideo</string>
- <string name="navigate_upwards_label">Przesuń w górę</string>
<string name="status_downloading_label">Odcinek jest pobierany</string>
<string name="in_queue_label">Odcinek jest w kolejce</string>
<string name="is_favorite_label">Odcinek oznaczony jako ulubiony</string>
@@ -696,6 +705,10 @@ https://gpodder.net/register/</string>
<string name="keep_updated">Utrzymuj zaktualizowane</string>
<string name="keep_updated_summary">Uwzględnij ten podcast przy (automatycznym) odświeżaniu wszystkich kanałów</string>
<string name="auto_download_disabled_globally">Automatyczne pobieranie jest wyłączone w globalnych ustawieniach AntennaPod</string>
+ <string name="statistics_listened_for">Słuchano przez:</string>
+ <string name="statistics_episodes_on_device">Odcinki na urządzeniu:</string>
+ <string name="statistics_space_used">Użyto pamięci:</string>
+ <string name="statistics_view_all">Zobacz wszystkie podcasty »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Aktualizacja bazy danych</string>
<!--AntennaPodSP-->
@@ -703,18 +716,29 @@ https://gpodder.net/register/</string>
<!--Add podcast fragment-->
<string name="search_podcast_hint">Szukaj podcast…</string>
<string name="search_itunes_label">Szukaj w iTunes</string>
+ <string name="search_podcastindex_label">Szukaj w Podcastindex.org</string>
<string name="search_fyyd_label">Szukaj w fyyd</string>
<string name="advanced">Zaawansowane</string>
<string name="add_podcast_by_url">Dodaj podcast za pomocą adresu URL</string>
<string name="browse_gpoddernet_label">Przeglądaj gpodder.net</string>
<string name="discover">Odkryj</string>
+ <string name="discover_hide">Ukryj</string>
+ <string name="discover_is_hidden">Wybrano ukrywanie \"sugerowanych\".</string>
<string name="discover_more">więcej »</string>
- <string name="search_powered_by">Wyszukiwanie przy pomocy %1$s</string>
+ <string name="discover_powered_by_itunes">Sugerowane przez iTunes</string>
+ <string name="search_powered_by">Wyniki z %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Dodaj lokalny folder</string>
+ <string name="local_folder">Lokalny folder</string>
+ <string name="reconnect_local_folder">Połącz ponownie lokalny folder</string>
+ <string name="reconnect_local_folder_warning">W przypadku odmowy uprawnień, możesz użyć tej opcji do ponownego połączenia do tego samego folderu lokalnego. Nie wybieraj innego folderu.</string>
+ <string name="local_feed_description">Ten wirtualny podcast został stworzony przez dodanie lokalnego folderu do AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Nie można uruchomić menedżera plików</string>
<string name="filter">Filtruj</string>
<!--Episodes apply actions-->
<string name="all_label">Wszystkie</string>
<string name="selected_all_label">Zaznaczono wszystkie odcinki</string>
- <string name="none_label">Brak</string>
+ <string name="select_none_label">Brak</string>
<string name="deselected_all_label">Odznaczono wszystkie odcinki</string>
<string name="played_label">Odtworzone</string>
<string name="selected_played_label">Zaznaczono odtworzone odcinki</string>
@@ -724,12 +748,21 @@ https://gpodder.net/register/</string>
<string name="selected_downloaded_label">Zaznaczono pobrane odcinki</string>
<string name="not_downloaded_label">Nie pobrane</string>
<string name="selected_not_downloaded_label">Zaznaczono niepobrane odcinki</string>
- <string name="queued_label">W kolejce</string>
<string name="selected_queued_label">Wybierz odcinki w kolejce</string>
- <string name="not_queued_label">Nie w kolejce</string>
<string name="selected_not_queued_label">Wybierz odcinki, które nie są w kolejce</string>
- <string name="has_media">Ma media</string>
<string name="selected_has_media_label">Wybrane odcinki z mediami</string>
+ <string name="hide_is_favorite_label">Ulubione</string>
+ <string name="not_favorite">Nie oznaczone jako ulubione</string>
+ <string name="hide_downloaded_episodes_label">Pobrane</string>
+ <string name="hide_not_downloaded_episodes_label">Nie pobrane</string>
+ <string name="queued_label">W kolejce</string>
+ <string name="not_queued_label">Nie w kolejce</string>
+ <string name="has_media">Ma media</string>
+ <string name="no_media">Bez multimediów</string>
+ <string name="hide_paused_episodes_label">Zatrzymane</string>
+ <string name="not_paused">Nie pauzowane</string>
+ <string name="hide_played_episodes_label">Odtworzone</string>
+ <string name="not_played">Nie odtworzone</string>
<!--Sort-->
<string name="sort_title_a_z">Tytuł (A \u2192 Z)</string>
<string name="sort_title_z_a">Tytuł (Z \u2192 A)</string>
@@ -749,6 +782,12 @@ https://gpodder.net/register/</string>
<string name="rating_never_label">Daj mi spokój</string>
<string name="rating_later_label">Przypomnij później</string>
<string name="rating_now_label">Pewnie, zróbmy to!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Dołącz:</string>
+ <string name="share_playback_position_dialog_label">Pozycja odtwarzania</string>
+ <string name="share_dialog_media_file_url_label">Adres pliku multimedialnego</string>
+ <string name="share_dialog_episode_website_label">Adres strony odcinka</string>
+ <string name="share_dialog_media_file_label">Plik multimedialny</string>
<!--Audio controls-->
<string name="audio_controls">Sterowanie audio</string>
<string name="playback_speed">Prędkość odtwarzania</string>
@@ -756,7 +795,7 @@ https://gpodder.net/register/</string>
<string name="left_short">Lewy</string>
<string name="right_short">Prawy</string>
<string name="audio_effects">Efekty audio</string>
- <string name="stereo_to_mono">Downmix: Stereo na mono</string>
+ <string name="stereo_to_mono">Miksuj: Stereo do mono</string>
<string name="sonic_only">Tylko Sonic</string>
<string name="exoplayer_only">Tylko ExoPlayer</string>
<!--proxy settings-->
@@ -795,7 +834,9 @@ https://gpodder.net/register/</string>
<string name="notification_channel_playing">Teraz odtwarzane</string>
<string name="notification_channel_playing_description">Pozwala na kontrolowanie odtwarzania. To jest główne powiadomienie, które zobaczysz podczas odtwarzania podcastu.</string>
<string name="notification_channel_error">Błędy</string>
- <string name="notification_channel_error_description">Pokazywane gdy coś pójdzie nie tak, na przykład jeśli nie powiedzie się pobieranie lub synchronizacja z gpodder.</string>
+ <string name="notification_channel_error_description">Pokazywane, gdy coś pójdzie nie tak, np. błąd pobierania lub błąd aktualizacji.</string>
+ <string name="notification_channel_sync_error">Błędy synchronizacji</string>
+ <string name="notification_channel_sync_error_description">Pokazywane, gdy synchronizacja z gpodder się nie powiedzie.</string>
<string name="notification_channel_auto_download">Automatyczne pobieranie</string>
<string name="notification_channel_episode_auto_download">Pokazywane, gdy odcinki zostały pobrane automatycznie</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-pt-rBR/strings.xml b/core/src/main/res/values-pt-rBR/strings.xml
index d285f81fb..a4b499bf0 100644
--- a/core/src/main/res/values-pt-rBR/strings.xml
+++ b/core/src/main/res/values-pt-rBR/strings.xml
@@ -25,8 +25,9 @@
<string name="episode_cache_full_message">O limite de cache de episódios foi alcançado. Você pode aumentar o tamanho do cache em Configurações.</string>
<string name="playback_statistics_label">Reprodução</string>
<string name="download_statistics_label">Downloads</string>
+ <string name="notification_pref_fragment">Notificações</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Tempo total de podcasts reproduzidos:</string>
+ <string name="total_time_listened_to_podcasts">Tempo total de reprodução de episódios:</string>
<string name="statistics_details_dialog">%1$d de %2$d episódios iniciados.\n\nReproduzidos %3$s de %4$s.</string>
<string name="statistics_mode">Modo Estatística</string>
<string name="statistics_mode_normal">Calcular a duração que foi realmente tocada. Tocar duas vezes é contado em dobro, enquanto marcar como tocada não é contado</string>
@@ -34,6 +35,7 @@
<string name="statistics_speed_not_counted">Nota: A velocidade de reprodução nunca é levada em conta.</string>
<string name="statistics_reset_data">Limpar dados de estatísticas</string>
<string name="statistics_reset_data_msg">Isso ira apagar o histórico de reprodução de todos os episódios. Tem certeza que deseja continuar?</string>
+ <string name="statistics_counting_since">Desde %s,\nvocê reproduziu</string>
<!--Download Statistics fragment-->
<string name="total_size_downloaded_podcasts">Tamanho total dos episódios baixados:</string>
<!--Main activity-->
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Número de episódios não reproduzidos</string>
<string name="drawer_feed_counter_downloaded">Número de episódios baixados</string>
<string name="drawer_feed_counter_none">Nenhum</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Nenhum aplicativo compatível encontrado</string>
<!--Webview actions-->
<string name="open_in_browser_label">Abrir no navegador</string>
<string name="copy_url_label">Copiar URL</string>
@@ -88,7 +92,7 @@
<string name="feed_volume_reduction_summary">Diminuir o volume para episódios deste feed: %1$s</string>
<string name="feed_volume_reduction_off">Desligar</string>
<string name="feed_volume_reduction_light">Leve</string>
- <string name="feed_volume_reduction_heavy">Forte</string>
+ <string name="feed_volume_reduction_heavy">Pesado</string>
<string name="parallel_downloads_suffix">\u0020 downloads paralelos</string>
<string name="feed_auto_download_global">Padrão global</string>
<string name="feed_auto_download_always">Sempre</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Configurações do podcast</string>
<string name="rename_feed_label">Renomear podcast</string>
<string name="remove_feed_label">Remover podcast</string>
- <string name="share_label">Compartilhar...</string>
- <string name="share_link_label">Compartilhar a URL do episódio</string>
- <string name="share_link_with_position_label">Compartilhar a URL do episódio com posição</string>
+ <string name="share_label">Compartilhar</string>
+ <string name="share_label_with_ellipses">Compartilhar...</string>
<string name="share_file_label">Compartilhar arquivo</string>
- <string name="share_website_url_label">Compartilhar link do site</string>
- <string name="share_feed_url_label">Compartilhar link do podcast</string>
- <string name="share_item_url_label">Compartilhar a URL do arquivo de mídia</string>
- <string name="share_item_url_with_position_label">Compartilhar a URL do arquivo de mídia com posição</string>
+ <string name="share_website_url_label">Endereço do site</string>
+ <string name="share_feed_url_label">URL do feed</string>
<string name="feed_delete_confirmation_msg">Confirme se deseja deletar o podcast \"%1$s\" e todos seus episódios (incluindo os baixados).</string>
+ <string name="feed_delete_confirmation_local_msg">Por favor confirme que você deseja remover o podcast \"%1$s\". Os arquivos na pasta local não serão apagados.</string>
<string name="feed_remover_msg">Removendo podcast</string>
<string name="load_complete_feed">Atualizar podcast completamente</string>
<string name="multi_select">Seleção múltipla</string>
<string name="select_all_above">Selecionar tudo acima</string>
<string name="select_all_below">Selecionar tudo abaixo</string>
<string name="hide_unplayed_episodes_label">Não reproduzido</string>
- <string name="hide_paused_episodes_label">Pausado</string>
- <string name="hide_played_episodes_label">Reproduzido</string>
<string name="hide_queued_episodes_label">Enfileirado</string>
<string name="hide_not_queued_episodes_label">Não enfileirado</string>
- <string name="hide_downloaded_episodes_label">Baixado</string>
- <string name="hide_not_downloaded_episodes_label">Não baixado</string>
<string name="hide_has_media_label">Possui mídia</string>
- <string name="hide_is_favorite_label">É favorito</string>
<string name="filtered_label">Filtrado</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Última Atualização falhou</string>
<string name="open_podcast">Abrir Podcast</string>
@@ -160,19 +157,15 @@
<string name="play_label">Reproduzir</string>
<string name="pause_label">Pausar</string>
<string name="stream_label">Stream</string>
- <string name="delete_label">Deletar</string>
- <string name="delete_failed">Não foi possível deletar o arquivo. Experimente reiniciar o dispositivo.</string>
+ <string name="delete_label">Apagar</string>
+ <string name="delete_failed">Não foi possível apagar o arquivo. Experimente reiniciar o dispositivo.</string>
<string name="delete_episode_label">Apagar Episódio</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d episódio apagado.</item>
- <item quantity="other">%d episódios apagados.</item>
- </plurals>
<string name="remove_new_flag_label">Remover etiqueta de \"novo\"</string>
<string name="removed_new_flag_label">Etiqueta de \"novo\" removida</string>
<string name="mark_read_label">Marcar como reproduzido</string>
<string name="marked_as_read_label">Marcado como reproduzido</string>
- <string name="mark_read_no_media_label">Marcar como reproduzido</string>
- <string name="marked_as_read_no_media_label">Marcado como reproduzido</string>
+ <string name="mark_read_no_media_label">Marcar como lido</string>
+ <string name="marked_as_read_no_media_label">Marcado como lido</string>
<string name="play_this_to_seek_position">Para pular para as posições, você precisa reproduzir o episódio</string>
<plurals name="marked_read_batch_label">
<item quantity="one">%d episódio marcado como reproduzido.</item>
@@ -211,7 +204,7 @@
<string name="download_pending">Download pendente</string>
<string name="download_running">Download em execução</string>
<string name="download_error_details">Detalhes</string>
- <string name="download_error_details_message">%1$s \n\nFile URL:\n%2$s</string>
+ <string name="download_error_details_message">%1$s \n\nURL do arquivo:\n%2$s</string>
<string name="download_error_device_not_found">Dispositivo de armazenamento não encontrado</string>
<string name="download_error_insufficient_space">Espaço insuficiente</string>
<string name="download_error_http_data_error">Erro de HTTP Data</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Processando downloads</string>
<string name="download_notification_title">Baixando dados do podcast</string>
- <string name="download_report_content">%1$d downloads com sucesso, %2$d falharam</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%ddownload com sucesso, %dfalhou</item>
+ <item quantity="other">%ddownloads com sucesso, %dfalharam</item>
+ </plurals>
<string name="download_log_title_unknown">Título desconhecido</string>
<string name="download_type_feed">Feed</string>
<string name="download_type_media">Arquivo de mídia</string>
@@ -247,11 +243,12 @@
<string name="authentication_notification_title">Autenticação requerida</string>
<string name="authentication_notification_msg">O recurso que você solicitou requer um usuário e uma senha</string>
<string name="confirm_mobile_download_dialog_title">Confirmar Download utilizando dados móveis</string>
- <string name="confirm_mobile_download_dialog_message_not_in_queue">O download utilizando plano de dados foi desabilitado nas configurações.\n\nVocê pode escolher entre apenas adicionar o episódio na fila ou você pode permitir o download temporáriamente.\n\n<small>Sua escolha será lembrada por 10 minutos.</small></string>
- <string name="confirm_mobile_download_dialog_message">O download sobre plano de dados foi desabilitado nas configurações.\n\n Você deseja permitir o download temporáriamente?\n\n<small>Sua escolha será lembrada por 10 minutos</small></string>
+ <string name="confirm_mobile_download_dialog_message_not_in_queue">O download utilizando redes móveis foi desabilitado nas configurações.\n\nVocê pode escolher entre apenas adicionar o episódio na fila ou você pode permitir o download temporariamente.\n\n<small>Sua escolha será lembrada por 10 minutos.</small></string>
+ <string name="confirm_mobile_download_dialog_message">O download utilizando redes móveis foi desabilitado nas configurações.\n\nVocê deseja permitir o download temporariamente?\n\n<small>Sua escolha será lembrada por 10 minutos</small></string>
<string name="confirm_mobile_streaming_notification_title">Confirmar streaming móvel</string>
<string name="confirm_mobile_streaming_notification_message">O streaming pela conexão de dados móveis está desativado nas configurações. Toque para transmitir de qualquer maneira.</string>
- <string name="confirm_mobile_streaming_button_always">Sempre permitir</string>
+ <string name="confirm_mobile_streaming_button_always">Sempre</string>
+ <string name="confirm_mobile_streaming_button_once">Uma vez</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Adicionar à fila</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Permitir temporariamente</string>
<!--Mediaplayer messages-->
@@ -291,14 +288,15 @@
<string name="smart_shuffle">Embaralhamento inteligente</string>
<string name="ascending">Crescente</string>
<string name="descending">Decrescente</string>
- <string name="clear_queue_confirmation_msg">Por favor confirme que você deseja limpar TODOS episódios da fila</string>
+ <string name="clear_queue_confirmation_msg">Por favor confirme que você deseja limpar TODOS os episódios da fila</string>
<string name="time_left_label">Tempo restante:\u0020</string>
<!--Variable Speed-->
<string name="download_plugin_label">Download Plugin</string>
<string name="no_playback_plugin_title">Plugin Não Instalado</string>
<string name="no_playback_plugin_or_sonic_msg">Para que a reprodução de velocidade variável funcione, recomendamos habilitar o reprodutor de mídia Sonic integrado.</string>
- <string name="set_playback_speed_label">Velocidades de Reprodução</string>
<string name="enable_sonic">Habilitar Sonic</string>
+ <string name="speed_presets">Presets</string>
+ <string name="preset_already_exists">%1$.2fx foi salvo com um preset.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Nenhum episódio na fila</string>
<string name="no_items_label">Adicione um episódio baixando-o ou mantenha pressionado um episódio e selecione \"Adicionar à fila\".</string>
@@ -342,16 +340,16 @@
<string name="media_player">Reprodutor de mídia</string>
<string name="pref_episode_cleanup_title">Limpar Episódio</string>
<string name="pref_episode_cleanup_summary">Episódios que não estão na fila e não estão nos favoritos podem ser removidos se o Download Automático precisar de espaço para novos episódios</string>
- <string name="pref_pauseOnDisconnect_sum">Pausar a reprodução quando o fone de ouvido ou bluetooth forem disconectados</string>
+ <string name="pref_pauseOnDisconnect_sum">Pausar a reprodução quando o fone de ouvido ou bluetooth forem desconectados</string>
<string name="pref_unpauseOnHeadsetReconnect_sum">Continuar a reprodução quando os fones de ouvido forem reconectados</string>
<string name="pref_unpauseOnBluetoothReconnect_sum">Continuar a reprodução quando o bluetooth reconectar</string>
<string name="pref_hardwareForwardButtonSkips_title">Botão avançar pula</string>
- <string name="pref_hardwareForwardButtonSkips_sum">Reproduz o próximo episódio ao pressionar o botão avançar num dispositivo bluetooth conectado, ao invés de avançar no mesmo.</string>
- <string name="pref_hardwarePreviousButtonRestarts_title">Botão anterior reinicia</string>
- <string name="pref_hardwarePreviousButtonRestarts_sum">Reinicia a reprodução atual ao pressionar o botão físico anterior ao invés de retroceder</string>
+ <string name="pref_hardwareForwardButtonSkips_sum">Ao pressionar um botão de avanço em um dispositivo conectado por bluetooth, pule para o próximo episódio em vez de avançar.</string>
+ <string name="pref_hardwarePreviousButtonRestarts_title">Botão Anterior reinicia</string>
+ <string name="pref_hardwarePreviousButtonRestarts_sum">Ao pressionar o botão Anterior do hardware, reinicie a reprodução do episódio atual em vez de retroceder</string>
<string name="pref_followQueue_sum">Pular para próximo item da fila quando a reprodução terminar</string>
<string name="pref_auto_delete_sum">Remover episódio quando a reprodução for concluída</string>
- <string name="pref_auto_delete_title">Deletar automaticamente</string>
+ <string name="pref_auto_delete_title">Apagar automaticamente</string>
<string name="pref_smart_mark_as_played_sum">Marcar episódios como reproduzidos mesmo que restem alguns segundos de reprodução</string>
<string name="pref_smart_mark_as_played_title">Marcar automaticamente como reproduzido</string>
<string name="pref_skip_keeps_episodes_sum">Manter os episódios quando eles forem avançados</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">cada %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">às %1$s</string>
<string name="pref_followQueue_title">Reprodução contínua</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Fones de ouvido desconectados</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Fones de ouvido ou Bluetooth desconectado</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Fones de ouvido reconectados</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth reconectado</string>
<string name="pref_stream_over_download_title">Preferir streaming</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Download de episódios</string>
<string name="pref_mobileUpdate_streaming">Streaming</string>
<string name="user_interface_label">Interface com usuário</string>
- <string name="user_interface_sum">Aparência, pedidos de assinatura, tela de bloqueio</string>
+ <string name="user_interface_sum">Aparência, Assinaturas, Tela de Bloqueio</string>
<string name="pref_set_theme_title">Selecionar tema</string>
<string name="pref_nav_drawer_items_title">Configurar itens da Gaveta de Navegação</string>
<string name="pref_nav_drawer_items_sum">Escolher quais itens irão aparecer na gaveta de navegação.</string>
@@ -399,7 +397,7 @@
<string name="pref_autodl_wifi_filter_sum">Permitir download automático somente pelas redes Wi-Fi selecionadas.</string>
<string name="pref_automatic_download_on_battery_title">Baixar enquanto não está carregando</string>
<string name="pref_automatic_download_on_battery_sum">Permitir download automático enquanto a bateria não está carregando</string>
- <string name="pref_parallel_downloads_title">Downloads paralelos</string>
+ <string name="pref_parallel_downloads_title">Downloads em paralelo</string>
<string name="pref_episode_cache_title">Cache de episódios</string>
<string name="pref_episode_cache_summary">Número total de episódios baixados em cache no dispositivo. O download automático será suspenso se esse número for atingido.</string>
<string name="pref_episode_cover_title">Usar capa do episódio</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Forçar sincronização completa</string>
<string name="pref_gpodnet_full_sync_sum">Sincronizar os estados das inscrições e episódios com o gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Entrou como <i>%1$s</i> com o dispositivo <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Exibir notificações de erros de sincronismo</string>
+ <string name="pref_gpodnet_notifications_title">Sincronização falhou</string>
<string name="pref_gpodnet_notifications_sum">Essa configuração não se aplica a erros de autenticação.</string>
- <string name="pref_playback_speed_title">Velocidades de Reprodução</string>
- <string name="pref_playback_speed_sum">Personalize as velocidades variáveis de reprodução de áudio.</string>
+ <string name="pref_playback_speed_sum">Personalize as velocidades disponíveis para reprodução de áudio.</string>
<string name="pref_feed_playback_speed_sum">A velocidade a ser usada ao iniciar a reprodução de áudio para episódios neste podcast</string>
<string name="pref_feed_skip">Salto automático</string>
<string name="pref_feed_skip_sum">Pule as introduções e os créditos finais.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Isso geralmente expande a notificação para exibir botões de reprodução.</string>
<string name="pref_persistNotify_title">Controles de Reprodução Persistentes</string>
<string name="pref_persistNotify_sum">Manter a notificação e controles na tela de bloqueio enquanto a reprodução está pausada.</string>
- <string name="pref_compact_notification_buttons_title">Configurar Botões da tela de bloqueio</string>
- <string name="pref_compact_notification_buttons_sum">Mudar os botões de reprodução na tela de bloqueio. O botão tocar/pausar sempre é incluso.</string>
+ <string name="pref_compact_notification_buttons_title">Definir botões compactos de notificação</string>
+ <string name="pref_compact_notification_buttons_sum">Altere os botões de reprodução quando a notificação for recolhida. O botão play / pause está sempre incluído.</string>
<string name="pref_compact_notification_buttons_dialog_title">Selecione no máximo %1$d itens</string>
<string name="pref_compact_notification_buttons_dialog_error">Você só pode selecionar no máximo %1$d itens.</string>
<string name="pref_lockscreen_background_title">Configurar plano de fundo da tela de bloqueio</string>
<string name="pref_lockscreen_background_sum">Configurar o plano de fundo da tela de bloqueio para a imagem do episódio atual. Como um efeito colateral, também ira mostrar imagens de aplicativos de terceiros.</string>
- <string name="pref_showDownloadReport_title">Mostrar Relatório de Downloads</string>
+ <string name="pref_showDownloadReport_title">Download falhou</string>
<string name="pref_showDownloadReport_sum">Se os downloads falharem, gerar um relatório que mostra os detalhes da falha.</string>
- <string name="pref_showAutoDownloadReport_title">Mostrar relatório de downloads automáticos</string>
+ <string name="pref_showAutoDownloadReport_title">Download automático finalizado</string>
<string name="pref_showAutoDownloadReport_sum">Mostra uma notificação para episódios baixados automaticamente.</string>
<string name="pref_expand_notify_unsupport_toast">Versões do Android inferiores a 4.1 não suportam notificações expansíveis</string>
<string name="pref_enqueue_location_title">Local da fila</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Enfileirar os baixados</string>
<string name="pref_enqueue_downloaded_summary">Adicionar episódios baixados à fila</string>
<string name="media_player_builtin">Reprodutor próprio do Android</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (recomendado)</string>
<string name="media_player_switch_to_exoplayer">Alterar para ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Alterado para ExoPlayer</string>
<string name="pref_skip_silence_title">Pular silêncio no áudio</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Selecione a página</string>
<string name="pref_delete_removes_from_queue_title">Apagar remove da fila</string>
<string name="pref_delete_removes_from_queue_sum">Remove automaticamente um episódio da fila quando ele é apagado.</string>
+ <string name="pref_filter_feed_title">Filtro de Assinaturas</string>
+ <string name="pref_filter_feed_sum">Filtre suas assinaturas na navegação e na tela de assinaturas.</string>
+ <string name="no_filter_label">Nenhum</string>
+ <string name="subscriptions_are_filtered">Assinaturas estão filtradas.</string>
+ <string name="subscriptions_counter_greater_zero">Contador maior que zero</string>
+ <string name="auto_downloaded">Download automático</string>
+ <string name="not_auto_downloaded">Download não automático</string>
+ <string name="kept_updated">Mantido atualizado</string>
+ <string name="not_kept_updated">Não atualizado</string>
<!--About screen-->
<string name="about_pref">Sobre</string>
<string name="antennapod_version">Versão do AntennaPod</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Transfira assinaturas, episódios ouvidos e fila para o AntennaPod em outro dispositivo</string>
<string name="database_import_summary">Importar banco de dados AntennaPod de outro dispositivo</string>
<string name="opml_import_label">Importação de OPML</string>
+ <string name="opml_add_podcast_label">Importar lista de podcasts (OPML)</string>
<string name="opml_reader_error">Um erro ocorreu ao ler o documento OPML:</string>
<string name="opml_import_error_no_file">Nenhum arquivo selecionado!</string>
<string name="select_all_label">Selecionar todos</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">O arquivo foi exportado para:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Acesso ao armazenamento externo é necessária para ler o arquivo OPML</string>
<string name="import_select_file">Selecione arquivo para importar</string>
- <string name="import_ok">Importado com sucesso.\n\nFavor pressionar OK para reiniciar o AntennaPod</string>
+ <string name="successful_import_label">Importação bem sucedida</string>
+ <string name="import_ok">Por favor, pressione OK para reiniciar o AntennaPod</string>
<string name="import_no_downgrade">Este banco de dados foi exportado com uma versão mais recente do AntennaPod. Sua instalação atual ainda não sabe como lidar com este arquivo.</string>
<string name="favorites_export_label">Exportar favoritos</string>
<string name="favorites_export_summary">Exportar favoritos salvos para arquivo</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Diminuir velocidade</string>
<string name="media_type_audio_label">Áudio</string>
<string name="media_type_video_label">Vídeo</string>
- <string name="navigate_upwards_label">Navegar para cima</string>
<string name="status_downloading_label">O epísódio está sendo baixado</string>
<string name="in_queue_label">Episódio está na fila</string>
<string name="is_favorite_label">Episódio está marcado como favorito</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Manter Atualizado</string>
<string name="keep_updated_summary">Incluir este podcast ao atualizar todos os podcasts</string>
<string name="auto_download_disabled_globally">O download automático está desativado nas configurações principais do AntennaPod</string>
+ <string name="statistics_listened_for">Ouvido por:</string>
+ <string name="statistics_episodes_on_device">Episódios no dispositivo:</string>
+ <string name="statistics_space_used">Espaço utilizado:</string>
+ <string name="statistics_view_all">Visualização para todos os podcasts »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Atualizando o banco de dados</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Procurar podcast...</string>
<string name="search_itunes_label">Procurar no iTunes</string>
+ <string name="search_podcastindex_label">Buscando em Podcastindex.org</string>
<string name="search_fyyd_label">Pesquisar em fyyd</string>
<string name="advanced">Avançado</string>
- <string name="add_podcast_by_url">Adicionar podcast usando uma URL</string>
+ <string name="add_podcast_by_url">Adicionar podcast usando um endereço RSS</string>
<string name="browse_gpoddernet_label">Pesquisar no gpodder.net</string>
<string name="discover">Descobrir</string>
+ <string name="discover_hide">Esconder</string>
+ <string name="discover_is_hidden">Você selecionou esconder sugestões.</string>
<string name="discover_more">mais »</string>
- <string name="search_powered_by">Pesquisa usando %1$s</string>
+ <string name="discover_powered_by_itunes">Sugestões do iTunes</string>
+ <string name="search_powered_by">Resultados por %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Adicionar pasta local</string>
+ <string name="local_folder">Pasta local</string>
+ <string name="reconnect_local_folder">Reconectar pasta local</string>
+ <string name="reconnect_local_folder_warning">Em caso de negação de permissão, você pode usar isso para se reconectar exatamente à mesma pasta. Não selecione outra pasta.</string>
+ <string name="local_feed_description">Este podcast virtual foi criado adicionando uma pasta ao AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Incapaz de iniciar o gerenciador de arquivos do sistema</string>
<string name="filter">Filtrar</string>
<!--Episodes apply actions-->
<string name="all_label">Todos</string>
<string name="selected_all_label">Selecionar todos Episódios</string>
- <string name="none_label">Nenhum</string>
+ <string name="select_none_label">Nenhum</string>
<string name="deselected_all_label">Desmarcar todos Episódios</string>
<string name="played_label">Reproduzido</string>
<string name="selected_played_label">Selecionar episódios reproduzidos</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Episódios baixados selecionados</string>
<string name="not_downloaded_label">Não baixados</string>
<string name="selected_not_downloaded_label">Episídios não baixados selecionados</string>
- <string name="queued_label">Enfileirado</string>
<string name="selected_queued_label">Episódios enfileirados selecionados</string>
- <string name="not_queued_label">Não enfileirado</string>
<string name="selected_not_queued_label">Episódios não enfileirados selecionados</string>
- <string name="has_media">Possui mídia</string>
<string name="selected_has_media_label">Episódios selecionados com mídia</string>
+ <string name="hide_is_favorite_label">É favorito</string>
+ <string name="not_favorite">Não favorito</string>
+ <string name="hide_downloaded_episodes_label">Baixado</string>
+ <string name="hide_not_downloaded_episodes_label">Não baixado</string>
+ <string name="queued_label">Enfileirado</string>
+ <string name="not_queued_label">Não enfileirado</string>
+ <string name="has_media">Possui mídia</string>
+ <string name="no_media">Nenhuma media</string>
+ <string name="hide_paused_episodes_label">Pausado</string>
+ <string name="not_paused">Não pausado</string>
+ <string name="hide_played_episodes_label">Reproduzido</string>
+ <string name="not_played">Não tocado</string>
<!--Sort-->
<string name="sort_title_a_z">Título (A \u2192 Z)</string>
<string name="sort_title_z_a">Título (Z \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Me deixe em paz</string>
<string name="rating_later_label">Lembre-me mais tarde</string>
<string name="rating_now_label">Claro, vamos fazer isso!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Incluir:</string>
+ <string name="share_playback_position_dialog_label">Posição do playback</string>
+ <string name="share_dialog_media_file_url_label">Endereço do arquivo de media</string>
+ <string name="share_dialog_episode_website_label">Webpage do episódio</string>
+ <string name="share_dialog_media_file_label">Arquivo de media</string>
<!--Audio controls-->
<string name="audio_controls">Controles de Àudio</string>
<string name="playback_speed">Velocidade da Reprodução</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Reproduzindo agora</string>
<string name="notification_channel_playing_description">Permite controlar a reprodução. Essa é a principal notificação vista ao reproduzir um podcast.</string>
<string name="notification_channel_error">Erros</string>
- <string name="notification_channel_error_description">Exibido caso algo dê errado, por exemplo se houver falha no download ou na sincronização com o gpodder.</string>
+ <string name="notification_channel_error_description">Exibido se algo der errado, por exemplo, se o download ou a atualização do feed falhar.</string>
+ <string name="notification_channel_sync_error">Erros de sincronização</string>
+ <string name="notification_channel_sync_error_description">Exibido quando a sincronização do gpodder falhou.</string>
<string name="notification_channel_auto_download">Downloads automáticos</string>
<string name="notification_channel_episode_auto_download">Exibido quando os episódios foram baixados automaticamente.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-pt/strings.xml b/core/src/main/res/values-pt/strings.xml
index 64a381953..7e2350504 100644
--- a/core/src/main/res/values-pt/strings.xml
+++ b/core/src/main/res/values-pt/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Atingido o limite máximo de itens em cache. Pode aumentar o tamanho de cache nas definições.</string>
<string name="playback_statistics_label">Reprodução</string>
<string name="download_statistics_label">Descargas</string>
+ <string name="notification_pref_fragment">Notificações</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Tempo total dos podcasts reproduzidos:</string>
+ <string name="total_time_listened_to_podcasts">Tempo total dos episódios reproduzidos:</string>
<string name="statistics_details_dialog">%1$d de %2$d episódios iniciados.\n\nReproduzidos %3$s de %4$s.</string>
<string name="statistics_mode">Modo estatístico</string>
<string name="statistics_mode_normal">Calcula a duração dos podcasts reproduzidos. Se os reproduzir duas vezes, serão contados duas vezes mas se os marcar como reproduzidos não serão contados.</string>
- <string name="statistics_mode_count_all">Somar todos os podcasts marcados como reproduzidos</string>
+ <string name="statistics_mode_count_all">Soma todos os episódios que tenham sido marcados como reproduzidos</string>
<string name="statistics_speed_not_counted">Aviso: a velocidade de reprodução nunca será considerada.</string>
<string name="statistics_reset_data">Reiniciar estatísticas dos dados</string>
<string name="statistics_reset_data_msg">Isto irá apagar o histórico do tempo de reprodução para todos os episódios. Tem a certeza de que deseja continuar?</string>
+ <string name="statistics_counting_since">Desde %s,\n você reproduziu</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Tamanho total dos podcasts descarregados:</string>
+ <string name="total_size_downloaded_podcasts">Tamanho total dos episódios no dispositivo:</string>
<!--Main activity-->
<string name="drawer_open">Abrir menu</string>
<string name="drawer_close">Fechar menu</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Número de episódios por reproduzir</string>
<string name="drawer_feed_counter_downloaded">Número de episódios descarregados</string>
<string name="drawer_feed_counter_none">Nenhum</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Não existem aplicações compatíveis</string>
<!--Webview actions-->
<string name="open_in_browser_label">Abrir no navegador</string>
<string name="copy_url_label">Copiar URL</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Definições do podcast</string>
<string name="rename_feed_label">Renomear podcast</string>
<string name="remove_feed_label">Remover podcast</string>
- <string name="share_label">Partilhar...</string>
- <string name="share_link_label">Partilhar URL do episódio</string>
- <string name="share_link_with_position_label">Partilhar URL do episódio (com posição)</string>
+ <string name="share_label">Partilhar</string>
+ <string name="share_label_with_ellipses">Partilhar...</string>
<string name="share_file_label">Partilhar ficheiro</string>
- <string name="share_website_url_label">Partilhar URL do site</string>
- <string name="share_feed_url_label">Partilhar URL do podcast</string>
- <string name="share_item_url_label">Partilhar URL do ficheiro multimédia</string>
- <string name="share_item_url_with_position_label">Partilhar URL do ficheiro multimédia (com posição)</string>
+ <string name="share_website_url_label">Endereço web</string>
+ <string name="share_feed_url_label">URL da fonte do podcast</string>
<string name="feed_delete_confirmation_msg">Tem a certeza de que deseja eliminar o podcast \"%1$s\" e TODOS os seus episódios (inclusive descarregados)?</string>
+ <string name="feed_delete_confirmation_local_msg">Por favor confirme de que deseja remover o podcast \"%1$s\". Os ficheiros existentes na pasta local não serão eliminados.</string>
<string name="feed_remover_msg">A remover podcast</string>
<string name="load_complete_feed">Recarregar podcast</string>
<string name="multi_select">Seleção múltipla</string>
<string name="select_all_above">Marcar tudo acima</string>
<string name="select_all_below">Marcar tudo abaixo</string>
<string name="hide_unplayed_episodes_label">Não reproduzidos</string>
- <string name="hide_paused_episodes_label">Em pausa</string>
- <string name="hide_played_episodes_label">Reproduzidos</string>
<string name="hide_queued_episodes_label">Na fila</string>
<string name="hide_not_queued_episodes_label">Não na fila</string>
- <string name="hide_downloaded_episodes_label">Descarregados</string>
- <string name="hide_not_downloaded_episodes_label">Não descarregados</string>
<string name="hide_has_media_label">Tem ficheiro</string>
- <string name="hide_is_favorite_label">É favorito</string>
<string name="filtered_label">Filtrados</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Última atualização falhada</string>
<string name="open_podcast">Abrir podcast</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Eliminar</string>
<string name="delete_failed">Episódio não eliminado. Tente reiniciar o dispositivo.</string>
<string name="delete_episode_label">Eliminar episódio</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d episódio eliminado.</item>
- <item quantity="other">%d episódios eliminados.</item>
- </plurals>
<string name="remove_new_flag_label">Remover a marca \"novo\"</string>
<string name="removed_new_flag_label">A marca \"novo\" foi removida</string>
<string name="mark_read_label">Marcar como reproduzido</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Processamento de descargas</string>
<string name="download_notification_title">A descarregar dados do podcast</string>
- <string name="download_report_content">%1$d descargas efetuadas, %2$d falhadas</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d descarga com sucesso, %d com falha</item>
+ <item quantity="other">%d descargas com sucesso, %d com falha</item>
+ </plurals>
<string name="download_log_title_unknown">Título desconhecido</string>
<string name="download_type_feed">Fonte</string>
<string name="download_type_media">Ficheiro multimédia</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">A descarga através de dados móveis está desativada nas definições.\n\nAtivar temporariamente?\n\n<small>A sua decisão será memorizada durante 10 minutos.</small></string>
<string name="confirm_mobile_streaming_notification_title">Confirmação de reprodução em dados móveis</string>
<string name="confirm_mobile_streaming_notification_message">A reprodução de podcasts através de dados móveis está desativada nas definições. Toque para, ainda assim, reproduzir o podcast.</string>
- <string name="confirm_mobile_streaming_button_always">Permitir sempre</string>
+ <string name="confirm_mobile_streaming_button_always">Sempre</string>
+ <string name="confirm_mobile_streaming_button_once">Uma vez</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Apenas adicionados à fila</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Ativar temporariamente</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Descarregar extra</string>
<string name="no_playback_plugin_title">Extra não instalado</string>
<string name="no_playback_plugin_or_sonic_msg">Para que a velocidade variável de reprodução funcione, recomendamos que ative o Sonic Media Player incorporado na aplicação.</string>
- <string name="set_playback_speed_label">Velocidades de reprodução</string>
<string name="enable_sonic">Ativar Sonic</string>
+ <string name="speed_presets">Predefinições</string>
+ <string name="preset_already_exists">%1$.2fx já está definido como predefinição.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Não existem episódios na fila</string>
<string name="no_items_label">Pode adicionar um episódio se o descarregar ou com um toque longo no episódio e escolher \"Adicionar à fila\".</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">a cada %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">às %1$s</string>
<string name="pref_followQueue_title">Reprodução contínua</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Auscultadores removidos</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Auscultadores ou Bluetooth desligados</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Auscultadores inseridos</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Ligação bluetooth</string>
<string name="pref_stream_over_download_title">Preferir transmissão</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Descarga de episódios</string>
<string name="pref_mobileUpdate_streaming">Reprodução</string>
<string name="user_interface_label">Interface</string>
- <string name="user_interface_sum">Aparência, ordem das subscrições, ecrã de bloqueio</string>
+ <string name="user_interface_sum">Aparência, subscrições e ecrã de bloqueio</string>
<string name="pref_set_theme_title">Tema</string>
<string name="pref_nav_drawer_items_title">Alterar itens do menu</string>
<string name="pref_nav_drawer_items_sum">Alterar os itens que aparecem no menu de navegação.</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Impor sincronização total</string>
<string name="pref_gpodnet_full_sync_sum">Sincronizar todas as subscrições e estados dos episódios com o gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Sessão iniciada como <i>%1$s</i> com o dispositivo <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Mostrar erros de sincronização</string>
+ <string name="pref_gpodnet_notifications_title">Falha de sinconização</string>
<string name="pref_gpodnet_notifications_sum">Esta definição não é aplicável aos erros de autenticação.</string>
- <string name="pref_playback_speed_title">Velocidades de reprodução</string>
- <string name="pref_playback_speed_sum">Personalizar as velocidades de reprodução disponíveis.</string>
+ <string name="pref_playback_speed_sum">Personalizar disponibilidade das velocidades variáveis de reprodução</string>
<string name="pref_feed_playback_speed_sum">Velocidade utilizada para a reprodução áudio dos episódios deste podcast</string>
<string name="pref_feed_skip">Ignorar automaticamente</string>
<string name="pref_feed_skip_sum">Ignorar introduções e créditos finais.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Normalmente, esta opção é utilizada para expandir a notificação e mostrar os botões de reprodução.</string>
<string name="pref_persistNotify_title">Controlos de reprodução</string>
<string name="pref_persistNotify_sum">Manter controlos de notificação e ecrã de bloqueio ao colocar a reprodução em pausa.</string>
- <string name="pref_compact_notification_buttons_title">Definir botões do ecrã de bloqueio</string>
- <string name="pref_compact_notification_buttons_sum">Alterar botões de reprodução do ecrã de bloqueio. Os botões Reproduzir/Pausa serão sempre incluídos.</string>
+ <string name="pref_compact_notification_buttons_title">Definir botões compactos para a notificação</string>
+ <string name="pref_compact_notification_buttons_sum">Alterar botões de reprodução ao recolher a notificação. Os botões Reproduzir/Pausa serão sempre incluídos.</string>
<string name="pref_compact_notification_buttons_dialog_title">Selecione no máximo %1$d itens</string>
<string name="pref_compact_notification_buttons_dialog_error">Apenas pode selecionar um máximo de %1$d itens.</string>
<string name="pref_lockscreen_background_title">Definir fundo do ecrã de bloqueio</string>
<string name="pref_lockscreen_background_sum">Define a imagem do episódio como fundo do ecrã de bloqueio. Efeito colateral: também será mostrada em outras aplicações.</string>
- <string name="pref_showDownloadReport_title">Mostrar relatório de erros</string>
+ <string name="pref_showDownloadReport_title">Falha ao descarregar</string>
<string name="pref_showDownloadReport_sum">Se a descarga falhar, gera um relatório que mostra os detalhes do erro.</string>
- <string name="pref_showAutoDownloadReport_title">Mostrar relatório de descargas automáticas</string>
+ <string name="pref_showAutoDownloadReport_title">Descarga automática terminada</string>
<string name="pref_showAutoDownloadReport_sum">Mostrar uma notificação para episódios descarregados automaticamente.</string>
<string name="pref_expand_notify_unsupport_toast">As versões Android anteriores à 4.1 não possuem suporte à expansão de notificações</string>
<string name="pref_enqueue_location_title">Localização na fila</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Colocar descargas na fila</string>
<string name="pref_enqueue_downloaded_summary">Adicionar à fila os episódios descarregados.</string>
<string name="media_player_builtin">Reprodutor nativo Android</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (recomendado)</string>
<string name="media_player_switch_to_exoplayer">Trocar para ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Trocou para ExoPlayer.</string>
<string name="pref_skip_silence_title">Ignorar silêncio no áudio</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Selecionar página</string>
<string name="pref_delete_removes_from_queue_title">Remover da fila</string>
<string name="pref_delete_removes_from_queue_sum">Remover episódio da fila se este for eliminado.</string>
+ <string name="pref_filter_feed_title">Filtro de subscrições</string>
+ <string name="pref_filter_feed_sum">Filtrar subscrições no menu de navegação e no ecrã de subscrições.</string>
+ <string name="no_filter_label">Nenhum</string>
+ <string name="subscriptions_are_filtered">Subscrições filtradas</string>
+ <string name="subscriptions_counter_greater_zero">Contagem maior do que zero</string>
+ <string name="auto_downloaded">Descarregado automaticamente</string>
+ <string name="not_auto_downloaded">Não descarregado automaticamente</string>
+ <string name="kept_updated">Manter atualizada</string>
+ <string name="not_kept_updated">Não manter atualizada</string>
<!--About screen-->
<string name="about_pref">Acerca</string>
<string name="antennapod_version">Versão do AntennaPod</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Transferir subscrições, episódios e fila de reprodução do AntennaPod para outro dispositivo</string>
<string name="database_import_summary">Importar base de dados AntennaPod de outro dispositivo</string>
<string name="opml_import_label">Importação OPML</string>
+ <string name="opml_add_podcast_label">Importar lista de podcasts (OPML)</string>
<string name="opml_reader_error">Ocorreu um erro ao ler o ficheiro OPML:</string>
<string name="opml_import_error_no_file">Nenhum ficheiro selecionado!</string>
<string name="select_all_label">Marcar tudo</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">O ficheiro exportado foi guardado em:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Requer acesso ao armazenamento externo para ler o ficheiro OPML</string>
<string name="import_select_file">Selecione o ficheiro a importar</string>
- <string name="import_ok">Importação bem sucedida.\n\nPor favor prima OK para reiniciar o AntennaPod</string>
+ <string name="successful_import_label">Importação bem sucedida</string>
+ <string name="import_ok">Prima OK para reiniciar a aplicação</string>
<string name="import_no_downgrade">A base de dados foi exportada de uma versão mais recente do AntennaPod. A sua versão da aplicação não sabe como manipular este ficheiro.</string>
<string name="favorites_export_label">Exportação de favoritos</string>
<string name="favorites_export_summary">Exportar favoritos para um ficheiro</string>
@@ -585,7 +594,7 @@
<string name="gpodnet_taglist_header">Categorias</string>
<string name="gpodnet_toplist_header">Melhores</string>
<string name="gpodnet_suggestions_header">Sugestões</string>
- <string name="gpodnet_search_hint">Pesquisar no gpodder.net</string>
+ <string name="gpodnet_search_hint">Pesquisar em gpodder.net</string>
<string name="gpodnetauth_login_title">Acesso</string>
<string name="gpodnetauth_login_descr">Bem-vindo ao processo de acesso ao gpodder.net. Introduza os dados de acesso:</string>
<string name="gpodnetauth_login_butLabel">Acesso</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Diminuir velocidade</string>
<string name="media_type_audio_label">Áudio</string>
<string name="media_type_video_label">Vídeo</string>
- <string name="navigate_upwards_label">Navegar para cima</string>
<string name="status_downloading_label">A descarregar episódio</string>
<string name="in_queue_label">Episódio está na fila</string>
<string name="is_favorite_label">Episódio marcado como favorito</string>
@@ -669,25 +677,40 @@
<string name="keep_updated">Manter atualizada</string>
<string name="keep_updated_summary">Incluir este podcast ao recarregar automaticamente todos os podcasts</string>
<string name="auto_download_disabled_globally">A descarga automática está desativada nas definições do AntennaPod</string>
+ <string name="statistics_listened_for">Reproduzido durante:</string>
+ <string name="statistics_episodes_on_device">Episódios no dispositivo:</string>
+ <string name="statistics_space_used">Espaço utilizado:</string>
+ <string name="statistics_view_all">Ver para todos os podcasts »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Atualizando base de dados</string>
<!--AntennaPodSP-->
<string name="sp_apps_importing_feeds_msg">Importar subscrições de aplicações single-purpose...</string>
<!--Add podcast fragment-->
<string name="search_podcast_hint">Pesquisar podcast...</string>
- <string name="search_itunes_label">Pesquisar no iTunes</string>
- <string name="search_fyyd_label">Pesquisar no fyyd</string>
+ <string name="search_itunes_label">Pesquisar em iTunes</string>
+ <string name="search_podcastindex_label">Pesquisar em Podcastindex.org</string>
+ <string name="search_fyyd_label">Pesquisar em fyyd</string>
<string name="advanced">Avançado</string>
- <string name="add_podcast_by_url">Adicionar podcast via URL</string>
+ <string name="add_podcast_by_url">Adicionar podcast via endereço RSS</string>
<string name="browse_gpoddernet_label">Procurar no gPodder.net</string>
<string name="discover">Descobrir</string>
+ <string name="discover_hide">Ocultar</string>
+ <string name="discover_is_hidden">Você optou por ocultar sugestões.</string>
<string name="discover_more">mais »</string>
- <string name="search_powered_by">Disponibilizado por %1$s</string>
+ <string name="discover_powered_by_itunes">Sugestões de iTunes</string>
+ <string name="search_powered_by">Resultados de %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Adicionar pasta local</string>
+ <string name="local_folder">Pasta local</string>
+ <string name="reconnect_local_folder">Restabelecer ligação a pasta local</string>
+ <string name="reconnect_local_folder_warning">Em casos de recusa de permissões, pode utilizar isto para estabelecer uma nova ligação à mesma pasta. Não deve escolher outra pasta.</string>
+ <string name="local_feed_description">Este podcast virtual foi criado através da adição de uma pasta ao AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Não foi possível iniciar o gestor de ficheiros</string>
<string name="filter">Filtro</string>
<!--Episodes apply actions-->
<string name="all_label">Todos</string>
<string name="selected_all_label">Marcar todos os episódios</string>
- <string name="none_label">Nenhum</string>
+ <string name="select_none_label">Nenhum</string>
<string name="deselected_all_label">Desmarcar todos os episódios</string>
<string name="played_label">Reproduzidos</string>
<string name="selected_played_label">Selecionar episódios reproduzidos</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Selecionar episódios descarregados</string>
<string name="not_downloaded_label">Não descarregados</string>
<string name="selected_not_downloaded_label">Selecionar episódios não descarregados</string>
- <string name="queued_label">Na fila</string>
<string name="selected_queued_label">Episódios selecionados na fila</string>
- <string name="not_queued_label">Não na fila</string>
<string name="selected_not_queued_label">Episódios não selecionados na fila</string>
- <string name="has_media">Tem ficheiro</string>
<string name="selected_has_media_label">Episódios selecionados com ficheiros</string>
+ <string name="hide_is_favorite_label">É favorito</string>
+ <string name="not_favorite">Não favorito</string>
+ <string name="hide_downloaded_episodes_label">Descarregados</string>
+ <string name="hide_not_downloaded_episodes_label">Não descarregados</string>
+ <string name="queued_label">Na fila</string>
+ <string name="not_queued_label">Não na fila</string>
+ <string name="has_media">Tem ficheiro</string>
+ <string name="no_media">Sem ficheiro</string>
+ <string name="hide_paused_episodes_label">Em pausa</string>
+ <string name="not_paused">Não em pausa</string>
+ <string name="hide_played_episodes_label">Reproduzidos</string>
+ <string name="not_played">Não reproduzido</string>
<!--Sort-->
<string name="sort_title_a_z">Título (A \u2192 Z)</string>
<string name="sort_title_z_a">Título (Z \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Não avaliar</string>
<string name="rating_later_label">Lembrar mais tarde</string>
<string name="rating_now_label">Claro, vamos a isso!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Incluir:</string>
+ <string name="share_playback_position_dialog_label">Posição de reprodução</string>
+ <string name="share_dialog_media_file_url_label">Endereço do ficheiro multimédia</string>
+ <string name="share_dialog_episode_website_label">Página web do episódio</string>
+ <string name="share_dialog_media_file_label">Ficheiro multimédia</string>
<!--Audio controls-->
<string name="audio_controls">Controlos de áudio</string>
<string name="playback_speed">Velocidade de reprodução</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Reprodução atual</string>
<string name="notification_channel_playing_description">Permite o controlo da reprodução. Esta será a notificação que verá ao reproduzir um podcast.</string>
<string name="notification_channel_error">Erros</string>
- <string name="notification_channel_error_description">Mostrar se ocorrerem erros como, por exemplo, não for possível a descarga.</string>
+ <string name="notification_channel_error_description">Mostrar se ocorrerem erros como, por exemplo, não for possível descarregar ou atualizar a fonte.</string>
+ <string name="notification_channel_sync_error">Erros de sincronização</string>
+ <string name="notification_channel_sync_error_description">Mostrar se não for possível sincronizar com gpodder.</string>
<string name="notification_channel_auto_download">Descargas automáticas</string>
<string name="notification_channel_episode_auto_download">Notificar quando os episódios forem descarregados automaticamente.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-ru/strings.xml b/core/src/main/res/values-ru/strings.xml
index 58c177f95..90284b2cc 100644
--- a/core/src/main/res/values-ru/strings.xml
+++ b/core/src/main/res/values-ru/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Достигнут предел кэша выпусков. Объем кэша можно увеличить в настройках.</string>
<string name="playback_statistics_label">Воспроизведение</string>
<string name="download_statistics_label">Загрузки</string>
+ <string name="notification_pref_fragment">Уведомления</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Общее время прослушивания подкастов:</string>
+ <string name="total_time_listened_to_podcasts">Общее время прослушивания выпусков:</string>
<string name="statistics_details_dialog">%1$d из %2$d выпусков начато.\n\nПрослушано %3$s из %4$s.</string>
<string name="statistics_mode">Режим подсчета статистики</string>
<string name="statistics_mode_normal">Рассчитывать длительность действительного воспроизведения. Повторное воспроизведение засчитывается, а отметка о прослушивании — нет</string>
- <string name="statistics_mode_count_all">Прибавлять также все подкасты, отмеченные как прослушанные</string>
+ <string name="statistics_mode_count_all">Прибавлять все эпизоды, отмеченные как прослушанные</string>
<string name="statistics_speed_not_counted">Замечание: Скорость воспроизведения не учитывается никогда.</string>
<string name="statistics_reset_data">Сбросить статистику</string>
<string name="statistics_reset_data_msg">Вы уверены, что хотите стереть историю прослушивания?</string>
+ <string name="statistics_counting_since">Поскольку %s,\n вы играли</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Размер всех загруженных подкастов:</string>
+ <string name="total_size_downloaded_podcasts">Общий размер выпусков на устройстве:</string>
<!--Main activity-->
<string name="drawer_open">Открыть меню</string>
<string name="drawer_close">Закрыть меню</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Количество непрослушанных выпусков</string>
<string name="drawer_feed_counter_downloaded">Количество загруженных выпусков</string>
<string name="drawer_feed_counter_none">Ничего</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Совместимых приложений не найдено</string>
<!--Webview actions-->
<string name="open_in_browser_label">Открыть в браузере</string>
<string name="copy_url_label">Скопировать ссылку</string>
@@ -115,7 +119,7 @@
<item quantity="many">Выбрано: %d</item>
<item quantity="other">Выбрано: %d</item>
</plurals>
- <string name="loading_more">Загружается...</string>
+ <string name="loading_more">Загружается…</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Отметить как прослушанное</string>
<string name="mark_all_read_msg">Отметить все выпуски как прослушанные</string>
@@ -130,29 +134,22 @@
<string name="feed_settings_label">Настройки подкаста</string>
<string name="rename_feed_label">Переименовать подкаст</string>
<string name="remove_feed_label">Удалить подкаст</string>
- <string name="share_label">Поделиться…</string>
- <string name="share_link_label">Поделиться ссылкой на выпуск</string>
- <string name="share_link_with_position_label">Поделиться ссылкой на выпуск с отметкой времени</string>
+ <string name="share_label">Поделиться</string>
+ <string name="share_label_with_ellipses">Поделиться…</string>
<string name="share_file_label">Поделиться файлом</string>
- <string name="share_website_url_label">Поделиться ссылкой на сайт</string>
- <string name="share_feed_url_label">Поделиться ссылкой на канал</string>
- <string name="share_item_url_label">Поделиться ссылкой на файл</string>
- <string name="share_item_url_with_position_label">Поделиться ссылкой на файл с отметкой времени</string>
+ <string name="share_website_url_label">Адрес вебсайта</string>
+ <string name="share_feed_url_label">Ссылка на канал</string>
<string name="feed_delete_confirmation_msg">Подтвердите, что хотите удалить подкаст «%1$s» и все его выпуски (включая загруженные).</string>
+ <string name="feed_delete_confirmation_local_msg">Подтвердите, что хотите удалить подкаст «%1$s». Файлы в локальной исходной папке не будут удалены.</string>
<string name="feed_remover_msg">Подкаст удаляется</string>
<string name="load_complete_feed">Обновить весь подкаст</string>
<string name="multi_select">Множественный выбор</string>
<string name="select_all_above">Выбрать все выше</string>
<string name="select_all_below">Выбрать все ниже</string>
<string name="hide_unplayed_episodes_label">Непрослушанное</string>
- <string name="hide_paused_episodes_label">Приостановленное</string>
- <string name="hide_played_episodes_label">Прослушанное</string>
<string name="hide_queued_episodes_label">В очереди</string>
<string name="hide_not_queued_episodes_label">Не в очереди</string>
- <string name="hide_downloaded_episodes_label">Загружено</string>
- <string name="hide_not_downloaded_episodes_label">Не загружено</string>
<string name="hide_has_media_label">С файлами</string>
- <string name="hide_is_favorite_label">В Избранном</string>
<string name="filtered_label">Отфильтровано</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Последнее обновление не удалось</string>
<string name="open_podcast">Открыть подкаст</string>
@@ -171,12 +168,6 @@
<string name="delete_label">Удалить</string>
<string name="delete_failed">Невозможно удалить файл. Попробуйте перезагрузить устройство.</string>
<string name="delete_episode_label">Удалить выпуск</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d выпуск удален.</item>
- <item quantity="few">%d выпуска удалены.</item>
- <item quantity="many">%d выпусков удалены.</item>
- <item quantity="other">%d выпусков удалено.</item>
- </plurals>
<string name="remove_new_flag_label">Убрать пометку «Новый»</string>
<string name="removed_new_flag_label">Пометка «Новый» убрана</string>
<string name="mark_read_label">Отметить как прослушанное</string>
@@ -258,7 +249,12 @@
</plurals>
<string name="downloads_processing">Производится загрузка</string>
<string name="download_notification_title">Получение данных подкаста</string>
- <string name="download_report_content">%1$d загрузок завершено, %2$d не удалось</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d загрузка завершена, %d не удалось</item>
+ <item quantity="few">%d загрузок завершено, %d не удалось</item>
+ <item quantity="many"> %d загрузок завершено, %d не удалось</item>
+ <item quantity="other">%d загрузок завершено, %d не удалось</item>
+ </plurals>
<string name="download_log_title_unknown">Неизвестное название</string>
<string name="download_type_feed">Канал</string>
<string name="download_type_media">Медиафайл</string>
@@ -271,7 +267,8 @@
<string name="confirm_mobile_download_dialog_message">Загрузка через мобильное соединение отключена в настройках.\n\nЖелаете временно разрешить загрузку?\n\n<small>Настройка сохранится на 10 минут.</small></string>
<string name="confirm_mobile_streaming_notification_title">Подтвердите трансляцию через мобильное соединение</string>
<string name="confirm_mobile_streaming_notification_message">Трансляция через мобильное подключение отключена в настройках. Нажмите, чтобы продолжить трансляцию.</string>
- <string name="confirm_mobile_streaming_button_always">Разрешать всегда</string>
+ <string name="confirm_mobile_streaming_button_always">Всегда</string>
+ <string name="confirm_mobile_streaming_button_once">Однократно</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Добавить в очередь</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Разрешить временно</string>
<!--Mediaplayer messages-->
@@ -317,8 +314,9 @@
<string name="download_plugin_label">Загрузить плагин</string>
<string name="no_playback_plugin_title">Плагин не установлен</string>
<string name="no_playback_plugin_or_sonic_msg">Чтобы изменять скорость воспроизведения, рекомендуем включить встроенный проигрыватель Sonic.</string>
- <string name="set_playback_speed_label">Скорость воспроизведения</string>
<string name="enable_sonic">Включить Sonic</string>
+ <string name="speed_presets">Пресеты</string>
+ <string name="preset_already_exists">%1$.2fx уже сохранен как пресет.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Нет выпусков в очереди</string>
<string name="no_items_label">Добавьте выпуск, загрузив его, или после долгого нажатия на выпуск выберите «Добавить в очередь».</string>
@@ -391,7 +389,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">каждые %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">в %1$s</string>
<string name="pref_followQueue_title">Непрерывное воспроизведение</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">При отключении наушников</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Отключение наушников или Bluetooth</string>
<string name="pref_unpauseOnHeadsetReconnect_title">При подключении наушников</string>
<string name="pref_unpauseOnBluetoothReconnect_title">При подключении Bluetooth</string>
<string name="pref_stream_over_download_title">Трансляция вместо загрузки</string>
@@ -404,7 +402,7 @@
<string name="pref_mobileUpdate_episode_download">Загрузка выпусков</string>
<string name="pref_mobileUpdate_streaming">Трансляции по сети</string>
<string name="user_interface_label">Интерфейс</string>
- <string name="user_interface_sum">Внешний вид, сортировка подписок, экран блокировки</string>
+ <string name="user_interface_sum">Внешний вид, подписки, экран блокировки</string>
<string name="pref_set_theme_title">Выбрать оформление</string>
<string name="pref_nav_drawer_items_title">Выбрать пункты боковой панели</string>
<string name="pref_nav_drawer_items_sum">Изменение отображения пунктов меню боковой панели</string>
@@ -443,9 +441,8 @@
<string name="pref_gpodnet_full_sync_title">Выполнить полную синхронизацию</string>
<string name="pref_gpodnet_full_sync_sum">Синхронизировать состояния всех подписок и выпусков при помощи gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Вход как <i>%1$s</i> с устройства <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Показывать уведомления об ошибках синхронизации</string>
+ <string name="pref_gpodnet_notifications_title">Сбой синхронизации</string>
<string name="pref_gpodnet_notifications_sum">Не затрагивает ошибки авторизации.</string>
- <string name="pref_playback_speed_title">Скорости воспроизведения</string>
<string name="pref_playback_speed_sum">Выбрать значения скорости, доступные при воспроизведении</string>
<string name="pref_feed_playback_speed_sum">Скорость, с которой будут изначально воспроизводиться выпуски этого подкаста</string>
<string name="pref_feed_skip">Автоматический пропуск</string>
@@ -466,15 +463,15 @@
<string name="pref_expandNotify_sum">Как правило, разворачивает уведомление, показывая кнопки управления воспроизведением.</string>
<string name="pref_persistNotify_title">Постоянные кнопки воспроизведения</string>
<string name="pref_persistNotify_sum">Сохранять уведомление и кнопки воспроизведения на экране блокировки во время паузы.</string>
- <string name="pref_compact_notification_buttons_title">Выбрать кнопки экрана блокировки</string>
- <string name="pref_compact_notification_buttons_sum">Поменять кнопки управления на экране блокировки. Кнопка воспроизведения/паузы присутствует постоянно.</string>
+ <string name="pref_compact_notification_buttons_title">Установить компактные кнопки уведомлений</string>
+ <string name="pref_compact_notification_buttons_sum">Измените кнопки воспроизведения, когда уведомление свернуто. Кнопка воспроизведения/паузы присутствует всегда.</string>
<string name="pref_compact_notification_buttons_dialog_title">Выберите не более %1$d элементов</string>
<string name="pref_compact_notification_buttons_dialog_error">Нельзя выбрать больше %1$d элементов.</string>
<string name="pref_lockscreen_background_title">Менять фон экрана блокировки</string>
<string name="pref_lockscreen_background_sum">Изменяет фон экрана блокировки на обложку выпуска. Кроме того показывает обложку в сторонних приложениях.</string>
- <string name="pref_showDownloadReport_title">Показывать отчет о загрузках</string>
+ <string name="pref_showDownloadReport_title">Сбой загрузки</string>
<string name="pref_showDownloadReport_sum">Если загрузка не удается, показывать отчет с подробностями об ошибке.</string>
- <string name="pref_showAutoDownloadReport_title">Показывать результаты автозагрузки</string>
+ <string name="pref_showAutoDownloadReport_title">Автоматическая загрузка завершена</string>
<string name="pref_showAutoDownloadReport_sum">Показывать уведомление при автоматической загрузке выпусков</string>
<string name="pref_expand_notify_unsupport_toast">Версии Android ниже 4.1 не поддерживают расширенные уведомления.</string>
<string name="pref_enqueue_location_title">Размещение в очереди</string>
@@ -504,6 +501,7 @@
<string name="pref_enqueue_downloaded_title">Добавлять загруженные в очередь</string>
<string name="pref_enqueue_downloaded_summary">Добавлять загруженные выпуски в очередь</string>
<string name="media_player_builtin">Встроенный в Android</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (рекомендовано)</string>
<string name="media_player_switch_to_exoplayer">Переключить на ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Переключено на ExoPlayer.</string>
<string name="pref_skip_silence_title">Пропускать участки тишины</string>
@@ -524,6 +522,15 @@
<string name="back_button_go_to_page_title">Выберите страницу</string>
<string name="pref_delete_removes_from_queue_title">Убирать удаленные из очереди</string>
<string name="pref_delete_removes_from_queue_sum">Автоматически убирать выпуск из очереди при его удалении.</string>
+ <string name="pref_filter_feed_title">Фильтр подписок</string>
+ <string name="pref_filter_feed_sum">Отфильтруйте свои подписки на панели навигации и на экране подписок.</string>
+ <string name="no_filter_label">Ничего</string>
+ <string name="subscriptions_are_filtered">Подписки отфильтрованы</string>
+ <string name="subscriptions_counter_greater_zero">Счетчик больше нуля</string>
+ <string name="auto_downloaded">Авто загружено</string>
+ <string name="not_auto_downloaded">Не авто загружено</string>
+ <string name="kept_updated">Постоянно обновляется</string>
+ <string name="not_kept_updated">Не постоянно обновляется</string>
<!--About screen-->
<string name="about_pref">О программе</string>
<string name="antennapod_version">Версия AntennaPod</string>
@@ -544,7 +551,7 @@
<string name="sync_status_episodes_upload">Отправка изменений выпуска…</string>
<string name="sync_status_episodes_download">Загрузка изменений выпуска…</string>
<string name="sync_status_upload_played">Отправка состояния прослушивания…</string>
- <string name="sync_status_subscriptions">Синхронизация подписок ...</string>
+ <string name="sync_status_subscriptions">Синхронизация подписок…</string>
<string name="sync_status_success">Синхронизация выполнена</string>
<string name="sync_status_error">Сбой синхронизации</string>
<!--import and export-->
@@ -558,6 +565,7 @@
<string name="database_export_summary">Передать подписки, список прослушанных и очередь в AntennaPod на другом устройстве</string>
<string name="database_import_summary">Импортировать базу данных AntennaPod с другого устройства</string>
<string name="opml_import_label">Импорт OPML</string>
+ <string name="opml_add_podcast_label">Импортировать список подкастов (OPML)</string>
<string name="opml_reader_error">При чтении OPML произошла ошибка:</string>
<string name="opml_import_error_no_file">Ничего не выбрано!</string>
<string name="select_all_label">Выбрать все</string>
@@ -573,7 +581,8 @@
<string name="export_success_sum">Файл экспорта был сохранен в папку:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Для чтения файла OPML необходим доступ к внешнему хранилищу</string>
<string name="import_select_file">Выбрать файл для импорта</string>
- <string name="import_ok">Успешно импортировано.\n\nНажмите OK, чтобы перезапустить AntennaPod</string>
+ <string name="successful_import_label">Импорт успешен</string>
+ <string name="import_ok">Нажмите OK, чтобы перезапустить AntennaPod</string>
<string name="import_no_downgrade">Выбранная база данных экспортирована из более поздней версии AntennaPod. Установленная версия не сможет воспользоваться этой базой.</string>
<string name="favorites_export_label">Экспорт избранного</string>
<string name="favorites_export_summary">Экспортировать сохраненное избранное в файл</string>
@@ -674,7 +683,6 @@
<string name="decrease_speed">Уменьшить скорость</string>
<string name="media_type_audio_label">Аудио</string>
<string name="media_type_video_label">Видео</string>
- <string name="navigate_upwards_label">Перейти выше</string>
<string name="status_downloading_label">Выпуск загружается</string>
<string name="in_queue_label">Выпуск в очереди</string>
<string name="is_favorite_label">Эпизод отмечен как избранный</string>
@@ -695,25 +703,40 @@
<string name="keep_updated">Постоянно обновлять</string>
<string name="keep_updated_summary">Обновлять подкаст при (авто)обновлении всех подкастов</string>
<string name="auto_download_disabled_globally">Автоматическая загрузка отключена в основных настройках AntennaPod</string>
+ <string name="statistics_listened_for">Слушали:</string>
+ <string name="statistics_episodes_on_device">Выпуски на устройстве:</string>
+ <string name="statistics_space_used">Используемое пространство:</string>
+ <string name="statistics_view_all">Просмотреть все подкасты »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Обновление базы данных</string>
<!--AntennaPodSP-->
<string name="sp_apps_importing_feeds_msg">Импорт подписок из моноприложений…</string>
<!--Add podcast fragment-->
- <string name="search_podcast_hint">Найти подкаст...</string>
+ <string name="search_podcast_hint">Найти подкаст…</string>
<string name="search_itunes_label">Поиск в iTunes</string>
+ <string name="search_podcastindex_label">Поиск на Podcastindex.org</string>
<string name="search_fyyd_label">Поиск в fyyd</string>
<string name="advanced">Дополнительные</string>
- <string name="add_podcast_by_url">Добавить подкаст по адресу</string>
+ <string name="add_podcast_by_url">Добавить подкаст по RSS адресу</string>
<string name="browse_gpoddernet_label">Просмотр gpodder.net</string>
<string name="discover">Ознакомиться</string>
+ <string name="discover_hide">Скрыть</string>
+ <string name="discover_is_hidden">Вы выбрали скрытие предложений.</string>
<string name="discover_more">еще »</string>
- <string name="search_powered_by">Для поиска используется %1$s</string>
+ <string name="discover_powered_by_itunes">Предложения iTunes</string>
+ <string name="search_powered_by">Результаты по %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Добавить локальную папку</string>
+ <string name="local_folder">Локальная папка</string>
+ <string name="reconnect_local_folder">Переподключить локальную папку</string>
+ <string name="reconnect_local_folder_warning">В случае отказа в разрешении вы можете использовать это для переподключения к той же самой папке. Не выбирайте другую папку.</string>
+ <string name="local_feed_description">Этот виртуальный подкаст был создан путем добавления папки в AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Невозможно запустить системный файловый менеджер</string>
<string name="filter">Фильтровать</string>
<!--Episodes apply actions-->
<string name="all_label">Все</string>
<string name="selected_all_label">Выбраны все выпуски</string>
- <string name="none_label">Ничего</string>
+ <string name="select_none_label">Ничего</string>
<string name="deselected_all_label">Выбор снят со всех выпусков</string>
<string name="played_label">Прослушанное</string>
<string name="selected_played_label">Выбраны прослушанные выпуски</string>
@@ -723,12 +746,21 @@
<string name="selected_downloaded_label">Выбраны загруженные выпуски</string>
<string name="not_downloaded_label">Не загруженное</string>
<string name="selected_not_downloaded_label">Выбраны не загруженные выпуски</string>
- <string name="queued_label">В очереди</string>
<string name="selected_queued_label">Выбраны выпуски из очереди</string>
- <string name="not_queued_label">Не в очереди</string>
<string name="selected_not_queued_label">Выбраны выпуски не из очереди</string>
- <string name="has_media">С файлами</string>
<string name="selected_has_media_label">Выбраны выпуски с файлами</string>
+ <string name="hide_is_favorite_label">В Избранном</string>
+ <string name="not_favorite">Не в избранном</string>
+ <string name="hide_downloaded_episodes_label">Загружено</string>
+ <string name="hide_not_downloaded_episodes_label">Не загружено</string>
+ <string name="queued_label">В очереди</string>
+ <string name="not_queued_label">Не в очереди</string>
+ <string name="has_media">С файлами</string>
+ <string name="no_media">Нет медиа</string>
+ <string name="hide_paused_episodes_label">Приостановленное</string>
+ <string name="not_paused">Не на паузе</string>
+ <string name="hide_played_episodes_label">Прослушанное</string>
+ <string name="not_played">Не проигрывается</string>
<!--Sort-->
<string name="sort_title_a_z">от А к Я</string>
<string name="sort_title_z_a">от Я к А</string>
@@ -748,6 +780,12 @@
<string name="rating_never_label">Не дождетесь</string>
<string name="rating_later_label">Позже, не сейчас</string>
<string name="rating_now_label">Конечно, давай!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Включая:</string>
+ <string name="share_playback_position_dialog_label">Позиция воспроизведения</string>
+ <string name="share_dialog_media_file_url_label">Адрес медиафайла</string>
+ <string name="share_dialog_episode_website_label">Вебстраница выпуска</string>
+ <string name="share_dialog_media_file_label">Медиафайл</string>
<!--Audio controls-->
<string name="audio_controls">Управление звучанием</string>
<string name="playback_speed">Скорость воспроизведения</string>
@@ -794,7 +832,9 @@
<string name="notification_channel_playing">Сейчас воспроизводится</string>
<string name="notification_channel_playing_description">Позволяет управлять воспроизведением. Основное уведомление, показывается при воспроизведении подкаста.</string>
<string name="notification_channel_error">Ошибки</string>
- <string name="notification_channel_error_description">Показывается если что-то пошло не так, к примеру, неудавшаяся загрузка или синхронизация с gpodder.</string>
+ <string name="notification_channel_error_description">Отображается, если что-то пошло не так, например, если не удалось загрузить или обновить канал.</string>
+ <string name="notification_channel_sync_error">Ошибки синхронизации</string>
+ <string name="notification_channel_sync_error_description">Отображается, если сбоит синхронизация gpodder.</string>
<string name="notification_channel_auto_download">Автозагрузка</string>
<string name="notification_channel_episode_auto_download">Показывается, когда новые выпуски были автоматически загружены</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-sv/strings.xml b/core/src/main/res/values-sv/strings.xml
index 632d5f94a..fdd6de667 100644
--- a/core/src/main/res/values-sv/strings.xml
+++ b/core/src/main/res/values-sv/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">Episodcachens gräns har nåtts. Du kan öka cachens storlek i inställningarna.</string>
<string name="playback_statistics_label">Uppspelning</string>
<string name="download_statistics_label">Nedladdningar</string>
+ <string name="notification_pref_fragment">Notifieringar</string>
<!--Statistics fragment-->
<string name="total_time_listened_to_podcasts">Total uppspelningstid:</string>
<string name="statistics_details_dialog">%1$d av %2$d episoder startade.\n\nSpelat %3$s av %4$s.</string>
<string name="statistics_mode">Statistikläge</string>
<string name="statistics_mode_normal">Beräkna faktisk speltid. Att spela två gånger räknas två gånger, men att markera som spelad räknas inte</string>
- <string name="statistics_mode_count_all">Summera alla podcasts som markerats som spelade</string>
+ <string name="statistics_mode_count_all">Summera alla episoder som är markerade som spelade</string>
<string name="statistics_speed_not_counted">Notera: Uppspelningshastighet tas inte med i beräkningarna. </string>
<string name="statistics_reset_data">Återställ statistikdata</string>
<string name="statistics_reset_data_msg">Detta kommer att radera historiken av spelad tid för alla episoder. Är du säker på att du vill fortsätta?</string>
+ <string name="statistics_counting_since">Sedan %s, har du spelat</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Totala storleken av nedladdade podcasts:</string>
+ <string name="total_size_downloaded_podcasts">Totala storleken för alla episoder på enheten:</string>
<!--Main activity-->
<string name="drawer_open">Öppna meny</string>
<string name="drawer_close">Stäng meny</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Antal ospelade episoder</string>
<string name="drawer_feed_counter_downloaded">Antal nedladdade episoder</string>
<string name="drawer_feed_counter_none">Inga</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">Hittade inga kompatibla appar</string>
<!--Webview actions-->
<string name="open_in_browser_label">Öppna i webbläsare</string>
<string name="copy_url_label">Kopiera URL</string>
@@ -124,29 +128,22 @@
<string name="feed_settings_label">Podcastinställningar</string>
<string name="rename_feed_label">Byt namn på podcast</string>
<string name="remove_feed_label">Ta bort podcast</string>
- <string name="share_label">Dela…</string>
- <string name="share_link_label">Dela episod-URL</string>
- <string name="share_link_with_position_label">Dela episod-URL med position</string>
+ <string name="share_label">Dela</string>
+ <string name="share_label_with_ellipses">Dela...</string>
<string name="share_file_label">Dela fil</string>
- <string name="share_website_url_label">Dela Webbsidans URL</string>
- <string name="share_feed_url_label">Dela Podcast URL</string>
- <string name="share_item_url_label">Dela mediafilens URL</string>
- <string name="share_item_url_with_position_label">Dela mediafilens URL med position</string>
+ <string name="share_website_url_label">Webbsideadress</string>
+ <string name="share_feed_url_label">Podcasflödes URL</string>
<string name="feed_delete_confirmation_msg">Bekräfta att du vill ta bort podcast \"%1$s\" och ALLA dess episoder (inklusive nedladdade episoder).</string>
+ <string name="feed_delete_confirmation_local_msg">Bekräfta att du vill ta bort alla podcasts \"%1$s\". Filerna i den lokala källkatalogen kommer inte att raderas.</string>
<string name="feed_remover_msg">Tar bort podcast</string>
<string name="load_complete_feed">Uppdatera hela podcasten</string>
<string name="multi_select">Välj flera</string>
<string name="select_all_above">Välj alla ovanför</string>
<string name="select_all_below">Välj alla nedanför</string>
<string name="hide_unplayed_episodes_label">Ospelade</string>
- <string name="hide_paused_episodes_label">Pausade</string>
- <string name="hide_played_episodes_label">Spelad</string>
<string name="hide_queued_episodes_label">Köade</string>
<string name="hide_not_queued_episodes_label">Inte köade</string>
- <string name="hide_downloaded_episodes_label">Nedladdade</string>
- <string name="hide_not_downloaded_episodes_label">Ej nedladdade</string>
<string name="hide_has_media_label">Har media</string>
- <string name="hide_is_favorite_label">Är favorit</string>
<string name="filtered_label">Filtrerad</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Senaste uppdateringen misslyckades</string>
<string name="open_podcast">Öppna podcast</string>
@@ -163,10 +160,6 @@
<string name="delete_label">Ta bort</string>
<string name="delete_failed">Kunde inte ta bort filen. Testa att starta om enheten.</string>
<string name="delete_episode_label">Radera episod</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">1%d episod raderad.</item>
- <item quantity="other">1%d episder raderade.</item>
- </plurals>
<string name="remove_new_flag_label">Ta bort \"ny\"-flagga</string>
<string name="removed_new_flag_label">Tog bort \"ny\"-flagga</string>
<string name="mark_read_label">Markera som spelad</string>
@@ -238,7 +231,10 @@
</plurals>
<string name="downloads_processing">Bearbetar nedladdningar</string>
<string name="download_notification_title">Laddar ner podcastdata</string>
- <string name="download_report_content">%1$d nedladdningar lyckades, %2$d misslyckades</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d nedladdning lyckades, %d misslyckades</item>
+ <item quantity="other">%dnedladdningar lyckades, %d misslyckades</item>
+ </plurals>
<string name="download_log_title_unknown">Okänd titel</string>
<string name="download_type_feed">Flöde</string>
<string name="download_type_media">Mediafil</string>
@@ -251,7 +247,8 @@
<string name="confirm_mobile_download_dialog_message">Nedladdning över mobil dataanslutning är avaktiverat i inställningarna.\n\nVill du tillfälligt tillåta nedladdning?\n\n<small>Ditt val gäller i 10 minuter.</small></string>
<string name="confirm_mobile_streaming_notification_title">Bekräfta mobil strömning</string>
<string name="confirm_mobile_streaming_notification_message">Strömning över mobilanslutningar är avaktiverat i inställningarna. Tryck för att strömma ändå.</string>
- <string name="confirm_mobile_streaming_button_always">Tillåt alltid</string>
+ <string name="confirm_mobile_streaming_button_always">Alltid</string>
+ <string name="confirm_mobile_streaming_button_once">En gång</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Köa</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Tillåt tillfälligt</string>
<!--Mediaplayer messages-->
@@ -297,8 +294,9 @@
<string name="download_plugin_label">Ladda ner tillägg</string>
<string name="no_playback_plugin_title">Tillägg ej installerat</string>
<string name="no_playback_plugin_or_sonic_msg">Vi rekommenderar att den inbyggda Sonic-spelaren används för att kunna variera uppspelningshastigheten.</string>
- <string name="set_playback_speed_label">Uppspelningshastigheter</string>
<string name="enable_sonic">Aktivera Sonic</string>
+ <string name="speed_presets">Förhandsinställningar</string>
+ <string name="preset_already_exists">%1$.2fx är redan sparad som en förhandsinställning.</string>
<!--Empty list labels-->
<string name="no_items_header_label">Inga köade episoder</string>
<string name="no_items_label">Lägg till en episod genom att ladda ner den, eller tryck länge på en episod och väl \"Lägg till i kön\".</string>
@@ -371,7 +369,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">var %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">vid %1$s</string>
<string name="pref_followQueue_title">Kontinuerlig uppspelning</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Hörlurar bortkopplas</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Hörlurar eller Bluetooth kopplas bort</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Hörlurar återanslutna</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Blutetooth återansluts</string>
<string name="pref_stream_over_download_title">Föredra Strömmning</string>
@@ -384,7 +382,7 @@
<string name="pref_mobileUpdate_episode_download">Episodnedladdning</string>
<string name="pref_mobileUpdate_streaming">Strömning</string>
<string name="user_interface_label">Användargränssnitt</string>
- <string name="user_interface_sum">Utseende, Prenumerationsordning, Låsskärm</string>
+ <string name="user_interface_sum">Utseende, Prenumerationer, Låsskärm</string>
<string name="pref_set_theme_title">Välj tema</string>
<string name="pref_nav_drawer_items_title">Välj objekt i navigeringsmenyn</string>
<string name="pref_nav_drawer_items_sum">Ändra vilka saker som visas på navigationsmenyn.</string>
@@ -423,10 +421,9 @@
<string name="pref_gpodnet_full_sync_title">Tvinga full synkronisering</string>
<string name="pref_gpodnet_full_sync_sum">Synkronisera alla prenumerationer och episodstatus med gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Inloggad som <i>%1$s</i> med enhet <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Visa notifieringar om synkroniseringsfel</string>
+ <string name="pref_gpodnet_notifications_title">Synkronisering misslyckades</string>
<string name="pref_gpodnet_notifications_sum">Denna inställning påverkar inte autentiseringsfel.</string>
- <string name="pref_playback_speed_title">Uppspelningshastigheter</string>
- <string name="pref_playback_speed_sum">Anpassa de tillgängliga hastigheterna för variabel uppspelningshastighet.</string>
+ <string name="pref_playback_speed_sum">Anpassa de tillgängliga hastigheterna för variabel uppspelningshastighet</string>
<string name="pref_feed_playback_speed_sum">Uppspelningshastigheten att använda för episoder i denna podcast</string>
<string name="pref_feed_skip">Automatisk överhoppning</string>
<string name="pref_feed_skip_sum">Hoppa över intron och outron.</string>
@@ -446,15 +443,15 @@
<string name="pref_expandNotify_sum">Detta expanderar oftast notifieringen och visar uppspelningskontroller.</string>
<string name="pref_persistNotify_title">Bestående uppspelningskontroller</string>
<string name="pref_persistNotify_sum">Behåll avisering och kontroller på låsskärmen när uppspelningen pausas.</string>
- <string name="pref_compact_notification_buttons_title">Val för låsskärmens knappar</string>
- <string name="pref_compact_notification_buttons_sum">Ändra uppspelningsknapparna på låsskärmen. Spela/pausa knappen är alltid inkluderad.</string>
+ <string name="pref_compact_notification_buttons_title">Kompakta Notifieringsknappar</string>
+ <string name="pref_compact_notification_buttons_sum">Ändra uppspelningsknapparna när notifieringen är kollapsad. Spela/paus-knappen visas alltid.</string>
<string name="pref_compact_notification_buttons_dialog_title">Välj maximalt %1$d st.</string>
<string name="pref_compact_notification_buttons_dialog_error">Du kan bara välja maximalt %1$d st.</string>
<string name="pref_lockscreen_background_title">Välj låsskärmens bakgrund</string>
<string name="pref_lockscreen_background_sum">Sätt låsskärmens bakgrund till den spelade episodens bild. En bieffekt är att även tredjepartsappar kan visa bilden.</string>
- <string name="pref_showDownloadReport_title">Visa nedladdningsrapport</string>
+ <string name="pref_showDownloadReport_title">Nedladdning misslyckades</string>
<string name="pref_showDownloadReport_sum">Visa en rapport med detaljer om felet när nedladdningar misslyckas.</string>
- <string name="pref_showAutoDownloadReport_title">Visa rapport över automatiska nedladdningar</string>
+ <string name="pref_showAutoDownloadReport_title">Automatisk nedladdning klar</string>
<string name="pref_showAutoDownloadReport_sum">Visa en avisering när episoder laddats ner automatiskt</string>
<string name="pref_expand_notify_unsupport_toast">Androidversioner före 4.1 har inte stöd för expanderade aviseringar.</string>
<string name="pref_enqueue_location_title">Köplats</string>
@@ -484,6 +481,7 @@
<string name="pref_enqueue_downloaded_title">Köa Nedladdade</string>
<string name="pref_enqueue_downloaded_summary">Lägg nedladdade episoder i uppspelningskön</string>
<string name="media_player_builtin">Andriods inbyggda spelare</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (rekommenderas)</string>
<string name="media_player_switch_to_exoplayer">Byt till ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Bytte till ExpPlayer.</string>
<string name="pref_skip_silence_title">Hoppa över tystnad i ljud</string>
@@ -495,7 +493,7 @@
<string name="pref_back_button_behavior_title">Tillbakaknappens beteende</string>
<string name="pref_back_button_behavior_sum">Byt tillbakaknappens beteende.</string>
<string name="back_button_default">Standard</string>
- <string name="back_button_open_drawer">Öppna navigationsrutan</string>
+ <string name="back_button_open_drawer">Öppna navigerinsmenyn</string>
<string name="back_button_double_tap">Dubbeltryck för att avsluta</string>
<string name="back_button_show_prompt">Bekräfta avslutning</string>
<string name="close_prompt">Är du säker på att du vill avsluta AntennaPod?</string>
@@ -504,6 +502,15 @@
<string name="back_button_go_to_page_title">Välj sida</string>
<string name="pref_delete_removes_from_queue_title">Radering tar bort från kön</string>
<string name="pref_delete_removes_from_queue_sum">Ta automatiskt bort episoder från kön när de raderas.</string>
+ <string name="pref_filter_feed_title">Prenumerationsfilter</string>
+ <string name="pref_filter_feed_sum">Filtrera dina prenumerationer i navigeringsmenyn och på prenumerationsskärmen.</string>
+ <string name="no_filter_label">Inga</string>
+ <string name="subscriptions_are_filtered">Prenumerationer är filtrerade.</string>
+ <string name="subscriptions_counter_greater_zero">Räknare högre än noll</string>
+ <string name="auto_downloaded">Automatiskt nedladdad</string>
+ <string name="not_auto_downloaded">Manuellt nedladdad</string>
+ <string name="kept_updated">Hålls uppdaterad</string>
+ <string name="not_kept_updated">Manuell uppdatering</string>
<!--About screen-->
<string name="about_pref">Om</string>
<string name="antennapod_version">AntennaPod version</string>
@@ -538,6 +545,7 @@
<string name="database_export_summary">Överför prenumerationer, spelade episoder och kön till AntennaPod på en annan enhet</string>
<string name="database_import_summary">Importera AntennaPods databas från en annan enhet</string>
<string name="opml_import_label">OPML importering</string>
+ <string name="opml_add_podcast_label">Importera podcastlista (OPML)</string>
<string name="opml_reader_error">Ett fel uppstod vid läsning av OPML dokumentet:</string>
<string name="opml_import_error_no_file">Ingen fil vald!</string>
<string name="select_all_label">Välj alla</string>
@@ -553,7 +561,8 @@
<string name="export_success_sum">Den exporterade filen skrevs till:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Tillgång till extern lagring krävs för att läsa OPML-filen</string>
<string name="import_select_file">Välj fil att importera</string>
- <string name="import_ok">Importen lyckades.\n\nTryck OK för att starta om AntennaPod</string>
+ <string name="successful_import_label">Importering lyckades</string>
+ <string name="import_ok">Tryck OK för att starta om AntennaPod</string>
<string name="import_no_downgrade">Denna databas var exporterad med en nyare version av AntennaPod. Din nuvarande installation vet inte hur den ska hantera filen än.</string>
<string name="favorites_export_label">Favoritexport</string>
<string name="favorites_export_summary">Exportera sparade favoriter till fil</string>
@@ -648,7 +657,6 @@
<string name="decrease_speed">Sänk hastigheten</string>
<string name="media_type_audio_label">Ljud</string>
<string name="media_type_video_label">Video</string>
- <string name="navigate_upwards_label">Navigera upp</string>
<string name="status_downloading_label">Episoden laddas ner</string>
<string name="in_queue_label">Episoden är i kön</string>
<string name="is_favorite_label">Episoden är markerad som favorit</string>
@@ -669,6 +677,10 @@
<string name="keep_updated">Håll uppdaterad</string>
<string name="keep_updated_summary">Inkludera detta flöde vid (auto-)uppdatering av alla podcasts</string>
<string name="auto_download_disabled_globally">Automatisk nedladdning är avstängt i AntennaPods huvudinställningar</string>
+ <string name="statistics_listened_for">Lyssnat i:</string>
+ <string name="statistics_episodes_on_device">Episoder på enheten:</string>
+ <string name="statistics_space_used">Använt utrymme:</string>
+ <string name="statistics_view_all">Visa för alla podcasts »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Uppgraderar databasen</string>
<!--AntennaPodSP-->
@@ -676,18 +688,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">Sök podcast...</string>
<string name="search_itunes_label">Leta i iTunes</string>
+ <string name="search_podcastindex_label">Sök Podcastindex.org</string>
<string name="search_fyyd_label">Sök i fyyd</string>
<string name="advanced">Avancerad</string>
- <string name="add_podcast_by_url">Lägg till podcast med URL</string>
+ <string name="add_podcast_by_url">Lägg till podcast med RSS adress</string>
<string name="browse_gpoddernet_label">Bläddra på gpodder.net</string>
<string name="discover">Upptäck</string>
+ <string name="discover_hide">Dölj</string>
+ <string name="discover_is_hidden">Du valde att dölja förslag.</string>
<string name="discover_more">mer »</string>
- <string name="search_powered_by">Sökt med %1$s</string>
+ <string name="discover_powered_by_itunes">Förslag från iTuenes</string>
+ <string name="search_powered_by">Resultat för %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Lägg till i lokal katalog</string>
+ <string name="local_folder">Lokal katalog</string>
+ <string name="reconnect_local_folder">Återanslut lokal katalog</string>
+ <string name="reconnect_local_folder_warning">Om åtkomst nekats kan du använda detta för att återansluta till exakt samma katalog. Välj inte en annan katalog.</string>
+ <string name="local_feed_description">Denna virtuella podcast skapades genom att lägga till en katalog till AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Kunde inte starta systemets filhanterare</string>
<string name="filter">Filtrera</string>
<!--Episodes apply actions-->
<string name="all_label">Alla</string>
<string name="selected_all_label">Välj alla episoder</string>
- <string name="none_label">Inga</string>
+ <string name="select_none_label">Inga</string>
<string name="deselected_all_label">Avmarkera alla episoder</string>
<string name="played_label">Spelade</string>
<string name="selected_played_label">Valde spelade episoder</string>
@@ -697,12 +720,21 @@
<string name="selected_downloaded_label">Valde nedladdade episoder</string>
<string name="not_downloaded_label">Ej nedladdade</string>
<string name="selected_not_downloaded_label">Valde ej nedladdade episoder</string>
- <string name="queued_label">Köad</string>
<string name="selected_queued_label">Valde köade episoder</string>
- <string name="not_queued_label">Ej köad</string>
<string name="selected_not_queued_label">Välj ej köade episoder</string>
- <string name="has_media">Har media</string>
<string name="selected_has_media_label">Valde episoder med media</string>
+ <string name="hide_is_favorite_label">Är favorit</string>
+ <string name="not_favorite">Ej favorit</string>
+ <string name="hide_downloaded_episodes_label">Nedladdade</string>
+ <string name="hide_not_downloaded_episodes_label">Ej nedladdade</string>
+ <string name="queued_label">Köad</string>
+ <string name="not_queued_label">Ej köad</string>
+ <string name="has_media">Har media</string>
+ <string name="no_media">Ingen media</string>
+ <string name="hide_paused_episodes_label">Pausade</string>
+ <string name="not_paused">Ej pausad</string>
+ <string name="hide_played_episodes_label">Spelad</string>
+ <string name="not_played">Ej spelad</string>
<!--Sort-->
<string name="sort_title_a_z">Titel (A \u2192 Ö)</string>
<string name="sort_title_z_a">Titel (Ö \u2192 A)</string>
@@ -722,6 +754,12 @@
<string name="rating_never_label">Lämna mig ifred</string>
<string name="rating_later_label">Påminn mig senare</string>
<string name="rating_now_label">Okej, gör det nu!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Inkludera:</string>
+ <string name="share_playback_position_dialog_label">Uppspelningsposition</string>
+ <string name="share_dialog_media_file_url_label">Mediafils adress</string>
+ <string name="share_dialog_episode_website_label">Episodes webbplats</string>
+ <string name="share_dialog_media_file_label">Mediafil</string>
<!--Audio controls-->
<string name="audio_controls">Ljudkontroller</string>
<string name="playback_speed">Uppspelningshastighet</string>
@@ -768,7 +806,9 @@
<string name="notification_channel_playing">Uppspelning pågår</string>
<string name="notification_channel_playing_description">Medger kontroll över uppspelning. Detta är huvudnotifieringen som du ser när en podcast spelas.</string>
<string name="notification_channel_error">Fel</string>
- <string name="notification_channel_error_description">Visas om något blev fel, exempelvis om nedladdning eller gpodder synkronisering misslyckas.</string>
+ <string name="notification_channel_error_description">Visas om något gick fel, till exempel om nedladdning eller flödesuppdatering misslyckas.</string>
+ <string name="notification_channel_sync_error">Synkroniseringsfel</string>
+ <string name="notification_channel_sync_error_description">Visas när synkronisering med gpodder misslyckas.</string>
<string name="notification_channel_auto_download">Automatiska nedladdningar</string>
<string name="notification_channel_episode_auto_download">Visas när episoder har laddats ner automatiskt.</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-tr/strings.xml b/core/src/main/res/values-tr/strings.xml
index 84d67e5b9..2a91b66b6 100644
--- a/core/src/main/res/values-tr/strings.xml
+++ b/core/src/main/res/values-tr/strings.xml
@@ -2,6 +2,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!--Activity and fragment titles-->
<string name="feed_update_receiver_name">Abonelikleri güncelle</string>
+ <string name="feeds_label">Podcasts</string>
<string name="statistics_label">İstatistikler</string>
<string name="add_feed_label">Cep yayını ekle</string>
<string name="episodes_label">Bölümler</string>
@@ -22,10 +23,21 @@
<string name="gpodnet_auth_label">gpodder.net giriş</string>
<string name="episode_cache_full_title">Bölüm önbelleği dolu</string>
<string name="episode_cache_full_message">Bölüm önbelleği limitine ulaşıldı. Ayarlardan önbellek limitini arttırabilirsiniz. </string>
+ <string name="playback_statistics_label">Playback</string>
+ <string name="download_statistics_label">Downloads</string>
+ <string name="notification_pref_fragment">Notifications</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Toplam cep yayını çalma zamanı:</string>
+ <string name="total_time_listened_to_podcasts">Total time of episodes played:</string>
+ <string name="statistics_details_dialog">%1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s.</string>
<string name="statistics_mode">İstatistik modu</string>
+ <string name="statistics_mode_normal">Calculate duration that was actually played. Playing twice is counted twice, while marking as played is not counted</string>
+ <string name="statistics_mode_count_all">Sum up all episodes marked as played</string>
+ <string name="statistics_speed_not_counted">Notice: Playback speed is never taken into account.</string>
+ <string name="statistics_reset_data">Reset statistics data</string>
+ <string name="statistics_reset_data_msg">This will erase the history of duration played for all episodes. Are you sure you want to proceed?</string>
+ <string name="statistics_counting_since">Since %s,\nyou played</string>
<!--Download Statistics fragment-->
+ <string name="total_size_downloaded_podcasts">Total size of episodes on the device:</string>
<!--Main activity-->
<string name="drawer_open">Münüyü aç</string>
<string name="drawer_close">Menüyü kapat</string>
@@ -39,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">Çalınmamış bölümlerin sayısı</string>
<string name="drawer_feed_counter_downloaded">İndirilen bölümlerin sayısı</string>
<string name="drawer_feed_counter_none">Hiçbiri</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">No compatible apps found</string>
<!--Webview actions-->
<string name="open_in_browser_label">Tarayıcıda aç</string>
<string name="copy_url_label">URL\'yi kopyala</string>
@@ -74,6 +88,11 @@
<string name="auto_download_apply_to_items_title">Önceki Bölümlere Uygula</string>
<string name="auto_download_apply_to_items_message">Yeni <i>Otomatik İndirme</i> ayarı otomatik olarak yeni bölümlere uygulanacak.\nBunu önceki bölümlere de uygulamak ister misiniz?</string>
<string name="auto_delete_label">Bölümü Otomatik Sil</string>
+ <string name="feed_volume_reduction">Volume Reduction</string>
+ <string name="feed_volume_reduction_summary">Turn down volume for episodes of this feed: %1$s</string>
+ <string name="feed_volume_reduction_off">Off</string>
+ <string name="feed_volume_reduction_light">Light</string>
+ <string name="feed_volume_reduction_heavy">Heavy</string>
<string name="parallel_downloads_suffix">\u0020paralel indirmeler</string>
<string name="feed_auto_download_global">Varsayılan ayarlar</string>
<string name="feed_auto_download_always">Her zaman</string>
@@ -82,56 +101,93 @@
<string name="episode_cleanup_never">Hiçbir zaman</string>
<string name="episode_cleanup_queue_removal">Sırada değilse</string>
<string name="episode_cleanup_after_listening">Bittikten sonra</string>
+ <plurals name="episode_cleanup_hours_after_listening">
+ <item quantity="one">1 hour after finishing</item>
+ <item quantity="other">%d hours after finishing</item>
+ </plurals>
<plurals name="episode_cleanup_days_after_listening">
<item quantity="one">Bittikten 1 gün sonra</item>
<item quantity="other">Bittikten %d gün sonra</item>
</plurals>
+ <plurals name="num_selected_label">
+ <item quantity="one">%d selected</item>
+ <item quantity="other">%d selected</item>
+ </plurals>
+ <string name="loading_more">Loading more…</string>
<!--Actions on feeds-->
<string name="mark_all_read_label">Hepsini oynatıldı olarak işaretle</string>
<string name="mark_all_read_msg">Tüm bölümleri oynatıldı olarak işaretle</string>
<string name="mark_all_read_confirmation_msg">Lütfen tüm bölümleri oynatıldı olarak işaretlemek istediğinizi onaylayın.</string>
<string name="mark_all_read_feed_confirmation_msg">Lütfen bu yayındaki bütün bölümleri oynatıldı olarak işaretlemek istediğinizi onaylayın.</string>
+ <string name="remove_all_new_flags_label">Remove all \"new\" flags</string>
+ <string name="removed_all_new_flags_msg">Removed all \"new\" flags</string>
+ <string name="remove_all_new_flags_confirmation_msg">Please confirm that you want to remove the \"new\" flag from all episodes.</string>
<string name="show_info_label">Bilgiyi göster</string>
<string name="show_feed_settings_label">Cepyayın ayarlarını göster</string>
<string name="feed_info_label">Cepyayın bilgisi</string>
<string name="feed_settings_label">Cepyayın ayarları</string>
<string name="rename_feed_label">Cepyayını yeniden adlandır</string>
<string name="remove_feed_label">Cepyayını kaldır</string>
- <string name="share_label">Paylaş...</string>
- <string name="share_link_label">Bölüm Adresini paylaş</string>
- <string name="share_link_with_position_label">Bölüm Adresini Konumla birlikte paylaş</string>
+ <string name="share_label">Share</string>
+ <string name="share_label_with_ellipses">Share…</string>
<string name="share_file_label">Dosyayı paylaş</string>
- <string name="share_item_url_label">Medya Dosyası URL\'si Paylaş</string>
- <string name="share_item_url_with_position_label">Medya dosyasının adresini pozisyon ile birlikte paylaş</string>
+ <string name="share_website_url_label">Website address</string>
+ <string name="share_feed_url_label">Podcast feed URL</string>
+ <string name="feed_delete_confirmation_msg">Please confirm that you want to delete the podcast \"%1$s\" and ALL its episodes (including downloaded episodes).</string>
+ <string name="feed_delete_confirmation_local_msg">Please confirm that you want to remove the podcast \"%1$s\". The files in the local source folder will not be deleted.</string>
<string name="feed_remover_msg">Cepyayını kaldırılıyor</string>
<string name="load_complete_feed">Tüm Cepyayınını yenile</string>
+ <string name="multi_select">Multi select</string>
<string name="select_all_above">Üsttekilerin tümünü seç</string>
<string name="select_all_below">Alttakilerin tümünü seç</string>
<string name="hide_unplayed_episodes_label">Oynatılmadı</string>
- <string name="hide_paused_episodes_label">Duraklatıldı</string>
- <string name="hide_played_episodes_label">Oynatıldı</string>
<string name="hide_queued_episodes_label">Kuyrukta</string>
<string name="hide_not_queued_episodes_label">Kuyrukta değil</string>
- <string name="hide_downloaded_episodes_label">İndirildi</string>
- <string name="hide_not_downloaded_episodes_label">İndirilmedi</string>
<string name="hide_has_media_label">Medya var</string>
- <string name="hide_is_favorite_label">Favori</string>
<string name="filtered_label">Filtrelendi</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Son yenileme başarısız oldu</string>
<string name="open_podcast">Cep yayını aç</string>
+ <string name="please_wait_for_data">Please wait until the data is loaded</string>
<!--actions on feeditems-->
<string name="download_label">İndir</string>
+ <plurals name="downloading_batch_label">
+ <item quantity="one">Downloading %d episode.</item>
+ <item quantity="other">Downloading %d episodes.</item>
+ </plurals>
<string name="play_label">Oynat</string>
<string name="pause_label">Duraklat</string>
<string name="stream_label">Akış</string>
<string name="delete_label">Sil</string>
<string name="delete_failed">Dosya silinemiyor. Cihazı yeniden başlatmak yardımcı olabilir.</string>
+ <string name="delete_episode_label">Delete Episode</string>
+ <string name="remove_new_flag_label">Remove \"new\" flag</string>
+ <string name="removed_new_flag_label">Removed \"new\" flag</string>
<string name="mark_read_label">Oynatıldı olarak işaretle</string>
<string name="marked_as_read_label">Oynatıldı olarak işaretlendi</string>
+ <string name="mark_read_no_media_label">Mark as read</string>
+ <string name="marked_as_read_no_media_label">Marked as read</string>
+ <string name="play_this_to_seek_position">To jump to positions, you need to play the episode</string>
+ <plurals name="marked_read_batch_label">
+ <item quantity="one">%d episode marked as played.</item>
+ <item quantity="other">%d episodes marked as played.</item>
+ </plurals>
<string name="mark_unread_label">Oynatılmadı olarak işaretle</string>
+ <string name="mark_unread_label_no_media">Mark as unread</string>
+ <plurals name="marked_unread_batch_label">
+ <item quantity="one">%d episode marked as unplayed.</item>
+ <item quantity="other">%d episodes marked as unplayed.</item>
+ </plurals>
<string name="add_to_queue_label">Kuyruğa Ekle</string>
<string name="added_to_queue_label">Kuyruğa Eklendi</string>
+ <plurals name="added_to_queue_batch_label">
+ <item quantity="one">%d episode added to queue.</item>
+ <item quantity="other">%d episodes added to queue.</item>
+ </plurals>
<string name="remove_from_queue_label">Kuyruktan Kaldır</string>
+ <plurals name="removed_from_queue_batch_label">
+ <item quantity="one">%d episode removed from queue.</item>
+ <item quantity="other">%d episodes removed from queue.</item>
+ </plurals>
<string name="add_to_favorite_label">Favorilere Ekle</string>
<string name="added_to_favorites">Favorilere Eklendi</string>
<string name="remove_from_favorite_label">Favorilerden Kaldır</string>
@@ -142,11 +198,13 @@
<string name="deactivate_auto_download">Otomatik indirmeyi devre dışı bırak</string>
<string name="reset_position">Çalme konumunu sıfırla</string>
<string name="removed_item">Öge kaldırıldı</string>
+ <string name="no_items_selected">No items selected</string>
<!--Download messages and labels-->
<string name="download_successful">başarılı</string>
<string name="download_pending">İndirme bekleniyor</string>
<string name="download_running">İndiriliyor</string>
<string name="download_error_details">Detaylar</string>
+ <string name="download_error_details_message">%1$s \n\nFile URL:\n%2$s</string>
<string name="download_error_device_not_found">Depolama aygıtı bulunamadı</string>
<string name="download_error_insufficient_space">Yetersiz alan</string>
<string name="download_error_http_data_error">HTTP Veri Hatası</string>
@@ -161,6 +219,7 @@
<string name="download_canceled_msg">İndirme iptal edildi</string>
<string name="download_canceled_autodownload_enabled_msg">İndirme iptal edildi\nBu öğe için <i>Otomatik İndirme</i> devre dışı</string>
<string name="download_report_title">İndirme hata(lar) ile tamamlandı</string>
+ <string name="auto_download_report_title">Auto-downloads completed</string>
<string name="download_report_content_title">İndirme raporu</string>
<string name="download_error_malformed_url">Bozuk URL</string>
<string name="download_error_io_error">G/Ç Hatası</string>
@@ -172,16 +231,24 @@
</plurals>
<string name="downloads_processing">İndirmeler işleniyor</string>
<string name="download_notification_title">Cep yayını verileri indiriliyor</string>
- <string name="download_report_content">%1$d indirme başarılı, %2$d başarısız</string>
+ <plurals name="download_report_content">
+ <item quantity="one">%d download succeeded, %d failed</item>
+ <item quantity="other">%d downloads succeeded, %d failed</item>
+ </plurals>
<string name="download_log_title_unknown">bilinmeyen başlık</string>
<string name="download_type_feed">Besleme</string>
<string name="download_type_media">Medya dosyası</string>
<string name="download_request_error_dialog_message_prefix">Dosyayı indirmeye çalışırken bir hata oluştu:\u0020</string>
+ <string name="null_value_podcast_error">No podcast was provided that could be shown.</string>
<string name="authentication_notification_title">Yetkilendirme gerekiyor</string>
<string name="authentication_notification_msg">İstediğiniz kaynak kullanıcı adı ve şifre istiyor</string>
<string name="confirm_mobile_download_dialog_title">Mobil İndirmeyi Onaylayın</string>
<string name="confirm_mobile_download_dialog_message_not_in_queue">Mobil veri ile indirme ayarlarda devre dışıdır.\n\nGeçici olarak açılsın mı yoksa sadece kuyruğa mı eklensin?\n\n<small>Bu tercihiniz 10 dakika boyunca hatırlanacak.</small></string>
<string name="confirm_mobile_download_dialog_message">Mobil veri ile indirme ayarlarda devre dışıdır.\n\nGeçici olarak açılsın mı?\n\n<small>Bu tercihiniz 10 dakika boyunca hatırlanacak.</small></string>
+ <string name="confirm_mobile_streaming_notification_title">Confirm Mobile streaming</string>
+ <string name="confirm_mobile_streaming_notification_message">Streaming over mobile data connection is disabled in the settings. Tap to stream anyway.</string>
+ <string name="confirm_mobile_streaming_button_always">Always</string>
+ <string name="confirm_mobile_streaming_button_once">Once</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Sadece Kuyruğa ekle</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Geçici olarak aç</string>
<!--Mediaplayer messages-->
@@ -191,21 +258,28 @@
<string name="player_ready_msg">Hazır</string>
<string name="player_seeking_msg">Aranıyor</string>
<string name="playback_error_server_died">Sunucu geberdi</string>
+ <string name="playback_error_unsupported">Unsupported media type</string>
+ <string name="playback_error_timeout">Operation timed out</string>
+ <string name="playback_error_source">Unable to access media file</string>
<string name="playback_error_unknown">Bilinmeyen Hata</string>
<string name="no_media_playing_label">Çalınan medya yok</string>
<string name="player_buffering_msg">Ara belleğe alınıyor</string>
<string name="player_go_to_picture_in_picture">Resim içinde Resim modu</string>
<string name="unknown_media_key">AntennaPod - Bilinmeyen medya anahtarı: %1$d</string>
+ <string name="error_file_not_found">File not found</string>
<!--Queue operations-->
<string name="lock_queue">Kuyruğu kilitle</string>
<string name="unlock_queue">Kuyruğun kilidini aç</string>
<string name="queue_locked">Kuyruk kilitlendi</string>
<string name="queue_unlocked">Kuyruk kilidi açıldı</string>
+ <string name="queue_lock_warning">If you lock the queue, you can no longer swipe or reorder episodes.</string>
+ <string name="checkbox_do_not_show_again">Do not show again</string>
<string name="clear_queue_label">Kuyruğu temizle</string>
<string name="undo">Geri al</string>
<string name="move_to_top_label">En üste taşı</string>
<string name="move_to_bottom_label">En alta taşı</string>
<string name="sort">Sırala</string>
+ <string name="keep_sorted">Keep sorted</string>
<string name="date">Tarih</string>
<string name="duration">Süre</string>
<string name="episode_title">Blüm başlığı</string>
@@ -219,21 +293,50 @@
<!--Variable Speed-->
<string name="download_plugin_label">Eklentiyi İndir</string>
<string name="no_playback_plugin_title">Eklenti Yüklenmedi</string>
- <string name="set_playback_speed_label">Çalma hızları</string>
+ <string name="no_playback_plugin_or_sonic_msg">For variable speed playback to work, we recommend to enable the built-in Sonic mediaplayer.</string>
<string name="enable_sonic">Sonic\'i Etkinleştir</string>
+ <string name="speed_presets">Presets</string>
+ <string name="preset_already_exists">%1$.2fx is already saved as a preset.</string>
<!--Empty list labels-->
+ <string name="no_items_header_label">No queued episodes</string>
+ <string name="no_items_label">Add an episode by downloading it, or long press an episode and select \"Add to queue\".</string>
<string name="no_shownotes_label">Bu dosya herhangi bir bilgi notu içermiyor.</string>
+ <string name="no_run_downloads_head_label">No downloads running</string>
+ <string name="no_run_downloads_label">You can download episodes on the podcast details screen.</string>
+ <string name="no_comp_downloads_head_label">No downloaded episodes</string>
+ <string name="no_comp_downloads_label">You can download episodes on the podcast details screen.</string>
+ <string name="no_log_downloads_head_label">No download log</string>
+ <string name="no_log_downloads_label">Download logs will appear here when available.</string>
+ <string name="no_history_head_label">No History</string>
+ <string name="no_history_label">After you listen to an episode, it will appear here.</string>
+ <string name="no_all_episodes_head_label">No Episodes</string>
+ <string name="no_all_episodes_label">When you add a podcast, the episodes will be shown here.</string>
+ <string name="no_new_episodes_head_label">No new episodes</string>
+ <string name="no_new_episodes_label">When new episodes arrive, they will be shown here.</string>
+ <string name="no_fav_episodes_head_label">No favorite episodes</string>
+ <string name="no_fav_episodes_label">You can add episodes to the favorites by long-pressing them.</string>
+ <string name="no_chapters_head_label">No chapters</string>
<string name="no_chapters_label">Bu dosya herhangi bir bölüm içermiyor.</string>
+ <string name="no_subscriptions_head_label">No subscriptions</string>
+ <string name="no_subscriptions_label">To subscribe to a podcast, press the plus icon below.</string>
<!--Preferences-->
<string name="storage_pref">Depolama</string>
+ <string name="storage_sum">Episode auto delete, Import, Export</string>
<string name="project_pref">Proje</string>
<string name="queue_label">Kuyruk</string>
+ <string name="synchronization_pref">Synchronization</string>
+ <string name="synchronization_sum">Synchronize with other devices using gpodder.net</string>
<string name="automation">Otomasyon</string>
<string name="download_pref_details">Detaylar</string>
<string name="import_export_pref">Al/Aktar</string>
+ <string name="import_export_search_keywords">backup, restore</string>
<string name="appearance">Görünüm</string>
<string name="external_elements">Dış elemanlar</string>
<string name="interruptions">Kesintiler</string>
+ <string name="playback_control">Playback control</string>
+ <string name="preference_search_hint">Search…</string>
+ <string name="preference_search_no_results">No results</string>
+ <string name="preference_search_clear_history">Clear history</string>
<string name="media_player">Medya oynatıcı</string>
<string name="pref_episode_cleanup_title">Bölüm Temizliği</string>
<string name="pref_episode_cleanup_summary">Yeni bölümleri otomatik indirme için alan gerekirse, kuyrukta veya favorilerde olmayan bölümler otomatik olarak silinebilir</string>
@@ -254,8 +357,11 @@
<string name="pref_favorite_keeps_episodes_sum">Bölümler Favori olarak işaretlendiğinde tut</string>
<string name="pref_favorite_keeps_episodes_title">Favori bölümleri tut</string>
<string name="playback_pref">Çalma</string>
+ <string name="playback_pref_sum">Headphone controls, Skip intervals, Queue</string>
<string name="network_pref">Ağ</string>
+ <string name="network_pref_sum">Update interval, Download controls, Mobile data</string>
<string name="pref_autoUpdateIntervallOrTime_title">Güncelleme Aralığı veya Belirli Zamanı</string>
+ <string name="pref_autoUpdateIntervallOrTime_sum">Specify an interval or a specific time of day to refresh the podcasts automatically</string>
<string name="pref_autoUpdateIntervallOrTime_message">Otomatik güncelleştirmelerin yapılması için \"her 2 saatte bir\" gibi <i>aralık</i>, \"07:00\" gibi \"belirli saat\" ayarlayabilirsiniz veya <i>devre dışı</i> bırakabilirsiniz.\n\n<small>Not: Güncelleme zamanları kesin değildir, kısa gecikmeler yaşanabilir.</small></string>
<string name="pref_autoUpdateIntervallOrTime_Disable">Devre dışı</string>
<string name="pref_autoUpdateIntervallOrTime_Interval">Aralık ayarla</string>
@@ -263,17 +369,27 @@
<string name="pref_autoUpdateIntervallOrTime_every">her%1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">süre%1$s</string>
<string name="pref_followQueue_title">Devamlı çalma</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Kulaklık bağlı değil</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">Headphones or Bluetooth disconnect</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Kulaklıklar yeniden bağlı</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth yeniden bağlandı</string>
+ <string name="pref_stream_over_download_title">Prefer Streaming</string>
+ <string name="pref_stream_over_download_sum">Display stream button instead of download button in lists.</string>
<string name="pref_mobileUpdate_title">Mobil güncellemeler</string>
+ <string name="pref_mobileUpdate_sum">Select what should be allowed over the mobile data connection</string>
+ <string name="pref_mobileUpdate_refresh">Podcast refresh</string>
+ <string name="pref_mobileUpdate_images">Cover images</string>
+ <string name="pref_mobileUpdate_auto_download">Auto download</string>
+ <string name="pref_mobileUpdate_episode_download">Episode download</string>
+ <string name="pref_mobileUpdate_streaming">Streaming</string>
<string name="user_interface_label">Kullanıcı Arayüzü</string>
+ <string name="user_interface_sum">Appearance, Subscriptions, Lockscreen</string>
<string name="pref_set_theme_title">Temayı seç</string>
<string name="pref_nav_drawer_items_title">Uygulama Çekmecesi öğelerini ayarla</string>
<string name="pref_nav_drawer_items_sum">Hangi öğelerin uygulama çekmecesinde görüneceğini değiştir.</string>
<string name="pref_nav_drawer_feed_order_title">Abonelik sıralamasını ayarla</string>
<string name="pref_nav_drawer_feed_order_sum">Abonelik sırasını değiştir</string>
<string name="pref_nav_drawer_feed_counter_title">Abonelik sayacını ayarla</string>
+ <string name="pref_nav_drawer_feed_counter_sum">Change the information displayed by the subscription counter. Also affects the sorting of subscriptions if \'Subscription Order\' is set to \'Counter\'.</string>
<string name="pref_set_theme_sum">AntennaPod\'un görüntüsünü değiştir.</string>
<string name="pref_automatic_download_title">Otomatk indirme</string>
<string name="pref_automatic_download_sum">Bölümlerin otomatik indirilmesini yapılandır.</string>
@@ -283,8 +399,13 @@
<string name="pref_automatic_download_on_battery_sum">Pil şarj olmuyorken otomatik indirmeye izin ver</string>
<string name="pref_parallel_downloads_title">Paralel indirmeler</string>
<string name="pref_episode_cache_title">Bölüm ön belleği</string>
+ <string name="pref_episode_cache_summary">Total number of downloaded episodes cached on the device. Automatic download will be suspended if this number is reached.</string>
+ <string name="pref_episode_cover_title">Use Episode Cover</string>
+ <string name="pref_episode_cover_summary">Use the episode specific cover whenever available. If unchecked, the app will always use the podcast cover image.</string>
+ <string name="pref_theme_title_use_system">Use system theme</string>
<string name="pref_theme_title_light">Aydınlık</string>
<string name="pref_theme_title_dark">Karanlık</string>
+ <string name="pref_theme_title_trueblack">Black (AMOLED ready)</string>
<string name="pref_episode_cache_unlimited">Sınırsız</string>
<string name="pref_update_interval_hours_plural">saat</string>
<string name="pref_update_interval_hours_singular">saat</string>
@@ -295,36 +416,161 @@
<string name="pref_gpodnet_logout_toast">Çıkış başarılı</string>
<string name="pref_gpodnet_setlogin_information_title">Giriş bilgisini değiştir</string>
<string name="pref_gpodnet_setlogin_information_sum">gpodder.net hesabınız için giriş bilgisini değiştirin.</string>
- <string name="pref_playback_speed_title">Çalma hızları</string>
- <string name="pref_playback_speed_sum">Değişken hızlı ses yürütmesi için kullanılabilir hızları özelleştirin</string>
+ <string name="pref_gpodnet_sync_changes_title">Synchronize now</string>
+ <string name="pref_gpodnet_sync_changes_sum">Sync subscription and episode state changes with gpodder.net.</string>
+ <string name="pref_gpodnet_full_sync_title">Force full synchronization</string>
+ <string name="pref_gpodnet_full_sync_sum">Sync all subscriptions and episode states with gpodder.net.</string>
+ <string name="pref_gpodnet_login_status"><![CDATA[Logged in as <i>%1$s</i> with device <i>%2$s</i>]]></string>
+ <string name="pref_gpodnet_notifications_title">Synchronization failed</string>
+ <string name="pref_gpodnet_notifications_sum">This setting does not apply to authentication errors.</string>
+ <string name="pref_playback_speed_sum">Customize the speeds available for variable speed playback</string>
+ <string name="pref_feed_playback_speed_sum">The speed to use when starting audio playback for episodes in this podcast</string>
+ <string name="pref_feed_skip">Auto Skip</string>
+ <string name="pref_feed_skip_sum">Skip introductions and ending credits.</string>
+ <string name="pref_feed_skip_ending">Skip last</string>
+ <string name="pref_feed_skip_intro">Skip first</string>
+ <string name="pref_feed_skip_ending_toast">Skipped last %d seconds</string>
+ <string name="pref_feed_skip_intro_toast">Skipped first %d seconds</string>
+ <string name="pref_playback_time_respects_speed_title">Adjust media info to playback speed</string>
+ <string name="pref_playback_time_respects_speed_sum">Displayed position and duration are adapted to playback speed</string>
+ <string name="pref_fast_forward">Fast Forward Skip Time</string>
+ <string name="pref_fast_forward_sum">Customize the number of seconds to jump forward when the fast forward button is clicked</string>
+ <string name="pref_rewind">Rewind Skip Time</string>
+ <string name="pref_rewind_sum">Customize the number of seconds to jump backwards when the rewind button is clicked</string>
<string name="pref_gpodnet_sethostname_title">Sunucu ismini ayarla</string>
<string name="pref_gpodnet_sethostname_use_default_host">Varsayılan sunucuyu kullan</string>
+ <string name="pref_expandNotify_title">High Notification priority</string>
+ <string name="pref_expandNotify_sum">This usually expands the notification to show playback buttons.</string>
<string name="pref_persistNotify_title">Kalıcı oynatma kontrolleri</string>
<string name="pref_persistNotify_sum">Çalma duraklatıldığında bildirim ve ekran kilidi ayarlarını sakla.</string>
- <string name="pref_showDownloadReport_title">İndirme Raporunu Göster</string>
+ <string name="pref_compact_notification_buttons_title">Set Compact Notification Buttons</string>
+ <string name="pref_compact_notification_buttons_sum">Change the playback buttons when the notification is collapsed. The play/pause button is always included.</string>
+ <string name="pref_compact_notification_buttons_dialog_title">Select a maximum of %1$d items</string>
+ <string name="pref_compact_notification_buttons_dialog_error">You can only select a maximum of %1$d items.</string>
+ <string name="pref_lockscreen_background_title">Set Lockscreen Background</string>
+ <string name="pref_lockscreen_background_sum">Set the lockscreen background to the current episode\'s image. As a side effect, this will also show the image in third party apps.</string>
+ <string name="pref_showDownloadReport_title">Download failed</string>
<string name="pref_showDownloadReport_sum">Eğer indirme başarısız olursa, hatanın ayrıntılarını gösteren bir rapor oluştur.</string>
+ <string name="pref_showAutoDownloadReport_title">Automatic download completed</string>
+ <string name="pref_showAutoDownloadReport_sum">Show a notification for automatically downloaded episodes.</string>
<string name="pref_expand_notify_unsupport_toast">Android 4.1 öncesi sürümler genişletilmiş bildirimleri desteklememektedir.</string>
+ <string name="pref_enqueue_location_title">Enqueue Location</string>
+ <string name="pref_enqueue_location_sum">Add episodes to: %1$s</string>
+ <string name="enqueue_location_back">Back</string>
+ <string name="enqueue_location_front">Front</string>
+ <string name="enqueue_location_after_current">After current episode</string>
<string name="pref_smart_mark_as_played_disabled">Devre dışı</string>
<string name="pref_image_cache_size_title">Görüntü Önbelleği Boyutu</string>
<string name="pref_image_cache_size_sum">Görüntüler için diskte tutulacak önbelleğin boyutu.</string>
+ <string name="visit_user_forum">User forum</string>
+ <string name="bug_report_title">Report bug</string>
+ <string name="open_bug_tracker">Open bug tracker</string>
+ <string name="export_logs">Export logs</string>
+ <string name="copy_to_clipboard">Copy to clipboard</string>
+ <string name="copied_to_clipboard">Copied to clipboard</string>
<string name="experimental_pref">Deneysel</string>
+ <string name="pref_media_player_message">Select which media player to use to play files</string>
+ <string name="pref_current_value">Current value: %1$s</string>
+ <string name="pref_proxy_title">Proxy</string>
+ <string name="pref_proxy_sum">Set a network proxy</string>
+ <string name="pref_faq">Frequently Asked Questions</string>
+ <string name="pref_no_browser_found">No web browser found.</string>
+ <string name="pref_cast_title">Chromecast support</string>
+ <string name="pref_cast_message_play_flavor">Enable support for remote media playback on Cast devices (such as Chromecast, Audio Speakers or Android TV)</string>
+ <string name="pref_cast_message_free_flavor">Chromecast requires third party proprietary libraries that are disabled in this version of AntennaPod</string>
+ <string name="pref_enqueue_downloaded_title">Enqueue Downloaded</string>
+ <string name="pref_enqueue_downloaded_summary">Add downloaded episodes to the queue</string>
+ <string name="media_player_builtin">Built-in Android player</string>
+ <string name="media_player_switch_to_exoplayer">Switch to ExoPlayer</string>
+ <string name="media_player_switched_to_exoplayer">Switched to ExoPlayer.</string>
+ <string name="pref_skip_silence_title">Skip Silence in Audio</string>
+ <string name="pref_videoBehavior_title">Upon exiting video</string>
+ <string name="pref_videoBehavior_sum">Behavior when leaving video playback</string>
+ <string name="stop_playback">Stop playback</string>
+ <string name="continue_playback">Continue audio playback</string>
+ <string name="behavior">Behavior</string>
+ <string name="pref_back_button_behavior_title">Back Button Behavior</string>
+ <string name="pref_back_button_behavior_sum">Change behavior of the back button.</string>
+ <string name="back_button_default">Default</string>
+ <string name="back_button_open_drawer">Open navigation drawer</string>
+ <string name="back_button_double_tap">Double tap to exit</string>
+ <string name="back_button_show_prompt">Confirm to exit</string>
+ <string name="close_prompt">Are you sure you want to close AntennaPod?</string>
+ <string name="double_tap_toast">Tap back button again to exit</string>
+ <string name="back_button_go_to_page">Go to page…</string>
+ <string name="back_button_go_to_page_title">Select page</string>
+ <string name="pref_delete_removes_from_queue_title">Delete removes from Queue</string>
+ <string name="pref_delete_removes_from_queue_sum">Automatically remove an episode from the queue when it is deleted.</string>
+ <string name="pref_filter_feed_title">Subscription Filter</string>
+ <string name="pref_filter_feed_sum">Filter your subscriptions in navigation drawer and subscriptions screen.</string>
+ <string name="no_filter_label">None</string>
+ <string name="subscriptions_are_filtered">Subscriptions are filtered.</string>
+ <string name="auto_downloaded">Auto downloaded</string>
+ <string name="not_auto_downloaded">Not auto downloaded</string>
+ <string name="kept_updated">Kept updated</string>
+ <string name="not_kept_updated">Not kept updated</string>
<!--About screen-->
<string name="about_pref">Hakkında</string>
+ <string name="antennapod_version">AntennaPod version</string>
+ <string name="contributors">Contributors</string>
+ <string name="contributors_summary">Everyone can help to make AntennaPod better - with code, translations or by helping users in our forum</string>
+ <string name="developers">Developers</string>
+ <string name="translators">Translators</string>
+ <string name="special_thanks">Special thanks</string>
+ <string name="privacy_policy">Privacy policy</string>
+ <string name="licenses">Licenses</string>
+ <string name="licenses_summary">AntennaPod uses other great software</string>
<!--Search-->
<string name="search_status_no_results">Sonuç bulunamadı</string>
<string name="search_label">Ara</string>
+ <string name="no_results_for_query">No results were found for \"%1$s\"</string>
<!--Synchronization-->
+ <string name="sync_status_started">Sync started</string>
+ <string name="sync_status_episodes_upload">Uploading episode changes…</string>
+ <string name="sync_status_episodes_download">Downloading episode changes…</string>
+ <string name="sync_status_upload_played">Uploading played status…</string>
+ <string name="sync_status_subscriptions">Synchronizing subscriptions…</string>
+ <string name="sync_status_success">Synchronization successful</string>
+ <string name="sync_status_error">Synchronization failed</string>
<!--import and export-->
+ <string name="import_export_summary">Move subscriptions and queue to another device</string>
+ <string name="database">Database</string>
+ <string name="opml">OPML</string>
+ <string name="html">HTML</string>
+ <string name="html_export_summary">Show your subscriptions to a friend</string>
+ <string name="opml_export_summary">Transfer your subscriptions to another podcast app</string>
+ <string name="opml_import_summary">Import your subscriptions from another podcast app</string>
+ <string name="database_export_summary">Transfer subscriptions, listened episodes and queue to AntennaPod on another device</string>
+ <string name="database_import_summary">Import AntennaPod database from another device</string>
<string name="opml_import_label">OPML içe aktar</string>
+ <string name="opml_add_podcast_label">Import podcast list (OPML)</string>
+ <string name="opml_reader_error">An error has occurred while reading the OPML document:</string>
+ <string name="opml_import_error_no_file">No file selected!</string>
<string name="select_all_label">Hepsini seç</string>
<string name="deselect_all_label">Tüm seçimleri geri al</string>
<string name="opml_export_label">OPML dışa aktar</string>
+ <string name="html_export_label">HTML export</string>
+ <string name="database_export_label">Database export</string>
+ <string name="database_import_label">Database import</string>
+ <string name="database_import_warning">Importing a database will replace all of your current subscriptions and playing history. You should export your current database as a backup. Do you want to replace?</string>
+ <string name="please_wait">Please wait…</string>
<string name="export_error_label">Dışa aktarma hatası</string>
+ <string name="export_success_title">Export successful</string>
+ <string name="export_success_sum">The exported file was written to:\n\n%1$s</string>
+ <string name="opml_import_ask_read_permission">Access to external storage is required to read the OPML file</string>
+ <string name="import_select_file">Select file to import</string>
+ <string name="successful_import_label">Import successful</string>
+ <string name="import_ok">Please press OK to restart AntennaPod</string>
+ <string name="import_no_downgrade">This database was exported with a newer version of AntennaPod. Your current installation does not yet know how to handle this file.</string>
+ <string name="favorites_export_label">Favorites export</string>
+ <string name="favorites_export_summary">Export saved favorites to file</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Zamanlayıcıyı ayarla</string>
<string name="disable_sleeptimer_label">Zamanlayıcıyı devre dışı bırak</string>
<string name="sleep_timer_label">Zamanlayıcı</string>
<string name="time_dialog_invalid_input">Geçersiz giriş, zaman bir tam sayı olmalıdır</string>
+ <string name="shake_to_reset_label">Shake to reset</string>
+ <string name="timer_vibration_label">Vibrate shortly before end</string>
<string name="time_seconds">saniye</string>
<string name="time_minutes">dakika</string>
<string name="time_hours">saat</string>
@@ -340,6 +586,8 @@
<item quantity="one">1 saat</item>
<item quantity="other">%d saat</item>
</plurals>
+ <string name="auto_enable_label">Auto-enable</string>
+ <string name="sleep_timer_enabled_label">Sleep timer enabled</string>
<!--gpodder.net-->
<string name="gpodnet_taglist_header">KATEGORİLER</string>
<string name="gpodnet_toplist_header">POPÜLER CEP YAYINLARI</string>
@@ -359,6 +607,7 @@
<string name="gpodnetauth_device_chooseExistingDevice">Bir cihaz seç:</string>
<string name="gpodnetauth_device_errorEmpty">Cihaz ID\'si boş olamaz</string>
<string name="gpodnetauth_device_errorAlreadyUsed">Cihaz ID\'si zaten var</string>
+ <string name="gpodnetauth_device_caption_errorEmpty">Caption must not be empty</string>
<string name="gpodnetauth_device_butChoose">Seç</string>
<string name="gpodnetauth_finish_title">Giriş başarılı</string>
<string name="gpodnetauth_finish_descr">Tebrikler! gpodder.net hesabınız cihazınızla ilişkilendirildi. AntennaPod bundan sonra gpodder.net hesabınızla üyeliklerinizi otomatik olarak senkronize edecek.</string>
@@ -368,11 +617,16 @@
<string name="gpodnetsync_auth_error_descr">Yanlış kullanıcı adı veya şifre</string>
<string name="gpodnetsync_error_title">gpodder.net senkronizasyon hatası</string>
<string name="gpodnetsync_error_descr">Senkronize edilirken bir hata oluştu:\u0020</string>
+ <string name="gpodnetsync_pref_report_successful">Successful</string>
+ <string name="gpodnetsync_pref_report_failed">Failed</string>
+ <string name="gpodnetsync_username_characters_error">Usernames may only contain letters, digits, hyphens and underscores.</string>
<!--Directory chooser-->
<string name="selected_folder_label">Seçilen dizin:</string>
<string name="create_folder_label">Dizin yarat</string>
<string name="choose_data_directory">Veri dizinini seç</string>
<string name="choose_data_directory_message">Lütfen verileriniz için ana klasörü seçin. AntennaPod gerekli alt-klasörleri oluşturacaktır.</string>
+ <string name="choose_data_directory_permission_rationale">Access to external storage is required to change the data folder</string>
+ <string name="choose_data_directory_available_space">%1$s of %2$s free</string>
<string name="create_folder_msg">\"%1$s\" isminde yeni dizin oluştur?</string>
<string name="create_folder_success">Yeni dizin yaratıldı</string>
<string name="create_folder_error_no_write_access">Bu dizine yazılamadı</string>
@@ -391,31 +645,68 @@
<string name="pref_restart_required">Bu değişikliğin geçerli olması için AntennaPod yeniden başlatılmalıdır.</string>
<!--Online feed view-->
<string name="subscribe_label">Üye ol</string>
+ <string name="subscribing_label">Subscribing…</string>
+ <string name="preview_episode">Preview</string>
+ <string name="stop_preview">Stop preview</string>
<!--Content descriptions for image buttons-->
<string name="rewind_label">Geri sar</string>
<string name="fast_forward_label">İleri sar</string>
+ <string name="increase_speed">Increase speed</string>
+ <string name="decrease_speed">Decrease speed</string>
<string name="media_type_audio_label">Ses</string>
<string name="media_type_video_label">Vidyo</string>
- <string name="navigate_upwards_label">Yukarı çık</string>
<string name="status_downloading_label">Bölüm indiriliyor</string>
<string name="in_queue_label">Bölüm kuyrukta</string>
+ <string name="is_favorite_label">Episode is marked as favorite</string>
<string name="drag_handle_content_description">Bu öğenin pozisyonunu değiştirmek için sürükleyin</string>
<string name="load_next_page_label">Sonraki sayfayı yükle</string>
+ <string name="switch_pages">Switch pages</string>
+ <string name="position">Position: %1$s</string>
+ <string name="apply_action">Apply action</string>
<!--Feed information screen-->
<string name="authentication_label">Yetkilendirme</string>
<string name="authentication_descr">Bu cep yayını ve içerdiği bölümler için kullanıcı adı şifreyi değiştir.</string>
<string name="auto_download_settings_label">Otomatik İndirme Seçenekleri</string>
+ <string name="episode_filters_label">Episode Filter</string>
+ <string name="episode_filters_description">List of terms used to decide if an episode should be included or excluded when auto downloading</string>
+ <string name="episode_filters_include">Include</string>
+ <string name="episode_filters_exclude">Exclude</string>
+ <string name="episode_filters_hint">Single words \n\"Multiple Words\"</string>
+ <string name="keep_updated">Keep Updated</string>
+ <string name="keep_updated_summary">Include this podcast when (auto-)refreshing all podcasts</string>
+ <string name="auto_download_disabled_globally">Auto download is disabled in the main AntennaPod settings</string>
+ <string name="statistics_listened_for">Listened for:</string>
+ <string name="statistics_episodes_on_device">Episodes on the device:</string>
+ <string name="statistics_space_used">Space used:</string>
+ <string name="statistics_view_all">View for all podcasts »</string>
<!--Progress information-->
<string name="progress_upgrading_database">Veritabanı yükseltiliyor</string>
<!--AntennaPodSP-->
<string name="sp_apps_importing_feeds_msg">Üyelikler tek-amaçlı uygulamalardan içe aktarılıyor...</string>
<!--Add podcast fragment-->
+ <string name="search_podcast_hint">Search podcast…</string>
<string name="search_itunes_label">iTunes\'da Arama</string>
+ <string name="search_podcastindex_label">Search Podcastindex.org</string>
+ <string name="search_fyyd_label">Search fyyd</string>
+ <string name="advanced">Advanced</string>
+ <string name="add_podcast_by_url">Add Podcast by RSS address</string>
<string name="browse_gpoddernet_label">gpodder.net\'e gözat</string>
+ <string name="discover">Discover</string>
+ <string name="discover_hide">Hide</string>
+ <string name="discover_is_hidden">You selected to hide suggestions.</string>
+ <string name="discover_more">more »</string>
+ <string name="discover_powered_by_itunes">Suggestions by iTunes</string>
+ <string name="search_powered_by">Results by %1$s</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">Add local folder</string>
+ <string name="reconnect_local_folder">Re-connect local folder</string>
+ <string name="reconnect_local_folder_warning">In case of permission denials, you can use this to re-connect to the exact same folder. Do not select another folder.</string>
+ <string name="local_feed_description">This virtual podcast was created by adding a folder to AntennaPod.</string>
+ <string name="filter">Filter</string>
<!--Episodes apply actions-->
<string name="all_label">Tümü</string>
<string name="selected_all_label">Tüm Bölümler Seçildi</string>
- <string name="none_label">Hiçbiri</string>
+ <string name="select_none_label">None</string>
<string name="deselected_all_label">Tüm Bölümlerin Seçimi Kaldırıldı</string>
<string name="played_label">Çalınan</string>
<string name="selected_played_label">Çalınan Bölümler Seçildi</string>
@@ -425,6 +716,21 @@
<string name="selected_downloaded_label">İndirilen Bölümler Seçildi</string>
<string name="not_downloaded_label">İndirilmeyen</string>
<string name="selected_not_downloaded_label">İndirilmeyen Bölümler Seçildi</string>
+ <string name="selected_queued_label">Selected queued Episodes</string>
+ <string name="selected_not_queued_label">Selected not queued Episodes</string>
+ <string name="selected_has_media_label">Selected episodes with media</string>
+ <string name="hide_is_favorite_label">Favori</string>
+ <string name="not_favorite">Not favorite</string>
+ <string name="hide_downloaded_episodes_label">İndirildi</string>
+ <string name="hide_not_downloaded_episodes_label">İndirilmedi</string>
+ <string name="queued_label">Queued</string>
+ <string name="not_queued_label">Not queued</string>
+ <string name="has_media">Has media</string>
+ <string name="no_media">No media</string>
+ <string name="hide_paused_episodes_label">Duraklatıldı</string>
+ <string name="not_paused">Not paused</string>
+ <string name="hide_played_episodes_label">Oynatıldı</string>
+ <string name="not_played">Not played</string>
<!--Sort-->
<string name="sort_title_a_z">Başlık (A \u2192 Z)</string>
<string name="sort_title_z_a">Başlık (Z \u2192 A)</string>
@@ -432,22 +738,81 @@
<string name="sort_date_old_new">Tarih (Eski \u2192 Yeni)</string>
<string name="sort_duration_short_long">Süre (Kısa \u2192 Uzun)</string>
<string name="sort_duration_long_short">Süre (Uzun \u2192 Kısa)</string>
+ <string name="sort_a_z">A \u2192 Z</string>
+ <string name="sort_z_a">Z \u2192 A</string>
+ <string name="sort_new_old">New \u2192 Old</string>
+ <string name="sort_old_new">Old \u2192 New</string>
+ <string name="sort_short_long">Short \u2192 Long</string>
+ <string name="sort_long_short">Long \u2192 Short</string>
<!--Rating dialog-->
<string name="rating_title">AntennaPod\'u beğendiniz mi?</string>
<string name="rating_message">Eğer AntennaPod\'a oy vermek için biraz zamanını ayırırsanız memnun oluruz.</string>
<string name="rating_never_label">Bir daha gösterme</string>
<string name="rating_later_label">Daha sonra hatırlat</string>
<string name="rating_now_label">Evet, şimdi yapalım!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">Include:</string>
+ <string name="share_playback_position_dialog_label">Playback position</string>
+ <string name="share_dialog_media_file_url_label">Media file address</string>
+ <string name="share_dialog_episode_website_label">Episode webpage</string>
+ <string name="share_dialog_media_file_label">Media file</string>
<!--Audio controls-->
+ <string name="audio_controls">Audio controls</string>
+ <string name="playback_speed">Playback Speed</string>
<string name="volume">Ses</string>
+ <string name="left_short">L</string>
+ <string name="right_short">R</string>
+ <string name="audio_effects">Audio Effects</string>
+ <string name="stereo_to_mono">Downmix: Stereo to mono</string>
+ <string name="sonic_only">Sonic only</string>
+ <string name="exoplayer_only">ExoPlayer only</string>
<!--proxy settings-->
+ <string name="proxy_type_label">Type</string>
+ <string name="host_label">Host</string>
+ <string name="port_label">Port</string>
+ <string name="optional_hint">(Optional)</string>
<string name="proxy_test_label">Test</string>
+ <string name="proxy_checking">Checking…</string>
<string name="proxy_test_successful">Test başarılı</string>
<string name="proxy_test_failed">Test başarısız</string>
+ <string name="proxy_host_empty_error">Host can not be empty</string>
+ <string name="proxy_host_invalid_error">Host is not a valid IP address or domain</string>
+ <string name="proxy_port_invalid_error">Port not valid</string>
<!--Subscriptions fragment-->
+ <string name="subscription_num_columns">Number of columns</string>
<!--Casting-->
+ <string name="cast_media_route_menu_title">Play on…</string>
+ <string name="cast_disconnect_label">Disconnect the cast session</string>
+ <string name="cast_not_castable">Media selected is not compatible with cast device</string>
+ <string name="cast_failed_to_play">Failed to start the playback of media</string>
+ <string name="cast_failed_to_stop">Failed to stop the playback of media</string>
+ <string name="cast_failed_to_pause">Failed to pause the playback of media</string>
+ <string name="cast_failed_setting_volume">Failed to set the volume</string>
+ <string name="cast_failed_no_connection">No connection to the cast device is present</string>
+ <string name="cast_failed_no_connection_trans">Connection to the cast device has been lost. Application is trying to re-establish the connection, if possible. Please wait for a few seconds and try again.</string>
+ <string name="cast_failed_status_request">Failed to sync up with the cast device</string>
<string name="cast_failed_seek">Yayın aygıtındaki yeni pozisyona erişilemedi</string>
+ <string name="cast_failed_receiver_player_error">Receiver player has encountered a severe error</string>
+ <string name="cast_failed_media_error_skipping">Error playing media. Skipping…</string>
<!--Notification channels-->
+ <string name="notification_channel_user_action">Action required</string>
+ <string name="notification_channel_user_action_description">Shown if your action is required, for example if you need to enter a password.</string>
+ <string name="notification_channel_downloading">Downloading</string>
+ <string name="notification_channel_downloading_description">Shown while currently downloading.</string>
+ <string name="notification_channel_playing">Currently playing</string>
+ <string name="notification_channel_playing_description">Allows to control playback. This is the main notification you see while playing a podcast.</string>
+ <string name="notification_channel_error">Errors</string>
+ <string name="notification_channel_error_description">Shown if something went wrong, for example if download or feed update fails.</string>
+ <string name="notification_channel_sync_error">Synchronization Errors</string>
+ <string name="notification_channel_sync_error_description">Shown when gpodder synchronization fails.</string>
+ <string name="notification_channel_auto_download">Auto Downloads</string>
+ <string name="notification_channel_episode_auto_download">Shown when episodes have been automatically downloaded.</string>
<!--Widget settings-->
+ <string name="widget_settings">Widget settings</string>
+ <string name="widget_create_button">Create widget</string>
+ <string name="widget_opacity">Opacity</string>
<!--On-Demand configuration-->
+ <string name="on_demand_config_setting_changed">Setting updated successfully.</string>
+ <string name="on_demand_config_stream_text">Looks like you stream a lot. Do you want episode lists to show stream buttons?</string>
+ <string name="on_demand_config_download_text">Looks like you download a lot. Do you want episode lists to show download buttons?</string>
</resources>
diff --git a/core/src/main/res/values-uk/strings.xml b/core/src/main/res/values-uk/strings.xml
index d61cb5977..f9c2abe20 100644
--- a/core/src/main/res/values-uk/strings.xml
+++ b/core/src/main/res/values-uk/strings.xml
@@ -23,11 +23,9 @@
<string name="episode_cache_full_title">Кеш епізодів заповнений</string>
<string name="episode_cache_full_message">Досягнута межа розміру кешу епізодів. Розмір кешу можна збільшити в налаштуваннях.</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Загальний час прослуханих подкастів:</string>
<string name="statistics_details_dialog">%1$d з %2$d епізодів почато.\n\nПрослухано %3$s з %4$s.</string>
<string name="statistics_mode">Режим статистики</string>
<string name="statistics_mode_normal">Обчислити тривалість дійсно прослуханого. Прослухане двічі враховується двічі, але просто позначене як прослухане не враховується </string>
- <string name="statistics_mode_count_all">Підсумувати всі подкасти позначені як прослухані</string>
<string name="statistics_speed_not_counted">Зауваження: Швидкість програвання не береться до уваги.</string>
<string name="statistics_reset_data">Cкинути статистику</string>
<string name="statistics_reset_data_msg">Це зітре історію тривалості відтворення всіх епізодів. Ви впевнені, що хочете продовжити?</string>
@@ -45,6 +43,7 @@
<string name="drawer_feed_counter_unplayed">Кількість непрослуханих епізодів</string>
<string name="drawer_feed_counter_downloaded">Кількість завантажених епізодів</string>
<string name="drawer_feed_counter_none">Жодних</string>
+ <!--Bug report activity-->
<!--Webview actions-->
<string name="open_in_browser_label">Відкрити в браузері</string>
<string name="copy_url_label">Копіювати URL</string>
@@ -111,27 +110,16 @@
<string name="feed_settings_label">Налаштування подкасту</string>
<string name="rename_feed_label">Перейменувати подкаст</string>
<string name="remove_feed_label">Видалити подкаст</string>
- <string name="share_label">Поділитися…</string>
- <string name="share_link_label">Поділитися URL на епізод</string>
- <string name="share_link_with_position_label">Поділитися URL на епізод з позицією відтворення</string>
<string name="share_file_label">Поділитися файлом</string>
- <string name="share_website_url_label">Поділитися URL на сайт</string>
- <string name="share_item_url_label">Поділитися URL на медіа-файл</string>
- <string name="share_item_url_with_position_label">Поділитися URL на медіа-файл з позицією відтворення</string>
<string name="feed_delete_confirmation_msg">Будь ласка, підтвердіть що ви бажаєте видалити подкаст \"%1$s\" і ВСІ його епізоди (разом з завантаженими).</string>
<string name="feed_remover_msg">Видалення подкасту</string>
<string name="load_complete_feed">Оновити весь подкаст</string>
<string name="select_all_above">Вибрати все вище</string>
<string name="select_all_below">Вибрати все нижче</string>
<string name="hide_unplayed_episodes_label">Невідтворені</string>
- <string name="hide_paused_episodes_label">Призупинені</string>
- <string name="hide_played_episodes_label">Відтворені</string>
<string name="hide_queued_episodes_label">В черзі</string>
<string name="hide_not_queued_episodes_label">Не в черзі</string>
- <string name="hide_downloaded_episodes_label">Завантажені</string>
- <string name="hide_not_downloaded_episodes_label">Не завантажені</string>
<string name="hide_has_media_label">Зі звуком або відео</string>
- <string name="hide_is_favorite_label">В улюблених</string>
<string name="filtered_label">Фільтровані</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} Останнє оновлення було невдалим</string>
<string name="open_podcast">Відкрити подкаст</string>
@@ -149,12 +137,6 @@
<string name="delete_label">Видалити</string>
<string name="delete_failed">Файл не видалено. Можливо, перезавантаження пристрою допоможе.</string>
<string name="delete_episode_label">Видалити епізод</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d епізод видалено.</item>
- <item quantity="few">%dепізода видалено. </item>
- <item quantity="many">%dепізодів видалено. </item>
- <item quantity="other">%d епізодів видалено.</item>
- </plurals>
<string name="mark_read_label">Позначити як відтворений</string>
<string name="marked_as_read_label">Позначено як відтворений</string>
<plurals name="marked_read_batch_label">
@@ -228,7 +210,6 @@
</plurals>
<string name="downloads_processing">Обробка завантаженого</string>
<string name="download_notification_title">Завантаження даних подкасту</string>
- <string name="download_report_content">Завантажилось %1$d успішно, %2$d з помилками</string>
<string name="download_log_title_unknown">Невідомий заголовок</string>
<string name="download_type_feed">Канал</string>
<string name="download_type_media">Файл з медіа</string>
@@ -239,7 +220,6 @@
<string name="confirm_mobile_download_dialog_title">Підтвердження завантажень через мобільні мережі</string>
<string name="confirm_mobile_download_dialog_message_not_in_queue">Завантаження через мобільні мережі вимкнено в налаштуваннях.\n\nВибрати додавання епізоду до черги чи тимчасове завантаження?\n\n<small>Ваш вибір буде дійсним 10 хвилин.</small></string>
<string name="confirm_mobile_download_dialog_message">Завантаження через мобільні мережі вимкнено в налаштуваннях.\n\nУвімкнути тимчасово?\n\n<small>Ваш вибір буде дійсним 10 хвилин.</small></string>
- <string name="confirm_mobile_streaming_button_always">Завжди дозволяти</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Лише додати до черги</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Увімкнути тимчасово</string>
<!--Mediaplayer messages-->
@@ -279,7 +259,6 @@
<!--Variable Speed-->
<string name="download_plugin_label">Завантажити додаток</string>
<string name="no_playback_plugin_title">Додаток не встановлено</string>
- <string name="set_playback_speed_label">Швидкість програвання</string>
<string name="enable_sonic">Включити Sonic</string>
<!--Empty list labels-->
<string name="no_items_header_label">В черзі немає епізодів.</string>
@@ -346,7 +325,6 @@
<string name="pref_autoUpdateIntervallOrTime_every">кожні %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">о %1$s</string>
<string name="pref_followQueue_title">Грати безперервно</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">Навушники від\'єднані</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Повторне під’єднання навушників</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Повторне під’єднання блютуз</string>
<string name="pref_mobileUpdate_title">Мобільне оновлення</string>
@@ -386,10 +364,7 @@
<string name="pref_gpodnet_sync_changes_sum">Синхронізувати підписки та зміни стану епізодів з gpodder.net</string>
<string name="pref_gpodnet_full_sync_sum">Синхронізувати всі підписки та стан епізодів з gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Ви увійшли як <i>%1$s</i> з пристрою <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Повідомляти про помилки синхронізації</string>
<string name="pref_gpodnet_notifications_sum">Це налаштування не застосовується до помилок автентифікації.</string>
- <string name="pref_playback_speed_title">Швидкість програвання</string>
- <string name="pref_playback_speed_sum">Налаштування швідкості доступно для змінної швидкості програвання</string>
<string name="pref_fast_forward">Час, що пропускається кнопкою перемотки вперед</string>
<string name="pref_fast_forward_sum">Налаштувати кількість секунд, які пропускаються при натисканні кнопки перемотки вперед</string>
<string name="pref_rewind">Час, що пропускається кнопкою відмотки назад</string>
@@ -400,13 +375,10 @@
<string name="pref_expandNotify_sum">Зазвичай це розширює сповіщення, щоб показати кнопки відтворення.</string>
<string name="pref_persistNotify_title">Завжди показувати елементи керування відтворенням</string>
<string name="pref_persistNotify_sum">Показувати повідомлення та елементи керування на екрані блокування в режимі паузи.</string>
- <string name="pref_compact_notification_buttons_title">Налаштувати кнопки на екрані блокування</string>
- <string name="pref_compact_notification_buttons_sum">Змінити кнопки на екрані блокування. Кнопки програвання/пауза завжди включені.</string>
<string name="pref_compact_notification_buttons_dialog_title">Оберіть не більше ніж %1$d кнопок</string>
<string name="pref_compact_notification_buttons_dialog_error">Ви можете обрати не більше ніж %1$d кнопок.</string>
<string name="pref_lockscreen_background_title">Встановити фон екрана блокування</string>
<string name="pref_lockscreen_background_sum">Встановити картинку поточного епізоду як фон екрана блокування. Побічний ефект - це зображення також буде видимим в інших додатках.</string>
- <string name="pref_showDownloadReport_title">Показати звіт про завантаження</string>
<string name="pref_showDownloadReport_sum">У разі помилки при завантаженні створити детальний звіт про помилку.</string>
<string name="pref_expand_notify_unsupport_toast">Android до версії 4.1 не підтримує розширені повідомлення.</string>
<string name="pref_enqueue_location_sum">Додати епізоди до: %1$s</string>
@@ -475,7 +447,6 @@
<string name="export_success_sum">Файл було записано в:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Щоб прочитати файл OPML потрібен доступ до зовнішнього носія</string>
<string name="import_select_file">Обрати файл для імпорту</string>
- <string name="import_ok">Імпорт пройшов успішно.\n\nБудь ласка, натисніть ОК щоб перезапустити AntennaPod</string>
<!--Sleep timer-->
<string name="set_sleeptimer_label">Таймер сну</string>
<string name="disable_sleeptimer_label">Вимкнути засинання</string>
@@ -567,7 +538,6 @@
<string name="fast_forward_label">Перемотка вперед</string>
<string name="media_type_audio_label">Звук</string>
<string name="media_type_video_label">Відео</string>
- <string name="navigate_upwards_label">Догори</string>
<string name="status_downloading_label">Епізод завантажується</string>
<string name="in_queue_label">Епізод чекає в черзі</string>
<string name="drag_handle_content_description">Перетягніть щоб змінити позицію</string>
@@ -594,11 +564,11 @@
<string name="browse_gpoddernet_label">Переглянути gpodder.net</string>
<string name="discover">Знайдіть канали</string>
<string name="discover_more">більше »</string>
+ <!--Local feeds-->
<string name="filter">Фільтр</string>
<!--Episodes apply actions-->
<string name="all_label">Всі</string>
<string name="selected_all_label">Обрано всі епізоди</string>
- <string name="none_label">Жодного</string>
<string name="deselected_all_label">Жодного епізода не обрано</string>
<string name="played_label">Відтворені</string>
<string name="selected_played_label">Обрано відтворені епізоди</string>
@@ -608,12 +578,17 @@
<string name="selected_downloaded_label">Обрано завантажені епізоди</string>
<string name="not_downloaded_label">Незавантажені</string>
<string name="selected_not_downloaded_label">Обрано незавантажені епізоди</string>
- <string name="queued_label">В черзі</string>
<string name="selected_queued_label">Обрано епізоди що в черзі</string>
- <string name="not_queued_label">Не в черзі</string>
<string name="selected_not_queued_label">Обрано епізоди що не в черзі</string>
- <string name="has_media">Зі звуком або відео</string>
<string name="selected_has_media_label">Обрано епізоди зі звуком або відео</string>
+ <string name="hide_is_favorite_label">В улюблених</string>
+ <string name="hide_downloaded_episodes_label">Завантажені</string>
+ <string name="hide_not_downloaded_episodes_label">Не завантажені</string>
+ <string name="queued_label">В черзі</string>
+ <string name="not_queued_label">Не в черзі</string>
+ <string name="has_media">Зі звуком або відео</string>
+ <string name="hide_paused_episodes_label">Призупинені</string>
+ <string name="hide_played_episodes_label">Відтворені</string>
<!--Sort-->
<string name="sort_title_a_z">Назва (А \u2192 Я)</string>
<string name="sort_title_z_a">Назва (Я \u2192 А)</string>
@@ -627,6 +602,7 @@
<string name="rating_never_label">Не зараз</string>
<string name="rating_later_label">Нагадати згодом</string>
<string name="rating_now_label">Звичайно, з задоволенням!</string>
+ <!--Share episode dialog-->
<!--Audio controls-->
<string name="audio_controls">Керування звуком</string>
<string name="playback_speed">Швидкість програвання</string>
@@ -673,7 +649,6 @@
<string name="notification_channel_playing">Відтворюється зараз</string>
<string name="notification_channel_playing_description">Дозволяє керувати відтворенням. Це основне сповіщення, яке ви бачите під час відтворення подкасту.</string>
<string name="notification_channel_error">Помилки</string>
- <string name="notification_channel_error_description">Відображається, якщо щось пішло не так, наприклад, якщо не вдалося завантажити або синхронізувати з gpodder.</string>
<!--Widget settings-->
<string name="widget_settings">Налаштування віджету</string>
<string name="widget_create_button">Створити віджет</string>
diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml
index 829f63846..fb74f256c 100644
--- a/core/src/main/res/values-zh-rCN/strings.xml
+++ b/core/src/main/res/values-zh-rCN/strings.xml
@@ -25,17 +25,19 @@
<string name="episode_cache_full_message">已达到曲目缓存限制,可以在设置中提高缓存大小。</string>
<string name="playback_statistics_label">回放</string>
<string name="download_statistics_label">下载</string>
+ <string name="notification_pref_fragment">通知</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">总播放时长:</string>
+ <string name="total_time_listened_to_podcasts">节目总播放时间:</string>
<string name="statistics_details_dialog">听过了总计 %2$d 期播客中的 %1$d 期。\n\n播放了总计 %4$s 中的 %3$s。</string>
<string name="statistics_mode">统计模式</string>
<string name="statistics_mode_normal">计算实际上的播放次数与时长。播放过两次则将被识别为两次,但是被手动标记为已播放状态的不算。</string>
- <string name="statistics_mode_count_all">统计播放次数时仅统计所有带有已播放播客标记的数量</string>
+ <string name="statistics_mode_count_all">计算所有标记为已播放的节目</string>
<string name="statistics_speed_not_counted">注意:播放速度不在考虑范围之内。</string>
<string name="statistics_reset_data">重置统计数据</string>
<string name="statistics_reset_data_msg">这将抹去总播放时间的历史。您确定要进行该操作吗?</string>
+ <string name="statistics_counting_since">自 %s起,\n您播放了</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">已下载播客音频文件的总大小</string>
+ <string name="total_size_downloaded_podcasts">设备上音频节目的总大小:</string>
<!--Main activity-->
<string name="drawer_open">打开菜单</string>
<string name="drawer_close">关闭菜单</string>
@@ -49,6 +51,8 @@
<string name="drawer_feed_counter_unplayed">未播曲目数</string>
<string name="drawer_feed_counter_downloaded">已下载曲目数量</string>
<string name="drawer_feed_counter_none">无</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">没有找到兼容的应用程序</string>
<!--Webview actions-->
<string name="open_in_browser_label">在浏览器打开</string>
<string name="copy_url_label">复制 URL</string>
@@ -122,28 +126,21 @@
<string name="rename_feed_label">重命名播客</string>
<string name="remove_feed_label">移除播客</string>
<string name="share_label">分享</string>
- <string name="share_link_label">分享剧集地址</string>
- <string name="share_link_with_position_label">分享带播放位置的节目地址</string>
+ <string name="share_label_with_ellipses">分享…</string>
<string name="share_file_label">分享文件</string>
- <string name="share_website_url_label">分享网站URL</string>
- <string name="share_feed_url_label">分享播客URL</string>
- <string name="share_item_url_label">分享媒体文件地址</string>
- <string name="share_item_url_with_position_label">分享带播放位置的媒体文件地址</string>
+ <string name="share_website_url_label">网站地址</string>
+ <string name="share_feed_url_label">播客订阅源 URL</string>
<string name="feed_delete_confirmation_msg">请确认您想删除播客“%1$s” 及其所有节目(包括已经下载的)</string>
+ <string name="feed_delete_confirmation_local_msg">请确认你想要移除播客\"%1$s\"。本地源文件夹中的文件不会被删除。</string>
<string name="feed_remover_msg">正在移除播客</string>
<string name="load_complete_feed">刷新所有播客</string>
<string name="multi_select">多选</string>
<string name="select_all_above">选中上面所有</string>
<string name="select_all_below">选中下面所有</string>
<string name="hide_unplayed_episodes_label">未播放</string>
- <string name="hide_paused_episodes_label">已暂停</string>
- <string name="hide_played_episodes_label">已播放</string>
<string name="hide_queued_episodes_label">已在播放列表中</string>
<string name="hide_not_queued_episodes_label">不在播放列表中</string>
- <string name="hide_downloaded_episodes_label">已下载</string>
- <string name="hide_not_downloaded_episodes_label">未下载</string>
<string name="hide_has_media_label">包含媒体文件</string>
- <string name="hide_is_favorite_label">喜爱的</string>
<string name="filtered_label">已过滤的</string>
<string name="refresh_failed_msg">{fa-exclamation-circle} 上次刷新失败</string>
<string name="open_podcast">打开播客</string>
@@ -159,9 +156,6 @@
<string name="delete_label">删除</string>
<string name="delete_failed">无法删除文件。重启可能解决该问题。</string>
<string name="delete_episode_label">删除节目</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="other">已删除%d个节目</item>
- </plurals>
<string name="remove_new_flag_label">移除“新的”标签</string>
<string name="removed_new_flag_label">已移除“新的”标签</string>
<string name="mark_read_label">标记已播放</string>
@@ -228,7 +222,9 @@
</plurals>
<string name="downloads_processing">正在处理下载</string>
<string name="download_notification_title">下载播客数据</string>
- <string name="download_report_content">%1$d 下载成功, %2$d 失败</string>
+ <plurals name="download_report_content">
+ <item quantity="other">%d个下载成功,%d下载失败</item>
+ </plurals>
<string name="download_log_title_unknown">未知标题</string>
<string name="download_type_feed">订阅</string>
<string name="download_type_media">媒体文件</string>
@@ -241,7 +237,8 @@
<string name="confirm_mobile_download_dialog_message">移动数据连接下载已于设置中被关闭。\n\n您要暂时允许下载吗?。<small>\n\n您的决定将会在10分钟后被遗忘。</small></string>
<string name="confirm_mobile_streaming_notification_title">确认使用移动数据播放</string>
<string name="confirm_mobile_streaming_notification_message">通过移动连接播放在设置中未启用。点击以确认您无论如何都要用移动数据来播放</string>
- <string name="confirm_mobile_streaming_button_always">始终允许</string>
+ <string name="confirm_mobile_streaming_button_always">始终</string>
+ <string name="confirm_mobile_streaming_button_once">一次</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">队列</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">暂时允许</string>
<!--Mediaplayer messages-->
@@ -287,8 +284,9 @@
<string name="download_plugin_label">插件下载</string>
<string name="no_playback_plugin_title">插件没有安装</string>
<string name="no_playback_plugin_or_sonic_msg">为了使变速播放正常工作,我们建议启用内置的Sonic媒体播放器</string>
- <string name="set_playback_speed_label">播放速度</string>
<string name="enable_sonic">允许声音</string>
+ <string name="speed_presets">预设定</string>
+ <string name="preset_already_exists">%1$.2fx已被保存为一个预设定。</string>
<!--Empty list labels-->
<string name="no_items_header_label">没有处在播放列表的曲目</string>
<string name="no_items_label">通过下载或者长按一项剧集再选择“添加到播放列表”以添加剧集</string>
@@ -328,7 +326,7 @@
<string name="playback_control">回放控制</string>
<string name="preference_search_hint">搜索</string>
<string name="preference_search_no_results">无结果</string>
- <string name="preference_search_clear_history">清楚历史记录</string>
+ <string name="preference_search_clear_history">清除历史记录</string>
<string name="media_player">媒体播放器</string>
<string name="pref_episode_cleanup_title">清理曲目</string>
<string name="pref_episode_cleanup_summary">如果自动下载需要为新剧集腾出空间时不在列表和收藏里的剧集可以被移除</string>
@@ -361,7 +359,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">每%1$s秒</string>
<string name="pref_autoUpdateIntervallOrTime_at">第%1$s秒</string>
<string name="pref_followQueue_title">连续播放</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">耳机断开</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">耳机或蓝牙断开</string>
<string name="pref_unpauseOnHeadsetReconnect_title">耳机重新连接</string>
<string name="pref_unpauseOnBluetoothReconnect_title">蓝牙重新连接</string>
<string name="pref_stream_over_download_title">偏好在线播放</string>
@@ -374,7 +372,7 @@
<string name="pref_mobileUpdate_episode_download">曲目下载</string>
<string name="pref_mobileUpdate_streaming">播放中</string>
<string name="user_interface_label">界面</string>
- <string name="user_interface_sum">外观、订阅顺序、锁屏</string>
+ <string name="user_interface_sum">外观、订阅、锁屏</string>
<string name="pref_set_theme_title">主题选择</string>
<string name="pref_nav_drawer_items_title">设置侧边栏的选项</string>
<string name="pref_nav_drawer_items_sum">改变侧边栏中的选项</string>
@@ -414,10 +412,9 @@
<string name="pref_gpodnet_full_sync_title">强制完整同步</string>
<string name="pref_gpodnet_full_sync_sum">与gpodder.net同步所有订阅和节目状态</string>
<string name="pref_gpodnet_login_status"><![CDATA[在设备 <i>%2$s</i> 上以 <i>%1$s</i> 身份登录]]></string>
- <string name="pref_gpodnet_notifications_title">显示同步失败的提示信息</string>
+ <string name="pref_gpodnet_notifications_title">同步失败</string>
<string name="pref_gpodnet_notifications_sum">该设置无法适用于验证错误。</string>
- <string name="pref_playback_speed_title">播放速度</string>
- <string name="pref_playback_speed_sum">自定义音频播放速度</string>
+ <string name="pref_playback_speed_sum">自定义可用于变速播放的速度</string>
<string name="pref_feed_playback_speed_sum">开始播放此播客中剧集时使用的速度</string>
<string name="pref_feed_skip">自动跳过</string>
<string name="pref_feed_skip_sum">跳过开头结尾</string>
@@ -437,15 +434,15 @@
<string name="pref_expandNotify_sum">这通常会拓展通知以显示播放按钮。</string>
<string name="pref_persistNotify_title">保持播放控制</string>
<string name="pref_persistNotify_sum">在暂停时保持通知和锁屏界面的控制。</string>
- <string name="pref_compact_notification_buttons_title">设置锁屏按钮</string>
- <string name="pref_compact_notification_buttons_sum">修改锁屏界面上的回放按钮(同样会影响播放/暂停按钮)。</string>
- <string name="pref_compact_notification_buttons_dialog_title">选择%1$d中的最大值</string>
- <string name="pref_compact_notification_buttons_dialog_error">你只能选择%1$d中的最大值</string>
+ <string name="pref_compact_notification_buttons_title">设置紧凑的通知按钮</string>
+ <string name="pref_compact_notification_buttons_sum">当通知被折叠时,更改播放按钮。播放/暂停按钮总是包含在内。</string>
+ <string name="pref_compact_notification_buttons_dialog_title">最多同时选择%1$d项</string>
+ <string name="pref_compact_notification_buttons_dialog_error">你最多只能同时选择%1$d项</string>
<string name="pref_lockscreen_background_title">设置锁屏背景</string>
<string name="pref_lockscreen_background_sum">将锁屏背景设置为当前播放节目的封面图(潜在的副作用是图片可能会在出现在第三方应用中)。</string>
- <string name="pref_showDownloadReport_title">显示下载报告</string>
+ <string name="pref_showDownloadReport_title">下载失败</string>
<string name="pref_showDownloadReport_sum">如果下载失败,生成一份显示详细失败信息的报告。</string>
- <string name="pref_showAutoDownloadReport_title">显示自动下载报告</string>
+ <string name="pref_showAutoDownloadReport_title">自动下载已完成</string>
<string name="pref_showAutoDownloadReport_sum">显示有关自动下载的剧集的通知。</string>
<string name="pref_expand_notify_unsupport_toast">Android 4.1 之前不支持扩展通知。</string>
<string name="pref_enqueue_location_title">排队位置</string>
@@ -470,11 +467,12 @@
<string name="pref_faq">常见问题</string>
<string name="pref_no_browser_found">无网络浏览器</string>
<string name="pref_cast_title">Chromecast 支持</string>
- <string name="pref_cast_message_play_flavor">启用在 Cast 设备(例如 Chromecast 、 Audio Speakers 和 Android TV )上对于远端媒体回放的支持</string>
+ <string name="pref_cast_message_play_flavor">启用投影设备(例如 Chromecast 、 Audio Speakers 和 Android TV )上对于远端媒体回放的支持</string>
<string name="pref_cast_message_free_flavor">Chromecast 所需要的第三方库文件在这个版本的 AntennaPod 中被禁用</string>
<string name="pref_enqueue_downloaded_title">已下载队列</string>
<string name="pref_enqueue_downloaded_summary">向队列添加已下载的节目</string>
<string name="media_player_builtin">内置安卓播放器</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (推荐)</string>
<string name="media_player_switch_to_exoplayer">转到ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">已转至ExoPlayer</string>
<string name="pref_skip_silence_title">跳过没有声音的音频</string>
@@ -495,6 +493,15 @@
<string name="back_button_go_to_page_title">选择页面</string>
<string name="pref_delete_removes_from_queue_title">删除队列间距</string>
<string name="pref_delete_removes_from_queue_sum">剧集被删除时自动将其移除列表</string>
+ <string name="pref_filter_feed_title">订阅过滤器</string>
+ <string name="pref_filter_feed_sum">在导航抽屉和订阅屏幕中筛选订阅。</string>
+ <string name="no_filter_label">没有</string>
+ <string name="subscriptions_are_filtered">订阅已过滤</string>
+ <string name="subscriptions_counter_greater_zero">仅显示有计数的订阅</string>
+ <string name="auto_downloaded">自动下载的</string>
+ <string name="not_auto_downloaded">非自动下载的</string>
+ <string name="kept_updated">保持更新的</string>
+ <string name="not_kept_updated">未保持更新的</string>
<!--About screen-->
<string name="about_pref">关于</string>
<string name="antennapod_version">AntennaPod版本</string>
@@ -529,6 +536,7 @@
<string name="database_export_summary">将订阅,听过的剧集和队列转移到另一台设备上的AntennaPod</string>
<string name="database_import_summary">从另一台设备导入AntennaPod数据库 </string>
<string name="opml_import_label">OPML 导入</string>
+ <string name="opml_add_podcast_label">导入播客列表 (OPML)</string>
<string name="opml_reader_error">读取 OPML 文档时发生错误</string>
<string name="opml_import_error_no_file">没有选择文件!</string>
<string name="select_all_label">全选</string>
@@ -544,7 +552,8 @@
<string name="export_success_sum">导出文件被写入:\n\n %1$s</string>
<string name="opml_import_ask_read_permission">读取 OPML 文件需要访问外部存储的权限</string>
<string name="import_select_file">选择导入文件</string>
- <string name="import_ok">成功导入,请按OK重启AntennaPod</string>
+ <string name="successful_import_label">导入成功</string>
+ <string name="import_ok">请按\"确定\"重新启动AntennaPod</string>
<string name="import_no_downgrade">该数据库是使用较新版本的AntennaPod导出的。您当前安装的版本尚不知如何处理该文件。</string>
<string name="favorites_export_label">收藏导出</string>
<string name="favorites_export_summary">将保存的收藏夹导出到文件</string>
@@ -636,7 +645,6 @@
<string name="decrease_speed">放慢速度</string>
<string name="media_type_audio_label">音频</string>
<string name="media_type_video_label">视频</string>
- <string name="navigate_upwards_label">向上导航</string>
<string name="status_downloading_label">曲目正在下载</string>
<string name="in_queue_label">曲目已经在播放列表中</string>
<string name="is_favorite_label">节目被标记为收藏</string>
@@ -657,6 +665,10 @@
<string name="keep_updated">保持最新</string>
<string name="keep_updated_summary">(自动)刷新所有播客时包括此播客 </string>
<string name="auto_download_disabled_globally">AntennaPod主设置中已禁用自动下载</string>
+ <string name="statistics_listened_for">已听了:</string>
+ <string name="statistics_episodes_on_device">设备上的节目:</string>
+ <string name="statistics_space_used">占用的空间: </string>
+ <string name="statistics_view_all">所有播客视图 »</string>
<!--Progress information-->
<string name="progress_upgrading_database">升级数据库</string>
<!--AntennaPodSP-->
@@ -664,18 +676,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">搜索播客……</string>
<string name="search_itunes_label">搜索 iTunes</string>
+ <string name="search_podcastindex_label">搜索 Podcastindex.org</string>
<string name="search_fyyd_label">搜索 fyyd</string>
<string name="advanced">高级</string>
- <string name="add_podcast_by_url">通过URL添加播客</string>
+ <string name="add_podcast_by_url">通过 RSS 地址添加播客</string>
<string name="browse_gpoddernet_label">浏览 gpodder.net</string>
<string name="discover">发现</string>
+ <string name="discover_hide">隐藏</string>
+ <string name="discover_is_hidden">您选择了隐藏建议</string>
<string name="discover_more">更多</string>
- <string name="search_powered_by">搜索由%1$s驱动</string>
+ <string name="discover_powered_by_itunes">iTunes 建议</string>
+ <string name="search_powered_by">按 %1$s 显示结果</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">添加本地文件夹</string>
+ <string name="local_folder">本地文件夹</string>
+ <string name="reconnect_local_folder">重新连接本地文件夹</string>
+ <string name="reconnect_local_folder_warning">在权限遭拒的情况下,您可以使用它重新连接到完全相同的文件夹。不要选择其他文件夹。</string>
+ <string name="local_feed_description">这个虚拟播客是通过向AntennaPod添加一个文件夹创建的</string>
+ <string name="unable_to_start_system_file_manager">无法启动系统文件管理器</string>
<string name="filter">过滤器</string>
<!--Episodes apply actions-->
<string name="all_label">全部</string>
<string name="selected_all_label">全选</string>
- <string name="none_label">无</string>
+ <string name="select_none_label">没有</string>
<string name="deselected_all_label">取消全选</string>
<string name="played_label">已播放</string>
<string name="selected_played_label">选择已播放的曲目</string>
@@ -685,12 +708,21 @@
<string name="selected_downloaded_label">选择已下载的曲目</string>
<string name="not_downloaded_label">未下载</string>
<string name="selected_not_downloaded_label">选择未下载的曲目</string>
- <string name="queued_label">已在播放列表中</string>
<string name="selected_queued_label">已选曲目</string>
- <string name="not_queued_label">不在播放列表中</string>
<string name="selected_not_queued_label">选择不在播放列表的曲目</string>
- <string name="has_media">包含媒体</string>
<string name="selected_has_media_label">已选中含媒体的节目</string>
+ <string name="hide_is_favorite_label">喜爱的</string>
+ <string name="not_favorite">非喜爱的节目</string>
+ <string name="hide_downloaded_episodes_label">已下载</string>
+ <string name="hide_not_downloaded_episodes_label">未下载</string>
+ <string name="queued_label">已在播放列表中</string>
+ <string name="not_queued_label">不在播放列表中</string>
+ <string name="has_media">包含媒体</string>
+ <string name="no_media">没有媒体</string>
+ <string name="hide_paused_episodes_label">已暂停</string>
+ <string name="not_paused">未暂停</string>
+ <string name="hide_played_episodes_label">已播放</string>
+ <string name="not_played">未播放</string>
<!--Sort-->
<string name="sort_title_a_z">标题 (A \u2192 Z)</string>
<string name="sort_title_z_a">标题 (Z \u2192 A)</string>
@@ -710,6 +742,12 @@
<string name="rating_never_label">请勿打扰</string>
<string name="rating_later_label">稍后提醒</string>
<string name="rating_now_label">好的, 就这样!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">包含:</string>
+ <string name="share_playback_position_dialog_label">播放位置</string>
+ <string name="share_dialog_media_file_url_label">媒体文件地址</string>
+ <string name="share_dialog_episode_website_label">节目网页</string>
+ <string name="share_dialog_media_file_label">媒体文件</string>
<!--Audio controls-->
<string name="audio_controls">音频控制</string>
<string name="playback_speed">播放速度</string>
@@ -756,7 +794,9 @@
<string name="notification_channel_playing">当前播放</string>
<string name="notification_channel_playing_description">允许控制回放。这是播放播客时您所见的主通知。</string>
<string name="notification_channel_error">错误</string>
- <string name="notification_channel_error_description">发生错误时显示,比如下载或与gpodder的同步失败</string>
+ <string name="notification_channel_error_description">出错时显示,比如下载或订阅源更新失败。</string>
+ <string name="notification_channel_sync_error">同步错误</string>
+ <string name="notification_channel_sync_error_description">gpodder 同步出错时显示</string>
<string name="notification_channel_auto_download">自动下载</string>
<string name="notification_channel_episode_auto_download">当节目已自动下载时显示。</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values-zh-rTW/strings.xml b/core/src/main/res/values-zh-rTW/strings.xml
index c432cab3e..2e3dacecc 100644
--- a/core/src/main/res/values-zh-rTW/strings.xml
+++ b/core/src/main/res/values-zh-rTW/strings.xml
@@ -20,22 +20,24 @@
<string name="cancel_download_label">取消下載</string>
<string name="playback_history_label">播放歷史</string>
<string name="gpodnet_main_label">gpodder.net</string>
- <string name="gpodnet_auth_label">gpodder.net 登錄</string>
+ <string name="gpodnet_auth_label">登入 gpodder.net</string>
<string name="episode_cache_full_title">暫存集數已達上限</string>
<string name="episode_cache_full_message">暫存集數已達上限,您可以在設定中調整限制。</string>
<string name="playback_statistics_label">播放</string>
<string name="download_statistics_label">下載</string>
+ <string name="notification_pref_fragment">通知</string>
<!--Statistics fragment-->
- <string name="total_time_listened_to_podcasts">Podcast 總播放時長:</string>
+ <string name="total_time_listened_to_podcasts">總播放時長:</string>
<string name="statistics_details_dialog">聽過 %1$d/%2$d集。\n\n播過%3$s/%4$s集。</string>
<string name="statistics_mode">統計模式</string>
<string name="statistics_mode_normal">計算真實的播放時長。如果播放同一劇集兩遍,則會記錄兩遍的時間;如果只是標記為已播放,則不會被計入播放時長</string>
- <string name="statistics_mode_count_all">累加所有標記為已播放的 Podcast</string>
- <string name="statistics_speed_not_counted">注意:播放速度不被計入。</string>
+ <string name="statistics_mode_count_all">累加所有標記為已播放的單集</string>
+ <string name="statistics_speed_not_counted">注意:此統計不考慮播放速度影響</string>
<string name="statistics_reset_data">重設統計數據</string>
<string name="statistics_reset_data_msg">這會清除過去的播放紀錄,您確定要進行嗎?</string>
+ <string name="statistics_counting_since">自 %s 起,\n您播放了</string>
<!--Download Statistics fragment-->
- <string name="total_size_downloaded_podcasts">Podcast 總下載容量:</string>
+ <string name="total_size_downloaded_podcasts">裝置上所有單集佔用的容量:</string>
<!--Main activity-->
<string name="drawer_open">打開選單</string>
<string name="drawer_close">關閉選單</string>
@@ -49,11 +51,13 @@
<string name="drawer_feed_counter_unplayed">未播放集數</string>
<string name="drawer_feed_counter_downloaded">已下載集數</string>
<string name="drawer_feed_counter_none">沒有</string>
+ <!--Bug report activity-->
+ <string name="log_file_share_exception">找不到相容的 App</string>
<!--Webview actions-->
<string name="open_in_browser_label">在瀏覽器中打開</string>
- <string name="copy_url_label">複製鏈接</string>
- <string name="share_url_label">分析鏈接</string>
- <string name="copied_url_msg">複製鏈接到剪貼板</string>
+ <string name="copy_url_label">複製網址</string>
+ <string name="share_url_label">分析網址</string>
+ <string name="copied_url_msg">複製網址到剪貼簿</string>
<string name="go_to_position_label">跳至此處</string>
<!--Playback history-->
<string name="clear_history_label">清除歷史</string>
@@ -65,7 +69,7 @@
<string name="reset">重置</string>
<string name="author_label">作者</string>
<string name="language_label">語言</string>
- <string name="url_label">鏈接</string>
+ <string name="url_label">網址</string>
<string name="cover_label">圖片</string>
<string name="error_label">錯誤</string>
<string name="error_msg_prefix">發生錯誤:</string>
@@ -89,7 +93,7 @@
<string name="feed_volume_reduction_off">關閉</string>
<string name="feed_volume_reduction_light">輕</string>
<string name="feed_volume_reduction_heavy">重</string>
- <string name="parallel_downloads_suffix">目前設定可同步下載 \u0020 集</string>
+ <string name="parallel_downloads_suffix">\u0020項同步下載</string>
<string name="feed_auto_download_global">預設值</string>
<string name="feed_auto_download_always">總是</string>
<string name="feed_auto_download_never">不予下載</string>
@@ -122,30 +126,23 @@
<string name="rename_feed_label">重新命名 Podcast</string>
<string name="remove_feed_label">移除 Podcast</string>
<string name="share_label">分享</string>
- <string name="share_link_label">分享這一集的網址</string>
- <string name="share_link_with_position_label">分享這一集網址及當前播放進度</string>
+ <string name="share_label_with_ellipses">分享…</string>
<string name="share_file_label">分享文件</string>
- <string name="share_website_url_label">分享網站網址</string>
- <string name="share_feed_url_label">分享 Podcast 的網址</string>
- <string name="share_item_url_label">分享該媒體網址</string>
- <string name="share_item_url_with_position_label">分享此媒體網址及當前播放進度</string>
+ <string name="share_website_url_label">網站網址</string>
+ <string name="share_feed_url_label">Podcast 來源網址</string>
<string name="feed_delete_confirmation_msg">請確認您是否要刪除「%1$s」這個 Podcast 及當中下載的每一集。</string>
+ <string name="feed_delete_confirmation_local_msg">您確定要刪除「%1$s」嗎?目前下載過的檔案將不會刪除。</string>
<string name="feed_remover_msg">移除 Podcast</string>
<string name="load_complete_feed">重新整理 Podcast</string>
<string name="multi_select">多重選取</string>
<string name="select_all_above">選取以上全部</string>
<string name="select_all_below">選取以下全部</string>
<string name="hide_unplayed_episodes_label">未播放</string>
- <string name="hide_paused_episodes_label">暫停</string>
- <string name="hide_played_episodes_label">已播放</string>
<string name="hide_queued_episodes_label">已列入待播清單</string>
<string name="hide_not_queued_episodes_label">未列入待播清單</string>
- <string name="hide_downloaded_episodes_label">已下載</string>
- <string name="hide_not_downloaded_episodes_label">未下載</string>
<string name="hide_has_media_label">包含媒體</string>
- <string name="hide_is_favorite_label">為最愛</string>
<string name="filtered_label">已過濾</string>
- <string name="refresh_failed_msg">{fa-exclamation-circle} 上次刷新失敗</string>
+ <string name="refresh_failed_msg">{fa-exclamation-circle} 更新失敗</string>
<string name="open_podcast">打開 Podcast</string>
<string name="please_wait_for_data">資料載入中,請稍候</string>
<!--actions on feeditems-->
@@ -159,9 +156,6 @@
<string name="delete_label">刪除</string>
<string name="delete_failed">刪除文件失敗。重啟設備試試看。</string>
<string name="delete_episode_label">刪除這一集</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="other">已刪除 %d 集。</item>
- </plurals>
<string name="remove_new_flag_label">移除「新」的標記</string>
<string name="removed_new_flag_label">已移除「新」的標記</string>
<string name="mark_read_label">標記為已播放</string>
@@ -202,24 +196,24 @@
<string name="download_pending">下載等待中</string>
<string name="download_running">下載中</string>
<string name="download_error_details">詳情</string>
- <string name="download_error_details_message">%1$s \n\n檔案 URL:\n%2$s</string>
+ <string name="download_error_details_message">%1$s \n\n檔案網址:\n%2$s</string>
<string name="download_error_device_not_found">沒找到儲存空間</string>
<string name="download_error_insufficient_space">儲存空間不足</string>
- <string name="download_error_http_data_error">HTTP數據錯誤</string>
+ <string name="download_error_http_data_error">HTTP 資料有誤</string>
<string name="download_error_error_unknown">位置錯誤</string>
<string name="download_error_parser_exception">解析器異常</string>
<string name="download_error_unsupported_type">不支援此來源類型</string>
- <string name="download_error_connection_error">鏈接錯誤</string>
+ <string name="download_error_connection_error">連接錯誤</string>
<string name="download_error_unknown_host">不明主機</string>
<string name="download_error_unauthorized">驗證失敗</string>
<string name="download_error_file_type_type">文件格式錯誤</string>
<string name="download_error_forbidden">禁止存取</string>
<string name="download_canceled_msg">下載已取消</string>
- <string name="download_canceled_autodownload_enabled_msg">下載已取消\n此項目的 <i>自動下載</i> 已停用</string>
+ <string name="download_canceled_autodownload_enabled_msg">下載已取消\n這一項的 <i>自動下載</i> 已停用</string>
<string name="download_report_title">下載已完成,但可能有錯誤</string>
<string name="auto_download_report_title">自動下載完畢</string>
<string name="download_report_content_title">下載報告</string>
- <string name="download_error_malformed_url">鏈接格式不正確</string>
+ <string name="download_error_malformed_url">網址格式不正確</string>
<string name="download_error_io_error">IO 錯誤</string>
<string name="download_error_request_error">請求錯誤</string>
<string name="download_error_db_access">資料庫存取錯誤</string>
@@ -228,7 +222,9 @@
</plurals>
<string name="downloads_processing">正在下載</string>
<string name="download_notification_title">Podcast 資料下載中</string>
- <string name="download_report_content">%1$d 個成功下載, %2$d 個失敗</string>
+ <plurals name="download_report_content">
+ <item quantity="other">成功下載 %d 個單集,失敗 %d 個</item>
+ </plurals>
<string name="download_log_title_unknown">標題不明</string>
<string name="download_type_feed">資料來源</string>
<string name="download_type_media">媒體檔案</string>
@@ -242,15 +238,16 @@
<string name="confirm_mobile_streaming_notification_title">確認以行動網路串流播放</string>
<string name="confirm_mobile_streaming_notification_message">目前您設定為不可使用行動網路串流播放,輕觸後可強制以串流播放。</string>
<string name="confirm_mobile_streaming_button_always">永遠允許</string>
+ <string name="confirm_mobile_streaming_button_once">允許一次</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">列入待播清單</string>
- <string name="confirm_mobile_download_dialog_enable_temporarily">臨時允許</string>
+ <string name="confirm_mobile_download_dialog_enable_temporarily">暫時允許</string>
<!--Mediaplayer messages-->
<string name="player_error_msg">錯誤!</string>
<string name="player_stopped_msg">播放完畢</string>
<string name="player_preparing_msg">準備中</string>
<string name="player_ready_msg">準備</string>
<string name="player_seeking_msg">搜索中</string>
- <string name="playback_error_server_died">服務器未響應</string>
+ <string name="playback_error_server_died">主機未回應</string>
<string name="playback_error_unsupported">不支援的媒體格式</string>
<string name="playback_error_timeout">操作逾時</string>
<string name="playback_error_source">無法取得該媒體檔案</string>
@@ -269,8 +266,8 @@
<string name="checkbox_do_not_show_again">不再顯示</string>
<string name="clear_queue_label">清空待播清單</string>
<string name="undo">返回</string>
- <string name="move_to_top_label">移動到頂部</string>
- <string name="move_to_bottom_label">移動的底部</string>
+ <string name="move_to_top_label">移到最前</string>
+ <string name="move_to_bottom_label">移到最後</string>
<string name="sort">排序</string>
<string name="keep_sorted">維持排序</string>
<string name="date">日期</string>
@@ -287,8 +284,9 @@
<string name="download_plugin_label">已下載的插件</string>
<string name="no_playback_plugin_title">插件未安裝</string>
<string name="no_playback_plugin_or_sonic_msg">為了方便您以不同速度聆聽節目,我們建議您啟用內建的 Sonic 播放器。</string>
- <string name="set_playback_speed_label">播放速度</string>
- <string name="enable_sonic">啟用Sonic</string>
+ <string name="enable_sonic">啟用 Sonic</string>
+ <string name="speed_presets">備選清單</string>
+ <string name="preset_already_exists">目前備選清單裡已有 %1$.2fx </string>
<!--Empty list labels-->
<string name="no_items_header_label">待播清單裡沒有任何單集</string>
<string name="no_items_label">下載或長按後選擇「加入待播清單」即可將這一集放入待播清單。</string>
@@ -361,7 +359,7 @@
<string name="pref_autoUpdateIntervallOrTime_every">每 %1$s</string>
<string name="pref_autoUpdateIntervallOrTime_at">於 %1$s</string>
<string name="pref_followQueue_title">連續播放</string>
- <string name="pref_pauseOnHeadsetDisconnect_title">拔除耳機時暫停播放</string>
+ <string name="pref_pauseOnHeadsetDisconnect_title">耳機或藍牙裝置拔除時</string>
<string name="pref_unpauseOnHeadsetReconnect_title">接上耳機時繼續播放</string>
<string name="pref_unpauseOnBluetoothReconnect_title">連上藍牙時繼續播放</string>
<string name="pref_stream_over_download_title">偏好串流</string>
@@ -374,7 +372,7 @@
<string name="pref_mobileUpdate_episode_download">下載單集</string>
<string name="pref_mobileUpdate_streaming">串流播放</string>
<string name="user_interface_label">使用者介面</string>
- <string name="user_interface_sum">外觀、訂閱排序、鎖定畫面</string>
+ <string name="user_interface_sum">外觀、訂閱、鎖定畫面</string>
<string name="pref_set_theme_title">選擇主題</string>
<string name="pref_nav_drawer_items_title">設定側邊選單</string>
<string name="pref_nav_drawer_items_sum">調整側邊選單裡要顯示的項目</string>
@@ -413,9 +411,8 @@
<string name="pref_gpodnet_full_sync_title">強制全部同步</string>
<string name="pref_gpodnet_full_sync_sum">與 gpodder.net 同步所有的訂閱及聆聽狀態。</string>
<string name="pref_gpodnet_login_status"><![CDATA[以 <i>%1$s</i> 登入,設備為 <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">顯示同步錯誤通知</string>
+ <string name="pref_gpodnet_notifications_title">同步失敗</string>
<string name="pref_gpodnet_notifications_sum">此設定不影響登入驗證錯誤。</string>
- <string name="pref_playback_speed_title">播放速度</string>
<string name="pref_playback_speed_sum">自訂可選用的播放速度</string>
<string name="pref_feed_playback_speed_sum">播放此 Podcast 中各單集時的播放速度</string>
<string name="pref_feed_skip">自動跳過</string>
@@ -436,15 +433,15 @@
<string name="pref_expandNotify_sum">此功能通常會加大通知訊息以便顯示控制鈕</string>
<string name="pref_persistNotify_title">保留播放控制鈕</string>
<string name="pref_persistNotify_sum">暫停播放時,在通知列及鎖定畫面上保留播放控制鈕</string>
- <string name="pref_compact_notification_buttons_title">設定鎖定畫面按鈕</string>
- <string name="pref_compact_notification_buttons_sum">設定鎖定畫面上的播放控制鈕。「暫停/播放」鈕一定會出現</string>
+ <string name="pref_compact_notification_buttons_title">設定精簡通知按鈕</string>
+ <string name="pref_compact_notification_buttons_sum">設定精簡通知訊息上的播放控制鈕。「暫停/播放」鈕一定會出現</string>
<string name="pref_compact_notification_buttons_dialog_title">最多可選擇 %1$d 項</string>
<string name="pref_compact_notification_buttons_dialog_error">您最多只能選擇 %1$d 項。</string>
<string name="pref_lockscreen_background_title">設定鎖定畫面背景</string>
<string name="pref_lockscreen_background_sum">在鎖定畫面背景採用本單集的圖片,同時也會在第三方 App 裡顯示圖片</string>
- <string name="pref_showDownloadReport_title">顯示下載報告</string>
+ <string name="pref_showDownloadReport_title">下載失敗</string>
<string name="pref_showDownloadReport_sum">如果下載失敗,產生錯誤相關細節的報告</string>
- <string name="pref_showAutoDownloadReport_title">顯示自動下載報告</string>
+ <string name="pref_showAutoDownloadReport_title">自動下載完畢</string>
<string name="pref_showAutoDownloadReport_sum">顯示自動下載通知</string>
<string name="pref_expand_notify_unsupport_toast">Android 4.1 以前尚未支援延伸通知工具。</string>
<string name="pref_enqueue_location_title">待播清單新增位置</string>
@@ -474,6 +471,7 @@
<string name="pref_enqueue_downloaded_title">下載後加入待播清單</string>
<string name="pref_enqueue_downloaded_summary">下載單集以後自動加入待播清單</string>
<string name="media_player_builtin">Android 內建播放器</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer(推薦使用)</string>
<string name="media_player_switch_to_exoplayer">切換至 ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">已切換至 ExoPlayer</string>
<string name="pref_skip_silence_title">跳過沒有聲音的部分</string>
@@ -494,6 +492,15 @@
<string name="back_button_go_to_page_title">選擇頁面</string>
<string name="pref_delete_removes_from_queue_title">刪除時同步自待播清單中移除</string>
<string name="pref_delete_removes_from_queue_sum">刪除某單集後,也自動將其從待播清單中移除</string>
+ <string name="pref_filter_feed_title">篩選訂閱內容</string>
+ <string name="pref_filter_feed_sum">篩選側邊選單及訂閱畫面中顯示的訂閱清單</string>
+ <string name="no_filter_label">無</string>
+ <string name="subscriptions_are_filtered">此為篩選過的訂閱清單。</string>
+ <string name="subscriptions_counter_greater_zero">計數大於 0 的</string>
+ <string name="auto_downloaded">已自動下載</string>
+ <string name="not_auto_downloaded">未自動下載</string>
+ <string name="kept_updated">已設定維持更新</string>
+ <string name="not_kept_updated">未設定維持更新</string>
<!--About screen-->
<string name="about_pref">關於</string>
<string name="antennapod_version">AntennaPod 版本</string>
@@ -528,6 +535,7 @@
<string name="database_export_summary">將訂閱、聆聽紀錄、待播清單等資訊傳送到其他設備上的 AntennaPod</string>
<string name="database_import_summary">自其他設備匯入 AntennaPod 資料庫</string>
<string name="opml_import_label">OPML 匯入</string>
+ <string name="opml_add_podcast_label">自 OPML 匯入 Podcast 清單</string>
<string name="opml_reader_error">讀取 OPML 時發生錯誤:</string>
<string name="opml_import_error_no_file">未選擇任何檔案!</string>
<string name="select_all_label">全選</string>
@@ -543,7 +551,8 @@
<string name="export_success_sum">檔案已匯出至:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">讀取 OPML 檔需要存取外部儲存空間的權限</string>
<string name="import_select_file">選取要匯入的檔案</string>
- <string name="import_ok">匯入成功。\n\n請按下 OK 重新啟動 AntennaPod</string>
+ <string name="successful_import_label">匯入完畢</string>
+ <string name="import_ok">請按下 OK 重新啟動 AntennaPod</string>
<string name="import_no_downgrade">此資料庫是以新版 AntennaPod 匯出的,您目前使用的版本無法使用這份資料。</string>
<string name="favorites_export_label">匯出我的最愛</string>
<string name="favorites_export_summary">將儲存的我的最愛清單匯出為檔案</string>
@@ -579,11 +588,11 @@
<string name="gpodnetauth_login_register">如果您還沒有帳號,可以先註冊一個:\nhttps://gpodder.net/register/</string>
<string name="username_label">帳號</string>
<string name="password_label">密碼</string>
- <string name="gpodnetauth_device_title">裝置選擇</string>
+ <string name="gpodnetauth_device_title">選擇裝置</string>
<string name="gpodnetauth_device_descr">為您的 gpodder.net 帳號建立新設備或選取既有設備:</string>
<string name="gpodnetauth_device_deviceID">設備代號:\u0020</string>
<string name="gpodnetauth_device_caption">標題</string>
- <string name="gpodnetauth_device_butCreateNewDevice">新增新裝置</string>
+ <string name="gpodnetauth_device_butCreateNewDevice">新增裝置</string>
<string name="gpodnetauth_device_chooseExistingDevice">選擇現存裝置:</string>
<string name="gpodnetauth_device_errorEmpty">設備代號不能留白</string>
<string name="gpodnetauth_device_errorAlreadyUsed">已經使用此設備代號</string>
@@ -615,7 +624,7 @@
<string name="folder_does_not_exist_error">找不到「%1$s」</string>
<string name="folder_not_readable_error">無法讀取「%1$s」</string>
<string name="folder_not_writable_error">無法寫入「%1$s」</string>
- <string name="folder_not_empty_dialog_title">資料夾並非空白</string>
+ <string name="folder_not_empty_dialog_title">資料夾裡已有檔案</string>
<string name="folder_not_empty_dialog_msg">您所選的資料夾裡已經存在其他檔案,AntennaPod 下載的媒體及其他檔案將直接放進此資料夾裡,確定要繼續嗎?</string>
<string name="set_to_default_folder">選擇預設資料夾</string>
<string name="pref_pausePlaybackForFocusLoss_sum">有其他 App 也要播放聲音時,停止播放 Podcast(而非降低音量)</string>
@@ -635,7 +644,6 @@
<string name="decrease_speed">放慢</string>
<string name="media_type_audio_label">聲音</string>
<string name="media_type_video_label">影片</string>
- <string name="navigate_upwards_label">Navigate upwards</string>
<string name="status_downloading_label">正在下載這集</string>
<string name="in_queue_label">單集已在待播清單中</string>
<string name="is_favorite_label">已將此單集標為最愛</string>
@@ -656,6 +664,10 @@
<string name="keep_updated">維持更新</string>
<string name="keep_updated_summary">自動更新所有 Podcast 時,也包括此 Podcast</string>
<string name="auto_download_disabled_globally">AntennaPod 的主設定中已停用自動下載功能</string>
+ <string name="statistics_listened_for">聆聽時間:</string>
+ <string name="statistics_episodes_on_device">裝置上的單集:</string>
+ <string name="statistics_space_used">佔用空間:</string>
+ <string name="statistics_view_all">檢視所有 Podcast »</string>
<!--Progress information-->
<string name="progress_upgrading_database">更新資料庫</string>
<!--AntennaPodSP-->
@@ -663,18 +675,29 @@
<!--Add podcast fragment-->
<string name="search_podcast_hint">搜尋 Podcast…</string>
<string name="search_itunes_label">搜尋 iTunes</string>
+ <string name="search_podcastindex_label">搜尋 Podcastindex.org</string>
<string name="search_fyyd_label">搜尋 fyyd</string>
<string name="advanced">進階</string>
- <string name="add_podcast_by_url">以 URL 新增 Podcast</string>
- <string name="browse_gpoddernet_label">瀏覽gpodder.net</string>
+ <string name="add_podcast_by_url">以 RSS 網址新增 Podcast</string>
+ <string name="browse_gpoddernet_label">瀏覽 gpodder.net</string>
<string name="discover">探索</string>
+ <string name="discover_hide">隱藏</string>
+ <string name="discover_is_hidden">您已隱藏推薦項目。</string>
<string name="discover_more">更多 »</string>
- <string name="search_powered_by">搜尋內容來自 %1$s</string>
+ <string name="discover_powered_by_itunes">由 iTunes 提供的建議</string>
+ <string name="search_powered_by">來自 %1$s 的搜尋結果</string>
+ <!--Local feeds-->
+ <string name="add_local_folder">新增本機資料夾</string>
+ <string name="local_folder">本機資料夾</string>
+ <string name="reconnect_local_folder">重新連接本機資料夾</string>
+ <string name="reconnect_local_folder_warning">若因權限問題被拒絕連接,您可以用此方法重新連上同一個資料夾。此時請勿選擇其他的資料夾。</string>
+ <string name="local_feed_description">此虛擬 Podcast 是在 AntennaPod 裡增加資料夾而產生的。</string>
+ <string name="unable_to_start_system_file_manager">無法啟用系統的檔案管理工具</string>
<string name="filter">篩選</string>
<!--Episodes apply actions-->
<string name="all_label">全部</string>
<string name="selected_all_label">全選</string>
- <string name="none_label">無</string>
+ <string name="select_none_label">不選</string>
<string name="deselected_all_label">不選</string>
<string name="played_label">播過的</string>
<string name="selected_played_label">選擇播放過的單集</string>
@@ -684,12 +707,21 @@
<string name="selected_downloaded_label">選擇下載過的單集</string>
<string name="not_downloaded_label">未下載的</string>
<string name="selected_not_downloaded_label">選擇沒下載過的單集</string>
- <string name="queued_label">已列入待播清單</string>
<string name="selected_queued_label">選擇待播清單中的單集</string>
- <string name="not_queued_label">未列入待播清單</string>
<string name="selected_not_queued_label">選擇不在待播清單中的單集</string>
- <string name="has_media">有額外媒體檔</string>
<string name="selected_has_media_label">選擇包含額外媒體的單集</string>
+ <string name="hide_is_favorite_label">為最愛</string>
+ <string name="not_favorite">未標記為最愛的</string>
+ <string name="hide_downloaded_episodes_label">已下載</string>
+ <string name="hide_not_downloaded_episodes_label">未下載</string>
+ <string name="queued_label">已列入待播清單</string>
+ <string name="not_queued_label">未列入待播清單</string>
+ <string name="has_media">有額外媒體檔</string>
+ <string name="no_media">無媒體的</string>
+ <string name="hide_paused_episodes_label">暫停</string>
+ <string name="not_paused">未暫停播放的</string>
+ <string name="hide_played_episodes_label">已播放</string>
+ <string name="not_played">未播放過的</string>
<!--Sort-->
<string name="sort_title_a_z">標題 (A \u2192 Z)</string>
<string name="sort_title_z_a">標題 (Z \u2192 A)</string>
@@ -709,6 +741,12 @@
<string name="rating_never_label">別吵我</string>
<string name="rating_later_label">以後再說</string>
<string name="rating_now_label">好啊,這就去!</string>
+ <!--Share episode dialog-->
+ <string name="share_dialog_include_label">包括:</string>
+ <string name="share_playback_position_dialog_label">播放進度</string>
+ <string name="share_dialog_media_file_url_label">媒體檔網址</string>
+ <string name="share_dialog_episode_website_label">此單集的網頁</string>
+ <string name="share_dialog_media_file_label">媒體檔案</string>
<!--Audio controls-->
<string name="audio_controls">聲音控制</string>
<string name="playback_speed">播放速度</string>
@@ -755,7 +793,9 @@
<string name="notification_channel_playing">現正播放</string>
<string name="notification_channel_playing_description">允許播放控制。這是您在播放 Podcast 時會看到的主要通知。</string>
<string name="notification_channel_error">錯誤通知</string>
- <string name="notification_channel_error_description">如果有任何錯誤(比方說下載或 gpodder 同步出錯)時顯示</string>
+ <string name="notification_channel_error_description">如果有任何錯誤(比方說下載或更新來源出錯)時顯示</string>
+ <string name="notification_channel_sync_error">同步時發生錯誤</string>
+ <string name="notification_channel_sync_error_description">在 gpodder 同步發生錯誤時顯示</string>
<string name="notification_channel_auto_download">自動下載</string>
<string name="notification_channel_episode_auto_download">自動下載後顯示</string>
<!--Widget settings-->
diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml
index 13ff092b0..1ab44d847 100644
--- a/core/src/main/res/values/arrays.xml
+++ b/core/src/main/res/values/arrays.xml
@@ -236,7 +236,7 @@
<string-array name="media_player_options">
<item>@string/media_player_builtin</item>
<item>@string/media_player_sonic</item>
- <item>@string/media_player_exoplayer</item>
+ <item>@string/media_player_exoplayer_recommended</item>
</string-array>
<string-array name="media_player_values">
diff --git a/core/src/main/res/values/attrs.xml b/core/src/main/res/values/attrs.xml
index a78f837bf..a6879b006 100644
--- a/core/src/main/res/values/attrs.xml
+++ b/core/src/main/res/values/attrs.xml
@@ -7,6 +7,7 @@
<attr name="av_fast_forward" format="reference"/>
<attr name="av_pause" format="reference"/>
<attr name="av_play" format="reference"/>
+ <attr name="av_replay" format="reference"/>
<attr name="av_skip" format="reference"/>
<attr name="av_rewind" format="reference"/>
<attr name="ic_delete" format="reference"/>
@@ -58,9 +59,10 @@
<attr name="action_icon_color" format="color"/>
<attr name="scrollbar_thumb" format="reference"/>
<attr name="background_elevated" format="color"/>
- <attr name="filter_dialog_clear" format="reference"/>
+ <attr name="filter_dialog_clear" format="color"/>
<attr name="filter_dialog_button_background" format="reference"/>
<attr name="ic_notifications" format="reference"/>
+ <attr name="ic_share" format="reference"/>
<declare-styleable name="SquareImageView">
<attr name="direction" format="enum">
diff --git a/core/src/main/res/values/colors.xml b/core/src/main/res/values/colors.xml
index d09f53d64..feee88bb4 100644
--- a/core/src/main/res/values/colors.xml
+++ b/core/src/main/res/values/colors.xml
@@ -5,6 +5,7 @@
<color name="grey100">#f5f5f5</color>
<color name="grey600">#757575</color>
<color name="light_gray">#bfbfbf</color>
+ <color name="medium_gray">#afafaf</color>
<color name="black">#000000</color>
<color name="download_success_green">#248800</color>
<color name="download_failed_red">#B00020</color>
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 5ad8ec5e9..0c87394b4 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -4,8 +4,8 @@
tools:ignore="MissingTranslation">
<!-- Activity and fragment titles -->
- <string name="app_name" translate="false">AntennaPod</string>
- <string name="provider_authority" translate="false">de.danoeh.antennapod.provider</string>
+ <string name="app_name" translatable="false">AntennaPod</string>
+ <string name="provider_authority" translatable="false">de.danoeh.antennapod.provider</string>
<string name="feed_update_receiver_name">Update Subscriptions</string>
<string name="feeds_label">Podcasts</string>
<string name="statistics_label">Statistics</string>
@@ -22,7 +22,7 @@
<string name="downloads_log_label">Log</string>
<string name="subscriptions_label">Subscriptions</string>
<string name="subscriptions_list_label">Subscriptions List</string>
- <string name="cancel_download_label">Cancel\nDownload</string>
+ <string name="cancel_download_label">Cancel Download</string>
<string name="playback_history_label">Playback History</string>
<string name="gpodnet_main_label">gpodder.net</string>
<string name="gpodnet_auth_label">gpodder.net Login</string>
@@ -62,6 +62,8 @@
<!-- Bug report activity -->
<string name="log_file_share_exception">No compatible apps found</string>
+ <string name="export_logs_menu_title">Export detailed logs</string>
+ <string name="confirm_export_log_dialog_message">Detailed logs may contain sensitive information, such as your subscriptions list</string>
<!-- Webview actions -->
<string name="open_in_browser_label">Open in Browser</string>
@@ -105,7 +107,7 @@
<string name="feed_volume_reduction_off">Off</string>
<string name="feed_volume_reduction_light">Light</string>
<string name="feed_volume_reduction_heavy">Heavy</string>
- <string name="parallel_downloads_suffix">\u0020parallel downloads</string>
+ <string name="parallel_downloads">%1$d parallel downloads</string>
<string name="feed_auto_download_global">Global default</string>
<string name="feed_auto_download_always">Always</string>
<string name="feed_auto_download_never">Never</string>
@@ -125,6 +127,11 @@
<item quantity="one">%d selected</item>
<item quantity="other">%d selected</item>
</plurals>
+ <plurals name="num_episodes">
+ <item quantity="zero">no episodes</item>
+ <item quantity="one">%d episode</item>
+ <item quantity="other">%d episodes</item>
+ </plurals>
<string name="loading_more">Loading more…</string>
<!-- Actions on feeds -->
@@ -174,9 +181,9 @@
<string name="delete_label">Delete</string>
<string name="delete_failed">Unable to delete file. Rebooting the device could help.</string>
<string name="delete_episode_label">Delete Episode</string>
- <plurals name="deleted_episode_batch_label">
- <item quantity="one">%d episode deleted.</item>
- <item quantity="other">%d episodes deleted.</item>
+ <plurals name="deleted_multi_episode_batch_label">
+ <item quantity="one">%d episode selected, %d download deleted.</item>
+ <item quantity="other">%d episodes selected, %d download(s) deleted.</item>
</plurals>
<string name="remove_new_flag_label">Remove \"new\" flag</string>
<string name="removed_new_flag_label">Removed \"new\" flag</string>
@@ -236,6 +243,7 @@
<string name="download_error_file_type_type">File Type Error</string>
<string name="download_error_forbidden">Forbidden</string>
<string name="download_canceled_msg">Download canceled</string>
+ <string name="download_wrong_size">The server connection was lost before completing the download</string>
<string name="download_canceled_autodownload_enabled_msg">Download canceled\nDisabled <i>Auto Download</i> for this item</string>
<string name="download_report_title">Downloads completed with error(s)</string>
<string name="auto_download_report_title">Auto-downloads completed</string>
@@ -283,11 +291,12 @@
<string name="playback_error_source">Unable to access media file</string>
<string name="playback_error_unknown">Unknown Error</string>
<string name="no_media_playing_label">No media playing</string>
- <string name="position_default_label" translate="false">00:00:00</string>
+ <string name="position_default_label" translatable="false">00:00:00</string>
<string name="player_buffering_msg">Buffering</string>
<string name="player_go_to_picture_in_picture">Picture-in-picture mode</string>
<string name="unknown_media_key">AntennaPod - Unknown media key: %1$d</string>
<string name="error_file_not_found">File not found</string>
+ <string name="no_media_label">Item does not contain a media file</string>
<!-- Queue operations -->
<string name="lock_queue">Lock Queue</string>
@@ -446,8 +455,6 @@
<string name="pref_gpodnet_full_sync_title">Force full synchronization</string>
<string name="pref_gpodnet_full_sync_sum">Sync all subscriptions and episode states with gpodder.net.</string>
<string name="pref_gpodnet_login_status"><![CDATA[Logged in as <i>%1$s</i> with device <i>%2$s</i>]]></string>
- <string name="pref_gpodnet_notifications_title">Synchronization failed</string>
- <string name="pref_gpodnet_notifications_sum">This setting does not apply to authentication errors.</string>
<string name="pref_playback_speed_sum">Customize the speeds available for variable speed playback</string>
<string name="pref_feed_playback_speed_sum">The speed to use when starting audio playback for episodes in this podcast</string>
<string name="pref_feed_skip">Auto Skip</string>
@@ -462,8 +469,6 @@
<string name="pref_fast_forward_sum">Customize the number of seconds to jump forward when the fast forward button is clicked</string>
<string name="pref_rewind">Rewind Skip Time</string>
<string name="pref_rewind_sum">Customize the number of seconds to jump backwards when the rewind button is clicked</string>
- <string name="pref_gpodnet_sethostname_title">Set hostname</string>
- <string name="pref_gpodnet_sethostname_use_default_host">Use default host</string>
<string name="pref_expandNotify_title">High Notification priority</string>
<string name="pref_expandNotify_sum">This usually expands the notification to show playback buttons.</string>
<string name="pref_persistNotify_title">Persistent Playback Controls</string>
@@ -474,10 +479,6 @@
<string name="pref_compact_notification_buttons_dialog_error">You can only select a maximum of %1$d items.</string>
<string name="pref_lockscreen_background_title">Set Lockscreen Background</string>
<string name="pref_lockscreen_background_sum">Set the lockscreen background to the current episode\'s image. As a side effect, this will also show the image in third party apps.</string>
- <string name="pref_showDownloadReport_title">Download failed</string>
- <string name="pref_showDownloadReport_sum">If downloads fail, generate a report that shows the details of the failure.</string>
- <string name="pref_showAutoDownloadReport_title">Automatic download completed</string>
- <string name="pref_showAutoDownloadReport_sum">Show a notification for automatically downloaded episodes.</string>
<string name="pref_expand_notify_unsupport_toast">Android versions before 4.1 do not support expanded notifications.</string>
<string name="pref_enqueue_location_title">Enqueue Location</string>
<string name="pref_enqueue_location_sum">Add episodes to: %1$s</string>
@@ -487,6 +488,7 @@
<string name="pref_smart_mark_as_played_disabled">Disabled</string>
<string name="pref_image_cache_size_title">Image Cache Size</string>
<string name="pref_image_cache_size_sum">Size of the disk cache for images.</string>
+ <string name="documentation_support">Documentation &amp; Support</string>
<string name="visit_user_forum">User forum</string>
<string name="bug_report_title">Report bug</string>
<string name="open_bug_tracker">Open bug tracker</string>
@@ -498,7 +500,6 @@
<string name="pref_current_value">Current value: %1$s</string>
<string name="pref_proxy_title">Proxy</string>
<string name="pref_proxy_sum">Set a network proxy</string>
- <string name="pref_faq">Frequently Asked Questions</string>
<string name="pref_no_browser_found">No web browser found.</string>
<string name="pref_cast_title">Chromecast support</string>
<string name="pref_cast_message_play_flavor">Enable support for remote media playback on Cast devices (such as Chromecast, Audio Speakers or Android TV)</string>
@@ -507,7 +508,7 @@
<string name="pref_enqueue_downloaded_summary">Add downloaded episodes to the queue</string>
<string name="media_player_builtin">Built-in Android player</string>
<string name="media_player_sonic" translatable="false">Sonic Media Player</string>
- <string name="media_player_exoplayer" translatable="false">ExoPlayer</string>
+ <string name="media_player_exoplayer_recommended">ExoPlayer (recommended)</string>
<string name="media_player_switch_to_exoplayer">Switch to ExoPlayer</string>
<string name="media_player_switched_to_exoplayer">Switched to ExoPlayer.</string>
<string name="pref_skip_silence_title">Skip Silence in Audio</string>
@@ -532,7 +533,7 @@
<string name="pref_filter_feed_sum">Filter your subscriptions in navigation drawer and subscriptions screen.</string>
<string name="no_filter_label">None</string>
<string name="subscriptions_are_filtered">Subscriptions are filtered.</string>
- <string name="subscriptions_counter_greater_zero">Counter greater zero</string>
+ <string name="subscriptions_counter_greater_zero">Counter greater than zero</string>
<string name="auto_downloaded">Auto downloaded</string>
<string name="not_auto_downloaded">Not auto downloaded</string>
<string name="kept_updated">Kept updated</string>
@@ -600,6 +601,7 @@
<!-- Sleep timer -->
<string name="set_sleeptimer_label">Set sleep timer</string>
<string name="disable_sleeptimer_label">Disable sleep timer</string>
+ <string name="extend_sleep_timer_label">+%d min</string>
<string name="sleep_timer_label">Sleep timer</string>
<string name="time_dialog_invalid_input">Invalid input, time has to be an integer</string>
<string name="shake_to_reset_label">Shake to reset</string>
@@ -628,23 +630,23 @@
<string name="gpodnet_suggestions_header">SUGGESTIONS</string>
<string name="gpodnet_search_hint">Search gpodder.net</string>
<string name="gpodnetauth_login_title">Login</string>
- <string name="gpodnetauth_login_descr">Welcome to the gpodder.net login process. First, type in your login information:</string>
<string name="gpodnetauth_login_butLabel">Login</string>
- <string name="gpodnetauth_login_register">If you do not have an account yet, you can create one here:\nhttps://gpodder.net/register/</string>
+ <string name="create_account">Create account</string>
<string name="username_label">Username</string>
<string name="password_label">Password</string>
- <string name="gpodnetauth_device_title">Device Selection</string>
+ <string name="gpodnet_description">Gpodder.net is an open-source podcast synchronization service that is independent of the AntennaPod project.</string>
+ <string name="gpodnetauth_server_official">Official gpodder.net server</string>
+ <string name="gpodnetauth_server_custom">Custom server</string>
+ <string name="gpodnetauth_host">Hostname</string>
+ <string name="gpodnetauth_select_server">Select server</string>
<string name="gpodnetauth_device_descr">Create a new device to use for your gpodder.net account or choose an existing one:</string>
- <string name="gpodnetauth_device_deviceID">Device ID:\u0020</string>
- <string name="gpodnetauth_device_caption">Caption</string>
- <string name="gpodnetauth_device_butCreateNewDevice">Create new device</string>
- <string name="gpodnetauth_device_chooseExistingDevice">Choose existing device:</string>
- <string name="gpodnetauth_device_errorEmpty">Device ID must not be empty</string>
- <string name="gpodnetauth_device_errorAlreadyUsed">Device ID already in use</string>
+ <string name="gpodnetauth_device_name">Device name</string>
+ <string name="gpodnetauth_device_name_default">AntennaPod on %1$s</string>
<string name="gpodnetauth_device_caption_errorEmpty">Caption must not be empty</string>
+ <string name="gpodnetauth_existing_devices">Existing devices</string>
+ <string name="gpodnetauth_create_device">Create device</string>
<string name="gpodnetauth_device_butChoose">Choose</string>
- <string name="gpodnetauth_finish_title">Login successful!</string>
<string name="gpodnetauth_finish_descr">Congratulations! Your gpodder.net account is now linked with your device. AntennaPod will from now on automatically sync subscriptions on your device with your gpodder.net account.</string>
<string name="gpodnetauth_finish_butsyncnow">Start sync now</string>
<string name="gpodnetauth_finish_butgomainscreen">Go to main screen</string>
@@ -702,6 +704,7 @@
<string name="switch_pages">Switch pages</string>
<string name="position">Position: %1$s</string>
<string name="apply_action">Apply action</string>
+ <string name="play_chapter">Play chapter</string>
<!-- Feed information screen -->
<string name="authentication_label">Authentication</string>
@@ -741,10 +744,14 @@
<string name="discover_more">more »</string>
<string name="discover_powered_by_itunes">Suggestions by iTunes</string>
<string name="search_powered_by">Results by %1$s</string>
+
+ <!-- Local feeds -->
<string name="add_local_folder">Add local folder</string>
+ <string name="local_folder">Local folder</string>
<string name="reconnect_local_folder">Re-connect local folder</string>
<string name="reconnect_local_folder_warning">In case of permission denials, you can use this to re-connect to the exact same folder. Do not select another folder.</string>
<string name="local_feed_description">This virtual podcast was created by adding a folder to AntennaPod.</string>
+ <string name="unable_to_start_system_file_manager">Unable to start system file manager</string>
<string name="filter">Filter</string>
@@ -850,17 +857,19 @@
<string name="cast_failed_media_error_skipping">Error playing media. Skipping&#8230;</string>
<!-- Notification channels -->
+ <string name="notification_group_errors">Errors</string>
+ <string name="notification_group_news">News</string>
<string name="notification_channel_user_action">Action required</string>
<string name="notification_channel_user_action_description">Shown if your action is required, for example if you need to enter a password.</string>
<string name="notification_channel_downloading">Downloading</string>
<string name="notification_channel_downloading_description">Shown while currently downloading.</string>
<string name="notification_channel_playing">Currently playing</string>
<string name="notification_channel_playing_description">Allows to control playback. This is the main notification you see while playing a podcast.</string>
- <string name="notification_channel_error">Errors</string>
- <string name="notification_channel_error_description">Shown if something went wrong, for example if download or feed update fails.</string>
- <string name="notification_channel_sync_error">Synchronization Errors</string>
+ <string name="notification_channel_download_error">Download failed</string>
+ <string name="notification_channel_download_error_description">Shown when download or feed update fails.</string>
+ <string name="notification_channel_sync_error">Synchronization failed</string>
<string name="notification_channel_sync_error_description">Shown when gpodder synchronization fails.</string>
- <string name="notification_channel_auto_download">Auto Downloads</string>
+ <string name="notification_channel_auto_download">Automatic download completed</string>
<string name="notification_channel_episode_auto_download">Shown when episodes have been automatically downloaded.</string>
<!-- Widget settings -->
diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml
index 9ec82215a..43e3823c5 100644
--- a/core/src/main/res/values/styles.xml
+++ b/core/src/main/res/values/styles.xml
@@ -20,6 +20,7 @@
<item name="action_icon_color">@color/black</item>
<item name="drawer_activated_color">@color/highlight_light</item>
<item name="android:textAllCaps">false</item>
+ <item name="android:textColorHint">@color/grey600</item>
<item name="storage">@drawable/ic_storage_black</item>
<item name="ic_network">@drawable/ic_network_black</item>
@@ -31,6 +32,7 @@
<item name="av_download">@drawable/ic_download_black</item>
<item name="av_pause">@drawable/ic_av_pause_black_48dp</item>
<item name="av_play">@drawable/ic_av_play_black_48dp</item>
+ <item name="av_replay">@drawable/ic_av_replay_black_48dp</item>
<item name="av_rewind">@drawable/ic_av_fast_rewind_black_48dp</item>
<item name="av_fast_forward">@drawable/ic_av_fast_forward_black_48dp</item>
<item name="av_skip">@drawable/ic_av_skip_black_48dp</item>
@@ -76,6 +78,7 @@
<item name="filter_dialog_clear">@color/filter_dialog_clear_light</item>
<item name="filter_dialog_button_background">@drawable/filter_dialog_background_light</item>
<item name="ic_notifications">@drawable/ic_notifications_black</item>
+ <item name="ic_share">@drawable/ic_share_black</item>
</style>
<style name="Theme.AntennaPod.Dark" parent="Theme.Base.AntennaPod.Dark">
@@ -98,6 +101,7 @@
<item name="currently_playing_background">@color/highlight_dark</item>
<item name="action_icon_color">@color/white</item>
<item name="android:textAllCaps">false</item>
+ <item name="android:textColorHint">@color/medium_gray</item>
<item name="storage">@drawable/ic_storage_white</item>
<item name="ic_network">@drawable/ic_network_white</item>
@@ -111,6 +115,7 @@
<item name="av_fast_forward">@drawable/ic_av_fast_forward_white_48dp</item>
<item name="av_pause">@drawable/ic_av_pause_white_48dp</item>
<item name="av_play">@drawable/ic_av_play_white_48dp</item>
+ <item name="av_replay">@drawable/ic_av_replay_white_48dp</item>
<item name="av_skip">@drawable/ic_av_skip_white_48dp</item>
<item name="ic_settings_speed">@drawable/ic_playback_speed_white</item>
<item name="ic_settings_skip">@drawable/ic_av_skip_white_24dp</item>
@@ -154,6 +159,7 @@
<item name="filter_dialog_clear">@color/filter_dialog_clear_dark</item>
<item name="filter_dialog_button_background">@drawable/filter_dialog_background_dark</item>
<item name="ic_notifications">@drawable/ic_notifications_white</item>
+ <item name="ic_share">@drawable/ic_share_white</item>
</style>
<style name="Theme.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.TrueBlack">
@@ -164,12 +170,14 @@
<item name="colorPrimaryDark">@color/black</item>
<item name="actionBarStyle">@style/Widget.AntennaPod.ActionBar.Black</item>
<item name="drawer_activated_color">@color/highlight_trueblack</item>
+ <item name="currently_playing_background">@color/highlight_trueblack</item>
<item name="android:textColorPrimary">@color/white</item>
<item name="android:color">@color/white</item>
<item name="android:colorBackground">@color/black</item>
<item name="android:windowBackground">@color/black</item>
<item name="android:actionBarStyle">@color/black</item>
<item name="background_elevated">@color/black</item>
+ <item name="android:textColorHint">@color/medium_gray</item>
</style>
<style name="Theme.AntennaPod.Light.NoTitle" parent="Theme.AntennaPod.Light">
@@ -318,4 +326,9 @@
<item name="android:clickable">true</item>
</style>
+ <style name="NoButtonRadio" parent="Widget.MaterialComponents.CompoundButton.RadioButton">
+ <item name="buttonCompat">@null</item> <!-- For Android 4.4 -->
+ <item name="android:button">@null</item>
+ </style>
+
</resources>
diff --git a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
index 41e95d99e..4b5e4d588 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
@@ -12,6 +12,7 @@ import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
import de.danoeh.antennapod.core.preferences.UsageStatistics;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
+import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
@@ -38,7 +39,7 @@ public class ClientConfig {
public static PlaybackServiceCallbacks playbackServiceCallbacks;
- public static DBTasksCallbacks dbTasksCallbacks;
+ public static AutomaticDownloadAlgorithm automaticDownloadAlgorithm;
public static CastCallbacks castCallbacks;
diff --git a/app/src/androidTest/java/de/test/antennapod/feed/FeedFilterTest.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedFilterTest.java
index fc2943205..8b4a13473 100644
--- a/app/src/androidTest/java/de/test/antennapod/feed/FeedFilterTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedFilterTest.java
@@ -1,19 +1,15 @@
-package de.test.antennapod.feed;
+package de.danoeh.antennapod.core.feed;
-import androidx.test.filters.SmallTest;
-import de.danoeh.antennapod.core.feed.FeedFilter;
-import de.danoeh.antennapod.core.feed.FeedItem;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-@SmallTest
public class FeedFilterTest {
@Test
- public void testNullFilter() throws Exception {
+ public void testNullFilter() {
FeedFilter filter = new FeedFilter();
FeedItem item = new FeedItem();
item.setTitle("Hello world");
@@ -26,7 +22,7 @@ public class FeedFilterTest {
}
@Test
- public void testBasicIncludeFilter() throws Exception {
+ public void testBasicIncludeFilter() {
String includeFilter = "Hello";
FeedFilter filter = new FeedFilter(includeFilter, "");
FeedItem item = new FeedItem();
@@ -44,7 +40,7 @@ public class FeedFilterTest {
}
@Test
- public void testBasicExcludeFilter() throws Exception {
+ public void testBasicExcludeFilter() {
String excludeFilter = "Hello";
FeedFilter filter = new FeedFilter("", excludeFilter);
FeedItem item = new FeedItem();
@@ -62,7 +58,7 @@ public class FeedFilterTest {
}
@Test
- public void testComplexIncludeFilter() throws Exception {
+ public void testComplexIncludeFilter() {
String includeFilter = "Hello \n\"Two words\"";
FeedFilter filter = new FeedFilter(includeFilter, "");
FeedItem item = new FeedItem();
@@ -84,7 +80,7 @@ public class FeedFilterTest {
}
@Test
- public void testComplexExcludeFilter() throws Exception {
+ public void testComplexExcludeFilter() {
String excludeFilter = "Hello \"Two words\"";
FeedFilter filter = new FeedFilter("", excludeFilter);
FeedItem item = new FeedItem();
@@ -106,7 +102,7 @@ public class FeedFilterTest {
}
@Test
- public void testComboFilter() throws Exception {
+ public void testComboFilter() {
String includeFilter = "Hello world";
String excludeFilter = "dislike";
FeedFilter filter = new FeedFilter(includeFilter, excludeFilter);
diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java
index 6bd753561..5bcbed97a 100644
--- a/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/feed/FeedItemTest.java
@@ -2,16 +2,23 @@ package de.danoeh.antennapod.core.feed;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
import java.text.SimpleDateFormat;
import java.util.Date;
+import de.danoeh.antennapod.core.storage.DBReader;
+
import static de.danoeh.antennapod.core.feed.FeedItemMother.anyFeedItemWithImage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
public class FeedItemTest {
+ private static final String TEXT_LONG = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+ private static final String TEXT_SHORT = "Lorem ipsum";
+
private FeedItem original;
private FeedItem changedFeedItem;
@@ -22,21 +29,21 @@ public class FeedItemTest {
}
@Test
- public void testUpdateFromOther_feedItemImageDownloadUrlChanged() throws Exception {
+ public void testUpdateFromOther_feedItemImageDownloadUrlChanged() {
setNewFeedItemImageDownloadUrl();
original.updateFromOther(changedFeedItem);
assertFeedItemImageWasUpdated();
}
@Test
- public void testUpdateFromOther_feedItemImageRemoved() throws Exception {
+ public void testUpdateFromOther_feedItemImageRemoved() {
feedItemImageRemoved();
original.updateFromOther(changedFeedItem);
assertFeedItemImageWasNotUpdated();
}
@Test
- public void testUpdateFromOther_feedItemImageAdded() throws Exception {
+ public void testUpdateFromOther_feedItemImageAdded() {
original.setImageUrl(null);
setNewFeedItemImageDownloadUrl();
original.updateFromOther(changedFeedItem);
@@ -102,4 +109,36 @@ public class FeedItemTest {
assertEquals(anyFeedItemWithImage().getImageUrl(), original.getImageUrl());
}
+ /**
+ * If one of `description` or `content:encoded` is null, use the other one.
+ */
+ @Test
+ public void testShownotesNullValues() throws Exception {
+ testShownotes(null, TEXT_LONG);
+ testShownotes(TEXT_LONG, null);
+ }
+
+ /**
+ * If `description` is reasonably longer than `content:encoded`, use `description`.
+ */
+ @Test
+ public void testShownotesLength() throws Exception {
+ testShownotes(TEXT_SHORT, TEXT_LONG);
+ testShownotes(TEXT_LONG, TEXT_SHORT);
+ }
+
+ /**
+ * Checks if the shownotes equal TEXT_LONG, using the given `description` and `content:encoded`.
+ *
+ * @param description Description of the feed item
+ * @param contentEncoded `content:encoded` of the feed item
+ */
+ private void testShownotes(String description, String contentEncoded) throws Exception {
+ try (MockedStatic<DBReader> ignore = Mockito.mockStatic(DBReader.class)) {
+ FeedItem item = new FeedItem();
+ item.setDescription(description);
+ item.setContentEncoded(contentEncoded);
+ assertEquals(TEXT_LONG, item.loadShownotes().call());
+ }
+ }
} \ No newline at end of file
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 b4d3b201e..b38f8586d 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
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.feed;
import android.app.Application;
import android.content.Context;
import android.media.MediaMetadataRetriever;
+import android.net.Uri;
import android.webkit.MimeTypeMap;
import androidx.annotation.NonNull;
@@ -30,11 +31,14 @@ 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;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
+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.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -82,6 +86,7 @@ public class LocalFeedUpdaterTest {
@After
public void tearDown() {
+ DBWriter.tearDownTests();
PodDBAdapter.tearDownTests();
}
@@ -92,7 +97,7 @@ public class LocalFeedUpdaterTest {
public void testUpdateFeed_AddNewFeed() {
// check for empty database
List<Feed> feedListBefore = DBReader.getFeedList();
- assertTrue(feedListBefore.isEmpty());
+ assertThat(feedListBefore, is(empty()));
callUpdateFeed(LOCAL_FEED_DIR2);
@@ -138,7 +143,7 @@ public class LocalFeedUpdaterTest {
callUpdateFeed(LOCAL_FEED_DIR2);
Feed feedAfter = verifySingleFeedInDatabase();
- assertTrue(feedAfter.getImageUrl().contains("local-feed2/folder.png"));
+ assertThat(feedAfter.getImageUrl(), endsWith("local-feed2/folder.png"));
}
/**
@@ -150,7 +155,7 @@ public class LocalFeedUpdaterTest {
Feed feedAfter = verifySingleFeedInDatabase();
String resourceEntryName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
- assertTrue(feedAfter.getImageUrl().contains(resourceEntryName));
+ assertThat(feedAfter.getImageUrl(), endsWith(resourceEntryName));
}
/**
@@ -179,6 +184,65 @@ public class LocalFeedUpdaterTest {
assertEquals(24, calendar.get(Calendar.SECOND));
}
+ @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));
+ }
+
+ @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));
+ }
+
+ @Test
+ public void testGetImageUrl_PreferredImagesFilenames() {
+ 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);
+ assertThat(imageUrl, endsWith(filename));
+ }
+ }
+
+ @Test
+ public void testGetImageUrl_OtherImageFilenameJpg() {
+ DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
+ mockDocumentFile("my-image.jpg", "image/jpeg"));
+ String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ assertThat(imageUrl, endsWith("my-image.jpg"));
+ }
+
+ @Test
+ public void testGetImageUrl_OtherImageFilenameJpeg() {
+ DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
+ mockDocumentFile("my-image.jpeg", "image/jpeg"));
+ String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ assertThat(imageUrl, endsWith("my-image.jpeg"));
+ }
+
+ @Test
+ public void testGetImageUrl_OtherImageFilenamePng() {
+ DocumentFile documentFolder = mockDocumentFolder(mockDocumentFile("audio.mp3", "audio/mp3"),
+ mockDocumentFile("my-image.png", "image/png"));
+ String imageUrl = LocalFeedUpdater.getImageUrl(context, documentFolder);
+ assertThat(imageUrl, endsWith("my-image.png"));
+ }
+
+ @Test
+ 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));
+ }
+
/**
* Fill ShadowMediaMetadataRetriever with dummy duration and title.
*
@@ -237,4 +301,26 @@ public class LocalFeedUpdaterTest {
List<FeedItem> feedItems = DBReader.getFeedItemList(feed);
assertEquals(expectedItemCount, feedItems.size());
}
+
+ /**
+ * Create a DocumentFile mock object.
+ */
+ @NonNull
+ private static DocumentFile mockDocumentFile(@NonNull String fileName, @NonNull String mimeType) {
+ DocumentFile file = mock(DocumentFile.class);
+ when(file.getName()).thenReturn(fileName);
+ when(file.getUri()).thenReturn(Uri.parse("file:///path/" + fileName));
+ when(file.getType()).thenReturn(mimeType);
+ return file;
+ }
+
+ /**
+ * Create a DocumentFile folder mock object with a list of files.
+ */
+ @NonNull
+ private static DocumentFile mockDocumentFolder(DocumentFile... files) {
+ DocumentFile documentFolder = mock(DocumentFile.class);
+ when(documentFolder.listFiles()).thenReturn(files);
+ return documentFolder;
+ }
}
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/service/download/DownloadRequestTest.java b/core/src/test/java/de/danoeh/antennapod/core/service/download/DownloadRequestTest.java
index fc7e26820..8c7ecbc52 100644
--- a/core/src/androidTest/java/de/danoeh/antennapod/core/service/download/DownloadRequestTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/service/download/DownloadRequestTest.java
@@ -3,9 +3,9 @@ package de.danoeh.antennapod.core.service.download;
import android.os.Bundle;
import android.os.Parcel;
-import androidx.test.filters.SmallTest;
-
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import java.util.ArrayList;
@@ -13,7 +13,7 @@ import de.danoeh.antennapod.core.feed.FeedFile;
import static org.junit.Assert.assertEquals;
-@SmallTest
+@RunWith(RobolectricTestRunner.class)
public class DownloadRequestTest {
@Test
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java b/core/src/test/java/de/danoeh/antennapod/core/storage/DbNullCleanupAlgorithmTest.java
index d7ebf2351..b4dbacb82 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/storage/DbNullCleanupAlgorithmTest.java
@@ -1,4 +1,4 @@
-package de.test.antennapod.storage;
+package de.danoeh.antennapod.core.storage;
import android.content.Context;
import android.content.SharedPreferences;
@@ -11,17 +11,15 @@ import java.util.Date;
import java.util.List;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.filters.SmallTest;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.DBTasks;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -29,32 +27,17 @@ import static org.junit.Assert.assertTrue;
/**
* Tests that the APNullCleanupAlgorithm is working correctly.
*/
-@SmallTest
-public class DBNullCleanupAlgorithmTest {
+@RunWith(RobolectricTestRunner.class)
+public class DbNullCleanupAlgorithmTest {
- private static final String TAG = "DBNullCleanupAlgorithmTest";
private static final int EPISODE_CACHE_SIZE = 5;
private Context context;
private File destFolder;
- @After
- public void tearDown() throws Exception {
- assertTrue(PodDBAdapter.deleteDatabase());
-
- cleanupDestFolder(destFolder);
- assertTrue(destFolder.delete());
- }
-
- private void cleanupDestFolder(File destFolder) {
- for (File f : destFolder.listFiles()) {
- assertTrue(f.delete());
- }
- }
-
@Before
- public void setUp() throws Exception {
+ public void setUp() {
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
destFolder = context.getExternalCacheDir();
cleanupDestFolder(destFolder);
@@ -69,35 +52,53 @@ public class DBNullCleanupAlgorithmTest {
adapter.open();
adapter.close();
- SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()).edit();
+ SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(context
+ .getApplicationContext()).edit();
prefEdit.putString(UserPreferences.PREF_EPISODE_CACHE_SIZE, Integer.toString(EPISODE_CACHE_SIZE));
- prefEdit.putString(UserPreferences.PREF_EPISODE_CLEANUP, Integer.toString(UserPreferences.EPISODE_CLEANUP_NULL));
+ prefEdit.putString(UserPreferences.PREF_EPISODE_CLEANUP,
+ Integer.toString(UserPreferences.EPISODE_CLEANUP_NULL));
prefEdit.commit();
UserPreferences.init(context);
}
+ @After
+ public void tearDown() {
+ DBWriter.tearDownTests();
+ PodDBAdapter.deleteDatabase();
+ PodDBAdapter.tearDownTests();
+
+ cleanupDestFolder(destFolder);
+ assertTrue(destFolder.delete());
+ }
+
+ private void cleanupDestFolder(File destFolder) {
+ //noinspection ConstantConditions
+ for (File f : destFolder.listFiles()) {
+ assertTrue(f.delete());
+ }
+ }
+
/**
* A test with no items in the queue, but multiple items downloaded.
* The null algorithm should never delete any items, even if they're played and not in the queue.
- * @throws IOException
*/
@Test
public void testPerformAutoCleanupShouldNotDelete() throws IOException {
- final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
+ final int numItems = EPISODE_CACHE_SIZE * 2;
Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>();
feed.setItems(items);
List<File> files = new ArrayList<>();
- for (int i = 0; i < NUM_ITEMS; i++) {
+ for (int i = 0; i < numItems; i++) {
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
File f = new File(destFolder, "file " + i);
assertTrue(f.createNewFile());
files.add(f);
item.setMedia(new FeedMedia(0, item, 1, 0, 1L, "m", f.getAbsolutePath(), "url", true,
- new Date(NUM_ITEMS - i), 0, 0));
+ new Date(numItems - i), 0, 0));
items.add(item);
}
@@ -109,6 +110,7 @@ public class DBNullCleanupAlgorithmTest {
assertTrue(feed.getId() != 0);
for (FeedItem item : items) {
assertTrue(item.getId() != 0);
+ //noinspection ConstantConditions
assertTrue(item.getMedia().getId() != 0);
}
DBTasks.performAutoCleanup(context);
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java b/core/src/test/java/de/danoeh/antennapod/core/storage/DbTasksTest.java
index c28ce5003..be9f53cdb 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/storage/DbTasksTest.java
@@ -1,13 +1,15 @@
-package de.test.antennapod.storage;
+package de.danoeh.antennapod.core.storage;
+import android.app.Application;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import java.util.ArrayList;
import java.util.Arrays;
@@ -15,14 +17,13 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
+import de.danoeh.antennapod.core.ApplicationCallbacks;
+import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.storage.DBTasks;
-import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
import static de.danoeh.antennapod.core.util.FeedItemUtil.getIdList;
import static java.util.Collections.singletonList;
@@ -32,22 +33,25 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
/**
- * Test class for DBTasks
+ * Test class for {@link DBTasks}.
*/
-@SmallTest
-public class DBTasksTest {
+@RunWith(RobolectricTestRunner.class)
+public class DbTasksTest {
private Context context;
- @After
- public void tearDown() throws Exception {
- assertTrue(PodDBAdapter.deleteDatabase());
- }
-
@Before
- public void setUp() throws Exception {
+ public void setUp() {
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ UserPreferences.init(context);
+ PlaybackPreferences.init(context);
+
+ Application app = (Application) context;
+ ClientConfig.applicationCallbacks = mock(ApplicationCallbacks.class);
+ when(ClientConfig.applicationCallbacks.getApplicationInstance()).thenReturn(app);
// create new database
PodDBAdapter.init(context);
@@ -55,18 +59,23 @@ public class DBTasksTest {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.close();
+ }
- UserPreferences.init(context);
+ @After
+ public void tearDown() {
+ DBWriter.tearDownTests();
+ PodDBAdapter.tearDownTests();
}
@Test
public void testUpdateFeedNewFeed() {
- final int NUM_ITEMS = 10;
+ final int numItems = 10;
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- 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));
+ for (int i = 0; i < numItems; i++) {
+ feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i,
+ new Date(), FeedItem.UNPLAYED, feed));
}
Feed newFeed = DBTasks.updateFeed(context, feed, false);
@@ -96,13 +105,14 @@ public class DBTasksTest {
@Test
public void testUpdateFeedUpdatedFeed() {
- final int NUM_ITEMS_OLD = 10;
- final int NUM_ITEMS_NEW = 10;
+ final int numItemsOld = 10;
+ final int numItemsNew = 10;
final Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- for (int i = 0; i < NUM_ITEMS_OLD; i++) {
- feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.PLAYED, feed));
+ for (int i = 0; i < numItemsOld; 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();
@@ -120,19 +130,20 @@ public class DBTasksTest {
item.setId(0);
}
- for (int i = NUM_ITEMS_OLD; i < NUM_ITEMS_NEW + NUM_ITEMS_OLD; i++) {
- feed.getItems().add(0, new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.UNPLAYED, feed));
+ for (int i = numItemsOld; i < numItemsNew + numItemsOld; i++) {
+ 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, false);
assertNotSame(newFeed, feed);
- updatedFeedTest(newFeed, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW);
+ updatedFeedTest(newFeed, feedID, itemIDs, numItemsOld, numItemsNew);
final Feed feedFromDB = DBReader.getFeed(newFeed.getId());
assertNotNull(feedFromDB);
assertEquals(newFeed.getId(), feedFromDB.getId());
- updatedFeedTest(feedFromDB, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW);
+ updatedFeedTest(feedFromDB, feedID, itemIDs, numItemsOld, numItemsNew);
}
@Test
@@ -186,12 +197,14 @@ public class DBTasksTest {
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) {
+ @SuppressWarnings("SameParameterValue")
+ private void updatedFeedTest(final Feed newFeed, long feedID, List<Long> itemIDs,
+ int numItemsOld, int numItemsNew) {
assertEquals(feedID, newFeed.getId());
- assertEquals(NUM_ITEMS_NEW + NUM_ITEMS_OLD, newFeed.getItems().size());
+ assertEquals(numItemsNew + numItemsOld, newFeed.getItems().size());
Collections.reverse(newFeed.getItems());
Date lastDate = new Date(0);
- for (int i = 0; i < NUM_ITEMS_OLD; i++) {
+ for (int i = 0; i < numItemsOld; i++) {
FeedItem item = newFeed.getItems().get(i);
assertSame(newFeed, item.getFeed());
assertEquals((long) itemIDs.get(i), item.getId());
@@ -199,7 +212,7 @@ public class DBTasksTest {
assertTrue(item.getPubDate().getTime() >= lastDate.getTime());
lastDate = item.getPubDate();
}
- for (int i = NUM_ITEMS_OLD; i < NUM_ITEMS_NEW + NUM_ITEMS_OLD; i++) {
+ for (int i = numItemsOld; i < numItemsNew + numItemsOld; i++) {
FeedItem item = newFeed.getItems().get(i);
assertSame(newFeed, item.getFeed());
assertTrue(item.getId() != 0);
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/core/src/test/java/de/danoeh/antennapod/core/storage/DbWriterTest.java
index 652389d00..3efb2705f 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/storage/DbWriterTest.java
@@ -1,38 +1,37 @@
-package de.test.antennapod.storage;
+package de.danoeh.antennapod.core.storage;
+import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
-import androidx.preference.PreferenceManager;
import android.util.Log;
import androidx.core.util.Consumer;
+import androidx.preference.PreferenceManager;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
import org.awaitility.Awaitility;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import de.danoeh.antennapod.core.ApplicationCallbacks;
+import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import static org.junit.Assert.assertEquals;
@@ -41,83 +40,92 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
/**
- * Test class for DBWriter
+ * Test class for {@link DBWriter}.
*/
-@MediumTest
-public class DBWriterTest {
+@RunWith(RobolectricTestRunner.class)
+public class DbWriterTest {
private static final String TAG = "DBWriterTest";
private static final String TEST_FOLDER = "testDBWriter";
private static final long TIMEOUT = 5L;
+
+ private Context context;
- @After
- public void tearDown() throws Exception {
- assertTrue(PodDBAdapter.deleteDatabase());
+ @Before
+ public void setUp() {
+ context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ UserPreferences.init(context);
+ PlaybackPreferences.init(context);
- final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- File testDir = context.getExternalFilesDir(TEST_FOLDER);
- assertNotNull(testDir);
- for (File f : testDir.listFiles()) {
- f.delete();
- }
- }
+ Application app = (Application) context;
+ ClientConfig.applicationCallbacks = mock(ApplicationCallbacks.class);
+ when(ClientConfig.applicationCallbacks.getApplicationInstance()).thenReturn(app);
- @Before
- public void setUp() throws Exception {
// create new database
- PodDBAdapter.init(InstrumentationRegistry.getInstrumentation().getTargetContext());
+ PodDBAdapter.init(context);
PodDBAdapter.deleteDatabase();
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.close();
- Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()).edit();
+ SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(
+ context.getApplicationContext()).edit();
prefEdit.putBoolean(UserPreferences.PREF_DELETE_REMOVES_FROM_QUEUE, true).commit();
+ }
- UserPreferences.init(context);
+ @After
+ public void tearDown() {
+ PodDBAdapter.tearDownTests();
+ DBWriter.tearDownTests();
+
+ File testDir = context.getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(testDir);
+ for (File f : testDir.listFiles()) {
+ //noinspection ResultOfMethodCallIgnored
+ f.delete();
+ }
}
@Test
- public void testSetFeedMediaPlaybackInformation()
- throws IOException, ExecutionException, InterruptedException, TimeoutException {
- final int POSITION = 50;
- final long LAST_PLAYED_TIME = 1000;
- final int PLAYED_DURATION = 60;
- final int DURATION = 100;
+ public void testSetFeedMediaPlaybackInformation() throws Exception {
+ final int position = 50;
+ final long lastPlayedTime = 1000;
+ final int playedDuration = 60;
+ final int duration = 100;
Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>();
feed.setItems(items);
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
items.add(item);
- FeedMedia media = new FeedMedia(0, item, DURATION, 1, 1, "mime_type", "dummy path", "download_url", true, null, 0, 0);
+ FeedMedia media = new FeedMedia(0, item, duration, 1, 1, "mime_type",
+ "dummy path", "download_url", true, null, 0, 0);
item.setMedia(media);
DBWriter.setFeedItem(item).get(TIMEOUT, TimeUnit.SECONDS);
- media.setPosition(POSITION);
- media.setLastPlayedTime(LAST_PLAYED_TIME);
- media.setPlayedDuration(PLAYED_DURATION);
+ media.setPosition(position);
+ media.setLastPlayedTime(lastPlayedTime);
+ media.setPlayedDuration(playedDuration);
DBWriter.setFeedMediaPlaybackInformation(item.getMedia()).get(TIMEOUT, TimeUnit.SECONDS);
FeedItem itemFromDb = DBReader.getFeedItem(item.getId());
FeedMedia mediaFromDb = itemFromDb.getMedia();
- assertEquals(POSITION, mediaFromDb.getPosition());
- assertEquals(LAST_PLAYED_TIME, mediaFromDb.getLastPlayedTime());
- assertEquals(PLAYED_DURATION, mediaFromDb.getPlayedDuration());
- assertEquals(DURATION, mediaFromDb.getDuration());
+ assertEquals(position, mediaFromDb.getPosition());
+ assertEquals(lastPlayedTime, mediaFromDb.getLastPlayedTime());
+ assertEquals(playedDuration, mediaFromDb.getPlayedDuration());
+ assertEquals(duration, mediaFromDb.getDuration());
}
@Test
- public void testDeleteFeedMediaOfItemFileExists()
- throws IOException, ExecutionException, InterruptedException, TimeoutException {
- File dest = new File(InstrumentationRegistry
- .getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER), "testFile");
+ public void testDeleteFeedMediaOfItemFileExists() throws Exception {
+ File dest = new File(context.getExternalFilesDir(TEST_FOLDER), "testFile");
assertTrue(dest.createNewFile());
@@ -126,7 +134,8 @@ public class DBWriterTest {
feed.setItems(items);
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
- FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", dest.getAbsolutePath(), "download_url", true, null, 0, 0);
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type",
+ dest.getAbsolutePath(), "download_url", true, null, 0, 0);
item.setMedia(media);
items.add(item);
@@ -138,7 +147,7 @@ public class DBWriterTest {
assertTrue(media.getId() != 0);
assertTrue(item.getId() != 0);
- DBWriter.deleteFeedMediaOfItem(InstrumentationRegistry.getInstrumentation().getTargetContext(), media.getId())
+ DBWriter.deleteFeedMediaOfItem(context, media.getId())
.get(TIMEOUT, TimeUnit.SECONDS);
media = DBReader.getFeedMedia(media.getId());
assertNotNull(media);
@@ -148,25 +157,24 @@ public class DBWriterTest {
}
@Test
- public void testDeleteFeedMediaOfItemRemoveFromQueue()
- throws IOException, ExecutionException, InterruptedException, TimeoutException {
+ public void testDeleteFeedMediaOfItemRemoveFromQueue() throws Exception {
assertTrue(UserPreferences.shouldDeleteRemoveFromQueue());
- File dest = new File(InstrumentationRegistry
- .getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER), "testFile");
+ File dest = new File(context.getExternalFilesDir(TEST_FOLDER), "testFile");
assertTrue(dest.createNewFile());
Feed feed = new Feed("url", null, "title");
List<FeedItem> items = new ArrayList<>();
- List<FeedItem> queue = new ArrayList<>();
feed.setItems(items);
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.UNPLAYED, feed);
- FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", dest.getAbsolutePath(), "download_url", true, null, 0, 0);
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type",
+ dest.getAbsolutePath(), "download_url", true, null, 0, 0);
item.setMedia(media);
items.add(item);
+ List<FeedItem> queue = new ArrayList<>();
queue.add(item);
PodDBAdapter adapter = PodDBAdapter.getInstance();
@@ -179,7 +187,7 @@ public class DBWriterTest {
queue = DBReader.getQueue();
assertTrue(queue.size() != 0);
- DBWriter.deleteFeedMediaOfItem(InstrumentationRegistry.getInstrumentation().getTargetContext(), media.getId());
+ DBWriter.deleteFeedMediaOfItem(context, media.getId());
Awaitility.await().until(() -> !dest.exists());
media = DBReader.getFeedMedia(media.getId());
assertNotNull(media);
@@ -191,8 +199,8 @@ public class DBWriterTest {
}
@Test
- public void testDeleteFeed() throws ExecutionException, InterruptedException, IOException, TimeoutException {
- File destFolder = InstrumentationRegistry.getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ public void testDeleteFeed() throws Exception {
+ File destFolder = context.getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
Feed feed = new Feed("url", null, "title");
@@ -208,7 +216,8 @@ public class DBWriterTest {
assertTrue(enc.createNewFile());
itemFiles.add(enc);
- FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null, 0, 0);
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type",
+ enc.getAbsolutePath(), "download_url", true, null, 0, 0);
item.setMedia(media);
}
@@ -223,8 +232,7 @@ public class DBWriterTest {
assertTrue(item.getMedia().getId() != 0);
}
- DBWriter.deleteFeed(InstrumentationRegistry
- .getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.deleteFeed(context, feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
// check if files still exist
for (File f : itemFiles) {
@@ -248,8 +256,8 @@ public class DBWriterTest {
}
@Test
- public void testDeleteFeedNoItems() throws IOException, ExecutionException, InterruptedException, TimeoutException {
- File destFolder = InstrumentationRegistry.getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ public void testDeleteFeedNoItems() throws Exception {
+ File destFolder = context.getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
Feed feed = new Feed("url", null, "title");
@@ -263,8 +271,7 @@ public class DBWriterTest {
assertTrue(feed.getId() != 0);
- DBWriter.deleteFeed(InstrumentationRegistry
- .getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.deleteFeed(context, feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -275,8 +282,8 @@ public class DBWriterTest {
}
@Test
- public void testDeleteFeedNoFeedMedia() throws IOException, ExecutionException, InterruptedException, TimeoutException {
- File destFolder = InstrumentationRegistry.getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ public void testDeleteFeedNoFeedMedia() throws Exception {
+ File destFolder = context.getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
Feed feed = new Feed("url", null, "title");
@@ -301,9 +308,7 @@ public class DBWriterTest {
assertTrue(item.getId() != 0);
}
- DBWriter.deleteFeed(InstrumentationRegistry
- .getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
-
+ DBWriter.deleteFeed(context, feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -319,8 +324,8 @@ public class DBWriterTest {
}
@Test
- public void testDeleteFeedWithQueueItems() throws ExecutionException, InterruptedException, TimeoutException {
- File destFolder = InstrumentationRegistry.getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ public void testDeleteFeedWithQueueItems() throws Exception {
+ File destFolder = context.getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
Feed feed = new Feed("url", null, "title");
@@ -333,7 +338,8 @@ public class DBWriterTest {
FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item);
File enc = new File(destFolder, "file " + i);
- FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", false, null, 0, 0);
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type",
+ enc.getAbsolutePath(), "download_url", false, null, 0, 0);
item.setMedia(media);
}
@@ -348,7 +354,6 @@ public class DBWriterTest {
assertTrue(item.getMedia().getId() != 0);
}
-
List<FeedItem> queue = new ArrayList<>(feed.getItems());
adapter.open();
adapter.setQueue(queue);
@@ -358,8 +363,7 @@ public class DBWriterTest {
queueCursor.close();
adapter.close();
- DBWriter.deleteFeed(InstrumentationRegistry
- .getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.deleteFeed(context, feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId());
@@ -380,8 +384,8 @@ public class DBWriterTest {
}
@Test
- public void testDeleteFeedNoDownloadedFiles() throws ExecutionException, InterruptedException, TimeoutException {
- File destFolder = InstrumentationRegistry.getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ public void testDeleteFeedNoDownloadedFiles() throws Exception {
+ File destFolder = context.getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
Feed feed = new Feed("url", null, "title");
@@ -394,7 +398,8 @@ public class DBWriterTest {
FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item);
File enc = new File(destFolder, "file " + i);
- FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", false, null, 0, 0);
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type",
+ enc.getAbsolutePath(), "download_url", false, null, 0, 0);
item.setMedia(media);
}
@@ -409,8 +414,7 @@ public class DBWriterTest {
assertTrue(item.getMedia().getId() != 0);
}
- DBWriter.deleteFeed(InstrumentationRegistry
- .getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.deleteFeed(context, feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -446,8 +450,7 @@ public class DBWriterTest {
adapter.close();
List<FeedItem> itemsToDelete = feed.getItems().subList(0, 2);
- DBWriter.deleteFeedItems(InstrumentationRegistry.getInstrumentation()
- .getTargetContext(), itemsToDelete).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.deleteFeedItems(context, itemsToDelete).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -468,7 +471,8 @@ public class DBWriterTest {
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
- FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null, "url", false, playbackCompletionDate, 0, 0);
+ FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null,
+ "url", false, playbackCompletionDate, 0, 0);
feed.getItems().add(item);
item.setMedia(media);
PodDBAdapter adapter = PodDBAdapter.getInstance();
@@ -480,8 +484,7 @@ public class DBWriterTest {
}
@Test
- public void testAddItemToPlaybackHistoryNotPlayedYet()
- throws ExecutionException, InterruptedException, TimeoutException {
+ public void testAddItemToPlaybackHistoryNotPlayedYet() throws Exception {
FeedMedia media = playbackHistorySetup(null);
DBWriter.addItemToPlaybackHistory(media).get(TIMEOUT, TimeUnit.SECONDS);
PodDBAdapter adapter = PodDBAdapter.getInstance();
@@ -494,11 +497,10 @@ public class DBWriterTest {
}
@Test
- public void testAddItemToPlaybackHistoryAlreadyPlayed()
- throws ExecutionException, InterruptedException, TimeoutException {
- final long OLD_DATE = 0;
+ public void testAddItemToPlaybackHistoryAlreadyPlayed() throws Exception {
+ final long oldDate = 0;
- FeedMedia media = playbackHistorySetup(new Date(OLD_DATE));
+ FeedMedia media = playbackHistorySetup(new Date(oldDate));
DBWriter.addItemToPlaybackHistory(media).get(TIMEOUT, TimeUnit.SECONDS);
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -507,11 +509,11 @@ public class DBWriterTest {
assertNotNull(media);
assertNotNull(media.getPlaybackCompletionDate());
- assertNotEquals(media.getPlaybackCompletionDate().getTime(), OLD_DATE);
+ assertNotEquals(media.getPlaybackCompletionDate().getTime(), oldDate);
}
- private Feed queueTestSetupMultipleItems(final int numItems) throws InterruptedException, ExecutionException, TimeoutException {
- final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ @SuppressWarnings("SameParameterValue")
+ private Feed queueTestSetupMultipleItems(final int numItems) throws Exception {
UserPreferences.setEnqueueLocation(UserPreferences.EnqueueLocation.BACK);
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
@@ -539,8 +541,7 @@ public class DBWriterTest {
}
@Test
- public void testAddQueueItemSingleItem() throws InterruptedException, ExecutionException, TimeoutException {
- final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ public void testAddQueueItemSingleItem() throws Exception {
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
@@ -564,8 +565,7 @@ public class DBWriterTest {
}
@Test
- public void testAddQueueItemSingleItemAlreadyInQueue() throws InterruptedException, ExecutionException, TimeoutException {
- final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ public void testAddQueueItemSingleItemAlreadyInQueue() throws Exception {
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
@@ -599,18 +599,20 @@ public class DBWriterTest {
}
@Test
- public void testAddQueueItemMultipleItems() throws InterruptedException, ExecutionException, TimeoutException {
- final int NUM_ITEMS = 10;
+ public void testAddQueueItemMultipleItems() throws Exception {
+ final int numItems = 10;
- Feed feed = queueTestSetupMultipleItems(NUM_ITEMS);
+ Feed feed;
+ feed = queueTestSetupMultipleItems(numItems);
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
Cursor cursor = adapter.getQueueIDCursor();
assertTrue(cursor.moveToFirst());
- assertEquals(NUM_ITEMS, cursor.getCount());
- List<Long> expectedIds = FeedItemUtil.getIdList(feed.getItems());
+ assertEquals(numItems, cursor.getCount());
+ List<Long> expectedIds;
+ expectedIds = FeedItemUtil.getIdList(feed.getItems());
List<Long> actualIds = new ArrayList<>();
- for (int i = 0; i < NUM_ITEMS; i++) {
+ for (int i = 0; i < numItems; i++) {
assertTrue(cursor.moveToPosition(i));
actualIds.add(cursor.getLong(0));
}
@@ -621,10 +623,10 @@ public class DBWriterTest {
}
@Test
- public void testClearQueue() throws InterruptedException, ExecutionException, TimeoutException {
- final int NUM_ITEMS = 10;
+ public void testClearQueue() throws Exception {
+ final int numItems = 10;
- queueTestSetupMultipleItems(NUM_ITEMS);
+ queueTestSetupMultipleItems(numItems);
DBWriter.clearQueue().get(TIMEOUT, TimeUnit.SECONDS);
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -635,12 +637,11 @@ public class DBWriterTest {
}
@Test
- public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
- final int NUM_ITEMS = 10;
- final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- Feed feed = createTestFeed(NUM_ITEMS);
+ public void testRemoveQueueItem() throws Exception {
+ final int numItems = 10;
+ Feed feed = createTestFeed(numItems);
- for (int removeIndex = 0; removeIndex < NUM_ITEMS; removeIndex++) {
+ for (int removeIndex = 0; removeIndex < numItems; removeIndex++) {
final FeedItem item = feed.getItems().get(removeIndex);
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -651,7 +652,7 @@ public class DBWriterTest {
adapter = PodDBAdapter.getInstance();
adapter.open();
Cursor queue = adapter.getQueueIDCursor();
- assertEquals(NUM_ITEMS - 1, queue.getCount());
+ assertEquals(numItems - 1, queue.getCount());
for (int i = 0; i < queue.getCount(); i++) {
assertTrue(queue.moveToPosition(i));
final long queueID = queue.getLong(0);
@@ -668,16 +669,13 @@ public class DBWriterTest {
}
@Test
- public void testRemoveQueueItemMultipleItems() throws InterruptedException, ExecutionException, TimeoutException {
- // Setup test data
- //
- final int NUM_ITEMS = 5;
- final int NUM_IN_QUEUE = NUM_ITEMS - 1; // the last one not in queue for boundary condition
- final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- Feed feed = createTestFeed(NUM_ITEMS);
+ public void testRemoveQueueItemMultipleItems() throws Exception {
+ final int numItems = 5;
+ final int numInQueue = numItems - 1; // the last one not in queue for boundary condition
+ Feed feed = createTestFeed(numItems);
- List<FeedItem> itemsToAdd = feed.getItems().subList(0, NUM_IN_QUEUE);
- withPodDB(adapter -> adapter.setQueue(itemsToAdd) );
+ List<FeedItem> itemsToAdd = feed.getItems().subList(0, numInQueue);
+ withPodDB(adapter -> adapter.setQueue(itemsToAdd));
// Actual tests
//
@@ -706,12 +704,13 @@ public class DBWriterTest {
}
@Test
- public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
- final int NUM_ITEMS = 10;
+ public void testMoveQueueItem() throws Exception {
+ final int numItems = 10;
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- for (int i = 0; i < NUM_ITEMS; i++) {
- FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
+ for (int i = 0; i < numItems; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i,
+ new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item);
}
@@ -723,8 +722,8 @@ public class DBWriterTest {
for (FeedItem item : feed.getItems()) {
assertTrue(item.getId() != 0);
}
- for (int from = 0; from < NUM_ITEMS; from++) {
- for (int to = 0; to < NUM_ITEMS; to++) {
+ for (int from = 0; from < numItems; from++) {
+ for (int to = 0; to < numItems; to++) {
if (from == to) {
continue;
}
@@ -740,7 +739,7 @@ public class DBWriterTest {
adapter = PodDBAdapter.getInstance();
adapter.open();
Cursor queue = adapter.getQueueIDCursor();
- assertEquals(NUM_ITEMS, queue.getCount());
+ assertEquals(numItems, queue.getCount());
assertTrue(queue.moveToPosition(from));
assertNotEquals(fromID, queue.getLong(0));
assertTrue(queue.moveToPosition(to));
@@ -753,12 +752,13 @@ public class DBWriterTest {
}
@Test
- public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException {
- final int NUM_ITEMS = 10;
+ public void testMarkFeedRead() throws Exception {
+ final int numItems = 10;
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- for (int i = 0; i < NUM_ITEMS; i++) {
- FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
+ for (int i = 0; i < numItems; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i,
+ new Date(), FeedItem.UNPLAYED, feed);
feed.getItems().add(item);
}
@@ -780,12 +780,13 @@ public class DBWriterTest {
}
@Test
- public void testMarkAllItemsReadSameFeed() throws InterruptedException, ExecutionException, TimeoutException {
- final int NUM_ITEMS = 10;
+ public void testMarkAllItemsReadSameFeed() throws Exception {
+ final int numItems = 10;
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- for (int i = 0; i < NUM_ITEMS; i++) {
- FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
+ for (int i = 0; i < numItems; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i,
+ new Date(), FeedItem.UNPLAYED, feed);
feed.getItems().add(item);
}
@@ -810,7 +811,8 @@ public class DBWriterTest {
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
for (int i = 0; i < numItems; i++) {
- FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i,
+ new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item);
}
@@ -832,10 +834,7 @@ public class DBWriterTest {
}
}
- private static void assertQueueByItemIds(
- String message,
- long... itemIdsExpected
- ) {
+ private static void assertQueueByItemIds(String message, long... itemIdsExpected) {
List<FeedItem> queue = DBReader.getQueue();
List<Long> itemIdsActualList = toItemIds(queue);
List<Long> itemIdsExpectedList = new ArrayList<>(itemIdsExpected.length);
@@ -848,10 +847,9 @@ public class DBWriterTest {
private static List<Long> toItemIds(List<FeedItem> items) {
List<Long> itemIds = new ArrayList<>(items.size());
- for(FeedItem item : items) {
+ for (FeedItem item : items) {
itemIds.add(item.getId());
}
return itemIds;
}
-
}
diff --git a/core/src/test/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java b/core/src/test/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java
new file mode 100644
index 000000000..6bc614364
--- /dev/null
+++ b/core/src/test/java/de/danoeh/antennapod/core/syndication/namespace/atom/AtomTextTest.java
@@ -0,0 +1,35 @@
+package de.danoeh.antennapod.core.syndication.namespace.atom;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Unit test for {@link AtomText}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class AtomTextTest {
+
+ private static final String[][] TEST_DATA = {
+ {"&gt;", ">"},
+ {">", ">"},
+ {"&lt;Fran&ccedil;ais&gt;", "<Français>"},
+ {"ßÄÖÜ", "ßÄÖÜ"},
+ {"&quot;", "\""},
+ {"&szlig;", "ß"},
+ {"&#8217;", "’"},
+ {"&#x2030;", "‰"},
+ {"&euro;", "€"}
+ };
+
+ @Test
+ public void testProcessingHtml() {
+ for (String[] pair : TEST_DATA) {
+ final AtomText atomText = new AtomText("", new NSAtom(), AtomText.TYPE_HTML);
+ atomText.setContent(pair[0]);
+ assertEquals(pair[1], atomText.getProcessedContent());
+ }
+ }
+}
diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/util/DateUtilsTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/DateUtilsTest.java
index 5d98f133c..92888ae8b 100644
--- a/core/src/androidTest/java/de/danoeh/antennapod/core/util/DateUtilsTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/util/DateUtilsTest.java
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.core.util;
-import androidx.test.filters.SmallTest;
import org.junit.Test;
import java.util.Calendar;
@@ -12,16 +11,11 @@ import static org.junit.Assert.assertEquals;
/**
* Unit test for {@link DateUtils}.
- *
- * Note: It NEEDS to be run in android devices, i.e., it cannot be run in standard JDK, because
- * the test invokes some android platform-specific behavior in the underlying
- * {@link java.text.SimpleDateFormat} used by {@link DateUtils}.
- *
*/
-@SmallTest
public class DateUtilsTest {
+
@Test
- public void testParseDateWithMicroseconds() throws Exception {
+ public void testParseDateWithMicroseconds() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 13, 31, 4);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis() + 963);
@@ -30,7 +24,7 @@ public class DateUtilsTest {
}
@Test
- public void testParseDateWithCentiseconds() throws Exception {
+ public void testParseDateWithCentiseconds() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 13, 31, 4);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis() + 960);
@@ -39,17 +33,17 @@ public class DateUtilsTest {
}
@Test
- public void testParseDateWithDeciseconds() throws Exception {
+ public void testParseDateWithDeciseconds() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 13, 31, 4);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis() + 900);
Date actual = DateUtils.parse("2015-03-28T13:31:04.9");
- assertEquals(expected.getTime()/1000, actual.getTime()/1000);
- assertEquals(900, actual.getTime()%1000);
+ assertEquals(expected.getTime() / 1000, actual.getTime() / 1000);
+ assertEquals(900, actual.getTime() % 1000);
}
@Test
- public void testParseDateWithMicrosecondsAndTimezone() throws Exception {
+ public void testParseDateWithMicrosecondsAndTimezone() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 4);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis() + 963);
@@ -58,7 +52,7 @@ public class DateUtilsTest {
}
@Test
- public void testParseDateWithCentisecondsAndTimezone() throws Exception {
+ public void testParseDateWithCentisecondsAndTimezone() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 4);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis() + 960);
@@ -67,17 +61,17 @@ public class DateUtilsTest {
}
@Test
- public void testParseDateWithDecisecondsAndTimezone() throws Exception {
+ public void testParseDateWithDecisecondsAndTimezone() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 4);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis() + 900);
Date actual = DateUtils.parse("2015-03-28T13:31:04.9 +0700");
- assertEquals(expected.getTime()/1000, actual.getTime()/1000);
- assertEquals(900, actual.getTime()%1000);
+ assertEquals(expected.getTime() / 1000, actual.getTime() / 1000);
+ assertEquals(900, actual.getTime() % 1000);
}
@Test
- public void testParseDateWithTimezoneName() throws Exception {
+ public void testParseDateWithTimezoneName() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 4);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis());
@@ -86,7 +80,7 @@ public class DateUtilsTest {
}
@Test
- public void testParseDateWithTimezoneName2() throws Exception {
+ public void testParseDateWithTimezoneName2() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 6, 31, 0);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis());
@@ -95,7 +89,7 @@ public class DateUtilsTest {
}
@Test
- public void testParseDateWithTimeZoneOffset() throws Exception {
+ public void testParseDateWithTimeZoneOffset() {
GregorianCalendar exp = new GregorianCalendar(2015, 2, 28, 12, 16, 12);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis());
@@ -104,7 +98,7 @@ public class DateUtilsTest {
}
@Test
- public void testAsctime() throws Exception {
+ public void testAsctime() {
GregorianCalendar exp = new GregorianCalendar(2011, 4, 25, 12, 33, 0);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis());
@@ -113,7 +107,7 @@ public class DateUtilsTest {
}
@Test
- public void testMultipleConsecutiveSpaces() throws Exception {
+ public void testMultipleConsecutiveSpaces() {
GregorianCalendar exp = new GregorianCalendar(2010, 2, 23, 6, 6, 26);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis());
@@ -121,14 +115,8 @@ public class DateUtilsTest {
assertEquals(expected, actual);
}
- /**
- * Requires Android platform.
- *
- * Reason: Standard JDK cannot parse timezone <code>-08:00</code> (ISO 8601 format). It only accepts
- * <code>-0800</code> (RFC 822 format)
- */
@Test
- public void testParseDateWithNoTimezonePadding() throws Exception {
+ public void testParseDateWithNoTimezonePadding() {
GregorianCalendar exp = new GregorianCalendar(2017, 1, 22, 22, 28, 0);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis() + 2);
@@ -143,7 +131,7 @@ public class DateUtilsTest {
* @see #testParseDateWithNoTimezonePadding()
*/
@Test
- public void testParseDateWithForCest() throws Exception {
+ public void testParseDateWithForCest() {
GregorianCalendar exp1 = new GregorianCalendar(2017, 0, 28, 22, 0, 0);
exp1.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected1 = new Date(exp1.getTimeInMillis());
diff --git a/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/FilenameGeneratorTest.java
index 93e5bcb74..af22a4b9d 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/util/FilenameGeneratorTest.java
@@ -1,24 +1,21 @@
-package de.test.antennapod.util;
+package de.danoeh.antennapod.core.util;
-import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
import android.text.TextUtils;
import java.io.File;
-import java.io.IOException;
-import de.danoeh.antennapod.core.util.FileNameGenerator;
import org.apache.commons.lang3.StringUtils;
-import org.junit.After;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
-@SmallTest
+@RunWith(RobolectricTestRunner.class)
public class FilenameGeneratorTest {
public FilenameGeneratorTest() {
@@ -26,21 +23,21 @@ public class FilenameGeneratorTest {
}
@Test
- public void testGenerateFileName() throws IOException {
+ public void testGenerateFileName() throws Exception {
String result = FileNameGenerator.generateFileName("abc abc");
assertEquals(result, "abc abc");
createFiles(result);
}
@Test
- public void testGenerateFileName1() throws IOException {
+ public void testGenerateFileName1() throws Exception {
String result = FileNameGenerator.generateFileName("ab/c: <abc");
assertEquals(result, "abc abc");
createFiles(result);
}
@Test
- public void testGenerateFileName2() throws IOException {
+ public void testGenerateFileName2() throws Exception {
String result = FileNameGenerator.generateFileName("abc abc ");
assertEquals(result, "abc abc");
createFiles(result);
@@ -71,7 +68,7 @@ public class FilenameGeneratorTest {
}
@Test
- public void testLongFilename() throws IOException {
+ public void testLongFilename() throws Exception {
String longName = StringUtils.repeat("x", 20 + FileNameGenerator.MAX_FILENAME_LENGTH);
String result = FileNameGenerator.generateFileName(longName);
assertTrue(result.length() <= FileNameGenerator.MAX_FILENAME_LENGTH);
@@ -89,16 +86,13 @@ public class FilenameGeneratorTest {
/**
* Tests if files can be created.
- *
- * @throws IOException
*/
- private void createFiles(String name) throws IOException {
+ private void createFiles(String name) throws Exception {
File cache = InstrumentationRegistry.getInstrumentation().getTargetContext().getExternalCacheDir();
File testFile = new File(cache, name);
- testFile.mkdir();
+ assertTrue(testFile.mkdir());
assertTrue(testFile.exists());
- testFile.delete();
+ assertTrue(testFile.delete());
assertTrue(testFile.createNewFile());
}
-
}
diff --git a/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/URLCheckerTest.java
index 7f26ff612..a4b3dee06 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/util/URLCheckerTest.java
@@ -1,17 +1,17 @@
-package de.test.antennapod.util;
+package de.danoeh.antennapod.core.util;
-import androidx.test.filters.SmallTest;
-import de.danoeh.antennapod.core.util.URLChecker;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
- * Test class for URLChecker
+ * Test class for {@link URLChecker}
*/
-@SmallTest
+@RunWith(RobolectricTestRunner.class)
public class URLCheckerTest {
@Test
@@ -78,7 +78,7 @@ public class URLCheckerTest {
}
@Test
- public void testAntennaPodSubscribeProtocolNoScheme() throws Exception {
+ public void testAntennaPodSubscribeProtocolNoScheme() {
final String in = "antennapod-subscribe://example.com";
final String out = URLChecker.prepareURL(in);
assertEquals("http://example.com", out);
@@ -92,14 +92,14 @@ public class URLCheckerTest {
}
@Test
- public void testAntennaPodSubscribeProtocolWithScheme() throws Exception {
+ public void testAntennaPodSubscribeProtocolWithScheme() {
final String in = "antennapod-subscribe://https://example.com";
final String out = URLChecker.prepareURL(in);
assertEquals("https://example.com", out);
}
@Test
- public void testProtocolRelativeUrlIsAbsolute() throws Exception {
+ public void testProtocolRelativeUrlIsAbsolute() {
final String in = "https://example.com";
final String inBase = "http://examplebase.com";
final String out = URLChecker.prepareURL(in, inBase);
@@ -107,7 +107,7 @@ public class URLCheckerTest {
}
@Test
- public void testProtocolRelativeUrlIsRelativeHttps() throws Exception {
+ public void testProtocolRelativeUrlIsRelativeHttps() {
final String in = "//example.com";
final String inBase = "https://examplebase.com";
final String out = URLChecker.prepareURL(in, inBase);
@@ -115,7 +115,7 @@ public class URLCheckerTest {
}
@Test
- public void testProtocolRelativeUrlIsHttpsWithAPSubscribeProtocol() throws Exception {
+ public void testProtocolRelativeUrlIsHttpsWithApSubscribeProtocol() {
final String in = "//example.com";
final String inBase = "antennapod-subscribe://https://examplebase.com";
final String out = URLChecker.prepareURL(in, inBase);
@@ -123,7 +123,7 @@ public class URLCheckerTest {
}
@Test
- public void testProtocolRelativeUrlBaseUrlNull() throws Exception {
+ public void testProtocolRelativeUrlBaseUrlNull() {
final String in = "example.com";
final String out = URLChecker.prepareURL(in, null);
assertEquals("http://example.com", out);
diff --git a/app/src/androidTest/java/de/test/antennapod/entities/ExternalMediaTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/playback/ExternalMediaTest.java
index 83d7a4d22..d5e63eeba 100644
--- a/app/src/androidTest/java/de/test/antennapod/entities/ExternalMediaTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/util/playback/ExternalMediaTest.java
@@ -1,29 +1,31 @@
-package de.test.antennapod.entities;
+package de.danoeh.antennapod.core.util.playback;
import android.annotation.SuppressLint;
+import android.content.Context;
import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.filters.SmallTest;
import de.danoeh.antennapod.core.feed.MediaType;
-import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import org.junit.After;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import static org.junit.Assert.assertEquals;
/**
* Tests for {@link ExternalMedia} entity.
*/
-@SmallTest
+@RunWith(RobolectricTestRunner.class)
public class ExternalMediaTest {
private static final int NOT_SET = -1;
+ private static final int POSITION = 50;
+ private static final int LAST_PLAYED_TIME = 1650;
@After
- public void tearDown() throws Exception {
+ public void tearDown() {
clearSharedPrefs();
}
@@ -36,14 +38,12 @@ public class ExternalMediaTest {
}
private SharedPreferences getDefaultSharedPrefs() {
- return PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getInstrumentation().getTargetContext());
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ return PreferenceManager.getDefaultSharedPreferences(context);
}
@Test
public void testSaveCurrentPositionUpdatesPreferences() {
- final int POSITION = 50;
- final int LAST_PLAYED_TIME = 1650;
-
assertEquals(NOT_SET, getDefaultSharedPrefs().getInt(ExternalMedia.PREF_POSITION, NOT_SET));
assertEquals(NOT_SET, getDefaultSharedPrefs().getLong(ExternalMedia.PREF_LAST_PLAYED_TIME, NOT_SET));
diff --git a/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/playback/TimelineTest.java
index ed37b7daa..8927a41de 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/util/playback/TimelineTest.java
@@ -1,9 +1,8 @@
-package de.test.antennapod.util.playback;
+package de.danoeh.antennapod.core.util.playback;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -15,10 +14,15 @@ import java.util.List;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.util.playback.Playable;
-import de.danoeh.antennapod.core.util.playback.Timeline;
+import de.danoeh.antennapod.core.storage.DBReader;
+
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.robolectric.RobolectricTestRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -26,18 +30,28 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
- * Test class for timeline.
+ * Test class for {@link Timeline}.
*/
-@SmallTest
+@RunWith(RobolectricTestRunner.class)
public class TimelineTest {
private Context context;
+ MockedStatic<DBReader> dbReaderMock;
@Before
public void setUp() {
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ // mock DBReader, because Timeline.processShownotes() calls FeedItem.loadShownotes()
+ // which calls DBReader.loadDescriptionOfFeedItem(), but we don't need the database here
+ dbReaderMock = Mockito.mockStatic(DBReader.class);
+ }
+
+ @After
+ public void tearDown() {
+ dbReaderMock.close();
}
+ @SuppressWarnings("SameParameterValue")
private Playable newTestPlayable(List<Chapter> chapters, String shownotes, int duration) {
FeedItem item = new FeedItem(0, "Item", "item-id", "http://example.com/item", new Date(), FeedItem.PLAYED, null);
item.setChapters(chapters);
@@ -49,7 +63,7 @@ public class TimelineTest {
}
@Test
- public void testProcessShownotesAddTimecodeHHMMSSNoChapters() {
+ public void testProcessShownotesAddTimecodeHhmmssNoChapters() {
final String timeStr = "10:11:12";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11 + 12 * 1000;
@@ -61,7 +75,7 @@ public class TimelineTest {
}
@Test
- public void testProcessShownotesAddTimecodeHHMMSSMoreThen24HoursNoChapters() {
+ public void testProcessShownotesAddTimecodeHhmmssMoreThen24HoursNoChapters() {
final String timeStr = "25:00:00";
final long time = 25 * 60 * 60 * 1000;
@@ -73,7 +87,7 @@ public class TimelineTest {
}
@Test
- public void testProcessShownotesAddTimecodeHHMMNoChapters() {
+ public void testProcessShownotesAddTimecodeHhmmNoChapters() {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
@@ -85,7 +99,7 @@ public class TimelineTest {
}
@Test
- public void testProcessShownotesAddTimecodeMMSSNoChapters() {
+ public void testProcessShownotesAddTimecodeMmssNoChapters() {
final String timeStr = "10:11";
final long time = 10 * 60 * 1000 + 11 * 1000;
@@ -97,7 +111,7 @@ public class TimelineTest {
}
@Test
- public void testProcessShownotesAddTimecodeHMMSSNoChapters() {
+ public void testProcessShownotesAddTimecodeHmmssNoChapters() {
final String timeStr = "2:11:12";
final long time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000;
Playable p = newTestPlayable(null, "<p> Some test text with a timecode "
@@ -108,7 +122,7 @@ public class TimelineTest {
}
@Test
- public void testProcessShownotesAddTimecodeMSSNoChapters() {
+ public void testProcessShownotesAddTimecodeMssNoChapters() {
final String timeStr = "1:12";
final long time = 60 * 1000 + 12 * 1000;
@@ -139,8 +153,8 @@ public class TimelineTest {
+ timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 2 * 60 * 60 * 1000);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
- checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000,
- 60 * 60 * 1000 + 10 * 60 * 1000 + 12 * 1000 }, timeStrings);
+ checkLinkCorrect(res, new long[]{10 * 60 * 1000 + 12 * 1000,
+ 60 * 60 * 1000 + 10 * 60 * 1000 + 12 * 1000}, timeStrings);
}
@Test
@@ -153,7 +167,7 @@ public class TimelineTest {
+ timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 3 * 60 * 60 * 1000);
Timeline t = new Timeline(context, p);
String res = t.processShownotes();
- checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000, 2 * 60 * 1000 + 12 * 1000 }, timeStrings);
+ checkLinkCorrect(res, new long[]{10 * 60 * 1000 + 12 * 1000, 2 * 60 * 1000 + 12 * 1000}, timeStrings);
}
@Test
diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/FeedDiscovererTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/syndication/FeedDiscovererTest.java
index b213a5efa..3df5230cc 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/syndication/FeedDiscovererTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/util/syndication/FeedDiscovererTest.java
@@ -1,26 +1,28 @@
-package de.test.antennapod.util.syndication;
+package de.danoeh.antennapod.core.util.syndication;
import androidx.test.platform.app.InstrumentationRegistry;
+
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import java.io.File;
import java.io.FileOutputStream;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.Map;
-import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
- * Test class for FeedDiscoverer
+ * Test class for {@link FeedDiscoverer}
*/
+@RunWith(RobolectricTestRunner.class)
public class FeedDiscovererTest {
private FeedDiscoverer fd;
@@ -28,10 +30,11 @@ public class FeedDiscovererTest {
private File testDir;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
fd = new FeedDiscoverer();
testDir = new File(InstrumentationRegistry
.getInstrumentation().getTargetContext().getFilesDir(), "FeedDiscovererTest");
+ //noinspection ResultOfMethodCallIgnored
testDir.mkdir();
assertTrue(testDir.exists());
}
@@ -41,6 +44,7 @@ public class FeedDiscovererTest {
FileUtils.deleteDirectory(testDir);
}
+ @SuppressWarnings("SameParameterValue")
private String createTestHtmlString(String rel, String type, String href, String title) {
return String.format("<html><head><title>Test</title><link rel=\"%s\" type=\"%s\" href=\"%s\" title=\"%s\"></head><body></body></html>",
rel, type, href, title);
@@ -69,7 +73,7 @@ public class FeedDiscovererTest {
} else {
File testFile = new File(testDir, "feed");
FileOutputStream out = new FileOutputStream(testFile);
- IOUtils.write(html, out, Charset.forName("UTF-8"));
+ IOUtils.write(html, out, StandardCharsets.UTF_8);
out.close();
res = fd.findLinks(testFile, base);
}
diff --git a/createContributors.py b/createContributors.py
new file mode 100644
index 000000000..fb9bed857
--- /dev/null
+++ b/createContributors.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+import pycountry
+import requests
+import configparser
+import os
+
+contributorsFile = open("CONTRIBUTORS.md", "w")
+
+###### Developers #####
+MAINTAINERS = ['ByteHamster', 'keunes']
+FORMER_MAINTAINERS = ['mfietz', 'TomHennen']
+
+csvFile = open("app/src/main/assets/developers.csv", "w")
+contributorsFile.write('# Developers\n\n')
+page = 1
+hasMore = True
+first = True
+while hasMore:
+ json = requests.get('https://api.github.com/repos/AntennaPod/AntennaPod/contributors'
+ + '?q=contributions&order=desc&per_page=100&page=' + str(page)).json()
+ for contributor in json:
+ role = 'Contributor'
+ if contributor['login'] == 'danieloeh':
+ role = 'Original creator of AntennaPod (retired)'
+ elif contributor['login'] in MAINTAINERS:
+ role = 'Maintainer'
+ elif contributor['login'] in FORMER_MAINTAINERS:
+ role = 'Maintainer (retired)'
+ csvFile.write(contributor['login'].replace(";", "") + ';' + str(contributor['id']) + ';' + role + '\n')
+ if not first:
+ contributorsFile.write(', ')
+ first = False
+ contributorsFile.write('[' + contributor['login'] + '](https://github.com/' + contributor['login'] + ')')
+ page = page + 1
+ hasMore = len(json) > 0
+csvFile.close()
+
+###### Translators #####
+config = configparser.ConfigParser()
+config.read(os.path.expanduser("~") + '/.transifexrc')
+if 'https://www.transifex.com' in config:
+ TRANSIFEX_USER = config['https://www.transifex.com']['username']
+ TRANSIFEX_PW = config['https://www.transifex.com']['password']
+else:
+ TRANSIFEX_USER = ""
+ TRANSIFEX_PW = ""
+
+csvFile = open("app/src/main/assets/translators.csv", "w")
+r = requests.get('http://www.transifex.com/api/2/project/antennapod/languages/',
+ auth=(TRANSIFEX_USER, TRANSIFEX_PW))
+contributorsFile.write('\n\n# Translators\n\n')
+contributorsFile.write('| Language | Translators |\n| :-- | :-- |\n')
+
+for lang in r.json():
+ langContributers = lang['coordinators'] + lang['reviewers'] + lang['translators']
+ langContributers = sorted(langContributers, key=str.lower)
+ langCode = lang['language_code']
+ try:
+ langName = pycountry.languages.lookup(langCode).name
+ except:
+ try:
+ langName = pycountry.languages.lookup(
+ langCode.split('_')[0]).name + ' (' + langCode + ')'
+ except:
+ langName = lang['language_code']
+ print('\033[91mLanguage code not found:' + langCode + '\033[0m')
+
+ joinedTranslators = ', '.join(langContributers).replace(';', '')
+ contributorsFile.write('| ' + langName + ' | ' + joinedTranslators + ' |\n')
+ csvFile.write(langName + ';' + joinedTranslators + '\n')
+csvFile.close()
+
+contributorsFile.close()
diff --git a/createDevelopersList.py b/createDevelopersList.py
deleted file mode 100644
index df804b979..000000000
--- a/createDevelopersList.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python3
-import requests
-
-MAINTAINERS = ['mfietz', 'ByteHamster']
-FORMER_MAINTAINERS = ['TomHennen']
-
-csvFile = open("app/src/main/assets/developers.csv", "w")
-contributorsFile = open("CONTRIBUTORS", "a")
-page = 1
-hasMore = True
-while hasMore:
- json = requests.get('https://api.github.com/repos/AntennaPod/AntennaPod/contributors'
- + '?q=contributions&order=desc&per_page=100&page=' + str(page)).json()
- for contributor in json:
- role = 'Contributor'
- if contributor['login'] == 'danieloeh':
- role = 'Original creator of AntennaPod (retired)'
- elif contributor['login'] in MAINTAINERS:
- role = 'Maintainer'
- elif contributor['login'] in FORMER_MAINTAINERS:
- role = 'Maintainer (retired)'
- line = contributor['login'].replace(";", "") + ';' + str(contributor['id']) + ';' + role
- csvFile.write(line + '\n')
- print(line)
- contributorsFile.write(contributor['login'] + '\n')
- page = page + 1
- hasMore = len(json) > 0
-csvFile.close()
-contributorsFile.close()
-
diff --git a/createTranslatorsList.py b/createTranslatorsList.py
deleted file mode 100644
index 8ada1397d..000000000
--- a/createTranslatorsList.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python3
-import pycountry
-import requests
-import configparser
-import os
-
-config = configparser.ConfigParser()
-config.read(os.path.expanduser("~") + '/.transifexrc')
-if 'https://www.transifex.com' in config:
- TRANSIFEX_USER = config['https://www.transifex.com']['username']
- TRANSIFEX_PW = config['https://www.transifex.com']['password']
-else:
- TRANSIFEX_USER = ""
- TRANSIFEX_PW = ""
-
-csvFile = open("app/src/main/assets/translators.csv", "w")
-contributorsFile = open("CONTRIBUTORS", "a")
-r = requests.get('http://www.transifex.com/api/2/project/antennapod/languages/',
- auth=(TRANSIFEX_USER, TRANSIFEX_PW))
-for lang in r.json():
- langContributers = lang['coordinators'] + lang['reviewers'] + lang['translators']
- langContributers = sorted(langContributers, key=str.lower)
- langCode = lang['language_code']
- try:
- langName = pycountry.languages.lookup(langCode).name
- except:
- try:
- langName = pycountry.languages.lookup(
- langCode.split('_')[0]).name + ' (' + langCode + ')'
- except:
- langName = lang['language_code']
- print('\033[91mLanguage code not found:' + langCode + '\033[0m')
-
- joinedTranslators = ', '.join(langContributers).replace(';', '')
- contributorsFile.write(langName + ": " + joinedTranslators + '\n')
- csvFile.write(langName + ';' + joinedTranslators + '\n')
- print(langName + ';' + joinedTranslators)
-csvFile.close()
-contributorsFile.close()