summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorByteHamster <ByteHamster@users.noreply.github.com>2024-03-31 18:40:15 +0200
committerGitHub <noreply@github.com>2024-03-31 18:40:15 +0200
commitedb440a5a9a05e24c344a71b272b9238217e9c55 (patch)
tree13623ca7d0dac052ac35d693aac940d0727c87f9 /app
parent4e47691e70e85736c7eeb30ce02c73176e565a86 (diff)
downloadAntennaPod-edb440a5a9a05e24c344a71b272b9238217e9c55.zip
Restructure related UI classes together (#7044)
Diffstat (limited to 'app')
-rw-r--r--app/build.gradle4
-rw-r--r--app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java12
-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.java2
-rw-r--r--app/src/main/AndroidManifest.xml31
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ClientConfigurator.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java (renamed from app/src/main/java/de/danoeh/antennapod/error/CrashReportWriter.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/PodcastApp.java24
-rw-r--r--app/src/main/java/de/danoeh/antennapod/PreferenceUpgrader.java (renamed from app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java)12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/RxJavaErrorHandlerSetup.java (renamed from app/src/main/java/de/danoeh/antennapod/error/RxJavaErrorHandlerSetup.java)3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/CancelDownloadActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/CancelDownloadActionButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/DeleteActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DeleteActionButton.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/DownloadActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/ItemActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/MarkAsPlayedActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MarkAsPlayedActionButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/PauseActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PauseActionButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/PlayActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/PlayLocalActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/StreamActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/actionbutton/VisitWebsiteActionButton.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java32
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java25
-rw-r--r--app/src/main/java/de/danoeh/antennapod/receiver/PowerConnectionReceiver.java48
-rw-r--r--app/src/main/java/de/danoeh/antennapod/spa/SPAReceiver.java (renamed from app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/AllEpisodesFilterDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/AllEpisodesFilterDialog.java)5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/CoverLoader.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/FeedItemFilterDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/FeedItemFilterDialog.java)5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/MenuItemUtils.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/SelectableAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/SelectableAdapter.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/SimpleChipAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/SimpleChipAdapter.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/StreamingConfirmationDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/TransitionEffect.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/TransitionEffect.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/cleaner/HtmlToPlainText.java123
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/cleaner/ShownotesCleaner.java208
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemListAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/EpisodeItemListAdapter.java)7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemListRecyclerView.java (renamed from app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemViewHolder.java (renamed from app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java)7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeMultiSelectActionHandler.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/actions/EpisodeMultiSelectActionHandler.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodesListFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java)38
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/FeedItemMenuHandler.java (renamed from app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java)8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/HorizontalItemListAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/HorizontalItemListAdapter.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/HorizontalItemViewHolder.java (renamed from app/src/main/java/de/danoeh/antennapod/view/viewholder/HorizontalItemViewHolder.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/MediaSizeLoader.java78
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/episodeslist/MoreContentListFooterUtil.java53
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/AddFeedFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java)3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/AllEpisodesFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java)7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/InboxFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java)5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/PlaybackHistoryFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java)5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/SearchFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java)22
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/chapter/ChaptersFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java)3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/chapter/ChaptersListAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/download/CompletedDownloadsFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java)25
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadErrorLabel.java46
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogDetailsDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/DownloadLogDetailsDialog.java)3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogItemViewHolder.java (renamed from app/src/main/java/de/danoeh/antennapod/view/viewholder/DownloadLogItemViewHolder.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/DrawerPreferencesDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/DrawerPreferencesDialog.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/NavDrawerFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java)31
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/NavListAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java)21
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/episode/ItemFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java)27
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/episode/ItemPagerFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java)5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedInfoFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java)10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedItemFilterGroup.java37
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedItemlistFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java)33
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ItemFilterDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/ItemFilterDialog.java)5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ItemSortDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/ItemSortDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/RemoveFeedDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/RenameFeedDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/RenameItemDialog.java)8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ToolbarIconTintManager.java (renamed from app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/EditUrlSettingsDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/EditUrlSettingsDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/EpisodeFilterDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/EpisodeFilterDialog.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/FeedPreferenceSkipDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/FeedPreferenceSkipDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/FeedSettingsFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java)5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/SkipPreferenceDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/TagSettingsDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/TagSettingsDialog.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/VolumeAdaptationPreference.java (renamed from app/src/main/java/de/danoeh/antennapod/preferences/VolumeAdaptationPreference.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/HomeFragment.java)20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeSection.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/HomeSection.java)12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeSectionsSettingsDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/HomeSectionsSettingsDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/AllowNotificationsSection.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/sections/AllowNotificationsSection.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/DownloadsSection.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/sections/DownloadsSection.java)14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/EchoSection.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/sections/EchoSection.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/EpisodesSurpriseSection.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/sections/EpisodesSurpriseSection.java)12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/InboxSection.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/sections/InboxSection.java)12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/QueueSection.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/sections/QueueSection.java)12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/SubscriptionsSection.java (renamed from app/src/main/java/de/danoeh/antennapod/ui/home/sections/SubscriptionsSection.java)10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedDiscoverer.java79
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedItemlistDescriptionAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/OnlineFeedViewActivity.java (renamed from app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java)8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/MediaPlayerErrorDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/MediaPlayerErrorDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlayButton.java (renamed from app/src/main/java/de/danoeh/antennapod/view/PlayButton.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackControlsDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackSpeedDialogActivity.java (renamed from app/src/main/java/de/danoeh/antennapod/activity/PlaybackSpeedDialogActivity.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackSpeedSeekBar.java (renamed from app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/SleepTimerDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/TimeRangeDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/TimeRangeDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/VariableSpeedDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java)5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/AudioPlayerFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java)15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ChapterSeekBar.java (renamed from app/src/main/java/de/danoeh/antennapod/view/ChapterSeekBar.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/CoverFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java)3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ExternalPlayerFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ItemDescriptionFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java)6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/NoRelayoutTextView.java (renamed from app/src/main/java/de/danoeh/antennapod/view/NoRelayoutTextView.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/AspectRatioVideoView.java (renamed from app/src/main/java/de/danoeh/antennapod/view/AspectRatioVideoView.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/PictureInPictureUtil.java27
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/VideoplayerActivity.java (renamed from app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java)20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/BugReportActivity.java (renamed from app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/DownloadsPreferencesFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/DownloadsPreferencesFragment.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/ImportExportPreferencesFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java)3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/MainPreferencesFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PlaybackPreferencesFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java)7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceActivity.java (renamed from app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java)8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceListDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/dialog/PreferenceListDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceSwitchDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/dialog/PreferenceSwitchDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/ProxyDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/SwipePreferencesFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/SwipePreferencesFragment.java)17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/UserInterfacePreferencesFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java)9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/queue/QueueFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java)26
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/queue/QueueRecyclerAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java)7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/rating/RatingDialogFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/rating/RatingDialogFragment.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/rating/RatingDialogManager.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/rating/RatingDialogManager.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMenuHandler.java (renamed from app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java)14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMultiSelectActionHandler.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java)10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedSortDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/FeedSortDialog.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/HorizontalFeedListAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/HorizontalFeedListAdapter.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionFragment.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java)19
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsFilterDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java)3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsFilterGroup.java33
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsRecyclerAdapter.java (renamed from app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java)7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/share/ShareDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/ShareDialog.java)3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/share/ShareUtils.java92
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/AddToQueueSwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/AddToQueueSwipeAction.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/DeleteSwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/DeleteSwipeAction.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/MarkFavoriteSwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/MarkFavoriteSwipeAction.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromHistorySwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromHistorySwipeAction.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromInboxSwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromInboxSwipeAction.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromQueueSwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromQueueSwipeAction.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/ShowFirstSwipeDialogAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/ShowFirstSwipeDialogAction.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/StartDownloadSwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/StartDownloadSwipeAction.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeAction.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeActions.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeActions.java)15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeActionsDialog.java (renamed from app/src/main/java/de/danoeh/antennapod/dialog/SwipeActionsDialog.java)24
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/swipeactions/TogglePlaybackStateSwipeAction.java (renamed from app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/TogglePlaybackStateSwipeAction.java)4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/view/EmptyViewHandler.java (renamed from app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/view/ItemOffsetDecoration.java (renamed from app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/view/LiftOnScrollListener.java (renamed from app/src/main/java/de/danoeh/antennapod/view/LiftOnScrollListener.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/view/LocalDeleteModal.java (renamed from app/src/main/java/de/danoeh/antennapod/view/LocalDeleteModal.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/view/LockableBottomSheetBehavior.java (renamed from app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/view/NestedScrollableHost.java (renamed from app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java)2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/view/ShownotesWebView.java (renamed from app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java)8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/ui/view/SimpleAdapterDataObserver.java (renamed from app/src/main/java/de/danoeh/antennapod/view/SimpleAdapterDataObserver.java)2
-rw-r--r--app/src/main/res/layout-sw720dp/main.xml2
-rw-r--r--app/src/main/res/layout/audioplayer_fragment.xml8
-rw-r--r--app/src/main/res/layout/episodes_list_fragment.xml2
-rw-r--r--app/src/main/res/layout/external_player_fragment.xml2
-rw-r--r--app/src/main/res/layout/feed_item_list_fragment.xml2
-rw-r--r--app/src/main/res/layout/feeditem_fragment.xml6
-rw-r--r--app/src/main/res/layout/item_description_fragment.xml15
-rw-r--r--app/src/main/res/layout/main.xml2
-rw-r--r--app/src/main/res/layout/playback_speed_feed_setting_dialog.xml2
-rw-r--r--app/src/main/res/layout/queue_fragment.xml2
-rw-r--r--app/src/main/res/layout/search_fragment.xml2
-rw-r--r--app/src/main/res/layout/simple_list_fragment.xml2
-rw-r--r--app/src/main/res/layout/speed_select_dialog.xml2
-rw-r--r--app/src/main/res/layout/videoplayer_activity.xml19
-rw-r--r--app/src/main/res/xml/feed_settings.xml2
-rw-r--r--app/src/test/java/de/danoeh/antennapod/ui/cleaner/ShownotesCleanerTest.java236
-rw-r--r--app/src/test/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedDiscovererTest.java128
173 files changed, 1662 insertions, 617 deletions
diff --git a/app/build.gradle b/app/build.gradle
index a07d0db4a..449488f58 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -122,6 +122,10 @@ dependencies {
implementation 'com.github.skydoves:balloon:1.5.3'
implementation 'com.github.xabaras:RecyclerViewSwipeDecorator:1.3'
+ testImplementation "androidx.test:core:$testCoreVersion"
+ testImplementation "junit:junit:$junitVersion"
+ testImplementation "org.robolectric:robolectric:$robolectricVersion"
+
androidTestImplementation "org.awaitility:awaitility:$awaitilityVersion"
androidTestImplementation 'com.nanohttpd:nanohttpd:2.1.1'
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
diff --git a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
index 041106017..c52df7f3e 100644
--- a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
@@ -25,7 +25,7 @@ import junit.framework.AssertionFailedError;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.fragment.NavDrawerFragment;
+import de.danoeh.antennapod.ui.screen.drawer.NavDrawerFragment;
import org.awaitility.Awaitility;
import org.awaitility.core.ConditionTimeoutException;
import org.hamcrest.Matcher;
diff --git a/app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java b/app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java
index 58a4a0bb6..2afe196b1 100644
--- a/app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java
@@ -8,7 +8,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
import de.test.antennapod.EspressoTestUtils;
import de.test.antennapod.ui.UITestUtils;
import org.hamcrest.Matcher;
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 5ccb35228..0246cf890 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java
@@ -7,14 +7,14 @@ 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.activity.PreferenceActivity;
-import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
+import de.danoeh.antennapod.ui.screen.preferences.PreferenceActivity;
+import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
-import de.danoeh.antennapod.fragment.NavDrawerFragment;
-import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
-import de.danoeh.antennapod.fragment.QueueFragment;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.drawer.NavDrawerFragment;
+import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
import de.test.antennapod.EspressoTestUtils;
import org.junit.After;
import org.junit.Before;
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 9ba4276be..8d956e3e4 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
@@ -9,7 +9,7 @@ import androidx.preference.PreferenceManager;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
+import de.danoeh.antennapod.ui.screen.preferences.PreferenceActivity;
import de.danoeh.antennapod.core.storage.APCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm;
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 da323af76..0f472b699 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java
@@ -5,7 +5,7 @@ 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.danoeh.antennapod.ui.screen.queue.QueueFragment;
import de.test.antennapod.EspressoTestUtils;
import org.junit.Before;
import org.junit.Rule;
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 66f0b8766..3d608133f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -44,7 +44,7 @@
android:networkSecurityConfig="@xml/network_security_config">
<activity
- android:name=".activity.PlaybackSpeedDialogActivity"
+ android:name=".ui.screen.playback.PlaybackSpeedDialogActivity"
android:noHistory="true"
android:exported="false"
android:excludeFromRecents="true"
@@ -129,7 +129,7 @@
</activity>
<activity
- android:name=".activity.PreferenceActivity"
+ android:name=".ui.screen.preferences.PreferenceActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="false"
android:label="@string/settings_label">
@@ -167,15 +167,15 @@
</intent-filter>
</activity>
<activity
- android:name=".activity.BugReportActivity"
+ android:name=".ui.screen.preferences.BugReportActivity"
android:label="@string/bug_report_title">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
+ android:value="de.danoeh.antennapod.ui.screen.preferences.PreferenceActivity"/>
</activity>
<activity
- android:name=".activity.VideoplayerActivity"
+ android:name=".ui.screen.playback.video.VideoplayerActivity"
android:configChanges="keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize"
android:supportsPictureInPicture="true"
android:screenOrientation="sensorLandscape"
@@ -190,7 +190,7 @@
</activity>
<activity
- android:name=".activity.OnlineFeedViewActivity"
+ android:name=".ui.screen.onlinefeedview.OnlineFeedViewActivity"
android:configChanges="orientation|screenSize"
android:theme="@style/Theme.AntennaPod.Dark.Translucent"
android:label="@string/add_feed_label"
@@ -322,24 +322,7 @@
</activity>
<receiver
- android:name=".receiver.ConnectivityActionReceiver"
- android:exported="true">
- <intent-filter>
- <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
- </intent-filter>
- </receiver>
-
- <receiver
- android:name=".receiver.PowerConnectionReceiver"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
- <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
- </intent-filter>
- </receiver>
-
- <receiver
- android:name=".receiver.SPAReceiver"
+ android:name=".spa.SPAReceiver"
android:exported="true">
<intent-filter>
<action android:name="de.danoeh.antennapdsp.intent.SP_APPS_QUERY_FEEDS_RESPONSE"/>
diff --git a/app/src/main/java/de/danoeh/antennapod/ClientConfigurator.java b/app/src/main/java/de/danoeh/antennapod/ClientConfigurator.java
index a0cf4bfc9..43be25afa 100644
--- a/app/src/main/java/de/danoeh/antennapod/ClientConfigurator.java
+++ b/app/src/main/java/de/danoeh/antennapod/ClientConfigurator.java
@@ -20,7 +20,6 @@ import de.danoeh.antennapod.net.common.AntennapodHttpClient;
import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface;
import de.danoeh.antennapod.net.download.service.feed.DownloadServiceInterfaceImpl;
import de.danoeh.antennapod.net.common.NetworkUtils;
-import de.danoeh.antennapod.core.util.download.NetworkConnectionChangeHandler;
import de.danoeh.antennapod.net.ssl.SslProviderInstaller;
import de.danoeh.antennapod.storage.database.PodDBAdapter;
@@ -48,7 +47,6 @@ public class ClientConfigurator {
PlaybackPreferences.init(context);
SslProviderInstaller.install(context);
NetworkUtils.init(context);
- NetworkConnectionChangeHandler.init(context);
DownloadServiceInterface.setImpl(new DownloadServiceInterfaceImpl());
FeedUpdateManager.setInstance(new FeedUpdateManagerImpl());
AutoDownloadManager.setInstance(new AutoDownloadManagerImpl());
diff --git a/app/src/main/java/de/danoeh/antennapod/error/CrashReportWriter.java b/app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java
index 356fd34ee..92d6785ab 100644
--- a/app/src/main/java/de/danoeh/antennapod/error/CrashReportWriter.java
+++ b/app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.error;
+package de.danoeh.antennapod;
import android.os.Build;
import android.util.Log;
diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
index a83e97d26..fb8c21883 100644
--- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
+++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
@@ -5,11 +5,9 @@ import android.os.StrictMode;
import com.google.android.material.color.DynamicColors;
-import de.danoeh.antennapod.error.CrashReportWriter;
-import de.danoeh.antennapod.error.RxJavaErrorHandlerSetup;
-import de.danoeh.antennapod.preferences.PreferenceUpgrader;
import de.danoeh.antennapod.spa.SPAUtil;
import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.EventBusException;
/** Main application class. */
public class PodcastApp extends Application {
@@ -30,16 +28,20 @@ public class PodcastApp extends Application {
StrictMode.setVmPolicy(builder.build());
}
+ try {
+ // Robolectric calls onCreate for every test, which causes problems with static members
+ EventBus.builder()
+ .addIndex(new ApEventBusIndex())
+ .logNoSubscriberMessages(false)
+ .sendNoSubscriberEvent(false)
+ .installDefaultEventBus();
+ } catch (EventBusException e) {
+ e.printStackTrace();
+ }
+
+ DynamicColors.applyToActivitiesIfAvailable(this);
ClientConfigurator.initialize(this);
PreferenceUpgrader.checkUpgrades(this);
-
SPAUtil.sendSPAppsQueryFeedsIntent(this);
- EventBus.builder()
- .addIndex(new ApEventBusIndex())
- .logNoSubscriberMessages(false)
- .sendNoSubscriberEvent(false)
- .installDefaultEventBus();
-
- DynamicColors.applyToActivitiesIfAvailable(this);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java b/app/src/main/java/de/danoeh/antennapod/PreferenceUpgrader.java
index 03355510d..02abc23fb 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java
+++ b/app/src/main/java/de/danoeh/antennapod/PreferenceUpgrader.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.preferences;
+package de.danoeh.antennapod;
import android.content.Context;
import android.content.SharedPreferences;
@@ -13,13 +13,13 @@ import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.storage.preferences.SleepTimerPreferences;
-import de.danoeh.antennapod.error.CrashReportWriter;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
+import de.danoeh.antennapod.CrashReportWriter;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.storage.preferences.UserPreferences.EnqueueLocation;
-import de.danoeh.antennapod.fragment.QueueFragment;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
+import de.danoeh.antennapod.ui.swipeactions.SwipeAction;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActions;
public class PreferenceUpgrader {
private static final String PREF_CONFIGURED_VERSION = "version_code";
diff --git a/app/src/main/java/de/danoeh/antennapod/error/RxJavaErrorHandlerSetup.java b/app/src/main/java/de/danoeh/antennapod/RxJavaErrorHandlerSetup.java
index 1c7f5f0b4..e909702ce 100644
--- a/app/src/main/java/de/danoeh/antennapod/error/RxJavaErrorHandlerSetup.java
+++ b/app/src/main/java/de/danoeh/antennapod/RxJavaErrorHandlerSetup.java
@@ -1,7 +1,6 @@
-package de.danoeh.antennapod.error;
+package de.danoeh.antennapod;
import android.util.Log;
-import de.danoeh.antennapod.BuildConfig;
import io.reactivex.exceptions.UndeliverableException;
import io.reactivex.plugins.RxJavaPlugins;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/CancelDownloadActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/CancelDownloadActionButton.java
index fa4b19b4d..3e8e65200 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/CancelDownloadActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/CancelDownloadActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import androidx.annotation.DrawableRes;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DeleteActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/DeleteActionButton.java
index 6b9114e81..3e88270da 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DeleteActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/DeleteActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import android.view.View;
@@ -11,7 +11,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.storage.database.DBWriter;
-import de.danoeh.antennapod.view.LocalDeleteModal;
+import de.danoeh.antennapod.ui.view.LocalDeleteModal;
public class DeleteActionButton extends ItemActionButton {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/DownloadActionButton.java
index af573218c..15f07d207 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/DownloadActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/DownloadActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import android.view.View;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/ItemActionButton.java
index 07ed5d443..84b246167 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/ItemActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/ItemActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import android.widget.ImageView;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MarkAsPlayedActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/MarkAsPlayedActionButton.java
index 34fef11dc..673a0c6ff 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/MarkAsPlayedActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/MarkAsPlayedActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import androidx.annotation.DrawableRes;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PauseActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/PauseActionButton.java
index 44b488df9..effb33e78 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PauseActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/PauseActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import android.view.KeyEvent;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/PlayActionButton.java
index 45a8e0cdd..6eeb42065 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/PlayActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import android.util.Log;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/PlayLocalActionButton.java
index 6acb62434..62a965494 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/PlayLocalActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import androidx.annotation.DrawableRes;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/StreamActionButton.java
index 372a7984e..afe1fcce8 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/StreamActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
@@ -13,7 +13,7 @@ import de.danoeh.antennapod.playback.service.PlaybackService;
import de.danoeh.antennapod.playback.service.PlaybackServiceStarter;
import de.danoeh.antennapod.storage.preferences.UsageStatistics;
import de.danoeh.antennapod.net.common.NetworkUtils;
-import de.danoeh.antennapod.dialog.StreamingConfirmationDialog;
+import de.danoeh.antennapod.ui.StreamingConfirmationDialog;
public class StreamActionButton extends ItemActionButton {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java b/app/src/main/java/de/danoeh/antennapod/actionbutton/VisitWebsiteActionButton.java
index 03ccce2fe..dbe937c14 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/actionbutton/VisitWebsiteActionButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter.actionbutton;
+package de.danoeh.antennapod.actionbutton;
import android.content.Context;
import android.view.View;
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 32884c9c9..fd4007736 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -40,23 +40,23 @@ import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import de.danoeh.antennapod.net.sync.serviceinterface.SynchronizationQueueSink;
import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter;
import de.danoeh.antennapod.ui.common.ThemeSwitcher;
-import de.danoeh.antennapod.dialog.rating.RatingDialogManager;
+import de.danoeh.antennapod.ui.screen.rating.RatingDialogManager;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
import de.danoeh.antennapod.event.MessageEvent;
-import de.danoeh.antennapod.fragment.AddFeedFragment;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
-import de.danoeh.antennapod.fragment.AudioPlayerFragment;
-import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
-import de.danoeh.antennapod.fragment.DownloadLogFragment;
-import de.danoeh.antennapod.fragment.FeedItemlistFragment;
-import de.danoeh.antennapod.fragment.InboxFragment;
-import de.danoeh.antennapod.fragment.NavDrawerFragment;
-import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
-import de.danoeh.antennapod.fragment.QueueFragment;
-import de.danoeh.antennapod.fragment.SearchFragment;
-import de.danoeh.antennapod.fragment.SubscriptionFragment;
-import de.danoeh.antennapod.fragment.TransitionEffect;
+import de.danoeh.antennapod.ui.screen.AddFeedFragment;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.playback.audio.AudioPlayerFragment;
+import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
+import de.danoeh.antennapod.ui.screen.download.DownloadLogFragment;
+import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
+import de.danoeh.antennapod.ui.screen.InboxFragment;
+import de.danoeh.antennapod.ui.screen.drawer.NavDrawerFragment;
+import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
+import de.danoeh.antennapod.ui.screen.SearchFragment;
+import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
+import de.danoeh.antennapod.ui.TransitionEffect;
import de.danoeh.antennapod.model.download.DownloadStatus;
import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface;
import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
@@ -65,8 +65,8 @@ import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter;
import de.danoeh.antennapod.ui.common.ThemeUtils;
import de.danoeh.antennapod.ui.discovery.DiscoveryFragment;
-import de.danoeh.antennapod.ui.home.HomeFragment;
-import de.danoeh.antennapod.view.LockableBottomSheetBehavior;
+import de.danoeh.antennapod.ui.screen.home.HomeFragment;
+import de.danoeh.antennapod.ui.view.LockableBottomSheetBehavior;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
import org.greenrobot.eventbus.EventBus;
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 43da309d7..4ea33ca3e 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
@@ -7,7 +7,7 @@ import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
-import de.danoeh.antennapod.error.CrashReportWriter;
+import de.danoeh.antennapod.CrashReportWriter;
import de.danoeh.antennapod.storage.database.PodDBAdapter;
import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers;
diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java b/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java
deleted file mode 100644
index 100869120..000000000
--- a/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package de.danoeh.antennapod.receiver;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import de.danoeh.antennapod.ClientConfigurator;
-import de.danoeh.antennapod.core.util.download.NetworkConnectionChangeHandler;
-
-public class ConnectivityActionReceiver extends BroadcastReceiver {
- private static final String TAG = "ConnectivityActionRecvr";
-
- @Override
- public void onReceive(final Context context, Intent intent) {
- if (TextUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION)) {
- Log.d(TAG, "Received intent");
-
- ClientConfigurator.initialize(context);
- NetworkConnectionChangeHandler.networkChangedDetected();
- }
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/PowerConnectionReceiver.java b/app/src/main/java/de/danoeh/antennapod/receiver/PowerConnectionReceiver.java
deleted file mode 100644
index 6e179647e..000000000
--- a/app/src/main/java/de/danoeh/antennapod/receiver/PowerConnectionReceiver.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.danoeh.antennapod.receiver;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-import de.danoeh.antennapod.ClientConfigurator;
-import de.danoeh.antennapod.net.download.serviceinterface.AutoDownloadManager;
-import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface;
-
-// modified from http://developer.android.com/training/monitoring-device-state/battery-monitoring.html
-// and ConnectivityActionReceiver.java
-// Updated based on http://stackoverflow.com/questions/20833241/android-charge-intent-has-no-extra-data
-// Since the intent doesn't have the EXTRA_STATUS like the android.com article says it does
-// (though it used to)
-public class PowerConnectionReceiver extends BroadcastReceiver {
- private static final String TAG = "PowerConnectionReceiver";
-
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
-
- Log.d(TAG, "charging intent: " + action);
-
- ClientConfigurator.initialize(context);
- if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
- Log.d(TAG, "charging, starting auto-download");
- // we're plugged in, this is a great time to auto-download if everything else is
- // right. So, even if the user allows auto-dl on battery, let's still start
- // downloading now. They shouldn't mind.
- // autodownloadUndownloadedItems will make sure we're on the right wifi networks,
- // etc... so we don't have to worry about it.
- AutoDownloadManager.getInstance().autodownloadUndownloadedItems(context);
- } else {
- // if we're not supposed to be auto-downloading when we're not charging, stop it
- if (!UserPreferences.isEnableAutodownloadOnBattery()) {
- Log.d(TAG, "not charging anymore, canceling auto-download");
- DownloadServiceInterface.get().cancelAll(context);
- } else {
- Log.d(TAG, "not charging anymore, but the user allows auto-download " +
- "when on battery so we'll keep going");
- }
- }
-
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java b/app/src/main/java/de/danoeh/antennapod/spa/SPAReceiver.java
index 1628229be..e91192164 100644
--- a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java
+++ b/app/src/main/java/de/danoeh/antennapod/spa/SPAReceiver.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.receiver;
+package de.danoeh.antennapod.spa;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java b/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java
index f9c10041e..7630d49cd 100644
--- a/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java
+++ b/app/src/main/java/de/danoeh/antennapod/spa/SPAUtil.java
@@ -7,7 +7,6 @@ import androidx.preference.PreferenceManager;
import android.util.Log;
import de.danoeh.antennapod.BuildConfig;
-import de.danoeh.antennapod.receiver.SPAReceiver;
/**
* Provides methods related to AntennaPodSP (https://github.com/danieloeh/AntennaPodSP)
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AllEpisodesFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/AllEpisodesFilterDialog.java
index f47a8f8eb..d3464cd54 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/AllEpisodesFilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/AllEpisodesFilterDialog.java
@@ -1,7 +1,8 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui;
import android.os.Bundle;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
+import de.danoeh.antennapod.ui.screen.feed.ItemFilterDialog;
import org.greenrobot.eventbus.EventBus;
import java.util.Set;
@@ -17,7 +18,7 @@ public class AllEpisodesFilterDialog extends ItemFilterDialog {
}
@Override
- void onFilterChanged(Set<String> newFilterValues) {
+ public void onFilterChanged(Set<String> newFilterValues) {
EventBus.getDefault().post(new AllEpisodesFilterChangedEvent(newFilterValues));
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java b/app/src/main/java/de/danoeh/antennapod/ui/CoverLoader.java
index c87228cdd..370a15919 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/CoverLoader.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui;
import android.graphics.drawable.Drawable;
import android.view.View;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FeedItemFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/FeedItemFilterDialog.java
index a88a6600a..cce78013a 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/FeedItemFilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/FeedItemFilterDialog.java
@@ -1,8 +1,9 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui;
import android.os.Bundle;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.model.feed.Feed;
+import de.danoeh.antennapod.ui.screen.feed.ItemFilterDialog;
import java.util.Set;
@@ -19,7 +20,7 @@ public class FeedItemFilterDialog extends ItemFilterDialog {
}
@Override
- void onFilterChanged(Set<String> newFilterValues) {
+ public void onFilterChanged(Set<String> newFilterValues) {
long feedId = getArguments().getLong(ARGUMENT_FEED_ID);
DBWriter.setFeedItemsFilter(feedId, newFilterValues);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/MenuItemUtils.java b/app/src/main/java/de/danoeh/antennapod/ui/MenuItemUtils.java
new file mode 100644
index 000000000..f9e8f0568
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/MenuItemUtils.java
@@ -0,0 +1,28 @@
+package de.danoeh.antennapod.ui;
+
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * Utilities for menu items
+ */
+public class MenuItemUtils {
+
+ /**
+ * When pressing a context menu item, Android calls onContextItemSelected
+ * for ALL fragments in arbitrary order, not just for the fragment that the
+ * context menu was created from. This assigns the listener to every menu item,
+ * so that the correct fragment is always called first and can consume the click.
+ * <p />
+ * Note that Android still calls the onContextItemSelected methods of all fragments
+ * when the passed listener returns false.
+ */
+ public static void setOnClickListeners(Menu menu, MenuItem.OnMenuItemClickListener listener) {
+ for (int i = 0; i < menu.size(); i++) {
+ if (menu.getItem(i).getSubMenu() != null) {
+ setOnClickListeners(menu.getItem(i).getSubMenu(), listener);
+ }
+ menu.getItem(i).setOnMenuItemClickListener(listener);
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SelectableAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/SelectableAdapter.java
index 70d00cbff..918562ec3 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SelectableAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/SelectableAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui;
import android.app.Activity;
import android.view.ActionMode;
@@ -21,7 +21,7 @@ public abstract class SelectableAdapter<T extends RecyclerView.ViewHolder> exten
private final HashSet<Long> selectedIds = new HashSet<>();
private final Activity activity;
private OnSelectModeListener onSelectModeListener;
- boolean shouldSelectLazyLoadedItems = false;
+ protected boolean shouldSelectLazyLoadedItems = false;
private int totalNumberOfItems = COUNT_AUTOMATICALLY;
public SelectableAdapter(Activity activity) {
@@ -153,7 +153,7 @@ public abstract class SelectableAdapter<T extends RecyclerView.ViewHolder> exten
}
}
- void updateTitle() {
+ protected void updateTitle() {
if (actionMode == null) {
return;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SimpleChipAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/SimpleChipAdapter.java
index c7a04c3c7..904d01883 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SimpleChipAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/SimpleChipAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui;
import android.content.Context;
import android.view.ViewGroup;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/StreamingConfirmationDialog.java
index 5b733138f..6199aa0fd 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/StreamingConfirmationDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui;
import android.content.Context;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/TransitionEffect.java b/app/src/main/java/de/danoeh/antennapod/ui/TransitionEffect.java
index e3ec14890..092aeb3a5 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/TransitionEffect.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/TransitionEffect.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui;
public enum TransitionEffect {
NONE, FADE, SLIDE
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/cleaner/HtmlToPlainText.java b/app/src/main/java/de/danoeh/antennapod/ui/cleaner/HtmlToPlainText.java
new file mode 100644
index 000000000..29099c1fd
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/cleaner/HtmlToPlainText.java
@@ -0,0 +1,123 @@
+package de.danoeh.antennapod.ui.cleaner;
+
+import android.text.TextUtils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.internal.StringUtil;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.nodes.TextNode;
+import org.jsoup.select.NodeTraversor;
+import org.jsoup.select.NodeVisitor;
+
+import java.util.regex.Pattern;
+
+/**
+ * This class is based on <code>HtmlToPlainText</code> from jsoup's examples package.
+ *
+ * HTML to plain-text. This example program demonstrates the use of jsoup to convert HTML input to lightly-formatted
+ * plain-text. That is divergent from the general goal of jsoup's .text() methods, which is to get clean data from a
+ * scrape.
+ * <p>
+ * Note that this is a fairly simplistic formatter -- for real world use you'll want to embrace and extend.
+ * </p>
+ * <p>
+ * To invoke from the command line, assuming you've downloaded the jsoup jar to your current directory:</p>
+ * <p><code>java -cp jsoup.jar org.jsoup.examples.HtmlToPlainText url [selector]</code></p>
+ * where <i>url</i> is the URL to fetch, and <i>selector</i> is an optional CSS selector.
+ *
+ * @author Jonathan Hedley, jonathan@hedley.net
+ * @author AntennaPod open source community
+ */
+public class HtmlToPlainText {
+
+ /**
+ * Use this method to strip off HTML encoding from given text.
+ * Replaces bullet points with *, ignores colors/bold/...
+ *
+ * @param str String with any encoding
+ * @return Human readable text with minimal HTML formatting
+ */
+ public static String getPlainText(String str) {
+ if (!TextUtils.isEmpty(str) && isHtml(str)) {
+ HtmlToPlainText formatter = new HtmlToPlainText();
+ Document feedDescription = Jsoup.parse(str);
+ str = StringUtils.trim(formatter.getPlainText(feedDescription));
+ } else if (TextUtils.isEmpty(str)) {
+ str = "";
+ }
+
+ return str;
+ }
+
+ /**
+ * Use this method to determine if a given text has any HTML tag
+ *
+ * @param str String to be tested for presence of HTML content
+ * @return <b>True</b> if text contains any HTML tags<br /><b>False</b> is no HTML tag is found
+ */
+ private static boolean isHtml(String str) {
+ final String htmlTagPattern = "<(\"[^\"]*\"|'[^']*'|[^'\">])*>";
+ return Pattern.compile(htmlTagPattern).matcher(str).find();
+ }
+
+ /**
+ * Format an Element to plain-text
+ * @param element the root element to format
+ * @return formatted text
+ */
+ public String getPlainText(Element element) {
+ FormattingVisitor formatter = new FormattingVisitor();
+ // walk the DOM, and call .head() and .tail() for each node
+ NodeTraversor.traverse(formatter, element);
+
+ return formatter.toString();
+ }
+
+ // the formatting rules, implemented in a breadth-first DOM traverse
+ private static class FormattingVisitor implements NodeVisitor {
+
+ private final StringBuilder accum = new StringBuilder(); // holds the accumulated text
+
+ // hit when the node is first seen
+ public void head(Node node, int depth) {
+ String name = node.nodeName();
+ if (node instanceof TextNode) {
+ append(((TextNode) node).text()); // TextNodes carry all user-readable text in the DOM.
+ } else if (name.equals("li")) {
+ append("\n * ");
+ } else if (name.equals("dt")) {
+ append(" ");
+ } else if (StringUtil.in(name, "p", "h1", "h2", "h3", "h4", "h5", "tr")) {
+ append("\n");
+ }
+ }
+
+ // hit when all of the node's children (if any) have been visited
+ public void tail(Node node, int depth) {
+ String name = node.nodeName();
+ if (StringUtil.in(name, "br", "dd", "dt", "p", "h1", "h2", "h3", "h4", "h5")) {
+ append("\n");
+ } else if (name.equals("a")) {
+ append(String.format(" <%s>", node.absUrl("href")));
+ }
+ }
+
+ // appends text to the string builder with a simple word wrap method
+ private void append(String text) {
+ if (text.equals(" ") &&
+ (accum.length() == 0 || StringUtil.in(accum.substring(accum.length() - 1), " ", "\n"))) {
+ return; // don't accumulate long runs of empty spaces
+ }
+
+ accum.append(text);
+ }
+
+ @Override
+ public String toString() {
+ return accum.toString();
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/cleaner/ShownotesCleaner.java b/app/src/main/java/de/danoeh/antennapod/ui/cleaner/ShownotesCleaner.java
new file mode 100644
index 000000000..57f91e35c
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/cleaner/ShownotesCleaner.java
@@ -0,0 +1,208 @@
+package de.danoeh.antennapod.ui.cleaner;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.TypedValue;
+
+import androidx.annotation.Nullable;
+import org.apache.commons.io.IOUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.ui.common.Converter;
+
+/**
+ * Cleans up and prepares shownotes:
+ * - Guesses time stamps to make them clickable
+ * - Removes some formatting
+ */
+public class ShownotesCleaner {
+ private static final String TAG = "Timeline";
+
+ private static final Pattern TIMECODE_LINK_REGEX = Pattern.compile("antennapod://timecode/(\\d+)");
+ private static final String TIMECODE_LINK = "<a class=\"timecode\" href=\"antennapod://timecode/%d\">%s</a>";
+ private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b((\\d+):)?(\\d+):(\\d{2})\\b");
+ private static final Pattern LINE_BREAK_REGEX = Pattern.compile("<br */?>");
+ private static final String CSS_COLOR = "(?<=(\\s|;|^))color\\s*:([^;])*;";
+ private static final String CSS_COMMENT = "/\\*.*?\\*/";
+
+ private final String rawShownotes;
+ private final String noShownotesLabel;
+ private final int playableDuration;
+ private final String webviewStyle;
+
+ public ShownotesCleaner(Context context, @Nullable String rawShownotes, int playableDuration) {
+ this.rawShownotes = rawShownotes;
+
+ noShownotesLabel = context.getString(R.string.no_shownotes_label);
+ this.playableDuration = playableDuration;
+ final String colorPrimary = colorToHtml(context, android.R.attr.textColorPrimary);
+ final String colorAccent = colorToHtml(context, R.attr.colorAccent);
+ final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
+ context.getResources().getDisplayMetrics());
+ String styleString = "";
+ try {
+ InputStream templateStream = context.getAssets().open("shownotes-style.css");
+ styleString = IOUtils.toString(templateStream, "UTF-8");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ webviewStyle = String.format(Locale.US, styleString, colorPrimary, colorAccent,
+ margin, margin, margin, margin);
+ }
+
+ private String colorToHtml(Context context, int colorAttr) {
+ TypedArray res = context.getTheme().obtainStyledAttributes(new int[]{colorAttr});
+ @ColorInt int col = res.getColor(0, 0);
+ final String color = "rgba(" + Color.red(col) + "," + Color.green(col) + ","
+ + Color.blue(col) + "," + (Color.alpha(col) / 255.0) + ")";
+ res.recycle();
+ return color;
+ }
+
+ /**
+ * Applies an app-specific CSS stylesheet and adds timecode links (optional).
+ * <p/>
+ * This method does NOT change the original shownotes string of the shownotesProvider object and it should
+ * also not be changed by the caller.
+ *
+ * @return The processed HTML string.
+ */
+ @NonNull
+ public String processShownotes() {
+ String shownotes = rawShownotes;
+
+ if (TextUtils.isEmpty(shownotes)) {
+ Log.d(TAG, "shownotesProvider contained no shownotes. Returning 'no shownotes' message");
+ shownotes = "<html><head></head><body><p id='apNoShownotes'>" + noShownotesLabel + "</p></body></html>";
+ }
+
+ // replace ASCII line breaks with HTML ones if shownotes don't contain HTML line breaks already
+ if (!LINE_BREAK_REGEX.matcher(shownotes).find() && !shownotes.contains("<p>")) {
+ shownotes = shownotes.replace("\n", "<br />");
+ }
+
+ Document document = Jsoup.parse(shownotes);
+ cleanCss(document);
+ document.head().appendElement("style").attr("type", "text/css").text(webviewStyle);
+ addTimecodes(document);
+ return document.toString();
+ }
+
+ /**
+ * Returns true if the given link is a timecode link.
+ */
+ public static boolean isTimecodeLink(String link) {
+ return link != null && link.matches(TIMECODE_LINK_REGEX.pattern());
+ }
+
+ /**
+ * Returns the time in milliseconds that is attached to this link or -1
+ * if the link is no valid timecode link.
+ */
+ public static int getTimecodeLinkTime(String link) {
+ if (isTimecodeLink(link)) {
+ Matcher m = TIMECODE_LINK_REGEX.matcher(link);
+
+ try {
+ if (m.find()) {
+ return Integer.parseInt(m.group(1));
+ }
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ }
+ return -1;
+ }
+
+ private void addTimecodes(Document document) {
+ Elements elementsWithTimeCodes = document.body().getElementsMatchingOwnText(TIMECODE_REGEX);
+ Log.d(TAG, "Recognized " + elementsWithTimeCodes.size() + " timecodes");
+
+ if (elementsWithTimeCodes.size() == 0) {
+ // No elements with timecodes
+ return;
+ }
+ boolean useHourFormat = true;
+
+ if (playableDuration != Integer.MAX_VALUE) {
+
+ // We need to decide if we are going to treat short timecodes as HH:MM or MM:SS. To do
+ // so we will parse all the short timecodes and see if they fit in the duration. If one
+ // does not we will use MM:SS, otherwise all will be parsed as HH:MM.
+ for (Element element : elementsWithTimeCodes) {
+ Matcher matcherForElement = TIMECODE_REGEX.matcher(element.html());
+ while (matcherForElement.find()) {
+
+ // We only want short timecodes right now.
+ if (matcherForElement.group(1) == null) {
+ int time = Converter.durationStringShortToMs(matcherForElement.group(0), true);
+
+ // If the parsed timecode is greater then the duration then we know we need to
+ // use the minute format so we are done.
+ if (time > playableDuration) {
+ useHourFormat = false;
+ break;
+ }
+ }
+ }
+
+ if (!useHourFormat) {
+ break;
+ }
+ }
+ }
+
+ for (Element element : elementsWithTimeCodes) {
+
+ Matcher matcherForElement = TIMECODE_REGEX.matcher(element.html());
+ StringBuffer buffer = new StringBuffer();
+
+ while (matcherForElement.find()) {
+ String group = matcherForElement.group(0);
+
+ int time = matcherForElement.group(1) != null
+ ? Converter.durationStringLongToMs(group)
+ : Converter.durationStringShortToMs(group, useHourFormat);
+
+ String replacementText = group;
+ if (time < playableDuration) {
+ replacementText = String.format(Locale.US, TIMECODE_LINK, time, group);
+ }
+
+ matcherForElement.appendReplacement(buffer, replacementText);
+ }
+
+ matcherForElement.appendTail(buffer);
+ element.html(buffer.toString());
+ }
+ }
+
+ private void cleanCss(Document document) {
+ for (Element element : document.getAllElements()) {
+ if (element.hasAttr("style")) {
+ element.attr("style", element.attr("style").replaceAll(CSS_COLOR, ""));
+ } else if (element.tagName().equals("style")) {
+ element.html(cleanStyleTag(element.html()));
+ }
+ }
+ }
+
+ public static String cleanStyleTag(String oldCss) {
+ return oldCss.replaceAll(CSS_COMMENT, "").replaceAll(CSS_COLOR, "");
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/EpisodeItemListAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemListAdapter.java
index 0ec7018a7..cb026240a 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/EpisodeItemListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemListAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.episodeslist;
import android.app.Activity;
import android.os.Build;
@@ -14,6 +14,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
+import de.danoeh.antennapod.ui.SelectableAdapter;
import de.danoeh.antennapod.ui.common.ThemeUtils;
import org.apache.commons.lang3.ArrayUtils;
@@ -25,9 +26,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.fragment.ItemPagerFragment;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.screen.episode.ItemPagerFragment;
/**
* List adapter for the list of new episodes.
diff --git a/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemListRecyclerView.java
index fb1c533c5..a4f33ec98 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemListRecyclerView.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemListRecyclerView.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.episodeslist;
import android.content.Context;
import android.content.SharedPreferences;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemViewHolder.java
index fd547aa09..2d9cf7004 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeItemViewHolder.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view.viewholder;
+package de.danoeh.antennapod.ui.episodeslist;
import android.os.Build;
import android.text.Layout;
@@ -18,10 +18,9 @@ import com.google.android.material.elevation.SurfaceColors;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.CoverLoader;
-import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
+import de.danoeh.antennapod.ui.CoverLoader;
+import de.danoeh.antennapod.actionbutton.ItemActionButton;
import de.danoeh.antennapod.playback.service.PlaybackStatus;
-import de.danoeh.antennapod.core.util.download.MediaSizeLoader;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
import de.danoeh.antennapod.ui.common.DateFormatter;
import de.danoeh.antennapod.model.feed.FeedItem;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/actions/EpisodeMultiSelectActionHandler.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeMultiSelectActionHandler.java
index 9325037ad..2a9f76939 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/actions/EpisodeMultiSelectActionHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodeMultiSelectActionHandler.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.actions;
+package de.danoeh.antennapod.ui.episodeslist;
import android.util.Log;
@@ -14,7 +14,7 @@ import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterfa
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.storage.database.LongList;
import de.danoeh.antennapod.model.feed.FeedItem;
-import de.danoeh.antennapod.view.LocalDeleteModal;
+import de.danoeh.antennapod.ui.view.LocalDeleteModal;
public class EpisodeMultiSelectActionHandler {
private static final String TAG = "EpisodeSelectHandler";
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodesListFragment.java
index 0f9e21b6e..054183f7c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/EpisodesListFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.episodeslist;
import android.content.DialogInterface;
import android.os.Bundle;
@@ -24,6 +24,7 @@ import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;
+import de.danoeh.antennapod.ui.screen.SearchFragment;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -35,9 +36,8 @@ import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.core.util.ConfirmationDialog;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FeedItemEvent;
@@ -46,15 +46,11 @@ import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActions;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
-import de.danoeh.antennapod.view.EmptyViewHandler;
-import de.danoeh.antennapod.view.EpisodeItemListRecyclerView;
-import de.danoeh.antennapod.view.LiftOnScrollListener;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.view.EmptyViewHandler;
+import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -74,18 +70,16 @@ public abstract class EpisodesListFragment extends Fragment
protected boolean hasMoreItems = false;
private boolean displayUpArrow;
- EpisodeItemListRecyclerView recyclerView;
- EpisodeItemListAdapter listAdapter;
- EmptyViewHandler emptyView;
- SpeedDialView speedDialView;
- MaterialToolbar toolbar;
- SwipeRefreshLayout swipeRefreshLayout;
- SwipeActions swipeActions;
+ protected EpisodeItemListRecyclerView recyclerView;
+ protected EpisodeItemListAdapter listAdapter;
+ protected EmptyViewHandler emptyView;
+ protected SpeedDialView speedDialView;
+ protected MaterialToolbar toolbar;
+ protected SwipeRefreshLayout swipeRefreshLayout;
+ protected SwipeActions swipeActions;
private ProgressBar progressBar;
-
@NonNull
- List<FeedItem> episodes = new ArrayList<>();
-
+ protected List<FeedItem> episodes = new ArrayList<>();
protected Disposable disposable;
protected TextView txtvInformation;
@@ -406,7 +400,7 @@ public abstract class EpisodesListFragment extends Fragment
loadItems();
}
- void loadItems() {
+ protected void loadItems() {
if (disposable != null) {
disposable.dispose();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/FeedItemMenuHandler.java
index 422f65090..12b455d1f 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/FeedItemMenuHandler.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.menuhandler;
+package de.danoeh.antennapod.ui.episodeslist;
import android.content.Context;
import android.os.Handler;
@@ -25,14 +25,14 @@ import de.danoeh.antennapod.storage.preferences.SynchronizationSettings;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.playback.service.PlaybackStatus;
-import de.danoeh.antennapod.core.util.ShareUtils;
-import de.danoeh.antennapod.dialog.ShareDialog;
+import de.danoeh.antennapod.ui.share.ShareUtils;
+import de.danoeh.antennapod.ui.share.ShareDialog;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.net.sync.model.EpisodeAction;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter;
-import de.danoeh.antennapod.view.LocalDeleteModal;
+import de.danoeh.antennapod.ui.view.LocalDeleteModal;
/**
* Handles interactions with the FeedItemMenu.
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/HorizontalItemListAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/HorizontalItemListAdapter.java
index 4e8a2b05e..f40851ec2 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/HorizontalItemListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/HorizontalItemListAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.episodeslist;
import android.view.ContextMenu;
import android.view.MenuInflater;
@@ -10,10 +10,8 @@ import androidx.recyclerview.widget.RecyclerView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.fragment.ItemPagerFragment;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.screen.episode.ItemPagerFragment;
import de.danoeh.antennapod.model.feed.FeedItem;
-import de.danoeh.antennapod.view.viewholder.HorizontalItemViewHolder;
import org.apache.commons.lang3.ArrayUtils;
import java.lang.ref.WeakReference;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/viewholder/HorizontalItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/HorizontalItemViewHolder.java
index ee642c041..c297725b0 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/viewholder/HorizontalItemViewHolder.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/HorizontalItemViewHolder.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view.viewholder;
+package de.danoeh.antennapod.ui.episodeslist;
import android.view.LayoutInflater;
import android.view.View;
@@ -11,8 +11,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.elevation.SurfaceColors;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.CoverLoader;
-import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
+import de.danoeh.antennapod.ui.CoverLoader;
+import de.danoeh.antennapod.actionbutton.ItemActionButton;
import de.danoeh.antennapod.ui.common.DateFormatter;
import de.danoeh.antennapod.playback.service.PlaybackStatus;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/MediaSizeLoader.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/MediaSizeLoader.java
new file mode 100644
index 000000000..57b29f3b3
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/MediaSizeLoader.java
@@ -0,0 +1,78 @@
+package de.danoeh.antennapod.ui.episodeslist;
+
+import android.text.TextUtils;
+import de.danoeh.antennapod.net.common.AntennapodHttpClient;
+import de.danoeh.antennapod.storage.database.DBWriter;
+import de.danoeh.antennapod.net.common.NetworkUtils;
+import de.danoeh.antennapod.model.feed.FeedMedia;
+import io.reactivex.Single;
+import io.reactivex.SingleOnSubscribe;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import android.util.Log;
+import okhttp3.Response;
+
+import java.io.File;
+import java.io.IOException;
+
+public abstract class MediaSizeLoader {
+ private static final String TAG = "MediaSizeLoader";
+
+ public static Single<Long> getFeedMediaSizeObservable(FeedMedia media) {
+ return Single.create((SingleOnSubscribe<Long>) emitter -> {
+ if (!NetworkUtils.isEpisodeHeadDownloadAllowed()) {
+ emitter.onSuccess(0L);
+ return;
+ }
+ long size = Integer.MIN_VALUE;
+ if (media.isDownloaded()) {
+ File mediaFile = new File(media.getLocalFileUrl());
+ if (mediaFile.exists()) {
+ size = mediaFile.length();
+ }
+ } else if (!media.checkedOnSizeButUnknown()) {
+ // only query the network if we haven't already checked
+
+ String url = media.getDownloadUrl();
+ if (TextUtils.isEmpty(url)) {
+ emitter.onSuccess(0L);
+ return;
+ }
+
+ OkHttpClient client = AntennapodHttpClient.getHttpClient();
+ Request.Builder httpReq = new Request.Builder()
+ .url(url)
+ .header("Accept-Encoding", "identity")
+ .head();
+ try {
+ Response response = client.newCall(httpReq.build()).execute();
+ if (response.isSuccessful()) {
+ String contentLength = response.header("Content-Length");
+ try {
+ size = Integer.parseInt(contentLength);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ }
+ }
+ } catch (IOException e) {
+ emitter.onSuccess(0L);
+ Log.e(TAG, Log.getStackTraceString(e));
+ return; // better luck next time
+ }
+ }
+ Log.d(TAG, "new size: " + size);
+ if (size <= 0) {
+ // they didn't tell us the size, but we don't want to keep querying on it
+ media.setCheckedOnSizeButUnknown();
+ } else {
+ media.setSize(size);
+ }
+ emitter.onSuccess(size);
+ DBWriter.setFeedMedia(media);
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread());
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/MoreContentListFooterUtil.java b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/MoreContentListFooterUtil.java
new file mode 100644
index 000000000..fe9ce71f0
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/episodeslist/MoreContentListFooterUtil.java
@@ -0,0 +1,53 @@
+package de.danoeh.antennapod.ui.episodeslist;
+
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+
+import de.danoeh.antennapod.core.R;
+
+/**
+ * Utility methods for the more_content_list_footer layout.
+ */
+public class MoreContentListFooterUtil {
+
+ private final View root;
+
+ private boolean loading;
+
+ private Listener listener;
+
+ public MoreContentListFooterUtil(View root) {
+ this.root = root;
+ root.setOnClickListener(v -> {
+ if (listener != null && !loading) {
+ listener.onClick();
+ }
+ });
+ }
+
+ public void setLoadingState(boolean newState) {
+ final ImageView imageView = root.findViewById(R.id.imgExpand);
+ final ProgressBar progressBar = root.findViewById(R.id.progBar);
+ if (newState) {
+ imageView.setVisibility(View.GONE);
+ progressBar.setVisibility(View.VISIBLE);
+ } else {
+ imageView.setVisibility(View.VISIBLE);
+ progressBar.setVisibility(View.GONE);
+ }
+ loading = newState;
+ }
+
+ public void setClickListener(Listener l) {
+ listener = l;
+ }
+
+ public interface Listener {
+ void onClick();
+ }
+
+ public View getRoot() {
+ return root;
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/AddFeedFragment.java
index 8fe5e1c18..0b95fd601 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/AddFeedFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
@@ -38,6 +38,7 @@ import de.danoeh.antennapod.net.discovery.ItunesPodcastSearcher;
import de.danoeh.antennapod.net.discovery.PodcastIndexPodcastSearcher;
import de.danoeh.antennapod.ui.appstartintent.OnlineFeedviewActivityStarter;
import de.danoeh.antennapod.ui.discovery.OnlineSearchFragment;
+import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/AllEpisodesFragment.java
index 5ef188534..36466c990 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/AllEpisodesFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -9,13 +9,14 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.storage.database.DBReader;
-import de.danoeh.antennapod.dialog.AllEpisodesFilterDialog;
-import de.danoeh.antennapod.dialog.ItemSortDialog;
+import de.danoeh.antennapod.ui.AllEpisodesFilterDialog;
+import de.danoeh.antennapod.ui.screen.feed.ItemSortDialog;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.model.feed.SortOrder;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
+import de.danoeh.antennapod.ui.episodeslist.EpisodesListFragment;
import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/InboxFragment.java
index e8016675b..5ac6e5bef 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/InboxFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen;
import android.content.Context;
import android.content.SharedPreferences;
@@ -16,12 +16,13 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.DBWriter;
-import de.danoeh.antennapod.dialog.ItemSortDialog;
+import de.danoeh.antennapod.ui.screen.feed.ItemSortDialog;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.model.feed.SortOrder;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
+import de.danoeh.antennapod.ui.episodeslist.EpisodesListFragment;
import org.greenrobot.eventbus.EventBus;
import java.util.List;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/PlaybackHistoryFragment.java
index beac47f7f..4efdf38a3 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/PlaybackHistoryFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen;
import android.content.DialogInterface;
import android.os.Bundle;
@@ -8,13 +8,14 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
+import de.danoeh.antennapod.core.util.ConfirmationDialog;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.event.playback.PlaybackHistoryEvent;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.model.feed.SortOrder;
+import de.danoeh.antennapod.ui.episodeslist.EpisodesListFragment;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/SearchFragment.java
index 73fce9f1f..8e21117b3 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/SearchFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen;
import android.content.Context;
@@ -28,28 +28,28 @@ import com.leinardi.android.speeddial.SpeedDialView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.adapter.HorizontalFeedListAdapter;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
+import de.danoeh.antennapod.ui.screen.subscriptions.HorizontalFeedListAdapter;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.databinding.MultiSelectSpeedDialBinding;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
-import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeMultiSelectActionHandler;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
import de.danoeh.antennapod.net.discovery.CombinedSearcher;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.ui.appstartintent.OnlineFeedviewActivityStarter;
import de.danoeh.antennapod.ui.discovery.OnlineSearchFragment;
-import de.danoeh.antennapod.view.EmptyViewHandler;
-import de.danoeh.antennapod.view.EpisodeItemListRecyclerView;
-import de.danoeh.antennapod.view.LiftOnScrollListener;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.view.EmptyViewHandler;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView;
+import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
@@ -60,7 +60,7 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.Collections;
import java.util.List;
-import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
+import de.danoeh.antennapod.ui.screen.subscriptions.FeedMenuHandler;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/chapter/ChaptersFragment.java
index 14a8e68e6..f1dcbf415 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/chapter/ChaptersFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.chapter;
import android.app.Dialog;
import android.content.DialogInterface;
@@ -19,7 +19,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.adapter.ChaptersListAdapter;
import de.danoeh.antennapod.core.util.ChapterUtils;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
import de.danoeh.antennapod.model.feed.Chapter;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/chapter/ChaptersListAdapter.java
index 8f9a77f76..33e55a7e2 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/chapter/ChaptersListAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.screen.chapter;
import android.content.Context;
import android.text.TextUtils;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/CompletedDownloadsFragment.java
index 9db4f585a..15be1e230 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/CompletedDownloadsFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.download;
import android.os.Bundle;
import android.util.Log;
@@ -16,31 +16,32 @@ import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.adapter.actionbutton.DeleteActionButton;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
+import de.danoeh.antennapod.actionbutton.DeleteActionButton;
import de.danoeh.antennapod.event.DownloadLogEvent;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.MenuItemUtils;
+import de.danoeh.antennapod.ui.screen.SearchFragment;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.dialog.ItemSortDialog;
+import de.danoeh.antennapod.ui.screen.feed.ItemSortDialog;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeMultiSelectActionHandler;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActions;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.model.feed.SortOrder;
import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.view.EmptyViewHandler;
-import de.danoeh.antennapod.view.EpisodeItemListRecyclerView;
-import de.danoeh.antennapod.view.LiftOnScrollListener;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.view.EmptyViewHandler;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView;
+import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadErrorLabel.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadErrorLabel.java
new file mode 100644
index 000000000..e5eedd54b
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadErrorLabel.java
@@ -0,0 +1,46 @@
+package de.danoeh.antennapod.ui.screen.download;
+
+import androidx.annotation.StringRes;
+import de.danoeh.antennapod.core.BuildConfig;
+import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.model.download.DownloadError;
+
+/**
+ * Provides user-visible labels for download errors.
+ */
+public class DownloadErrorLabel {
+
+ @StringRes
+ public static int from(DownloadError error) {
+ switch (error) {
+ case SUCCESS: return R.string.download_successful;
+ case ERROR_PARSER_EXCEPTION: return R.string.download_error_parser_exception;
+ case ERROR_UNSUPPORTED_TYPE: return R.string.download_error_unsupported_type;
+ case ERROR_CONNECTION_ERROR: return R.string.download_error_connection_error;
+ case ERROR_MALFORMED_URL: return R.string.download_error_error_unknown;
+ case ERROR_IO_ERROR: return R.string.download_error_io_error;
+ case ERROR_FILE_EXISTS: return R.string.download_error_error_unknown;
+ case ERROR_DOWNLOAD_CANCELLED: return R.string.download_canceled_msg;
+ case ERROR_DEVICE_NOT_FOUND: return R.string.download_error_device_not_found;
+ case ERROR_HTTP_DATA_ERROR: return R.string.download_error_http_data_error;
+ case ERROR_NOT_ENOUGH_SPACE: return R.string.download_error_insufficient_space;
+ case ERROR_UNKNOWN_HOST: return R.string.download_error_unknown_host;
+ case ERROR_REQUEST_ERROR: return R.string.download_error_request_error;
+ case ERROR_DB_ACCESS_ERROR: return R.string.download_error_db_access;
+ case ERROR_UNAUTHORIZED: return R.string.download_error_unauthorized;
+ case ERROR_FILE_TYPE: return R.string.download_error_file_type_type;
+ case ERROR_FORBIDDEN: return R.string.download_error_forbidden;
+ case ERROR_IO_WRONG_SIZE: return R.string.download_error_wrong_size;
+ case ERROR_IO_BLOCKED: return R.string.download_error_blocked;
+ case ERROR_UNSUPPORTED_TYPE_HTML: return R.string.download_error_unsupported_type_html;
+ case ERROR_NOT_FOUND: return R.string.download_error_not_found;
+ case ERROR_CERTIFICATE: return R.string.download_error_certificate;
+ case ERROR_PARSER_EXCEPTION_DUPLICATE: return R.string.download_error_parser_exception;
+ default:
+ if (BuildConfig.DEBUG) {
+ throw new IllegalArgumentException("No mapping from download error to label");
+ }
+ return R.string.download_error_error_unknown;
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogAdapter.java
index 84c9709bb..88472bcbf 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.screen.download;
import android.app.Activity;
import android.text.format.DateUtils;
@@ -9,15 +9,13 @@ import android.widget.BaseAdapter;
import android.widget.Toast;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.actionbutton.DownloadActionButton;
+import de.danoeh.antennapod.actionbutton.DownloadActionButton;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import de.danoeh.antennapod.storage.database.DBReader;
-import de.danoeh.antennapod.core.util.DownloadErrorLabel;
import de.danoeh.antennapod.model.download.DownloadError;
import de.danoeh.antennapod.model.download.DownloadResult;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedMedia;
-import de.danoeh.antennapod.view.viewholder.DownloadLogItemViewHolder;
import java.util.ArrayList;
import java.util.List;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/DownloadLogDetailsDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogDetailsDialog.java
index 82e32aed3..a035f58ff 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/DownloadLogDetailsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogDetailsDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.download;
import android.content.ClipData;
import android.content.ClipboardManager;
@@ -9,7 +9,6 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.util.DownloadErrorLabel;
import de.danoeh.antennapod.model.download.DownloadResult;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.event.MessageEvent;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogFragment.java
index 54c6d1a9b..b6c8875e1 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.download;
import android.os.Bundle;
import android.util.Log;
@@ -12,14 +12,12 @@ import androidx.annotation.Nullable;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.adapter.DownloadLogAdapter;
import de.danoeh.antennapod.event.DownloadLogEvent;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.databinding.DownloadLogFragmentBinding;
-import de.danoeh.antennapod.dialog.DownloadLogDetailsDialog;
import de.danoeh.antennapod.model.download.DownloadResult;
-import de.danoeh.antennapod.view.EmptyViewHandler;
+import de.danoeh.antennapod.ui.view.EmptyViewHandler;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/viewholder/DownloadLogItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogItemViewHolder.java
index ffb679830..97d368fac 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/viewholder/DownloadLogItemViewHolder.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/download/DownloadLogItemViewHolder.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view.viewholder;
+package de.danoeh.antennapod.ui.screen.download;
import android.content.Context;
import android.os.Build;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/DrawerPreferencesDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/DrawerPreferencesDialog.java
index 8f174f207..4923df19c 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/DrawerPreferencesDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/DrawerPreferencesDialog.java
@@ -1,10 +1,10 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.drawer;
import android.content.Context;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.fragment.NavDrawerFragment;
+import de.danoeh.antennapod.ui.screen.drawer.NavDrawerFragment;
import java.util.List;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/NavDrawerFragment.java
index 49ef099f9..fabcaf652 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/NavDrawerFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.drawer;
import android.app.Activity;
import android.content.Context;
@@ -34,6 +34,13 @@ import com.google.android.material.shape.MaterialShapeDrawable;
import com.google.android.material.shape.ShapeAppearanceModel;
import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithmFactory;
+import de.danoeh.antennapod.ui.screen.AddFeedFragment;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.InboxFragment;
+import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
+import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
+import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -47,18 +54,16 @@ import java.util.Set;
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.dialog.ConfirmationDialog;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.screen.preferences.PreferenceActivity;
+import de.danoeh.antennapod.core.util.ConfirmationDialog;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.storage.database.NavDrawerData;
-import de.danoeh.antennapod.dialog.DrawerPreferencesDialog;
-import de.danoeh.antennapod.dialog.RemoveFeedDialog;
-import de.danoeh.antennapod.dialog.RenameItemDialog;
-import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
-import de.danoeh.antennapod.dialog.TagSettingsDialog;
+import de.danoeh.antennapod.ui.screen.feed.RemoveFeedDialog;
+import de.danoeh.antennapod.ui.screen.feed.RenameFeedDialog;
+import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionsFilterDialog;
+import de.danoeh.antennapod.ui.screen.feed.preferences.TagSettingsDialog;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
import de.danoeh.antennapod.event.QueueEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
@@ -66,7 +71,7 @@ import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter;
import de.danoeh.antennapod.ui.common.ThemeUtils;
-import de.danoeh.antennapod.ui.home.HomeFragment;
+import de.danoeh.antennapod.ui.screen.home.HomeFragment;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
@@ -219,7 +224,7 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
.show(getChildFragmentManager(), TagSettingsDialog.TAG);
return true;
} else if (itemId == R.id.rename_item) {
- new RenameItemDialog(getActivity(), feed).show();
+ new RenameFeedDialog(getActivity(), feed).show();
return true;
} else if (itemId == R.id.remove_feed) {
RemoveFeedDialog.show(getContext(), feed, () -> {
@@ -237,7 +242,7 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
private boolean onTagContextMenuClicked(NavDrawerData.DrawerItem drawerItem, MenuItem item) {
final int itemId = item.getItemId();
if (itemId == R.id.rename_folder_item) {
- new RenameItemDialog(getActivity(), drawerItem).show();
+ new RenameFeedDialog(getActivity(), drawerItem).show();
return true;
}
return super.onContextItemSelected(item);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/NavListAdapter.java
index 4c8e074a1..aaf872460 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/drawer/NavListAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.screen.drawer;
import android.app.Activity;
import android.content.Intent;
@@ -24,19 +24,18 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
-import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
-import de.danoeh.antennapod.fragment.InboxFragment;
+import de.danoeh.antennapod.ui.screen.preferences.PreferenceActivity;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
+import de.danoeh.antennapod.ui.screen.InboxFragment;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.storage.database.NavDrawerData;
-import de.danoeh.antennapod.fragment.AddFeedFragment;
-import de.danoeh.antennapod.fragment.NavDrawerFragment;
-import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
-import de.danoeh.antennapod.fragment.QueueFragment;
-import de.danoeh.antennapod.fragment.SubscriptionFragment;
-import de.danoeh.antennapod.ui.home.HomeFragment;
+import de.danoeh.antennapod.ui.screen.AddFeedFragment;
+import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
+import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
+import de.danoeh.antennapod.ui.screen.home.HomeFragment;
import org.apache.commons.lang3.ArrayUtils;
import java.lang.ref.WeakReference;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/episode/ItemFragment.java
index 935d1f06d..b3a5cbbf0 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/episode/ItemFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.episode;
import android.content.Context;
import android.os.Build;
@@ -27,16 +27,16 @@ import com.skydoves.balloon.Balloon;
import com.skydoves.balloon.BalloonAnimation;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.actionbutton.CancelDownloadActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.DeleteActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.DownloadActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.MarkAsPlayedActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.PauseActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.PlayActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.PlayLocalActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.StreamActionButton;
-import de.danoeh.antennapod.adapter.actionbutton.VisitWebsiteActionButton;
+import de.danoeh.antennapod.actionbutton.CancelDownloadActionButton;
+import de.danoeh.antennapod.actionbutton.DeleteActionButton;
+import de.danoeh.antennapod.actionbutton.DownloadActionButton;
+import de.danoeh.antennapod.actionbutton.ItemActionButton;
+import de.danoeh.antennapod.actionbutton.MarkAsPlayedActionButton;
+import de.danoeh.antennapod.actionbutton.PauseActionButton;
+import de.danoeh.antennapod.actionbutton.PlayActionButton;
+import de.danoeh.antennapod.actionbutton.PlayLocalActionButton;
+import de.danoeh.antennapod.actionbutton.StreamActionButton;
+import de.danoeh.antennapod.actionbutton.VisitWebsiteActionButton;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.playback.service.PlaybackStatus;
import de.danoeh.antennapod.event.FeedItemEvent;
@@ -53,9 +53,10 @@ import de.danoeh.antennapod.ui.common.Converter;
import de.danoeh.antennapod.ui.common.DateFormatter;
import de.danoeh.antennapod.ui.common.CircularProgressBar;
import de.danoeh.antennapod.ui.common.ThemeUtils;
-import de.danoeh.antennapod.core.util.gui.ShownotesCleaner;
+import de.danoeh.antennapod.ui.cleaner.ShownotesCleaner;
import de.danoeh.antennapod.ui.episodes.ImageResourceUtils;
-import de.danoeh.antennapod.view.ShownotesWebView;
+import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
+import de.danoeh.antennapod.ui.view.ShownotesWebView;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/episode/ItemPagerFragment.java
index 637d4c7ba..524066587 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/episode/ItemPagerFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.episode;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -13,6 +13,7 @@ import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
+import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@@ -22,7 +23,7 @@ import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.storage.database.DBReader;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedInfoFragment.java
index c93837851..3e7fd3cdc 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedInfoFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.feed;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
@@ -34,18 +34,18 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.ui.TransitionEffect;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.FeedDatabaseWriter;
import de.danoeh.antennapod.core.util.IntentUtils;
-import de.danoeh.antennapod.core.util.ShareUtils;
-import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
-import de.danoeh.antennapod.dialog.EditUrlSettingsDialog;
+import de.danoeh.antennapod.ui.share.ShareUtils;
+import de.danoeh.antennapod.ui.cleaner.HtmlToPlainText;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedFunding;
import de.danoeh.antennapod.ui.glide.FastBlurTransformation;
+import de.danoeh.antennapod.ui.screen.feed.preferences.EditUrlSettingsDialog;
import de.danoeh.antennapod.ui.statistics.StatisticsFragment;
import de.danoeh.antennapod.ui.statistics.feed.FeedStatisticsFragment;
-import de.danoeh.antennapod.view.ToolbarIconTintManager;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.MaybeOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedItemFilterGroup.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedItemFilterGroup.java
new file mode 100644
index 000000000..5cb0f36fd
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedItemFilterGroup.java
@@ -0,0 +1,37 @@
+package de.danoeh.antennapod.ui.screen.feed;
+
+import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.model.feed.FeedItemFilter;
+
+public enum FeedItemFilterGroup {
+ PLAYED(new ItemProperties(R.string.hide_played_episodes_label, FeedItemFilter.PLAYED),
+ new ItemProperties(R.string.not_played, FeedItemFilter.UNPLAYED)),
+ PAUSED(new ItemProperties(R.string.hide_paused_episodes_label, FeedItemFilter.PAUSED),
+ new ItemProperties(R.string.not_paused, FeedItemFilter.NOT_PAUSED)),
+ FAVORITE(new ItemProperties(R.string.hide_is_favorite_label, FeedItemFilter.IS_FAVORITE),
+ new ItemProperties(R.string.not_favorite, FeedItemFilter.NOT_FAVORITE)),
+ MEDIA(new ItemProperties(R.string.has_media, FeedItemFilter.HAS_MEDIA),
+ new ItemProperties(R.string.no_media, FeedItemFilter.NO_MEDIA)),
+ QUEUED(new ItemProperties(R.string.queued_label, FeedItemFilter.QUEUED),
+ new ItemProperties(R.string.not_queued_label, FeedItemFilter.NOT_QUEUED)),
+ DOWNLOADED(new ItemProperties(R.string.hide_downloaded_episodes_label, FeedItemFilter.DOWNLOADED),
+ new ItemProperties(R.string.hide_not_downloaded_episodes_label, FeedItemFilter.NOT_DOWNLOADED));
+
+ public final ItemProperties[] values;
+
+ FeedItemFilterGroup(ItemProperties... values) {
+ this.values = values;
+ }
+
+ public static class ItemProperties {
+
+ public final int displayName;
+ public final String filterId;
+
+ public ItemProperties(int displayName, String filterId) {
+ this.displayName = displayName;
+ this.filterId = filterId;
+ }
+
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedItemlistFragment.java
index 1884012ea..7743f1cd9 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/FeedItemlistFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.feed;
import android.content.Context;
import android.content.res.Configuration;
@@ -26,7 +26,12 @@ import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;
+import de.danoeh.antennapod.ui.screen.episode.ItemPagerFragment;
+import de.danoeh.antennapod.ui.screen.SearchFragment;
+import de.danoeh.antennapod.ui.TransitionEffect;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
+import de.danoeh.antennapod.ui.screen.download.DownloadLogFragment;
+import de.danoeh.antennapod.ui.screen.feed.preferences.FeedSettingsFragment;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.greenrobot.eventbus.EventBus;
@@ -39,23 +44,20 @@ import java.util.concurrent.ExecutionException;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
import de.danoeh.antennapod.event.FeedEvent;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.storage.database.FeedItemPermutors;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.IntentUtils;
-import de.danoeh.antennapod.core.util.ShareUtils;
-import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
+import de.danoeh.antennapod.ui.share.ShareUtils;
+import de.danoeh.antennapod.ui.episodeslist.MoreContentListFooterUtil;
import de.danoeh.antennapod.databinding.FeedItemListFragmentBinding;
import de.danoeh.antennapod.databinding.MultiSelectSpeedDialBinding;
-import de.danoeh.antennapod.dialog.DownloadLogDetailsDialog;
-import de.danoeh.antennapod.dialog.FeedItemFilterDialog;
-import de.danoeh.antennapod.dialog.ItemSortDialog;
-import de.danoeh.antennapod.dialog.RemoveFeedDialog;
-import de.danoeh.antennapod.dialog.RenameItemDialog;
+import de.danoeh.antennapod.ui.screen.download.DownloadLogDetailsDialog;
+import de.danoeh.antennapod.ui.FeedItemFilterDialog;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FavoritesEvent;
import de.danoeh.antennapod.event.FeedItemEvent;
@@ -65,9 +67,9 @@ import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.QueueEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeMultiSelectActionHandler;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActions;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
import de.danoeh.antennapod.model.download.DownloadResult;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedItem;
@@ -75,8 +77,7 @@ import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.model.feed.SortOrder;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.glide.FastBlurTransformation;
-import de.danoeh.antennapod.view.ToolbarIconTintManager;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -289,7 +290,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
} else if (item.getItemId() == R.id.sort_items) {
SingleFeedSortDialog.newInstance(feed).show(getChildFragmentManager(), "SortDialog");
} else if (item.getItemId() == R.id.rename_item) {
- new RenameItemDialog(getActivity(), feed).show();
+ new RenameFeedDialog(getActivity(), feed).show();
} else if (item.getItemId() == R.id.remove_feed) {
RemoveFeedDialog.show(getContext(), feed, () -> {
((MainActivity) getActivity()).loadFragment(UserPreferences.getDefaultPage(), null);
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ItemFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ItemFilterDialog.java
index 359c513af..8dbcce699 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/ItemFilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ItemFilterDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed;
import android.app.Dialog;
import android.os.Bundle;
@@ -23,7 +23,6 @@ import java.util.HashSet;
import java.util.Set;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.FeedItemFilterGroup;
import de.danoeh.antennapod.databinding.FilterDialogBinding;
import de.danoeh.antennapod.databinding.FilterDialogRowBinding;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
@@ -119,5 +118,5 @@ public abstract class ItemFilterDialog extends BottomSheetDialogFragment {
return newFilterValues;
}
- abstract void onFilterChanged(Set<String> newFilterValues);
+ public abstract void onFilterChanged(Set<String> newFilterValues);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ItemSortDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ItemSortDialog.java
index cd6cc4b0a..bb68477df 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/ItemSortDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ItemSortDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed;
import android.app.Dialog;
import android.os.Bundle;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/RemoveFeedDialog.java
index ffa374b6f..415948a81 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/RemoveFeedDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed;
import android.app.ProgressDialog;
import android.content.Context;
@@ -11,7 +11,7 @@ import java.util.Collections;
import java.util.List;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
+import de.danoeh.antennapod.core.util.ConfirmationDialog;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.storage.database.DBWriter;
import io.reactivex.Completable;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RenameItemDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/RenameFeedDialog.java
index bbe6fd16c..4bc63f732 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/RenameItemDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/RenameFeedDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed;
import android.app.Activity;
@@ -16,18 +16,18 @@ import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.databinding.EditTextDialogBinding;
import de.danoeh.antennapod.model.feed.FeedPreferences;
-public class RenameItemDialog {
+public class RenameFeedDialog {
private final WeakReference<Activity> activityRef;
private Feed feed = null;
private NavDrawerData.DrawerItem drawerItem = null;
- public RenameItemDialog(Activity activity, Feed feed) {
+ public RenameFeedDialog(Activity activity, Feed feed) {
this.activityRef = new WeakReference<>(activity);
this.feed = feed;
}
- public RenameItemDialog(Activity activity, NavDrawerData.DrawerItem drawerItem) {
+ public RenameFeedDialog(Activity activity, NavDrawerData.DrawerItem drawerItem) {
this.activityRef = new WeakReference<>(activity);
this.drawerItem = drawerItem;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ToolbarIconTintManager.java
index 67c2e2555..e158053d0 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/ToolbarIconTintManager.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/ToolbarIconTintManager.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.screen.feed;
import android.content.Context;
import android.graphics.PorterDuff.Mode;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EditUrlSettingsDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/EditUrlSettingsDialog.java
index 67c5d85cf..767de3ecc 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EditUrlSettingsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/EditUrlSettingsDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed.preferences;
import android.app.Activity;
import android.os.CountDownTimer;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodeFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/EpisodeFilterDialog.java
index 220650f0f..f07d37fec 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodeFilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/EpisodeFilterDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed.preferences;
import android.content.Context;
import android.content.DialogInterface;
@@ -7,10 +7,10 @@ import android.view.LayoutInflater;
import androidx.recyclerview.widget.GridLayoutManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.adapter.SimpleChipAdapter;
+import de.danoeh.antennapod.ui.SimpleChipAdapter;
import de.danoeh.antennapod.databinding.EpisodeFilterDialogBinding;
import de.danoeh.antennapod.model.feed.FeedFilter;
-import de.danoeh.antennapod.view.ItemOffsetDecoration;
+import de.danoeh.antennapod.ui.view.ItemOffsetDecoration;
import java.util.List;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FeedPreferenceSkipDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/FeedPreferenceSkipDialog.java
index 77c9ff67e..bac336d2f 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/FeedPreferenceSkipDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/FeedPreferenceSkipDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed.preferences;
import android.content.Context;
import android.view.View;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/FeedSettingsFragment.java
index 69cfb0087..4ac844479 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/FeedSettingsFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.feed.preferences;
import android.Manifest;
import android.content.Intent;
@@ -38,9 +38,6 @@ import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.DBWriter;
-import de.danoeh.antennapod.dialog.EpisodeFilterDialog;
-import de.danoeh.antennapod.dialog.FeedPreferenceSkipDialog;
-import de.danoeh.antennapod.dialog.TagSettingsDialog;
import de.danoeh.antennapod.ui.preferences.screen.synchronization.AuthenticationDialog;
import io.reactivex.Maybe;
import io.reactivex.MaybeOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/SkipPreferenceDialog.java
index a5eca4bc2..983e265c1 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/SkipPreferenceDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed.preferences;
import android.content.Context;
import android.widget.TextView;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/TagSettingsDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/TagSettingsDialog.java
index 8112c0955..accc5cc60 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/TagSettingsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/TagSettingsDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.feed.preferences;
import android.app.Dialog;
import android.os.Bundle;
@@ -21,7 +21,7 @@ import java.util.List;
import java.util.Set;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.adapter.SimpleChipAdapter;
+import de.danoeh.antennapod.ui.SimpleChipAdapter;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.storage.database.NavDrawerData;
@@ -29,7 +29,7 @@ import de.danoeh.antennapod.databinding.EditTagsDialogBinding;
import de.danoeh.antennapod.model.feed.FeedCounter;
import de.danoeh.antennapod.model.feed.FeedOrder;
import de.danoeh.antennapod.model.feed.FeedPreferences;
-import de.danoeh.antennapod.view.ItemOffsetDecoration;
+import de.danoeh.antennapod.ui.view.ItemOffsetDecoration;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/VolumeAdaptationPreference.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/VolumeAdaptationPreference.java
index a4ed402ed..70f5da5fc 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/VolumeAdaptationPreference.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/feed/preferences/VolumeAdaptationPreference.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.preferences;
+package de.danoeh.antennapod.ui.screen.feed.preferences;
import android.content.Context;
import android.util.AttributeSet;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/HomeFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeFragment.java
index 90d4817da..bcbc2675a 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/HomeFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home;
+package de.danoeh.antennapod.ui.screen.home;
import android.Manifest;
import android.content.Context;
@@ -21,6 +21,13 @@ import androidx.fragment.app.FragmentContainerView;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import de.danoeh.antennapod.ui.echo.EchoConfig;
+import de.danoeh.antennapod.ui.screen.home.sections.AllowNotificationsSection;
+import de.danoeh.antennapod.ui.screen.home.sections.DownloadsSection;
+import de.danoeh.antennapod.ui.screen.home.sections.EchoSection;
+import de.danoeh.antennapod.ui.screen.home.sections.EpisodesSurpriseSection;
+import de.danoeh.antennapod.ui.screen.home.sections.InboxSection;
+import de.danoeh.antennapod.ui.screen.home.sections.QueueSection;
+import de.danoeh.antennapod.ui.screen.home.sections.SubscriptionsSection;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@@ -36,16 +43,9 @@ import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.databinding.HomeFragmentBinding;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
-import de.danoeh.antennapod.fragment.SearchFragment;
+import de.danoeh.antennapod.ui.screen.SearchFragment;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.ui.home.sections.AllowNotificationsSection;
-import de.danoeh.antennapod.ui.home.sections.DownloadsSection;
-import de.danoeh.antennapod.ui.home.sections.EchoSection;
-import de.danoeh.antennapod.ui.home.sections.EpisodesSurpriseSection;
-import de.danoeh.antennapod.ui.home.sections.InboxSection;
-import de.danoeh.antennapod.ui.home.sections.QueueSection;
-import de.danoeh.antennapod.ui.home.sections.SubscriptionsSection;
-import de.danoeh.antennapod.view.LiftOnScrollListener;
+import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/HomeSection.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeSection.java
index 03036d267..908267f47 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/HomeSection.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeSection.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home;
+package de.danoeh.antennapod.ui.screen.home;
import android.os.Bundle;
import android.text.TextUtils;
@@ -11,12 +11,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.adapter.HorizontalFeedListAdapter;
-import de.danoeh.antennapod.adapter.HorizontalItemListAdapter;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
+import de.danoeh.antennapod.ui.screen.subscriptions.HorizontalFeedListAdapter;
+import de.danoeh.antennapod.ui.episodeslist.HorizontalItemListAdapter;
import de.danoeh.antennapod.databinding.HomeSectionBinding;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
-import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.screen.subscriptions.FeedMenuHandler;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedItem;
import org.greenrobot.eventbus.EventBus;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/HomeSectionsSettingsDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeSectionsSettingsDialog.java
index e651aea48..3238c299c 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/HomeSectionsSettingsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/HomeSectionsSettingsDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home;
+package de.danoeh.antennapod.ui.screen.home;
import android.content.Context;
import android.content.DialogInterface;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/AllowNotificationsSection.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/AllowNotificationsSection.java
index 0a0d30485..0b26865c8 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/AllowNotificationsSection.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/AllowNotificationsSection.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home.sections;
+package de.danoeh.antennapod.ui.screen.home.sections;
import android.Manifest;
import android.content.Context;
@@ -20,7 +20,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.databinding.HomeSectionNotificationBinding;
-import de.danoeh.antennapod.ui.home.HomeFragment;
+import de.danoeh.antennapod.ui.screen.home.HomeFragment;
public class AllowNotificationsSection extends Fragment {
HomeSectionNotificationBinding viewBinding;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/DownloadsSection.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/DownloadsSection.java
index 9540bc2e3..4dc34a80e 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/DownloadsSection.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/DownloadsSection.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home.sections;
+package de.danoeh.antennapod.ui.screen.home.sections;
import android.os.Bundle;
import android.util.Log;
@@ -12,21 +12,21 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
import de.danoeh.antennapod.event.DownloadLogEvent;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
+import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActions;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.model.feed.SortOrder;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.ui.home.HomeSection;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.screen.home.HomeSection;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/EchoSection.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/EchoSection.java
index 28ff05512..d8df470f0 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/EchoSection.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/EchoSection.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home.sections;
+package de.danoeh.antennapod.ui.screen.home.sections;
import android.content.Context;
import android.content.Intent;
@@ -16,7 +16,7 @@ import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.StatisticsItem;
import de.danoeh.antennapod.ui.echo.EchoActivity;
import de.danoeh.antennapod.ui.echo.EchoConfig;
-import de.danoeh.antennapod.ui.home.HomeFragment;
+import de.danoeh.antennapod.ui.screen.home.HomeFragment;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/EpisodesSurpriseSection.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/EpisodesSurpriseSection.java
index f93e28cbd..451a0aedc 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/EpisodesSurpriseSection.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/EpisodesSurpriseSection.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home.sections;
+package de.danoeh.antennapod.ui.screen.home.sections;
import android.os.Bundle;
import android.util.Log;
@@ -12,18 +12,18 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.HorizontalItemListAdapter;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.episodeslist.HorizontalItemListAdapter;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
import de.danoeh.antennapod.model.feed.FeedItem;
-import de.danoeh.antennapod.ui.home.HomeSection;
-import de.danoeh.antennapod.view.viewholder.HorizontalItemViewHolder;
+import de.danoeh.antennapod.ui.screen.home.HomeSection;
+import de.danoeh.antennapod.ui.episodeslist.HorizontalItemViewHolder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/InboxSection.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/InboxSection.java
index e5a72f72c..de6f6bef4 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/InboxSection.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/InboxSection.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home.sections;
+package de.danoeh.antennapod.ui.screen.home.sections;
import android.os.Bundle;
import android.util.Log;
@@ -13,20 +13,20 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
-import de.danoeh.antennapod.fragment.InboxFragment;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
+import de.danoeh.antennapod.ui.screen.InboxFragment;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActions;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.ui.home.HomeSection;
+import de.danoeh.antennapod.ui.screen.home.HomeSection;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/QueueSection.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/QueueSection.java
index 4344f967c..57d896ae9 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/QueueSection.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/QueueSection.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home.sections;
+package de.danoeh.antennapod.ui.screen.home.sections;
import android.os.Bundle;
import android.util.Log;
@@ -12,8 +12,8 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.HorizontalItemListAdapter;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.episodeslist.HorizontalItemListAdapter;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
@@ -21,10 +21,10 @@ import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.QueueEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.fragment.QueueFragment;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
import de.danoeh.antennapod.model.feed.FeedItem;
-import de.danoeh.antennapod.ui.home.HomeSection;
-import de.danoeh.antennapod.view.viewholder.HorizontalItemViewHolder;
+import de.danoeh.antennapod.ui.screen.home.HomeSection;
+import de.danoeh.antennapod.ui.episodeslist.HorizontalItemViewHolder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/SubscriptionsSection.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/SubscriptionsSection.java
index b97254d49..a37d1367f 100644
--- a/app/src/main/java/de/danoeh/antennapod/ui/home/sections/SubscriptionsSection.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/home/sections/SubscriptionsSection.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.ui.home.sections;
+package de.danoeh.antennapod.ui.screen.home.sections;
import android.content.Context;
import android.content.SharedPreferences;
@@ -14,13 +14,13 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.HorizontalFeedListAdapter;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.screen.subscriptions.HorizontalFeedListAdapter;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
-import de.danoeh.antennapod.fragment.SubscriptionFragment;
+import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
import de.danoeh.antennapod.model.feed.Feed;
-import de.danoeh.antennapod.ui.home.HomeSection;
+import de.danoeh.antennapod.ui.screen.home.HomeSection;
import de.danoeh.antennapod.ui.statistics.StatisticsFragment;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedDiscoverer.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedDiscoverer.java
new file mode 100644
index 000000000..1109c86d8
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedDiscoverer.java
@@ -0,0 +1,79 @@
+package de.danoeh.antennapod.ui.screen.onlinefeedview;
+
+import android.net.Uri;
+import androidx.collection.ArrayMap;
+import android.text.TextUtils;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Finds RSS/Atom URLs in a HTML document using the auto-discovery techniques described here:
+ * <p/>
+ * http://www.rssboard.org/rss-autodiscovery
+ * <p/>
+ * http://blog.whatwg.org/feed-autodiscovery
+ */
+public class FeedDiscoverer {
+
+ private static final String MIME_RSS = "application/rss+xml";
+ private static final String MIME_ATOM = "application/atom+xml";
+
+ /**
+ * Discovers links to RSS and Atom feeds in the given File which must be a HTML document.
+ *
+ * @return A map which contains the feed URLs as keys and titles as values (the feed URL is also used as a title if
+ * a title cannot be found).
+ */
+ public Map<String, String> findLinks(File in, String baseUrl) throws IOException {
+ return findLinks(Jsoup.parse(in), baseUrl);
+ }
+
+ /**
+ * Discovers links to RSS and Atom feeds in the given File which must be a HTML document.
+ *
+ * @return A map which contains the feed URLs as keys and titles as values (the feed URL is also used as a title if
+ * a title cannot be found).
+ */
+ public Map<String, String> findLinks(String in, String baseUrl) {
+ return findLinks(Jsoup.parse(in), baseUrl);
+ }
+
+ private Map<String, String> findLinks(Document document, String baseUrl) {
+ Map<String, String> res = new ArrayMap<>();
+ Elements links = document.head().getElementsByTag("link");
+ for (Element link : links) {
+ String rel = link.attr("rel");
+ String href = link.attr("href");
+ if (!TextUtils.isEmpty(href) &&
+ (rel.equals("alternate") || rel.equals("feed"))) {
+ String type = link.attr("type");
+ if (type.equals(MIME_RSS) || type.equals(MIME_ATOM)) {
+ String title = link.attr("title");
+ String processedUrl = processURL(baseUrl, href);
+ if (processedUrl != null) {
+ res.put(processedUrl,
+ (TextUtils.isEmpty(title)) ? href : title);
+ }
+ }
+ }
+ }
+ return res;
+ }
+
+ private String processURL(String baseUrl, String strUrl) {
+ Uri uri = Uri.parse(strUrl);
+ if (uri.isRelative()) {
+ Uri res = Uri.parse(baseUrl).buildUpon().path(strUrl).build();
+ return (res != null) ? res.toString() : null;
+ } else {
+ return strUrl;
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedItemlistDescriptionAdapter.java
index b55f2a6bc..f46d786cf 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedItemlistDescriptionAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.screen.onlinefeedview;
import android.content.Context;
import android.view.LayoutInflater;
@@ -20,8 +20,8 @@ import de.danoeh.antennapod.playback.service.PlaybackService;
import de.danoeh.antennapod.playback.service.PlaybackServiceStarter;
import de.danoeh.antennapod.ui.common.DateFormatter;
import de.danoeh.antennapod.model.playback.Playable;
-import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
-import de.danoeh.antennapod.dialog.StreamingConfirmationDialog;
+import de.danoeh.antennapod.ui.cleaner.HtmlToPlainText;
+import de.danoeh.antennapod.ui.StreamingConfirmationDialog;
import java.util.List;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/OnlineFeedViewActivity.java
index 1f3963d46..42050e718 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/onlinefeedview/OnlineFeedViewActivity.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.activity;
+package de.danoeh.antennapod.ui.screen.onlinefeedview;
import android.app.Dialog;
import android.content.Context;
@@ -27,7 +27,6 @@ import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.adapter.FeedItemlistDescriptionAdapter;
import de.danoeh.antennapod.net.download.service.feed.remote.Downloader;
import de.danoeh.antennapod.net.download.service.feed.remote.HttpDownloader;
import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter;
@@ -36,7 +35,7 @@ import de.danoeh.antennapod.net.download.serviceinterface.DownloadRequestCreator
import de.danoeh.antennapod.net.discovery.FeedUrlNotFoundException;
import de.danoeh.antennapod.storage.database.FeedDatabaseWriter;
import de.danoeh.antennapod.playback.service.PlaybackServiceInterface;
-import de.danoeh.antennapod.core.util.DownloadErrorLabel;
+import de.danoeh.antennapod.ui.screen.download.DownloadErrorLabel;
import de.danoeh.antennapod.databinding.EditTextDialogBinding;
import de.danoeh.antennapod.databinding.OnlinefeedviewHeaderBinding;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
@@ -57,8 +56,7 @@ import de.danoeh.antennapod.parser.feed.FeedHandlerResult;
import de.danoeh.antennapod.model.download.DownloadError;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.net.common.UrlChecker;
-import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer;
-import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
+import de.danoeh.antennapod.ui.cleaner.HtmlToPlainText;
import de.danoeh.antennapod.databinding.OnlinefeedviewActivityBinding;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedPreferences;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/MediaPlayerErrorDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/MediaPlayerErrorDialog.java
index 8425e0bfa..62dff00fd 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/MediaPlayerErrorDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/MediaPlayerErrorDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.playback;
import android.app.Activity;
import android.text.Spannable;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/PlayButton.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlayButton.java
index 04b277fb4..fbd791e71 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/PlayButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlayButton.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.screen.playback;
import android.content.Context;
import android.util.AttributeSet;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackControlsDialog.java
index 97b161955..b46c5e80c 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackControlsDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.playback;
import android.app.Dialog;
import android.os.Bundle;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PlaybackSpeedDialogActivity.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackSpeedDialogActivity.java
index 37f13272a..9d73e81a7 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/PlaybackSpeedDialogActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackSpeedDialogActivity.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.activity;
+package de.danoeh.antennapod.ui.screen.playback;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
@@ -7,7 +7,7 @@ import android.content.DialogInterface;
import android.os.Bundle;
import de.danoeh.antennapod.ui.common.ThemeSwitcher;
-import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+import de.danoeh.antennapod.ui.screen.playback.VariableSpeedDialog;
public class PlaybackSpeedDialogActivity extends AppCompatActivity {
diff --git a/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackSpeedSeekBar.java
index 33f0d47b8..c65d3656c 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/PlaybackSpeedSeekBar.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.screen.playback;
import android.content.Context;
import android.util.AttributeSet;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/SleepTimerDialog.java
index 5525ee8c2..911460d58 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/SleepTimerDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.playback;
import android.app.Activity;
import android.app.Dialog;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/TimeRangeDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/TimeRangeDialog.java
index 1d84c7c22..683c162fc 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/TimeRangeDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/TimeRangeDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.playback;
import android.content.Context;
import android.graphics.Canvas;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/VariableSpeedDialog.java
index ee5777d35..8343e933a 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/VariableSpeedDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.playback;
import android.os.Bundle;
import android.os.Handler;
@@ -19,8 +19,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.event.playback.SpeedChangedEvent;
import de.danoeh.antennapod.playback.service.PlaybackController;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.view.ItemOffsetDecoration;
-import de.danoeh.antennapod.view.PlaybackSpeedSeekBar;
+import de.danoeh.antennapod.ui.view.ItemOffsetDecoration;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/AudioPlayerFragment.java
index 3695e7426..5e1f5c818 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/AudioPlayerFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.playback.audio;
import android.content.Intent;
import android.os.Bundle;
@@ -29,6 +29,10 @@ import de.danoeh.antennapod.playback.service.PlaybackController;
import de.danoeh.antennapod.ui.appstartintent.MediaButtonStarter;
import de.danoeh.antennapod.ui.episodes.PlaybackSpeedUtils;
import de.danoeh.antennapod.ui.episodes.TimeSpeedConverter;
+import de.danoeh.antennapod.ui.screen.playback.MediaPlayerErrorDialog;
+import de.danoeh.antennapod.ui.screen.playback.PlayButton;
+import de.danoeh.antennapod.ui.screen.playback.SleepTimerDialog;
+import de.danoeh.antennapod.ui.screen.playback.VariableSpeedDialog;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@@ -41,10 +45,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.util.ChapterUtils;
import de.danoeh.antennapod.ui.common.Converter;
-import de.danoeh.antennapod.dialog.MediaPlayerErrorDialog;
-import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
-import de.danoeh.antennapod.dialog.SleepTimerDialog;
-import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+import de.danoeh.antennapod.ui.screen.feed.preferences.SkipPreferenceDialog;
import de.danoeh.antennapod.event.FavoritesEvent;
import de.danoeh.antennapod.event.PlayerErrorEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
@@ -53,7 +54,7 @@ import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
import de.danoeh.antennapod.event.playback.PlaybackServiceEvent;
import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent;
import de.danoeh.antennapod.event.playback.SpeedChangedEvent;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
import de.danoeh.antennapod.model.feed.Chapter;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedMedia;
@@ -61,8 +62,6 @@ import de.danoeh.antennapod.model.playback.Playable;
import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.common.PlaybackSpeedIndicatorView;
-import de.danoeh.antennapod.view.ChapterSeekBar;
-import de.danoeh.antennapod.view.PlayButton;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/ChapterSeekBar.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ChapterSeekBar.java
index d35206647..0ce284f97 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/ChapterSeekBar.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ChapterSeekBar.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.screen.playback.audio;
import android.content.Context;
import android.graphics.Canvas;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/CoverFragment.java
index 3076b6e63..05e6f3d6c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/CoverFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.playback.audio;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -33,6 +33,7 @@ import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.util.ChapterUtils;
+import de.danoeh.antennapod.ui.screen.chapter.ChaptersFragment;
import de.danoeh.antennapod.playback.service.PlaybackController;
import de.danoeh.antennapod.ui.common.DateFormatter;
import de.danoeh.antennapod.databinding.CoverFragmentBinding;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ExternalPlayerFragment.java
index 981f8f4b1..67514697f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ExternalPlayerFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.playback.audio;
import android.content.Intent;
import android.os.Bundle;
@@ -25,7 +25,7 @@ import de.danoeh.antennapod.playback.base.PlayerStatus;
import de.danoeh.antennapod.playback.service.PlaybackController;
import de.danoeh.antennapod.playback.service.PlaybackService;
import de.danoeh.antennapod.ui.episodes.ImageResourceUtils;
-import de.danoeh.antennapod.view.PlayButton;
+import de.danoeh.antennapod.ui.screen.playback.PlayButton;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ItemDescriptionFragment.java
index 6ab9dc671..3e7366431 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/ItemDescriptionFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.playback.audio;
import android.app.Activity;
import android.content.Context;
@@ -15,10 +15,10 @@ import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.playback.service.PlaybackController;
import de.danoeh.antennapod.storage.database.DBReader;
-import de.danoeh.antennapod.core.util.gui.ShownotesCleaner;
+import de.danoeh.antennapod.ui.cleaner.ShownotesCleaner;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.model.playback.Playable;
-import de.danoeh.antennapod.view.ShownotesWebView;
+import de.danoeh.antennapod.ui.view.ShownotesWebView;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/NoRelayoutTextView.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/NoRelayoutTextView.java
index cbb2ef0af..86f9a53e9 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/NoRelayoutTextView.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/audio/NoRelayoutTextView.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.screen.playback.audio;
import android.content.Context;
import android.util.AttributeSet;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/AspectRatioVideoView.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/AspectRatioVideoView.java
index 4c116fa2d..59fa0a07f 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/AspectRatioVideoView.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/AspectRatioVideoView.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.screen.playback.video;
/*
* Copyright (C) Google Inc. All rights reserved.
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/PictureInPictureUtil.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/PictureInPictureUtil.java
new file mode 100644
index 000000000..7f40610cc
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/PictureInPictureUtil.java
@@ -0,0 +1,27 @@
+package de.danoeh.antennapod.ui.screen.playback.video;
+
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.os.Build;
+
+public class PictureInPictureUtil {
+ private PictureInPictureUtil() {
+ }
+
+ public static boolean supportsPictureInPicture(Activity activity) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ PackageManager packageManager = activity.getPackageManager();
+ return packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean isInPictureInPictureMode(Activity activity) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && supportsPictureInPicture(activity)) {
+ return activity.isInPictureInPictureMode();
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/VideoplayerActivity.java
index 313d97248..2a0746f54 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/playback/video/VideoplayerActivity.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.activity;
+package de.danoeh.antennapod.ui.screen.playback.video;
import android.content.Intent;
import android.graphics.PixelFormat;
@@ -34,15 +34,14 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import com.bumptech.glide.Glide;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.dialog.MediaPlayerErrorDialog;
-import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.event.MessageEvent;
import de.danoeh.antennapod.event.playback.BufferUpdateEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
import de.danoeh.antennapod.event.PlayerErrorEvent;
import de.danoeh.antennapod.event.playback.PlaybackServiceEvent;
import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent;
-import de.danoeh.antennapod.fragment.ChaptersFragment;
+import de.danoeh.antennapod.ui.screen.chapter.ChaptersFragment;
import de.danoeh.antennapod.playback.service.PlaybackController;
import de.danoeh.antennapod.playback.service.PlaybackService;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
@@ -51,13 +50,10 @@ import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.ui.common.Converter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.IntentUtils;
-import de.danoeh.antennapod.core.util.ShareUtils;
-import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
+import de.danoeh.antennapod.ui.share.ShareUtils;
import de.danoeh.antennapod.databinding.VideoplayerActivityBinding;
-import de.danoeh.antennapod.dialog.PlaybackControlsDialog;
-import de.danoeh.antennapod.dialog.ShareDialog;
-import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
-import de.danoeh.antennapod.dialog.SleepTimerDialog;
+import de.danoeh.antennapod.ui.share.ShareDialog;
+import de.danoeh.antennapod.ui.screen.feed.preferences.SkipPreferenceDialog;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.model.playback.Playable;
@@ -65,6 +61,10 @@ import de.danoeh.antennapod.playback.base.PlayerStatus;
import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter;
import de.danoeh.antennapod.ui.episodes.TimeSpeedConverter;
+import de.danoeh.antennapod.ui.screen.playback.MediaPlayerErrorDialog;
+import de.danoeh.antennapod.ui.screen.playback.PlaybackControlsDialog;
+import de.danoeh.antennapod.ui.screen.playback.SleepTimerDialog;
+import de.danoeh.antennapod.ui.screen.playback.VariableSpeedDialog;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/BugReportActivity.java
index e379b5eb2..b4a5218ee 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/BugReportActivity.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.activity;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.content.ClipData;
import android.content.ClipboardManager;
@@ -22,7 +22,7 @@ import android.widget.TextView;
import de.danoeh.antennapod.ui.common.ThemeSwitcher;
-import de.danoeh.antennapod.error.CrashReportWriter;
+import de.danoeh.antennapod.CrashReportWriter;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.IntentUtils;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/DownloadsPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/DownloadsPreferencesFragment.java
index 58e968155..fad8c6986 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/DownloadsPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/DownloadsPreferencesFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.preferences;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.content.SharedPreferences;
import android.os.Bundle;
@@ -9,10 +9,8 @@ import androidx.preference.TwoStatePreference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import de.danoeh.antennapod.ui.preferences.screen.downloads.ChooseDataFolderDialog;
-import de.danoeh.antennapod.dialog.ProxyDialog;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import java.io.File;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/ImportExportPreferencesFragment.java
index 7c607c242..5ffa7e57a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/ImportExportPreferencesFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.preferences;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.app.Activity;
import android.app.ProgressDialog;
@@ -27,7 +27,6 @@ import androidx.preference.PreferenceFragmentCompat;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.OpmlImportActivity;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/MainPreferencesFragment.java
index 50d201f39..40a9dd605 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/MainPreferencesFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.preferences;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.content.Intent;
import android.graphics.PorterDuff;
@@ -13,8 +13,6 @@ import com.bytehamster.lib.preferencesearch.SearchConfiguration;
import com.bytehamster.lib.preferencesearch.SearchPreference;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.BugReportActivity;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.ui.preferences.screen.about.AboutFragment;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PlaybackPreferencesFragment.java
index dcbd96d5b..70d2828bb 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PlaybackPreferencesFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.preferences;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.app.Activity;
import android.content.res.Resources;
@@ -10,12 +10,11 @@ import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.storage.preferences.UsageStatistics;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
-import de.danoeh.antennapod.dialog.VariableSpeedDialog;
+import de.danoeh.antennapod.ui.screen.feed.preferences.SkipPreferenceDialog;
+import de.danoeh.antennapod.ui.screen.playback.VariableSpeedDialog;
import java.util.Map;
import org.greenrobot.eventbus.EventBus;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceActivity.java
index aa3b05715..e82c2c084 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceActivity.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.activity;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.content.Intent;
import android.os.Build;
@@ -23,12 +23,6 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.ui.common.ThemeSwitcher;
import de.danoeh.antennapod.event.MessageEvent;
-import de.danoeh.antennapod.fragment.preferences.ImportExportPreferencesFragment;
-import de.danoeh.antennapod.fragment.preferences.MainPreferencesFragment;
-import de.danoeh.antennapod.fragment.preferences.DownloadsPreferencesFragment;
-import de.danoeh.antennapod.fragment.preferences.PlaybackPreferencesFragment;
-import de.danoeh.antennapod.fragment.preferences.SwipePreferencesFragment;
-import de.danoeh.antennapod.fragment.preferences.UserInterfacePreferencesFragment;
import de.danoeh.antennapod.ui.preferences.screen.AutoDownloadPreferencesFragment;
import de.danoeh.antennapod.ui.preferences.screen.NotificationPreferencesFragment;
import de.danoeh.antennapod.ui.preferences.screen.synchronization.SynchronizationPreferencesFragment;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/dialog/PreferenceListDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceListDialog.java
index b6a11c001..26ed7eada 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/dialog/PreferenceListDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceListDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.preferences.dialog;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/dialog/PreferenceSwitchDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceSwitchDialog.java
index 10fbe6137..217785f90 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/dialog/PreferenceSwitchDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/PreferenceSwitchDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.preferences.dialog;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.content.Context;
import android.view.LayoutInflater;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/ProxyDialog.java
index 8c7a30bff..ca4b4b5e5 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/ProxyDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.app.Dialog;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/SwipePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/SwipePreferencesFragment.java
index 5b81ff7a5..7522c2a1b 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/SwipePreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/SwipePreferencesFragment.java
@@ -1,16 +1,15 @@
-package de.danoeh.antennapod.fragment.preferences;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.os.Bundle;
import androidx.preference.PreferenceFragmentCompat;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
-import de.danoeh.antennapod.dialog.SwipeActionsDialog;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
-import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
-import de.danoeh.antennapod.fragment.FeedItemlistFragment;
-import de.danoeh.antennapod.fragment.InboxFragment;
-import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
-import de.danoeh.antennapod.fragment.QueueFragment;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActionsDialog;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
+import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
+import de.danoeh.antennapod.ui.screen.InboxFragment;
+import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
public class SwipePreferencesFragment extends PreferenceFragmentCompat {
private static final String PREF_SWIPE_QUEUE = "prefSwipeQueue";
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/UserInterfacePreferencesFragment.java
index af48c705d..86840f759 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/preferences/UserInterfacePreferencesFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.preferences;
+package de.danoeh.antennapod.ui.screen.preferences;
import android.content.Context;
import android.content.DialogInterface;
@@ -15,15 +15,14 @@ import androidx.preference.PreferenceFragmentCompat;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
+import de.danoeh.antennapod.ui.screen.subscriptions.FeedSortDialog;
import org.greenrobot.eventbus.EventBus;
import java.util.List;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
-import de.danoeh.antennapod.dialog.DrawerPreferencesDialog;
-import de.danoeh.antennapod.dialog.FeedSortDialog;
-import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
+import de.danoeh.antennapod.ui.screen.drawer.DrawerPreferencesDialog;
+import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionsFilterDialog;
import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/queue/QueueFragment.java
index 126d0d748..31fedda1d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/queue/QueueFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.queue;
import android.content.Context;
import android.content.DialogInterface;
@@ -28,6 +28,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;
+import de.danoeh.antennapod.ui.screen.SearchFragment;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import de.danoeh.antennapod.ui.episodes.PlaybackSpeedUtils;
import org.greenrobot.eventbus.EventBus;
@@ -38,15 +39,14 @@ import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.adapter.QueueRecyclerAdapter;
-import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
+import de.danoeh.antennapod.core.util.ConfirmationDialog;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.ui.common.Converter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.dialog.ItemSortDialog;
+import de.danoeh.antennapod.ui.screen.feed.ItemSortDialog;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
@@ -54,17 +54,17 @@ import de.danoeh.antennapod.event.PlayerStatusEvent;
import de.danoeh.antennapod.event.QueueEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeMultiSelectActionHandler;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActions;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.model.feed.SortOrder;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.view.EmptyViewHandler;
-import de.danoeh.antennapod.view.EpisodeItemListRecyclerView;
-import de.danoeh.antennapod.view.LiftOnScrollListener;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.view.EmptyViewHandler;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView;
+import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/queue/QueueRecyclerAdapter.java
index 1f4cfd0cf..371118166 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/queue/QueueRecyclerAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.screen.queue;
import android.annotation.SuppressLint;
import android.util.Log;
@@ -9,9 +9,10 @@ import android.view.View;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.swipeactions.SwipeActions;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
/**
* List adapter for the queue.
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/rating/RatingDialogFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/rating/RatingDialogFragment.java
index 4e9da8b9a..9adf885b1 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/rating/RatingDialogFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/rating/RatingDialogFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog.rating;
+package de.danoeh.antennapod.ui.screen.rating;
import android.app.Dialog;
import android.content.DialogInterface;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/rating/RatingDialogManager.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/rating/RatingDialogManager.java
index 53e1c8c72..edba0ec83 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/rating/RatingDialogManager.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/rating/RatingDialogManager.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog.rating;
+package de.danoeh.antennapod.ui.screen.rating;
import android.content.Context;
import android.content.SharedPreferences;
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMenuHandler.java
index c0448884d..e1e9f2287 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMenuHandler.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.menuhandler;
+package de.danoeh.antennapod.ui.screen.subscriptions;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -7,11 +7,11 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
+import de.danoeh.antennapod.core.util.ConfirmationDialog;
import de.danoeh.antennapod.storage.database.DBWriter;
-import de.danoeh.antennapod.dialog.RemoveFeedDialog;
-import de.danoeh.antennapod.dialog.RenameItemDialog;
-import de.danoeh.antennapod.dialog.TagSettingsDialog;
+import de.danoeh.antennapod.ui.screen.feed.RemoveFeedDialog;
+import de.danoeh.antennapod.ui.screen.feed.RenameFeedDialog;
+import de.danoeh.antennapod.ui.screen.feed.preferences.TagSettingsDialog;
import de.danoeh.antennapod.model.feed.Feed;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -31,7 +31,7 @@ public abstract class FeedMenuHandler {
@NonNull Feed selectedFeed, Runnable callback) {
@NonNull Context context = fragment.requireContext();
if (menuItemId == R.id.rename_folder_item) {
- new RenameItemDialog(fragment.getActivity(), selectedFeed).show();
+ new RenameFeedDialog(fragment.getActivity(), selectedFeed).show();
} else if (menuItemId == R.id.remove_all_inbox_item) {
ConfirmationDialog dialog = new ConfirmationDialog(fragment.getActivity(),
R.string.remove_all_inbox_label, R.string.remove_all_inbox_confirmation_msg) {
@@ -52,7 +52,7 @@ public abstract class FeedMenuHandler {
TagSettingsDialog.newInstance(Collections.singletonList(selectedFeed.getPreferences()))
.show(fragment.getChildFragmentManager(), TagSettingsDialog.TAG);
} else if (menuItemId == R.id.rename_item) {
- new RenameItemDialog(fragment.getActivity(), selectedFeed).show();
+ new RenameFeedDialog(fragment.getActivity(), selectedFeed).show();
} else if (menuItemId == R.id.remove_feed) {
RemoveFeedDialog.show(context, selectedFeed, null);
} else {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMultiSelectActionHandler.java
index 5a6b4ffa9..f2c89f12f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedMultiSelectActionHandler.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.actions;
+package de.danoeh.antennapod.ui.screen.subscriptions;
import android.util.Log;
@@ -16,12 +16,12 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.databinding.PlaybackSpeedFeedSettingDialogBinding;
-import de.danoeh.antennapod.dialog.RemoveFeedDialog;
-import de.danoeh.antennapod.dialog.TagSettingsDialog;
+import de.danoeh.antennapod.ui.screen.feed.RemoveFeedDialog;
+import de.danoeh.antennapod.ui.screen.feed.preferences.TagSettingsDialog;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedPreferences;
-import de.danoeh.antennapod.fragment.preferences.dialog.PreferenceListDialog;
-import de.danoeh.antennapod.fragment.preferences.dialog.PreferenceSwitchDialog;
+import de.danoeh.antennapod.ui.screen.preferences.PreferenceListDialog;
+import de.danoeh.antennapod.ui.screen.preferences.PreferenceSwitchDialog;
public class FeedMultiSelectActionHandler {
private static final String TAG = "FeedSelectHandler";
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FeedSortDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedSortDialog.java
index daa00b8a3..7e42581ce 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/FeedSortDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/FeedSortDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.subscriptions;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/HorizontalFeedListAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/HorizontalFeedListAdapter.java
index 304bf9f64..e66b447f8 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/HorizontalFeedListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/HorizontalFeedListAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.screen.subscriptions;
import android.view.View;
import android.view.ViewGroup;
@@ -12,7 +12,7 @@ import com.bumptech.glide.request.RequestOptions;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.model.feed.Feed;
-import de.danoeh.antennapod.fragment.FeedItemlistFragment;
+import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
import de.danoeh.antennapod.ui.common.SquareImageView;
import java.lang.ref.WeakReference;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionFragment.java
index dcc78f152..f115db0ff 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionFragment.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment;
+package de.danoeh.antennapod.ui.screen.subscriptions;
import android.content.Context;
import android.content.SharedPreferences;
@@ -22,6 +22,8 @@ import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.leinardi.android.speeddial.SpeedDialView;
+import de.danoeh.antennapod.ui.screen.AddFeedFragment;
+import de.danoeh.antennapod.ui.screen.SearchFragment;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -33,23 +35,18 @@ import java.util.Locale;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.SubscriptionsRecyclerAdapter;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.database.NavDrawerData;
-import de.danoeh.antennapod.dialog.FeedSortDialog;
-import de.danoeh.antennapod.dialog.RenameItemDialog;
-import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
+import de.danoeh.antennapod.ui.screen.feed.RenameFeedDialog;
import de.danoeh.antennapod.event.FeedListUpdateEvent;
import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
-import de.danoeh.antennapod.fragment.actions.FeedMultiSelectActionHandler;
-import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.statistics.StatisticsFragment;
-import de.danoeh.antennapod.view.EmptyViewHandler;
-import de.danoeh.antennapod.view.LiftOnScrollListener;
+import de.danoeh.antennapod.ui.view.EmptyViewHandler;
+import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
@@ -323,7 +320,7 @@ public class SubscriptionFragment extends Fragment
}
int itemId = item.getItemId();
if (drawerItem.type == NavDrawerData.DrawerItem.Type.TAG && itemId == R.id.rename_folder_item) {
- new RenameItemDialog(getActivity(), drawerItem).show();
+ new RenameFeedDialog(getActivity(), drawerItem).show();
return true;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsFilterDialog.java
index 929e6b1ad..53ced5f11 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsFilterDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.screen.subscriptions;
import android.app.Dialog;
import android.os.Bundle;
@@ -16,7 +16,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.google.android.material.button.MaterialButtonToggleGroup;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.SubscriptionsFilterGroup;
import de.danoeh.antennapod.databinding.FilterDialogBinding;
import de.danoeh.antennapod.databinding.FilterDialogRowBinding;
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsFilterGroup.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsFilterGroup.java
new file mode 100644
index 000000000..41dce16f0
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsFilterGroup.java
@@ -0,0 +1,33 @@
+package de.danoeh.antennapod.ui.screen.subscriptions;
+
+import de.danoeh.antennapod.core.R;
+
+public enum SubscriptionsFilterGroup {
+ COUNTER_GREATER_ZERO(new ItemProperties(R.string.subscriptions_counter_greater_zero, "counter_greater_zero")),
+ AUTO_DOWNLOAD(new ItemProperties(R.string.auto_downloaded, "enabled_auto_download"),
+ new ItemProperties(R.string.not_auto_downloaded, "disabled_auto_download")),
+ UPDATED(new ItemProperties(R.string.kept_updated, "enabled_updates"),
+ new ItemProperties(R.string.not_kept_updated, "disabled_updates")),
+ NEW_EPISODE_NOTIFICATION(new ItemProperties(R.string.new_episode_notification_enabled,
+ "episode_notification_enabled"),
+ new ItemProperties(R.string.new_episode_notification_disabled, "episode_notification_disabled"));
+
+
+ public final ItemProperties[] values;
+
+ SubscriptionsFilterGroup(ItemProperties... values) {
+ this.values = values;
+ }
+
+ public static class ItemProperties {
+
+ public final int displayName;
+ public final String filterId;
+
+ public ItemProperties(int displayName, String filterId) {
+ this.displayName = displayName;
+ this.filterId = filterId;
+ }
+
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsRecyclerAdapter.java
index 262c1f906..fecb191b3 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/screen/subscriptions/SubscriptionsRecyclerAdapter.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.adapter;
+package de.danoeh.antennapod.ui.screen.subscriptions;
import android.content.Context;
import android.graphics.Canvas;
@@ -32,10 +32,11 @@ import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.ui.CoverLoader;
+import de.danoeh.antennapod.ui.SelectableAdapter;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.storage.database.NavDrawerData;
-import de.danoeh.antennapod.fragment.FeedItemlistFragment;
-import de.danoeh.antennapod.fragment.SubscriptionFragment;
+import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
import de.danoeh.antennapod.model.feed.Feed;
/**
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ShareDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/share/ShareDialog.java
index 5fb8a352f..963c0b14b 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/ShareDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/share/ShareDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.share;
import android.content.Context;
import android.content.SharedPreferences;
@@ -9,7 +9,6 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
-import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.databinding.ShareEpisodeDialogBinding;
import de.danoeh.antennapod.model.feed.FeedItem;
diff --git a/app/src/main/java/de/danoeh/antennapod/ui/share/ShareUtils.java b/app/src/main/java/de/danoeh/antennapod/ui/share/ShareUtils.java
new file mode 100644
index 000000000..77d5f4305
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/ui/share/ShareUtils.java
@@ -0,0 +1,92 @@
+package de.danoeh.antennapod.ui.share;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.ShareCompat;
+import androidx.core.content.FileProvider;
+
+import de.danoeh.antennapod.core.util.FeedItemUtil;
+import de.danoeh.antennapod.ui.common.Converter;
+import java.io.File;
+import java.net.URLEncoder;
+
+import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.model.feed.Feed;
+import de.danoeh.antennapod.model.feed.FeedItem;
+import de.danoeh.antennapod.model.feed.FeedMedia;
+
+/** Utility methods for sharing data */
+public class ShareUtils {
+ private static final String TAG = "ShareUtils";
+
+ private ShareUtils() {
+ }
+
+ public static void shareLink(@NonNull Context context, @NonNull String text) {
+ Intent intent = new ShareCompat.IntentBuilder(context)
+ .setType("text/plain")
+ .setText(text)
+ .setChooserTitle(R.string.share_url_label)
+ .createChooserIntent();
+ context.startActivity(intent);
+ }
+
+ public static void shareFeedLink(Context context, Feed feed) {
+ String text = feed.getTitle()
+ + "\n\n"
+ + "https://antennapod.org/deeplink/subscribe/?url="
+ + URLEncoder.encode(feed.getDownloadUrl())
+ + "&title="
+ + URLEncoder.encode(feed.getTitle());
+ shareLink(context, text);
+ }
+
+ public static boolean hasLinkToShare(FeedItem item) {
+ return FeedItemUtil.getLinkWithFallback(item) != null;
+ }
+
+ public static void shareMediaDownloadLink(Context context, FeedMedia media) {
+ shareLink(context, media.getDownloadUrl());
+ }
+
+ public static void shareFeedItemLinkWithDownloadLink(Context context, FeedItem item, boolean withPosition) {
+ String text = item.getFeed().getTitle() + ": " + item.getTitle();
+ int pos = 0;
+ if (item.getMedia() != null && withPosition) {
+ text += "\n" + context.getResources().getString(R.string.share_starting_position_label) + ": ";
+ pos = item.getMedia().getPosition();
+ text += Converter.getDurationStringLong(pos);
+ }
+
+ if (hasLinkToShare(item)) {
+ text += "\n\n" + context.getResources().getString(R.string.share_dialog_episode_website_label) + ": ";
+ text += FeedItemUtil.getLinkWithFallback(item);
+ }
+
+ if (item.getMedia() != null && item.getMedia().getDownloadUrl() != null) {
+ text += "\n\n" + context.getResources().getString(R.string.share_dialog_media_file_label) + ": ";
+ text += item.getMedia().getDownloadUrl();
+ if (withPosition) {
+ text += "#t=" + pos / 1000;
+ }
+ }
+ shareLink(context, text);
+ }
+
+ public static void shareFeedItemFile(Context context, FeedMedia media) {
+ Uri fileUri = FileProvider.getUriForFile(context, context.getString(R.string.provider_authority),
+ new File(media.getLocalFileUrl()));
+
+ new ShareCompat.IntentBuilder(context)
+ .setType(media.getMimeType())
+ .addStream(fileUri)
+ .setChooserTitle(R.string.share_file_label)
+ .startChooser();
+
+ Log.e(TAG, "shareFeedItemFile called");
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/AddToQueueSwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/AddToQueueSwipeAction.java
index 06efda3ee..0870adff9 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/AddToQueueSwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/AddToQueueSwipeAction.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/DeleteSwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/DeleteSwipeAction.java
index 52f214eed..1ecfd11e0 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/DeleteSwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/DeleteSwipeAction.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
import androidx.fragment.app.Fragment;
@@ -9,7 +9,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.storage.database.DBWriter;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
-import de.danoeh.antennapod.view.LocalDeleteModal;
+import de.danoeh.antennapod.ui.view.LocalDeleteModal;
public class DeleteSwipeAction implements SwipeAction {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/MarkFavoriteSwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/MarkFavoriteSwipeAction.java
index dcea8c031..8ce0f8482 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/MarkFavoriteSwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/MarkFavoriteSwipeAction.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromHistorySwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromHistorySwipeAction.java
index 46285734e..e757ece42 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromHistorySwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromHistorySwipeAction.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromInboxSwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromInboxSwipeAction.java
index 41d79a711..c7bebecab 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromInboxSwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromInboxSwipeAction.java
@@ -1,11 +1,11 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromQueueSwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromQueueSwipeAction.java
index f5cbf66c6..dbdc3126b 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/RemoveFromQueueSwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/RemoveFromQueueSwipeAction.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/ShowFirstSwipeDialogAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/ShowFirstSwipeDialogAction.java
index 3a6174e8f..3c0afee81 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/ShowFirstSwipeDialogAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/ShowFirstSwipeDialogAction.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/StartDownloadSwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/StartDownloadSwipeAction.java
index 84dc8f417..0df3bcaec 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/StartDownloadSwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/StartDownloadSwipeAction.java
@@ -1,9 +1,9 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.adapter.actionbutton.DownloadActionButton;
+import de.danoeh.antennapod.actionbutton.DownloadActionButton;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeAction.java
index 4b1cfdc78..007bdeff3 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeAction.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeActions.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeActions.java
index 28320099a..fdc22094e 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeActions.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeActions.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
import android.content.SharedPreferences;
@@ -18,16 +18,15 @@ import java.util.Collections;
import java.util.List;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.dialog.SwipeActionsDialog;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
-import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
-import de.danoeh.antennapod.fragment.InboxFragment;
-import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
-import de.danoeh.antennapod.fragment.QueueFragment;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
+import de.danoeh.antennapod.ui.screen.InboxFragment;
+import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.ui.common.ThemeUtils;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
import it.xabaras.android.recyclerview.swipedecorator.RecyclerViewSwipeDecorator;
public class SwipeActions extends ItemTouchHelper.SimpleCallback implements LifecycleObserver {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SwipeActionsDialog.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeActionsDialog.java
index 2cd03e21d..a02a685f0 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SwipeActionsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/SwipeActionsDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.dialog;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
import android.content.SharedPreferences;
@@ -22,22 +22,12 @@ import de.danoeh.antennapod.databinding.SwipeactionsDialogBinding;
import de.danoeh.antennapod.databinding.SwipeactionsPickerBinding;
import de.danoeh.antennapod.databinding.SwipeactionsPickerItemBinding;
import de.danoeh.antennapod.databinding.SwipeactionsRowBinding;
-import de.danoeh.antennapod.fragment.AllEpisodesFragment;
-import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
-import de.danoeh.antennapod.fragment.FeedItemlistFragment;
-import de.danoeh.antennapod.fragment.InboxFragment;
-import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
-import de.danoeh.antennapod.fragment.QueueFragment;
-import de.danoeh.antennapod.fragment.swipeactions.AddToQueueSwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.DeleteSwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.MarkFavoriteSwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.RemoveFromHistorySwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.RemoveFromInboxSwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.RemoveFromQueueSwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.StartDownloadSwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeAction;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
-import de.danoeh.antennapod.fragment.swipeactions.TogglePlaybackStateSwipeAction;
+import de.danoeh.antennapod.ui.screen.AllEpisodesFragment;
+import de.danoeh.antennapod.ui.screen.download.CompletedDownloadsFragment;
+import de.danoeh.antennapod.ui.screen.feed.FeedItemlistFragment;
+import de.danoeh.antennapod.ui.screen.InboxFragment;
+import de.danoeh.antennapod.ui.screen.PlaybackHistoryFragment;
+import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
import de.danoeh.antennapod.ui.common.ThemeUtils;
public class SwipeActionsDialog {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/TogglePlaybackStateSwipeAction.java b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/TogglePlaybackStateSwipeAction.java
index 8d4133058..aa83d5e3e 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/TogglePlaybackStateSwipeAction.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/swipeactions/TogglePlaybackStateSwipeAction.java
@@ -1,11 +1,11 @@
-package de.danoeh.antennapod.fragment.swipeactions;
+package de.danoeh.antennapod.ui.swipeactions;
import android.content.Context;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.ui.episodeslist.FeedItemMenuHandler;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java b/app/src/main/java/de/danoeh/antennapod/ui/view/EmptyViewHandler.java
index 2ecaaa5b3..b467f6f0e 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/EmptyViewHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/view/EmptyViewHandler.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.view;
import android.content.Context;
import android.database.DataSetObserver;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java b/app/src/main/java/de/danoeh/antennapod/ui/view/ItemOffsetDecoration.java
index 4a1267d81..4c3adcbc1 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/ItemOffsetDecoration.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/view/ItemOffsetDecoration.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.view;
import android.content.Context;
import android.graphics.Rect;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/LiftOnScrollListener.java b/app/src/main/java/de/danoeh/antennapod/ui/view/LiftOnScrollListener.java
index 020fb40e8..e046dd43e 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/LiftOnScrollListener.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/view/LiftOnScrollListener.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.view;
import android.animation.ValueAnimator;
import android.view.View;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/LocalDeleteModal.java b/app/src/main/java/de/danoeh/antennapod/ui/view/LocalDeleteModal.java
index a3f541e06..f0a1105c1 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/LocalDeleteModal.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/view/LocalDeleteModal.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.view;
import android.content.Context;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java b/app/src/main/java/de/danoeh/antennapod/ui/view/LockableBottomSheetBehavior.java
index 1b96c7c4f..aa506aaea 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/view/LockableBottomSheetBehavior.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.view;
import android.content.Context;
import android.util.AttributeSet;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java b/app/src/main/java/de/danoeh/antennapod/ui/view/NestedScrollableHost.java
index 660aa1ea9..b29792d90 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/NestedScrollableHost.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/view/NestedScrollableHost.java
@@ -17,7 +17,7 @@
* And modified for our need
*/
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.view;
import android.content.Context;
import android.content.res.TypedArray;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java b/app/src/main/java/de/danoeh/antennapod/ui/view/ShownotesWebView.java
index f470b0aac..67a659418 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/view/ShownotesWebView.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.view;
import android.content.ClipData;
import android.content.ClipboardManager;
@@ -24,12 +24,12 @@ import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
+import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.ui.common.Converter;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.net.common.NetworkUtils;
-import de.danoeh.antennapod.core.util.ShareUtils;
-import de.danoeh.antennapod.core.util.gui.ShownotesCleaner;
+import de.danoeh.antennapod.ui.share.ShareUtils;
+import de.danoeh.antennapod.ui.cleaner.ShownotesCleaner;
public class ShownotesWebView extends WebView implements View.OnLongClickListener {
private static final String TAG = "ShownotesWebView";
diff --git a/app/src/main/java/de/danoeh/antennapod/view/SimpleAdapterDataObserver.java b/app/src/main/java/de/danoeh/antennapod/ui/view/SimpleAdapterDataObserver.java
index 5bd335532..2e00aa436 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/SimpleAdapterDataObserver.java
+++ b/app/src/main/java/de/danoeh/antennapod/ui/view/SimpleAdapterDataObserver.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.view;
+package de.danoeh.antennapod.ui.view;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
diff --git a/app/src/main/res/layout-sw720dp/main.xml b/app/src/main/res/layout-sw720dp/main.xml
index d2b231992..e8edc260f 100644
--- a/app/src/main/res/layout-sw720dp/main.xml
+++ b/app/src/main/res/layout-sw720dp/main.xml
@@ -40,7 +40,7 @@
android:background="?android:attr/colorBackground"
android:elevation="8dp"
android:visibility="gone"
- app:layout_behavior="de.danoeh.antennapod.view.LockableBottomSheetBehavior" />
+ app:layout_behavior="de.danoeh.antennapod.ui.view.LockableBottomSheetBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout/audioplayer_fragment.xml b/app/src/main/res/layout/audioplayer_fragment.xml
index 1a6794db9..5f4775141 100644
--- a/app/src/main/res/layout/audioplayer_fragment.xml
+++ b/app/src/main/res/layout/audioplayer_fragment.xml
@@ -86,7 +86,7 @@
android:layoutDirection="ltr"
android:orientation="vertical">
- <de.danoeh.antennapod.view.ChapterSeekBar
+ <de.danoeh.antennapod.ui.screen.playback.audio.ChapterSeekBar
android:id="@+id/sbPosition"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -104,7 +104,7 @@
android:paddingLeft="8dp"
android:paddingRight="8dp">
- <de.danoeh.antennapod.view.NoRelayoutTextView
+ <de.danoeh.antennapod.ui.screen.playback.audio.NoRelayoutTextView
android:id="@+id/txtvPosition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -116,7 +116,7 @@
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/text_size_micro" />
- <de.danoeh.antennapod.view.NoRelayoutTextView
+ <de.danoeh.antennapod.ui.screen.playback.audio.NoRelayoutTextView
android:id="@+id/txtvLength"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -138,7 +138,7 @@
android:layout_height="wrap_content"
android:layout_marginBottom="24dp">
- <de.danoeh.antennapod.view.PlayButton
+ <de.danoeh.antennapod.ui.screen.playback.PlayButton
android:id="@+id/butPlay"
android:layout_width="@dimen/audioplayer_playercontrols_length_big"
android:layout_height="@dimen/audioplayer_playercontrols_length_big"
diff --git a/app/src/main/res/layout/episodes_list_fragment.xml b/app/src/main/res/layout/episodes_list_fragment.xml
index 19b21f4f6..d408f531c 100644
--- a/app/src/main/res/layout/episodes_list_fragment.xml
+++ b/app/src/main/res/layout/episodes_list_fragment.xml
@@ -40,7 +40,7 @@
android:layout_height="match_parent"
android:layout_below="@id/appbar">
- <de.danoeh.antennapod.view.EpisodeItemListRecyclerView
+ <de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/app/src/main/res/layout/external_player_fragment.xml b/app/src/main/res/layout/external_player_fragment.xml
index 4012595bc..233d06077 100644
--- a/app/src/main/res/layout/external_player_fragment.xml
+++ b/app/src/main/res/layout/external_player_fragment.xml
@@ -55,7 +55,7 @@
</LinearLayout>
- <de.danoeh.antennapod.view.PlayButton
+ <de.danoeh.antennapod.ui.screen.playback.PlayButton
android:id="@+id/butPlay"
android:layout_width="52dp"
android:layout_height="match_parent"
diff --git a/app/src/main/res/layout/feed_item_list_fragment.xml b/app/src/main/res/layout/feed_item_list_fragment.xml
index 1072924d5..23cbe0f05 100644
--- a/app/src/main/res/layout/feed_item_list_fragment.xml
+++ b/app/src/main/res/layout/feed_item_list_fragment.xml
@@ -52,7 +52,7 @@
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
- <de.danoeh.antennapod.view.EpisodeItemListRecyclerView
+ <de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/app/src/main/res/layout/feeditem_fragment.xml b/app/src/main/res/layout/feeditem_fragment.xml
index 0e5ace85f..37db9067c 100644
--- a/app/src/main/res/layout/feeditem_fragment.xml
+++ b/app/src/main/res/layout/feeditem_fragment.xml
@@ -190,19 +190,19 @@
</LinearLayout>
- <de.danoeh.antennapod.view.NestedScrollableHost
+ <de.danoeh.antennapod.ui.view.NestedScrollableHost
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/header"
app:preferVertical="3">
- <de.danoeh.antennapod.view.ShownotesWebView
+ <de.danoeh.antennapod.ui.view.ShownotesWebView
android:id="@+id/webvDescription"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="?android:windowContentOverlay" />
- </de.danoeh.antennapod.view.NestedScrollableHost>
+ </de.danoeh.antennapod.ui.view.NestedScrollableHost>
<FrameLayout
android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/item_description_fragment.xml b/app/src/main/res/layout/item_description_fragment.xml
index 469cd4098..13c31b68f 100644
--- a/app/src/main/res/layout/item_description_fragment.xml
+++ b/app/src/main/res/layout/item_description_fragment.xml
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
-<de.danoeh.antennapod.view.NestedScrollableHost xmlns:android="http://schemas.android.com/apk/res/android"
+<de.danoeh.antennapod.ui.view.NestedScrollableHost
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- xmlns:app="http://schemas.android.com/apk/res-auto"
android:fillViewport="false"
- app:preferVertical="10"
- android:nestedScrollingEnabled="true">
+ android:nestedScrollingEnabled="true"
+ app:preferVertical="10">
- <de.danoeh.antennapod.view.ShownotesWebView
+ <de.danoeh.antennapod.ui.view.ShownotesWebView
android:id="@+id/webview"
android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent" />
-</de.danoeh.antennapod.view.NestedScrollableHost> \ No newline at end of file
+</de.danoeh.antennapod.ui.view.NestedScrollableHost>
diff --git a/app/src/main/res/layout/main.xml b/app/src/main/res/layout/main.xml
index 3a368e90e..e205707d5 100644
--- a/app/src/main/res/layout/main.xml
+++ b/app/src/main/res/layout/main.xml
@@ -32,7 +32,7 @@
android:background="?android:attr/colorBackground"
android:elevation="8dp"
android:visibility="gone"
- app:layout_behavior="de.danoeh.antennapod.view.LockableBottomSheetBehavior" />
+ app:layout_behavior="de.danoeh.antennapod.ui.view.LockableBottomSheetBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout/playback_speed_feed_setting_dialog.xml b/app/src/main/res/layout/playback_speed_feed_setting_dialog.xml
index 50eb4f84f..317f86093 100644
--- a/app/src/main/res/layout/playback_speed_feed_setting_dialog.xml
+++ b/app/src/main/res/layout/playback_speed_feed_setting_dialog.xml
@@ -19,7 +19,7 @@
android:orientation="horizontal"
android:gravity="center_vertical">
- <de.danoeh.antennapod.view.PlaybackSpeedSeekBar
+ <de.danoeh.antennapod.ui.screen.playback.PlaybackSpeedSeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/queue_fragment.xml b/app/src/main/res/layout/queue_fragment.xml
index 50a0337fb..801c9e93a 100644
--- a/app/src/main/res/layout/queue_fragment.xml
+++ b/app/src/main/res/layout/queue_fragment.xml
@@ -41,7 +41,7 @@
android:layout_height="match_parent"
android:layout_below="@id/appbar">
- <de.danoeh.antennapod.view.EpisodeItemListRecyclerView
+ <de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/app/src/main/res/layout/search_fragment.xml b/app/src/main/res/layout/search_fragment.xml
index 17f679cc3..59853a9ee 100644
--- a/app/src/main/res/layout/search_fragment.xml
+++ b/app/src/main/res/layout/search_fragment.xml
@@ -52,7 +52,7 @@
android:paddingRight="12dp"
android:clipToPadding="false" />
- <de.danoeh.antennapod.view.EpisodeItemListRecyclerView
+ <de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/app/src/main/res/layout/simple_list_fragment.xml b/app/src/main/res/layout/simple_list_fragment.xml
index bcc43cfcc..273a08846 100644
--- a/app/src/main/res/layout/simple_list_fragment.xml
+++ b/app/src/main/res/layout/simple_list_fragment.xml
@@ -20,7 +20,7 @@
</com.google.android.material.appbar.AppBarLayout>
- <de.danoeh.antennapod.view.EpisodeItemListRecyclerView
+ <de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/app/src/main/res/layout/speed_select_dialog.xml b/app/src/main/res/layout/speed_select_dialog.xml
index 0b9e422a8..ad8e1ddcd 100644
--- a/app/src/main/res/layout/speed_select_dialog.xml
+++ b/app/src/main/res/layout/speed_select_dialog.xml
@@ -24,7 +24,7 @@
</LinearLayout>
- <de.danoeh.antennapod.view.PlaybackSpeedSeekBar
+ <de.danoeh.antennapod.ui.screen.playback.PlaybackSpeedSeekBar
android:id="@+id/speed_seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/videoplayer_activity.xml b/app/src/main/res/layout/videoplayer_activity.xml
index fcc1c5f15..d677b930b 100644
--- a/app/src/main/res/layout/videoplayer_activity.xml
+++ b/app/src/main/res/layout/videoplayer_activity.xml
@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/videoPlayerContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
- xmlns:tools="http://schemas.android.com/tools"
android:background="@color/black"
- android:orientation="vertical"
- android:id="@+id/videoPlayerContainer">
+ android:orientation="vertical">
- <de.danoeh.antennapod.view.AspectRatioVideoView
+ <de.danoeh.antennapod.ui.screen.playback.video.AspectRatioVideoView
android:id="@+id/videoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -41,7 +42,7 @@
android:contentDescription="@string/rewind_label"
app:srcCompat="@drawable/ic_fast_rewind_video_white" />
- <de.danoeh.antennapod.view.PlayButton
+ <de.danoeh.antennapod.ui.screen.playback.PlayButton
android:id="@+id/playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -67,7 +68,7 @@
android:layout_height="wrap_content"
android:visibility="gone"
android:padding="64dp"
- android:layout_gravity="center"/>
+ android:layout_gravity="center" />
<LinearLayout
android:id="@+id/bottomControlsContainer"
@@ -78,9 +79,9 @@
<androidx.cardview.widget.CardView
android:id="@+id/seekCardView"
- android:alpha="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:alpha="0"
android:layout_marginBottom="12dp"
android:layout_gravity="center"
app:cardCornerRadius="8dp"
@@ -90,9 +91,9 @@
<TextView
android:id="@+id/seekPositionLabel"
- android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:gravity="center"
android:paddingLeft="24dp"
android:paddingTop="4dp"
android:paddingRight="24dp"
diff --git a/app/src/main/res/xml/feed_settings.xml b/app/src/main/res/xml/feed_settings.xml
index 2662b1906..11e7132a5 100644
--- a/app/src/main/res/xml/feed_settings.xml
+++ b/app/src/main/res/xml/feed_settings.xml
@@ -48,7 +48,7 @@
android:summary="@string/global_default"
android:title="@string/auto_delete_label" />
- <de.danoeh.antennapod.preferences.VolumeAdaptationPreference
+ <de.danoeh.antennapod.ui.screen.feed.preferences.VolumeAdaptationPreference
android:defaultValue="off"
android:entries="@array/spnVolumeAdaptationItems"
android:entryValues="@array/spnVolumeAdaptationValues"
diff --git a/app/src/test/java/de/danoeh/antennapod/ui/cleaner/ShownotesCleanerTest.java b/app/src/test/java/de/danoeh/antennapod/ui/cleaner/ShownotesCleanerTest.java
new file mode 100644
index 000000000..cf7d9db34
--- /dev/null
+++ b/app/src/test/java/de/danoeh/antennapod/ui/cleaner/ShownotesCleanerTest.java
@@ -0,0 +1,236 @@
+package de.danoeh.antennapod.ui.cleaner;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import org.junit.Before;
+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.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for {@link ShownotesCleaner}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class ShownotesCleanerTest {
+
+ private Context context;
+
+ @Before
+ public void setUp() {
+ context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeHhmmssNoChapters() {
+ final String timeStr = "10:11:12";
+ final long time = 3600 * 1000 * 10 + 60 * 1000 * 11 + 12 * 1000;
+
+ String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeHhmmssMoreThen24HoursNoChapters() {
+ final String timeStr = "25:00:00";
+ final long time = 25 * 60 * 60 * 1000;
+
+ String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeHhmmNoChapters() {
+ final String timeStr = "10:11";
+ final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
+
+ String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeMmssNoChapters() {
+ final String timeStr = "10:11";
+ final long time = 10 * 60 * 1000 + 11 * 1000;
+
+ String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, 11 * 60 * 1000);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeHmmssNoChapters() {
+ final String timeStr = "2:11:12";
+ final long time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000;
+
+ String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeMssNoChapters() {
+ final String timeStr = "1:12";
+ final long time = 60 * 1000 + 12 * 1000;
+
+ String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, 2 * 60 * 1000);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAddNoTimecodeDuration() {
+ final String timeStr = "2:11:12";
+ final int time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000;
+
+ String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, time);
+ String res = t.processShownotes();
+ Document d = Jsoup.parse(res);
+ assertEquals("Should not parse time codes that equal duration", 0, d.body().getElementsByTag("a").size());
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeMultipleFormatsNoChapters() {
+ final String[] timeStrings = new String[]{ "10:12", "1:10:12" };
+
+ String shownotes = "<p> Some test text with a timecode " + timeStrings[0]
+ + " here. Hey look another one " + timeStrings[1] + " here!</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, 2 * 60 * 60 * 1000);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{10 * 60 * 1000 + 12 * 1000,
+ 60 * 60 * 1000 + 10 * 60 * 1000 + 12 * 1000}, timeStrings);
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeMultipleShortFormatNoChapters() {
+
+ // One of these timecodes fits as HH:MM and one does not so both should be parsed as MM:SS.
+ final String[] timeStrings = new String[]{ "10:12", "2:12" };
+
+ String shownotes = "<p> Some test text with a timecode " + timeStrings[0]
+ + " here. Hey look another one " + timeStrings[1] + " here!</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, 3 * 60 * 60 * 1000);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{10 * 60 * 1000 + 12 * 1000, 2 * 60 * 1000 + 12 * 1000}, timeStrings);
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeParentheses() {
+ final String timeStr = "10:11";
+ final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
+
+ String shownotes = "<p> Some test text with a timecode (" + timeStr + ") here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeBrackets() {
+ final String timeStr = "10:11";
+ final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
+
+ String shownotes = "<p> Some test text with a timecode [" + timeStr + "] here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAddTimecodeAngleBrackets() {
+ final String timeStr = "10:11";
+ final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
+
+ String shownotes = "<p> Some test text with a timecode <" + timeStr + "> here.</p>";
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ @Test
+ public void testProcessShownotesAndInvalidTimecode() {
+ final String[] timeStrs = new String[] {"2:1", "0:0", "000", "00", "00:000"};
+
+ StringBuilder shownotes = new StringBuilder("<p> Some test text with timecodes ");
+ for (String timeStr : timeStrs) {
+ shownotes.append(timeStr).append(" ");
+ }
+ shownotes.append("here.</p>");
+
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes.toString(), Integer.MAX_VALUE);
+ String res = t.processShownotes();
+ checkLinkCorrect(res, new long[0], new String[0]);
+ }
+
+ private void checkLinkCorrect(String res, long[] timecodes, String[] timecodeStr) {
+ assertNotNull(res);
+ Document d = Jsoup.parse(res);
+ Elements links = d.body().getElementsByTag("a");
+ int countedLinks = 0;
+ for (Element link : links) {
+ String href = link.attributes().get("href");
+ String text = link.text();
+ if (href.startsWith("antennapod://")) {
+ assertTrue(href.endsWith(String.valueOf(timecodes[countedLinks])));
+ assertEquals(timecodeStr[countedLinks], text);
+ countedLinks++;
+ assertTrue("Contains too many links: " + countedLinks + " > "
+ + timecodes.length, countedLinks <= timecodes.length);
+ }
+ }
+ assertEquals(timecodes.length, countedLinks);
+ }
+
+ @Test
+ public void testIsTimecodeLink() {
+ assertFalse(ShownotesCleaner.isTimecodeLink(null));
+ assertFalse(ShownotesCleaner.isTimecodeLink("http://antennapod/timecode/123123"));
+ assertFalse(ShownotesCleaner.isTimecodeLink("antennapod://timecode/"));
+ assertFalse(ShownotesCleaner.isTimecodeLink("antennapod://123123"));
+ assertFalse(ShownotesCleaner.isTimecodeLink("antennapod://timecode/123123a"));
+ assertTrue(ShownotesCleaner.isTimecodeLink("antennapod://timecode/123"));
+ assertTrue(ShownotesCleaner.isTimecodeLink("antennapod://timecode/1"));
+ }
+
+ @Test
+ public void testGetTimecodeLinkTime() {
+ assertEquals(-1, ShownotesCleaner.getTimecodeLinkTime(null));
+ assertEquals(-1, ShownotesCleaner.getTimecodeLinkTime("http://timecode/123"));
+ assertEquals(123, ShownotesCleaner.getTimecodeLinkTime("antennapod://timecode/123"));
+ }
+
+ @Test
+ public void testCleanupColors() {
+ final String input = "/* /* */ .foo { text-decoration: underline;color:#f00;font-weight:bold;}"
+ + "#bar { text-decoration: underline;color:#f00;font-weight:bold; }"
+ + "div {text-decoration: underline; color /* */ : /* */ #f00 /* */; font-weight:bold; }"
+ + "#foobar { /* color: */ text-decoration: underline; /* color: */font-weight:bold /* ; */; }"
+ + "baz { background-color:#f00;border: solid 2px;border-color:#0f0;text-decoration: underline; }";
+ final String expected = " .foo { text-decoration: underline;font-weight:bold;}"
+ + "#bar { text-decoration: underline;font-weight:bold; }"
+ + "div {text-decoration: underline; font-weight:bold; }"
+ + "#foobar { text-decoration: underline; font-weight:bold ; }"
+ + "baz { background-color:#f00;border: solid 2px;border-color:#0f0;text-decoration: underline; }";
+ assertEquals(expected, ShownotesCleaner.cleanStyleTag(input));
+ }
+}
diff --git a/app/src/test/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedDiscovererTest.java b/app/src/test/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedDiscovererTest.java
new file mode 100644
index 000000000..ee9f8a6d5
--- /dev/null
+++ b/app/src/test/java/de/danoeh/antennapod/ui/screen/onlinefeedview/FeedDiscovererTest.java
@@ -0,0 +1,128 @@
+package de.danoeh.antennapod.ui.screen.onlinefeedview;
+
+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.StandardCharsets;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for {@link FeedDiscoverer}
+ */
+@RunWith(RobolectricTestRunner.class)
+public class FeedDiscovererTest {
+
+ private FeedDiscoverer fd;
+
+ private File testDir;
+
+ @Before
+ public void setUp() {
+ fd = new FeedDiscoverer();
+ testDir = new File(InstrumentationRegistry
+ .getInstrumentation().getTargetContext().getFilesDir(), "FeedDiscovererTest");
+ //noinspection ResultOfMethodCallIgnored
+ testDir.mkdir();
+ assertTrue(testDir.exists());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ 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);
+ }
+
+ private String createTestHtmlString(String rel, String type, String href) {
+ return String.format("<html><head><title>Test</title><link rel=\"%s\" type=\"%s\" href=\"%s\"></head><body></body></html>",
+ rel, type, href);
+ }
+
+ private void checkFindUrls(boolean isAlternate, boolean isRss, boolean withTitle, boolean isAbsolute, boolean fromString) throws Exception {
+ final String title = "Test title";
+ final String hrefAbs = "http://example.com/feed";
+ final String hrefRel = "/feed";
+ final String base = "http://example.com";
+
+ final String rel = (isAlternate) ? "alternate" : "feed";
+ final String type = (isRss) ? "application/rss+xml" : "application/atom+xml";
+ final String href = (isAbsolute) ? hrefAbs : hrefRel;
+
+ Map<String, String> res;
+ String html = (withTitle) ? createTestHtmlString(rel, type, href, title)
+ : createTestHtmlString(rel, type, href);
+ if (fromString) {
+ res = fd.findLinks(html, base);
+ } else {
+ File testFile = new File(testDir, "feed");
+ FileOutputStream out = new FileOutputStream(testFile);
+ IOUtils.write(html, out, StandardCharsets.UTF_8);
+ out.close();
+ res = fd.findLinks(testFile, base);
+ }
+
+ assertNotNull(res);
+ assertEquals(1, res.size());
+ for (String key : res.keySet()) {
+ assertEquals(hrefAbs, key);
+ }
+ assertTrue(res.containsKey(hrefAbs));
+ if (withTitle) {
+ assertEquals(title, res.get(hrefAbs));
+ } else {
+ assertEquals(href, res.get(hrefAbs));
+ }
+ }
+
+ @Test
+ public void testAlternateRSSWithTitleAbsolute() throws Exception {
+ checkFindUrls(true, true, true, true, true);
+ }
+
+ @Test
+ public void testAlternateRSSWithTitleRelative() throws Exception {
+ checkFindUrls(true, true, true, false, true);
+ }
+
+ @Test
+ public void testAlternateRSSNoTitleAbsolute() throws Exception {
+ checkFindUrls(true, true, false, true, true);
+ }
+
+ @Test
+ public void testAlternateRSSNoTitleRelative() throws Exception {
+ checkFindUrls(true, true, false, false, true);
+ }
+
+ @Test
+ public void testAlternateAtomWithTitleAbsolute() throws Exception {
+ checkFindUrls(true, false, true, true, true);
+ }
+
+ @Test
+ public void testFeedAtomWithTitleAbsolute() throws Exception {
+ checkFindUrls(false, false, true, true, true);
+ }
+
+ @Test
+ public void testAlternateRSSWithTitleAbsoluteFromFile() throws Exception {
+ checkFindUrls(true, true, true, true, false);
+ }
+}