From 069a156d3dc6642dd57948b409b1444f425bb346 Mon Sep 17 00:00:00 2001 From: Xilin Jia <6257601+XilinJia@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:24:18 +0100 Subject: [PATCH] 6.0.7 commit --- README.md | 1 + app/build.gradle | 4 +- .../ac/test/podcini/playback/PlaybackTest.kt | 6 +- .../ac/mdiq/podcini/net/sync/SyncService.kt | 4 +- .../podcini/net/sync/wifi/WifiSyncService.kt | 8 +- .../podcini/preferences/UserPreferences.kt | 30 ++-- .../ImportExportPreferencesFragment.kt | 10 +- .../UserInterfacePreferencesFragment.kt | 5 +- .../storage/algorithms/AutoCleanups.kt | 8 +- .../storage/algorithms/AutoDownloads.kt | 4 +- .../mdiq/podcini/storage/database/Episodes.kt | 4 +- .../ac/mdiq/podcini/storage/database/Feeds.kt | 2 +- .../mdiq/podcini/storage/database/Queues.kt | 4 +- .../{SortOrder.kt => EpisodeSortOrder.kt} | 16 +-- .../ac/mdiq/podcini/storage/model/Feed.kt | 4 +- .../podcini/storage/model/FeedSortOrder.kt | 26 ++++ .../mdiq/podcini/ui/activity/MainActivity.kt | 4 +- .../podcini/ui/dialog/EpisodeSortDialog.kt | 28 ++-- .../mdiq/podcini/ui/dialog/FeedSortDialog.kt | 33 ----- .../podcini/ui/dialog/FeedSortDialogNew.kt | 133 ++++++++++++++++++ .../podcini/ui/dialog/TagSettingsDialog.kt | 23 ++- .../podcini/ui/fragment/AddFeedFragment.kt | 4 +- .../ui/fragment/AllEpisodesFragment.kt | 8 +- .../podcini/ui/fragment/DownloadsFragment.kt | 14 +- .../ui/fragment/FeedEpisodesFragment.kt | 16 +-- .../podcini/ui/fragment/HistoryFragment.kt | 18 +-- .../mdiq/podcini/ui/fragment/QueueFragment.kt | 16 +-- .../ui/fragment/SubscriptionsFragment.kt | 38 ++--- .../ui/view/viewholder/EpisodeViewHolder.kt | 26 ++-- .../ac/mdiq/podcini/util/event/FlowEvent.kt | 4 +- .../podcini/util/sorting/EpisodesPermutors.kt | 42 +++--- app/src/main/res/values-ar/strings.xml | 14 +- app/src/main/res/values-ast/strings.xml | 12 +- app/src/main/res/values-br/strings.xml | 14 +- app/src/main/res/values-ca/strings.xml | 14 +- app/src/main/res/values-cs/strings.xml | 14 +- app/src/main/res/values-da/strings.xml | 14 +- app/src/main/res/values-de/strings.xml | 14 +- app/src/main/res/values-es/strings.xml | 14 +- app/src/main/res/values-et/strings.xml | 14 +- app/src/main/res/values-eu/strings.xml | 12 +- app/src/main/res/values-fa/strings.xml | 14 +- app/src/main/res/values-fi/strings.xml | 14 +- app/src/main/res/values-fr/strings.xml | 14 +- app/src/main/res/values-gl/strings.xml | 14 +- app/src/main/res/values-hu/strings.xml | 14 +- app/src/main/res/values-in/strings.xml | 14 +- app/src/main/res/values-it/strings.xml | 14 +- app/src/main/res/values-iw/strings.xml | 14 +- app/src/main/res/values-ja/strings.xml | 14 +- app/src/main/res/values-ko/strings.xml | 14 +- app/src/main/res/values-lt/strings.xml | 12 +- app/src/main/res/values-nb/strings.xml | 14 +- app/src/main/res/values-nl/strings.xml | 14 +- app/src/main/res/values-pl/strings.xml | 14 +- app/src/main/res/values-pt-rBR/strings.xml | 14 +- app/src/main/res/values-pt/strings.xml | 14 +- app/src/main/res/values-ro/strings.xml | 14 +- app/src/main/res/values-ru/strings.xml | 14 +- app/src/main/res/values-sk/strings.xml | 14 +- app/src/main/res/values-sl/strings.xml | 12 +- app/src/main/res/values-sv/strings.xml | 14 +- app/src/main/res/values-tr/strings.xml | 14 +- app/src/main/res/values-uk/strings.xml | 14 +- app/src/main/res/values-zh-rCN/strings.xml | 14 +- app/src/main/res/values-zh-rTW/strings.xml | 12 +- app/src/main/res/values/arrays.xml | 43 ++---- app/src/main/res/values/strings.xml | 18 ++- .../kotlin/ac/mdiq/podcini/feed/FeedTest.kt | 6 +- .../ac/mdiq/podcini/storage/DbReaderTest.kt | 6 +- .../mdiq/podcini/util/EpisodePermutorsTest.kt | 32 ++--- changelog.md | 7 + .../android/en-US/changelogs/3020207.txt | 7 + 73 files changed, 609 insertions(+), 533 deletions(-) rename app/src/main/kotlin/ac/mdiq/podcini/storage/model/{SortOrder.kt => EpisodeSortOrder.kt} (76%) create mode 100644 app/src/main/kotlin/ac/mdiq/podcini/storage/model/FeedSortOrder.kt delete mode 100644 app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialog.kt create mode 100644 app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialogNew.kt create mode 100644 fastlane/metadata/android/en-US/changelogs/3020207.txt diff --git a/README.md b/README.md index 63a5b95f..6b926ffe 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ While podcast subscriptions' OPML files (from AntennaPod or any other sources) c * in episode list view, if episode has no media, TTS button is shown for fetching transcript (if not exist) and then generating audio file from the transcript. TTS audio files are playable in the same way as local media (with speed setting, pause and rewind/forward) * Long-press filter button in FeedEpisode view enables/disables filters without changing filter settings * Subscriptions view has various explicit measures for sorting +* subscriptions sorting is now bi-directional * in Subscriptions view, click on cover image of a feed opens the FeedInfo view (not FeedEpisodes view) * History view shows time of last play, and allows filters and sorts * 5 queues are provided by default: Default queue, and Queues 1-4 diff --git a/app/build.gradle b/app/build.gradle index 6be6fd0a..6cce4a9a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -125,8 +125,8 @@ android { buildConfig true } defaultConfig { - versionCode 3020206 - versionName "6.0.6" + versionCode 3020207 + versionName "6.0.7" applicationId "ac.mdiq.podcini.R" def commit = "" diff --git a/app/src/androidTest/kotlin/ac/test/podcini/playback/PlaybackTest.kt b/app/src/androidTest/kotlin/ac/test/podcini/playback/PlaybackTest.kt index 27bb1cf9..78578270 100644 --- a/app/src/androidTest/kotlin/ac/test/podcini/playback/PlaybackTest.kt +++ b/app/src/androidTest/kotlin/ac/test/podcini/playback/PlaybackTest.kt @@ -12,7 +12,7 @@ import ac.mdiq.podcini.storage.database.Episodes.getEpisodes import ac.mdiq.podcini.storage.database.Queues.clearQueue import ac.mdiq.podcini.storage.database.Queues.getInQueueEpisodeIds import ac.mdiq.podcini.storage.model.EpisodeFilter.Companion.unfiltered -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.activity.MainActivity import android.content.Context import android.content.Intent @@ -221,7 +221,7 @@ class PlaybackTest { EspressoTestUtils.openNavDrawer() EspressoTestUtils.onDrawerItem(ViewMatchers.withText(R.string.episodes_label)).perform(ViewActions.click()) - val episodes = getEpisodes(0, 10, unfiltered(), SortOrder.DATE_NEW_OLD) + val episodes = getEpisodes(0, 10, unfiltered(), EpisodeSortOrder.DATE_NEW_OLD) val allEpisodesMatcher = Matchers.allOf(ViewMatchers.withId(R.id.recyclerView), ViewMatchers.isDisplayed(), ViewMatchers.hasMinimumChildCount(2)) @@ -262,7 +262,7 @@ class PlaybackTest { uiTestUtils!!.addLocalFeedData(true) runBlocking { clearQueue().join() } activityTestRule.launchActivity(Intent()) - val episodes = getEpisodes(0, 10, unfiltered(), SortOrder.DATE_NEW_OLD) + val episodes = getEpisodes(0, 10, unfiltered(), EpisodeSortOrder.DATE_NEW_OLD) startLocalPlayback() val media = episodes[0].media diff --git a/app/src/main/kotlin/ac/mdiq/podcini/net/sync/SyncService.kt b/app/src/main/kotlin/ac/mdiq/podcini/net/sync/SyncService.kt index fe841f2b..684bad04 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/net/sync/SyncService.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/net/sync/SyncService.kt @@ -30,7 +30,7 @@ import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.Feed import ac.mdiq.podcini.storage.model.EpisodeFilter import ac.mdiq.podcini.storage.utils.EpisodeUtil.hasAlmostEnded -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.utils.NotificationUtils import ac.mdiq.podcini.util.Logd import ac.mdiq.podcini.util.event.* @@ -210,7 +210,7 @@ open class SyncService(context: Context, params: WorkerParameters) : Worker(cont val queuedEpisodeActions: MutableList = synchronizationQueueStorage.queuedEpisodeActions if (lastSync == 0L) { EventFlow.postStickyEvent(FlowEvent.SyncServiceEvent(R.string.sync_status_upload_played)) - val readItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PLAYED), SortOrder.DATE_NEW_OLD) + val readItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PLAYED), EpisodeSortOrder.DATE_NEW_OLD) Logd(TAG, "First sync. Upload state for all " + readItems.size + " played episodes") for (item in readItems) { val media = item.media ?: continue diff --git a/app/src/main/kotlin/ac/mdiq/podcini/net/sync/wifi/WifiSyncService.kt b/app/src/main/kotlin/ac/mdiq/podcini/net/sync/wifi/WifiSyncService.kt index da1b019c..42d09716 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/net/sync/wifi/WifiSyncService.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/net/sync/wifi/WifiSyncService.kt @@ -13,7 +13,7 @@ import ac.mdiq.podcini.storage.database.Episodes.persistEpisode import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeFilter import ac.mdiq.podcini.storage.utils.EpisodeUtil.hasAlmostEnded -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.util.Logd import ac.mdiq.podcini.util.event.EventFlow import ac.mdiq.podcini.util.event.FlowEvent @@ -244,9 +244,9 @@ import kotlin.math.min if (lastSync == 0L) { EventFlow.postStickyEvent(FlowEvent.SyncServiceEvent(R.string.sync_status_upload_played)) // only push downloaded items - val pausedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PAUSED), SortOrder.DATE_NEW_OLD) - val readItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PLAYED), SortOrder.DATE_NEW_OLD) - val favoriteItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.IS_FAVORITE), SortOrder.DATE_NEW_OLD) + val pausedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PAUSED), EpisodeSortOrder.DATE_NEW_OLD) + val readItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PLAYED), EpisodeSortOrder.DATE_NEW_OLD) + val favoriteItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.IS_FAVORITE), EpisodeSortOrder.DATE_NEW_OLD) val comItems = mutableSetOf() comItems.addAll(pausedItems) comItems.addAll(readItems) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/preferences/UserPreferences.kt b/app/src/main/kotlin/ac/mdiq/podcini/preferences/UserPreferences.kt index 6ba5b47d..0c59d8e7 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/preferences/UserPreferences.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/preferences/UserPreferences.kt @@ -2,7 +2,7 @@ package ac.mdiq.podcini.preferences import ac.mdiq.podcini.storage.model.Feed import ac.mdiq.podcini.storage.model.ProxyConfig -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.storage.model.MediaType import ac.mdiq.podcini.util.Logd import android.content.Context @@ -38,6 +38,7 @@ object UserPreferences { const val PREF_TINTED_COLORS: String = "prefTintedColors" const val PREF_HIDDEN_DRAWER_ITEMS: String = "prefHiddenDrawerItems" const val PREF_DRAWER_FEED_ORDER: String = "prefDrawerFeedOrder" + const val PREF_DRAWER_FEED_ORDER_DIRECTION: String = "prefDrawerFeedOrderDir" const val PREF_FEED_GRID_LAYOUT: String = "prefFeedGridLayout" const val PREF_DRAWER_FEED_COUNTER: String = "prefDrawerFeedIndicator" const val PREF_EXPANDED_NOTIFICATION: String = "prefExpandNotify" @@ -194,12 +195,18 @@ object UserPreferences { get() = appPrefs.getBoolean(PREF_OPML_BACKUP, true) - val feedOrder: Int + val feedOrderBy: Int get() { val value = appPrefs.getString(PREF_DRAWER_FEED_ORDER, "" + FEED_ORDER_UNPLAYED) return value!!.toInt() } + val feedOrderDir: Int + get() { + val value = appPrefs.getInt(PREF_DRAWER_FEED_ORDER_DIRECTION, 0) + return value + } + val useGridLayout: Boolean get() = appPrefs.getBoolean(PREF_FEED_GRID_LAYOUT, false) @@ -507,7 +514,7 @@ object UserPreferences { appPrefs.edit().putBoolean(PREF_QUEUE_KEEP_SORTED, keepSorted).apply() } - var queueKeepSortedOrder: SortOrder? + var queueKeepSortedOrder: EpisodeSortOrder? /** * Returns the sort order for the queue keep sorted mode. * Note: This value is stored independently from the keep sorted state. @@ -515,7 +522,7 @@ object UserPreferences { */ get() { val sortOrderStr = appPrefs.getString(PREF_QUEUE_KEEP_SORTED_ORDER, "use-default") - return SortOrder.parseWithDefault(sortOrderStr, SortOrder.DATE_NEW_OLD) + return EpisodeSortOrder.parseWithDefault(sortOrderStr, EpisodeSortOrder.DATE_NEW_OLD) } /** * Sets the sort order for the queue keep sorted mode. @@ -527,17 +534,17 @@ object UserPreferences { } // the sort order for the downloads. - var downloadsSortedOrder: SortOrder? + var downloadsSortedOrder: EpisodeSortOrder? get() { - val sortOrderStr = appPrefs.getString(PREF_DOWNLOADS_SORTED_ORDER, "" + SortOrder.DATE_NEW_OLD.code) - return SortOrder.fromCodeString(sortOrderStr) + val sortOrderStr = appPrefs.getString(PREF_DOWNLOADS_SORTED_ORDER, "" + EpisodeSortOrder.DATE_NEW_OLD.code) + return EpisodeSortOrder.fromCodeString(sortOrderStr) } set(sortOrder) { appPrefs.edit().putString(PREF_DOWNLOADS_SORTED_ORDER, "" + sortOrder!!.code).apply() } - var allEpisodesSortOrder: SortOrder? - get() = SortOrder.fromCodeString(appPrefs.getString(PREF_SORT_ALL_EPISODES, "" + SortOrder.DATE_NEW_OLD.code)) + var allEpisodesSortOrder: EpisodeSortOrder? + get() = EpisodeSortOrder.fromCodeString(appPrefs.getString(PREF_SORT_ALL_EPISODES, "" + EpisodeSortOrder.DATE_NEW_OLD.code)) set(s) { appPrefs.edit().putString(PREF_SORT_ALL_EPISODES, "" + s!!.code).apply() } @@ -597,10 +604,13 @@ object UserPreferences { return appPrefs.getBoolean(PREF_SHOW_TIME_LEFT, false) } - fun setFeedOrder(selected: String?) { + fun setFeedOrder(selected: String, dir: Int) { appPrefs.edit() .putString(PREF_DRAWER_FEED_ORDER, selected) .apply() + appPrefs.edit() + .putInt(PREF_DRAWER_FEED_ORDER_DIRECTION, dir) + .apply() } fun enqueueDownloadedEpisodes(): Boolean { diff --git a/app/src/main/kotlin/ac/mdiq/podcini/preferences/fragments/ImportExportPreferencesFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/preferences/fragments/ImportExportPreferencesFragment.kt index 27b6d409..e621c625 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/preferences/fragments/ImportExportPreferencesFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/preferences/fragments/ImportExportPreferencesFragment.kt @@ -19,7 +19,7 @@ import ac.mdiq.podcini.storage.model.Feed import ac.mdiq.podcini.preferences.OpmlTransporter.* import ac.mdiq.podcini.storage.model.EpisodeFilter import ac.mdiq.podcini.storage.utils.EpisodeUtil.hasAlmostEnded -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.activity.OpmlImportActivity import ac.mdiq.podcini.ui.activity.PreferenceActivity import ac.mdiq.podcini.util.Logd @@ -732,9 +732,9 @@ class ImportExportPreferencesFragment : PreferenceFragmentCompat() { override fun writeDocument(feeds: List?, writer: Writer?, context: Context) { Logd(TAG, "Starting to write document") val queuedEpisodeActions: MutableList = mutableListOf() - val pausedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PAUSED), SortOrder.DATE_NEW_OLD) - val readItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PLAYED), SortOrder.DATE_NEW_OLD) - val favoriteItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.IS_FAVORITE), SortOrder.DATE_NEW_OLD) + val pausedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PAUSED), EpisodeSortOrder.DATE_NEW_OLD) + val readItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.PLAYED), EpisodeSortOrder.DATE_NEW_OLD) + val favoriteItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.IS_FAVORITE), EpisodeSortOrder.DATE_NEW_OLD) val comItems = mutableSetOf() comItems.addAll(pausedItems) comItems.addAll(readItems) @@ -793,7 +793,7 @@ class ImportExportPreferencesFragment : PreferenceFragmentCompat() { val favTemplate = IOUtils.toString(favTemplateStream, UTF_8) val feedTemplateStream = context.assets.open(FEED_TEMPLATE) val feedTemplate = IOUtils.toString(feedTemplateStream, UTF_8) - val allFavorites = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.IS_FAVORITE), SortOrder.DATE_NEW_OLD) + val allFavorites = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.IS_FAVORITE), EpisodeSortOrder.DATE_NEW_OLD) val favoritesByFeed = buildFeedMap(allFavorites) writer!!.append(templateParts[0]) for (feedId in favoritesByFeed.keys) { diff --git a/app/src/main/kotlin/ac/mdiq/podcini/preferences/fragments/UserInterfacePreferencesFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/preferences/fragments/UserInterfacePreferencesFragment.kt index 931505d9..a66c2e37 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/preferences/fragments/UserInterfacePreferencesFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/preferences/fragments/UserInterfacePreferencesFragment.kt @@ -6,7 +6,7 @@ import ac.mdiq.podcini.preferences.UserPreferences.fullNotificationButtons import ac.mdiq.podcini.preferences.UserPreferences.setShowRemainTimeSetting import ac.mdiq.podcini.ui.activity.PreferenceActivity import ac.mdiq.podcini.ui.dialog.DrawerPreferencesDialog -import ac.mdiq.podcini.ui.dialog.FeedSortDialog +import ac.mdiq.podcini.ui.dialog.FeedSortDialogNew import ac.mdiq.podcini.util.event.EventFlow import ac.mdiq.podcini.util.event.FlowEvent import android.content.Context @@ -66,7 +66,8 @@ class UserInterfacePreferencesFragment : PreferenceFragmentCompat() { // }) findPreference(UserPreferences.PREF_DRAWER_FEED_ORDER)?.onPreferenceClickListener = (Preference.OnPreferenceClickListener { - FeedSortDialog.showDialog(requireContext()) +// FeedSortDialog.showDialog(requireContext()) + FeedSortDialogNew().show(childFragmentManager, "FeedSortDialog") true }) findPreference(PREF_SWIPE)?.setOnPreferenceClickListener { diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/algorithms/AutoCleanups.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/algorithms/AutoCleanups.kt index 4027f5b4..7bda8f9c 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/storage/algorithms/AutoCleanups.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/algorithms/AutoCleanups.kt @@ -10,7 +10,7 @@ import ac.mdiq.podcini.storage.database.Episodes.getEpisodesCount import ac.mdiq.podcini.storage.database.Queues.getInQueueEpisodeIds import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeFilter -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import android.content.Context import android.util.Log import androidx.annotation.OptIn @@ -52,7 +52,7 @@ object AutoCleanups { private val candidates: List get() { val candidates: MutableList = ArrayList() - val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), SortOrder.DATE_NEW_OLD) + val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), EpisodeSortOrder.DATE_NEW_OLD) for (item in downloadedItems) { if (item.media != null && item.media!!.downloaded && !item.isFavorite) candidates.add(item) } @@ -110,7 +110,7 @@ object AutoCleanups { private val candidates: List get() { val candidates: MutableList = ArrayList() - val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), SortOrder.DATE_NEW_OLD) + val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), EpisodeSortOrder.DATE_NEW_OLD) val idsInQueues = getInQueueEpisodeIds() for (item in downloadedItems) { if (item.media != null && item.media!!.downloaded && !idsInQueues.contains(item.id) && !item.isFavorite) @@ -187,7 +187,7 @@ object AutoCleanups { private val candidates: List get() { val candidates: MutableList = ArrayList() - val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), SortOrder.DATE_NEW_OLD) + val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), EpisodeSortOrder.DATE_NEW_OLD) val idsInQueues = getInQueueEpisodeIds() val mostRecentDateForDeletion = calcMostRecentDateForDeletion(Date()) for (item in downloadedItems) { diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/algorithms/AutoDownloads.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/algorithms/AutoDownloads.kt index 5e69dc4f..52488f69 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/storage/algorithms/AutoDownloads.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/algorithms/AutoDownloads.kt @@ -12,7 +12,7 @@ import ac.mdiq.podcini.storage.database.Episodes.getEpisodes import ac.mdiq.podcini.storage.database.Episodes.getEpisodesCount import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeFilter -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.util.Logd import android.content.Context import android.content.Intent @@ -80,7 +80,7 @@ object AutoDownloads { Logd(TAG, "Performing auto-dl of undownloaded episodes") val candidates: MutableList val queue = curQueue.episodes - val newItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.NEW), SortOrder.DATE_NEW_OLD) + val newItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.NEW), EpisodeSortOrder.DATE_NEW_OLD) Logd(TAG, "newItems: ${newItems.size}") candidates = ArrayList(queue.size + newItems.size) candidates.addAll(queue) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Episodes.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Episodes.kt index c8feeff6..5aed5ac5 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Episodes.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Episodes.kt @@ -20,7 +20,7 @@ import ac.mdiq.podcini.storage.database.RealmDB.upsertBlk import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeMedia import ac.mdiq.podcini.storage.model.EpisodeFilter -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.util.IntentUtils.sendLocalBroadcast import ac.mdiq.podcini.util.Logd import ac.mdiq.podcini.util.event.EventFlow @@ -48,7 +48,7 @@ object Episodes { * @param filter The filter describing which episodes to filter out. * TODO: filters of queued and notqueued don't work in this */ - fun getEpisodes(offset: Int, limit: Int, filter: EpisodeFilter?, sortOrder: SortOrder?, copy: Boolean = true): List { + fun getEpisodes(offset: Int, limit: Int, filter: EpisodeFilter?, sortOrder: EpisodeSortOrder?, copy: Boolean = true): List { Logd(TAG, "getEpisodes called with: offset=$offset, limit=$limit") val queryString = filter?.queryString()?:"id > 0" var episodes = realm.query(Episode::class).query(queryString).find().toMutableList() diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Feeds.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Feeds.kt index d8049ed4..d7625471 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Feeds.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Feeds.kt @@ -72,7 +72,7 @@ object Feeds { for (feed in feedsCopy) { if (feed.preferences != null) tagsSet.addAll(feed.preferences!!.tags.filter { it != TAG_ROOT }) } - val newTags = tagsSet.intersect(tags.toSet()) + val newTags = tagsSet - tags.toSet() if (newTags.isNotEmpty()) { tags.clear() tags.addAll(tagsSet) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Queues.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Queues.kt index 654ac69f..e3f22e22 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Queues.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Queues.kt @@ -17,7 +17,7 @@ import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeMedia import ac.mdiq.podcini.storage.model.PlayQueue import ac.mdiq.podcini.storage.model.Playable -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.util.Logd import ac.mdiq.podcini.util.event.EventFlow import ac.mdiq.podcini.util.event.FlowEvent @@ -126,7 +126,7 @@ object Queues { // Sort queue by configured sort order val sortOrder = queueKeepSortedOrder // do not shuffle the list on every change - if (sortOrder == SortOrder.RANDOM) return + if (sortOrder == EpisodeSortOrder.RANDOM) return if (sortOrder != null) { val permutor = getPermutor(sortOrder) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/model/SortOrder.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/model/EpisodeSortOrder.kt similarity index 76% rename from app/src/main/kotlin/ac/mdiq/podcini/storage/model/SortOrder.kt rename to app/src/main/kotlin/ac/mdiq/podcini/storage/model/EpisodeSortOrder.kt index dcd6050e..920af2c8 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/storage/model/SortOrder.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/model/EpisodeSortOrder.kt @@ -3,7 +3,7 @@ package ac.mdiq.podcini.storage.model /** * Provides sort orders to sort a list of episodes. */ -enum class SortOrder(@JvmField val code: Int, @JvmField val scope: Scope) { +enum class EpisodeSortOrder(@JvmField val code: Int, @JvmField val scope: Scope) { DATE_OLD_NEW(1, Scope.INTRA_FEED), DATE_NEW_OLD(2, Scope.INTRA_FEED), EPISODE_TITLE_A_Z(3, Scope.INTRA_FEED), @@ -35,7 +35,7 @@ enum class SortOrder(@JvmField val code: Int, @JvmField val scope: Scope) { * Converts the string representation to its enum value. If the string value is unknown, * the given default value is returned. */ - fun parseWithDefault(value: String?, defaultValue: SortOrder): SortOrder { + fun parseWithDefault(value: String?, defaultValue: EpisodeSortOrder): EpisodeSortOrder { return try { valueOf(value!!) } catch (e: IllegalArgumentException) { @@ -44,7 +44,7 @@ enum class SortOrder(@JvmField val code: Int, @JvmField val scope: Scope) { } @JvmStatic - fun fromCodeString(codeStr: String?): SortOrder? { + fun fromCodeString(codeStr: String?): EpisodeSortOrder? { if (codeStr.isNullOrEmpty()) return null val code = codeStr.toInt() @@ -55,17 +55,17 @@ enum class SortOrder(@JvmField val code: Int, @JvmField val scope: Scope) { } @JvmStatic - fun fromCode(code: Int): SortOrder? { - return enumValues().firstOrNull { it.code == code } + fun fromCode(code: Int): EpisodeSortOrder? { + return enumValues().firstOrNull { it.code == code } } @JvmStatic - fun toCodeString(sortOrder: SortOrder?): String? { + fun toCodeString(sortOrder: EpisodeSortOrder?): String? { return sortOrder?.code?.toString() } - fun valuesOf(stringValues: Array): Array { - val values = arrayOfNulls(stringValues.size) + fun valuesOf(stringValues: Array): Array { + val values = arrayOfNulls(stringValues.size) for (i in stringValues.indices) { values[i] = valueOf(stringValues[i]!!) } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/model/Feed.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/model/Feed.kt index 4133f3d0..78222f48 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/storage/model/Feed.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/model/Feed.kt @@ -1,7 +1,7 @@ package ac.mdiq.podcini.storage.model import ac.mdiq.podcini.storage.model.FeedFunding.Companion.extractPaymentLinks -import ac.mdiq.podcini.storage.model.SortOrder.Companion.fromCode +import ac.mdiq.podcini.storage.model.EpisodeSortOrder.Companion.fromCode import io.realm.kotlin.ext.realmListOf import io.realm.kotlin.types.RealmList import io.realm.kotlin.types.RealmObject @@ -122,7 +122,7 @@ class Feed : RealmObject { get() = EpisodeFilter(preferences?.filterString ?: "") @Ignore - var sortOrder: SortOrder? = null + var sortOrder: EpisodeSortOrder? = null get() = fromCode(preferences?.sortOrderCode ?: 0) set(value) { if (value == null) return diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/model/FeedSortOrder.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/model/FeedSortOrder.kt new file mode 100644 index 00000000..9dc447e3 --- /dev/null +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/model/FeedSortOrder.kt @@ -0,0 +1,26 @@ +package ac.mdiq.podcini.storage.model + +enum class FeedSortOrder(val code: Int, val index: Int) { + UNPLAYED_NEW_OLD(1, 0), + UNPLAYED_OLD_NEW(2, 0), + ALPHABETIC_A_Z(3, 1), + ALPHABETIC_Z_A(4,1 ), + LAST_UPDATED_NEW_OLD(5, 2), + LAST_UPDATED_OLD_NEW(6, 2), + LAST_UPDATED_UNPLAYED_NEW_OLD(7, 3), + LAST_UPDATED_UNPLAYED_OLD_NEW(8, 3), + MOST_PLAYED(9, 4), + LEAST_PLAYED(10, 4), + MOST_DOWNLOADED(11, 5), + LEAST_DOWNLAODED(12, 5), + MOST_DOWNLOADED_UNPLAYED(13, 6), + LEAST_DOWNLAODED_UNPLAYED(14, 6), + NEW_EPISODES_MOST(15, 7), + NEW_EPISODES_LEAST(16, 7); + + companion object { + fun getSortOrder(dir: Int, index: Int): FeedSortOrder? { + return enumValues().firstOrNull { it.code == 2*index+dir+1 && it.index == index } + } + } +} diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/activity/MainActivity.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/activity/MainActivity.kt index a1cc3e5a..6c1c25c1 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/activity/MainActivity.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/activity/MainActivity.kt @@ -19,6 +19,7 @@ import ac.mdiq.podcini.preferences.UserPreferences.defaultPage import ac.mdiq.podcini.preferences.UserPreferences.hiddenDrawerItems import ac.mdiq.podcini.receiver.MediaButtonReceiver.Companion.createIntent import ac.mdiq.podcini.receiver.PlayerWidget +import ac.mdiq.podcini.storage.database.Feeds.buildTags import ac.mdiq.podcini.storage.database.Feeds.monitorFeeds import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope import ac.mdiq.podcini.ui.actions.swipeactions.SwipeActions @@ -130,6 +131,7 @@ class MainActivity : CastEnabledActivity() { SwipeActions.getSharedPrefs(this@MainActivity) QueueFragment.getSharedPrefs(this@MainActivity) // updateFeedMap() + buildTags() monitorFeeds() // InTheatre.apply { } PlayerDetailsFragment.getSharedPrefs(this@MainActivity) @@ -403,7 +405,7 @@ class MainActivity : CastEnabledActivity() { val playerView = findViewById(R.id.playerFragment1) val playerParams = playerView?.layoutParams as? MarginLayoutParams playerParams?.setMargins(navigationBarInsets.left, 0, navigationBarInsets.right, 0) - playerView.layoutParams = playerParams + playerView?.layoutParams = playerParams audioPlayerView.visibility = if (visible) View.VISIBLE else View.GONE } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeSortDialog.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeSortDialog.kt index 29c79d5c..d2511bb4 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeSortDialog.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeSortDialog.kt @@ -4,7 +4,7 @@ import ac.mdiq.podcini.R import ac.mdiq.podcini.databinding.SortDialogBinding import ac.mdiq.podcini.databinding.SortDialogItemActiveBinding import ac.mdiq.podcini.databinding.SortDialogItemBinding -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import android.app.Dialog import android.content.DialogInterface import android.os.Bundle @@ -22,7 +22,7 @@ open class EpisodeSortDialog : BottomSheetDialogFragment() { protected var _binding: SortDialogBinding? = null protected val binding get() = _binding!! - protected var sortOrder: SortOrder? = null + protected var sortOrder: EpisodeSortOrder? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { _binding = SortDialogBinding.inflate(inflater) @@ -38,22 +38,22 @@ open class EpisodeSortDialog : BottomSheetDialogFragment() { private fun populateList() { binding.gridLayout.removeAllViews() - onAddItem(R.string.episode_title, SortOrder.EPISODE_TITLE_A_Z, SortOrder.EPISODE_TITLE_Z_A, true) - onAddItem(R.string.feed_title, SortOrder.FEED_TITLE_A_Z, SortOrder.FEED_TITLE_Z_A, true) - onAddItem(R.string.duration, SortOrder.DURATION_SHORT_LONG, SortOrder.DURATION_LONG_SHORT, true) - onAddItem(R.string.publish_date, SortOrder.DATE_OLD_NEW, SortOrder.DATE_NEW_OLD, false) - onAddItem(R.string.last_played_date, SortOrder.PLAYED_DATE_OLD_NEW, SortOrder.PLAYED_DATE_NEW_OLD, false) - onAddItem(R.string.completed_date, SortOrder.COMPLETED_DATE_OLD_NEW, SortOrder.COMPLETED_DATE_NEW_OLD, false) - onAddItem(R.string.size, SortOrder.SIZE_SMALL_LARGE, SortOrder.SIZE_LARGE_SMALL, false) - onAddItem(R.string.filename, SortOrder.EPISODE_FILENAME_A_Z, SortOrder.EPISODE_FILENAME_Z_A, true) - onAddItem(R.string.random, SortOrder.RANDOM, SortOrder.RANDOM, true) - onAddItem(R.string.smart_shuffle, SortOrder.SMART_SHUFFLE_OLD_NEW, SortOrder.SMART_SHUFFLE_NEW_OLD, false) + onAddItem(R.string.episode_title, EpisodeSortOrder.EPISODE_TITLE_A_Z, EpisodeSortOrder.EPISODE_TITLE_Z_A, true) + onAddItem(R.string.feed_title, EpisodeSortOrder.FEED_TITLE_A_Z, EpisodeSortOrder.FEED_TITLE_Z_A, true) + onAddItem(R.string.duration, EpisodeSortOrder.DURATION_SHORT_LONG, EpisodeSortOrder.DURATION_LONG_SHORT, true) + onAddItem(R.string.publish_date, EpisodeSortOrder.DATE_OLD_NEW, EpisodeSortOrder.DATE_NEW_OLD, false) + onAddItem(R.string.last_played_date, EpisodeSortOrder.PLAYED_DATE_OLD_NEW, EpisodeSortOrder.PLAYED_DATE_NEW_OLD, false) + onAddItem(R.string.completed_date, EpisodeSortOrder.COMPLETED_DATE_OLD_NEW, EpisodeSortOrder.COMPLETED_DATE_NEW_OLD, false) + onAddItem(R.string.size, EpisodeSortOrder.SIZE_SMALL_LARGE, EpisodeSortOrder.SIZE_LARGE_SMALL, false) + onAddItem(R.string.filename, EpisodeSortOrder.EPISODE_FILENAME_A_Z, EpisodeSortOrder.EPISODE_FILENAME_Z_A, true) + onAddItem(R.string.random, EpisodeSortOrder.RANDOM, EpisodeSortOrder.RANDOM, true) + onAddItem(R.string.smart_shuffle, EpisodeSortOrder.SMART_SHUFFLE_OLD_NEW, EpisodeSortOrder.SMART_SHUFFLE_NEW_OLD, false) } - protected open fun onAddItem(title: Int, ascending: SortOrder, descending: SortOrder, ascendingIsDefault: Boolean) { + protected open fun onAddItem(title: Int, ascending: EpisodeSortOrder, descending: EpisodeSortOrder, ascendingIsDefault: Boolean) { if (sortOrder == ascending || sortOrder == descending) { val item = SortDialogItemActiveBinding.inflate(layoutInflater, binding.gridLayout, false) - val other: SortOrder + val other: EpisodeSortOrder when { ascending == descending -> { item.button.setText(title) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialog.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialog.kt deleted file mode 100644 index 6b5be7d7..00000000 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialog.kt +++ /dev/null @@ -1,33 +0,0 @@ -package ac.mdiq.podcini.ui.dialog - -import ac.mdiq.podcini.R -import ac.mdiq.podcini.preferences.UserPreferences.feedOrder -import ac.mdiq.podcini.preferences.UserPreferences.setFeedOrder -import ac.mdiq.podcini.util.event.EventFlow -import ac.mdiq.podcini.util.event.FlowEvent -import android.content.Context -import android.content.DialogInterface -import com.google.android.material.dialog.MaterialAlertDialogBuilder - -object FeedSortDialog { - fun showDialog(context: Context) { - val dialog = MaterialAlertDialogBuilder(context) - dialog.setTitle(context.getString(R.string.pref_nav_drawer_feed_order_title)) - dialog.setNegativeButton(android.R.string.cancel) { d: DialogInterface, _: Int -> d.dismiss() } - - val selected = feedOrder - val entryValues = listOf(*context.resources.getStringArray(R.array.nav_drawer_feed_order_values)) - val selectedIndex = entryValues.indexOf("" + selected) - - val items = context.resources.getStringArray(R.array.nav_drawer_feed_order_options) - dialog.setSingleChoiceItems(items, selectedIndex) { d: DialogInterface, which: Int -> - if (selectedIndex != which) { - setFeedOrder(entryValues[which]) - //Update subscriptions - EventFlow.postEvent(FlowEvent.FeedsSortedEvent()) - } - d.dismiss() - } - dialog.show() - } -} diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialogNew.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialogNew.kt new file mode 100644 index 00000000..f138acdc --- /dev/null +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialogNew.kt @@ -0,0 +1,133 @@ +package ac.mdiq.podcini.ui.dialog + +import ac.mdiq.podcini.R +import ac.mdiq.podcini.databinding.SortDialogBinding +import ac.mdiq.podcini.databinding.SortDialogItemActiveBinding +import ac.mdiq.podcini.databinding.SortDialogItemBinding +import ac.mdiq.podcini.preferences.UserPreferences.feedOrderBy +import ac.mdiq.podcini.preferences.UserPreferences.feedOrderDir +import ac.mdiq.podcini.preferences.UserPreferences.setFeedOrder +import ac.mdiq.podcini.storage.model.FeedSortOrder +import ac.mdiq.podcini.storage.model.FeedSortOrder.Companion.getSortOrder +import ac.mdiq.podcini.util.Logd +import ac.mdiq.podcini.util.event.EventFlow +import ac.mdiq.podcini.util.event.FlowEvent +import android.app.Dialog +import android.content.DialogInterface +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.widget.CompoundButton +import android.widget.FrameLayout +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.google.android.material.bottomsheet.BottomSheetDialogFragment + +open class FeedSortDialogNew : BottomSheetDialogFragment() { + private val TAG: String = FeedSortDialogNew::class.simpleName ?: "Anonymous" + + protected var _binding: SortDialogBinding? = null + protected val binding get() = _binding!! + + protected var sortOrder: FeedSortOrder? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + sortOrder = getSortOrder(feedOrderDir, feedOrderBy) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + _binding = SortDialogBinding.inflate(inflater) + populateList() + binding.keepSortedCheckbox.setOnCheckedChangeListener { _: CompoundButton?, _: Boolean -> this@FeedSortDialogNew.onSelectionChanged() } + return binding.root + } + + override fun onStart() { + super.onStart() + dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) + } + + private fun populateList() { + binding.gridLayout.removeAllViews() + onAddItem(R.string.feed_order_unplayed_count, FeedSortOrder.UNPLAYED_OLD_NEW, FeedSortOrder.UNPLAYED_NEW_OLD, false) + onAddItem(R.string.feed_order_alphabetical, FeedSortOrder.ALPHABETIC_A_Z, FeedSortOrder.ALPHABETIC_Z_A, true) + onAddItem(R.string.feed_order_last_update, FeedSortOrder.LAST_UPDATED_OLD_NEW, FeedSortOrder.LAST_UPDATED_NEW_OLD, false) + onAddItem(R.string.feed_order_last_unread_update, FeedSortOrder.LAST_UPDATED_UNPLAYED_OLD_NEW, FeedSortOrder.LAST_UPDATED_UNPLAYED_NEW_OLD, false) + onAddItem(R.string.feed_order_most_played, FeedSortOrder.LEAST_PLAYED, FeedSortOrder.MOST_PLAYED, false) + onAddItem(R.string.feed_counter_downloaded, FeedSortOrder.LEAST_DOWNLAODED, FeedSortOrder.MOST_DOWNLOADED, false) + onAddItem(R.string.feed_counter_downloaded_unplayed, FeedSortOrder.LEAST_DOWNLAODED_UNPLAYED, FeedSortOrder.MOST_DOWNLOADED_UNPLAYED, false) + onAddItem(R.string.feed_order_new_episodes, FeedSortOrder.NEW_EPISODES_LEAST, FeedSortOrder.NEW_EPISODES_MOST, false) + } + + protected open fun onAddItem(title: Int, ascending: FeedSortOrder, descending: FeedSortOrder, ascendingIsDefault: Boolean) { + Logd(TAG, "onAddItem $title") + if (sortOrder == ascending || sortOrder == descending) { + val item = SortDialogItemActiveBinding.inflate(layoutInflater, binding.gridLayout, false) + val other: FeedSortOrder + when { + ascending == descending -> { + item.button.setText(title) + other = ascending + } + sortOrder == ascending -> { + item.button.text = getString(title) + "\u00A0▲" + other = descending + } + else -> { + item.button.text = getString(title) + "\u00A0▼" + other = ascending + } + } + item.button.setOnClickListener { + Logd(TAG, "button clicked: $title ${other.name} ${other.code}") + sortOrder = other + populateList() + setFeedOrder(sortOrder!!.index.toString(), if (sortOrder == ascending) 0 else 1) + onSelectionChanged() + EventFlow.postEvent(FlowEvent.FeedsSortedEvent()) + } + binding.gridLayout.addView(item.root) + } else { + val item = SortDialogItemBinding.inflate(layoutInflater, binding.gridLayout, false) + item.button.setText(title) + item.button.setOnClickListener { + sortOrder = if (ascendingIsDefault) ascending else descending + Logd(TAG, "button clicked 1: ${getString(title)} ${sortOrder!!.name} ${sortOrder!!.code}") + populateList() + setFeedOrder(sortOrder!!.index.toString(), if (sortOrder == ascending) 0 else 1) + onSelectionChanged() + EventFlow.postEvent(FlowEvent.FeedsSortedEvent()) + } + binding.gridLayout.addView(item.root) + } + } + + protected open fun onSelectionChanged() {} + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val dialog = super.onCreateDialog(savedInstanceState) + dialog.setOnShowListener { dialogInterface: DialogInterface -> + val bottomSheetDialog = dialogInterface as BottomSheetDialog + setupFullHeight(bottomSheetDialog) + } + return dialog + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) { + val bottomSheet = bottomSheetDialog.findViewById(com.leinardi.android.speeddial.R.id.design_bottom_sheet) + if (bottomSheet != null) { + val behavior = BottomSheetBehavior.from(bottomSheet) + val layoutParams = bottomSheet.layoutParams + bottomSheet.layoutParams = layoutParams + behavior.state = BottomSheetBehavior.STATE_EXPANDED + } + } +} diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/TagSettingsDialog.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/TagSettingsDialog.kt index f9d6d29f..4d715fff 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/TagSettingsDialog.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/TagSettingsDialog.kt @@ -6,10 +6,13 @@ import ac.mdiq.podcini.storage.database.Feeds.buildTags import ac.mdiq.podcini.storage.database.Feeds.getTags import ac.mdiq.podcini.storage.database.Feeds.persistFeedPreferences import ac.mdiq.podcini.storage.database.RealmDB.unmanaged +import ac.mdiq.podcini.storage.database.RealmDB.upsert +import ac.mdiq.podcini.storage.database.RealmDB.upsertBlk import ac.mdiq.podcini.storage.model.Feed import ac.mdiq.podcini.storage.model.FeedPreferences import ac.mdiq.podcini.ui.adapter.SimpleChipAdapter import ac.mdiq.podcini.ui.utils.ItemOffsetDecoration +import ac.mdiq.podcini.util.Logd import android.app.Dialog import android.content.DialogInterface import android.os.Bundle @@ -53,7 +56,6 @@ class TagSettingsDialog : DialogFragment() { } } binding.tagsRecycler.adapter = adapter -// binding.rootFolderCheckbox.isChecked = commonTags.contains(FeedPreferences.TAG_ROOT) binding.newTagTextInput.setEndIconOnClickListener { addTag(binding.newTagEditText.text.toString().trim { it <= ' ' }) @@ -76,14 +78,12 @@ class TagSettingsDialog : DialogFragment() { addTag(binding.newTagEditText.text.toString().trim { it <= ' ' }) updatePreferencesTags(commonTags) buildTags() -// EventFlow.postEvent(FlowEvent.FeedTagsChangedEvent()) } dialog.setNegativeButton(R.string.cancel_label, null) return dialog.create() } private fun loadTags() { -// val scope = CoroutineScope(Dispatchers.Main) val acAdapter = ArrayAdapter(requireContext(), R.layout.single_tag_text_view, getTags()) binding.newTagEditText.setAdapter(acAdapter) } @@ -102,16 +102,13 @@ class TagSettingsDialog : DialogFragment() { } @OptIn(UnstableApi::class) private fun updatePreferencesTags(commonTags: Set) { -// if (binding.rootFolderCheckbox.isChecked) { -// displayedTags.add(FeedPreferences.TAG_ROOT) -// } - for (feed_ in feedList) { - val feed = unmanaged(feed_) - if (feed.preferences != null) { - feed.preferences!!.tags.removeAll(commonTags) - feed.preferences!!.tags.addAll(displayedTags) - persistFeedPreferences(feed) -// EventFlow.postEvent(FlowEvent.FeedPrefsChangeEvent(feed)) + for (f in feedList) { + Logd(TAG, "${f.title} $displayedTags") + upsertBlk(f) { + if (it.preferences != null) { + it.preferences!!.tags.removeAll(commonTags) + it.preferences!!.tags.addAll(displayedTags) + } } } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AddFeedFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AddFeedFragment.kt index 49bf4869..dadddd4d 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AddFeedFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AddFeedFragment.kt @@ -7,7 +7,7 @@ import ac.mdiq.podcini.net.feed.discovery.* import ac.mdiq.podcini.net.feed.FeedUpdateManager import ac.mdiq.podcini.storage.database.Feeds.updateFeed import ac.mdiq.podcini.storage.model.Feed -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.activity.MainActivity import ac.mdiq.podcini.ui.activity.OpmlImportActivity import ac.mdiq.podcini.util.Logd @@ -193,7 +193,7 @@ class AddFeedFragment : Fragment() { val dirFeed = Feed(Feed.PREFIX_LOCAL_FOLDER + uri.toString(), null, title) dirFeed.episodes.clear() - dirFeed.sortOrder = SortOrder.EPISODE_TITLE_A_Z + dirFeed.sortOrder = EpisodeSortOrder.EPISODE_TITLE_A_Z val fromDatabase: Feed? = updateFeed(requireContext(), dirFeed, false) FeedUpdateManager.runOnce(requireContext(), fromDatabase) return fromDatabase diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AllEpisodesFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AllEpisodesFragment.kt index a7bfd70e..fedc6636 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AllEpisodesFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AllEpisodesFragment.kt @@ -7,7 +7,7 @@ import ac.mdiq.podcini.storage.database.Episodes.getEpisodes import ac.mdiq.podcini.storage.database.Episodes.getEpisodesCount import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeFilter -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.activity.MainActivity import ac.mdiq.podcini.ui.dialog.EpisodeFilterDialog import ac.mdiq.podcini.ui.dialog.EpisodeSortDialog @@ -146,9 +146,9 @@ import kotlin.math.min super.onCreate(savedInstanceState) sortOrder = allEpisodesSortOrder } - override fun onAddItem(title: Int, ascending: SortOrder, descending: SortOrder, ascendingIsDefault: Boolean) { - if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.DURATION_SHORT_LONG - || ascending == SortOrder.PLAYED_DATE_OLD_NEW || ascending == SortOrder.COMPLETED_DATE_OLD_NEW) + override fun onAddItem(title: Int, ascending: EpisodeSortOrder, descending: EpisodeSortOrder, ascendingIsDefault: Boolean) { + if (ascending == EpisodeSortOrder.DATE_OLD_NEW || ascending == EpisodeSortOrder.DURATION_SHORT_LONG + || ascending == EpisodeSortOrder.PLAYED_DATE_OLD_NEW || ascending == EpisodeSortOrder.COMPLETED_DATE_OLD_NEW) super.onAddItem(title, ascending, descending, ascendingIsDefault) } override fun onSelectionChanged() { diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/DownloadsFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/DownloadsFragment.kt index d428a776..e38b363d 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/DownloadsFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/DownloadsFragment.kt @@ -13,7 +13,7 @@ import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeMedia import ac.mdiq.podcini.storage.model.EpisodeFilter import ac.mdiq.podcini.storage.utils.EpisodeUtil -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.actions.EpisodeMultiSelectHandler import ac.mdiq.podcini.ui.actions.actionbutton.DeleteActionButton import ac.mdiq.podcini.ui.actions.menuhandler.EpisodeMenuHandler @@ -323,7 +323,7 @@ import java.util.* lifecycleScope.launch { try { withContext(Dispatchers.IO) { - val sortOrder: SortOrder? = UserPreferences.downloadsSortedOrder + val sortOrder: EpisodeSortOrder? = UserPreferences.downloadsSortedOrder val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), sortOrder) if (runningDownloads.isEmpty()) episodes = downloadedItems.toMutableList() else { @@ -411,11 +411,11 @@ import java.util.* sortOrder = UserPreferences.downloadsSortedOrder } - override fun onAddItem(title: Int, ascending: SortOrder, descending: SortOrder, ascendingIsDefault: Boolean) { - if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.PLAYED_DATE_OLD_NEW - || ascending == SortOrder.COMPLETED_DATE_OLD_NEW - || ascending == SortOrder.DURATION_SHORT_LONG || ascending == SortOrder.EPISODE_TITLE_A_Z - || ascending == SortOrder.SIZE_SMALL_LARGE || ascending == SortOrder.FEED_TITLE_A_Z) { + override fun onAddItem(title: Int, ascending: EpisodeSortOrder, descending: EpisodeSortOrder, ascendingIsDefault: Boolean) { + if (ascending == EpisodeSortOrder.DATE_OLD_NEW || ascending == EpisodeSortOrder.PLAYED_DATE_OLD_NEW + || ascending == EpisodeSortOrder.COMPLETED_DATE_OLD_NEW + || ascending == EpisodeSortOrder.DURATION_SHORT_LONG || ascending == EpisodeSortOrder.EPISODE_TITLE_A_Z + || ascending == EpisodeSortOrder.SIZE_SMALL_LARGE || ascending == EpisodeSortOrder.FEED_TITLE_A_Z) { super.onAddItem(title, ascending, descending, ascendingIsDefault) } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedEpisodesFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedEpisodesFragment.kt index b7bd53d9..f13426f5 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedEpisodesFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedEpisodesFragment.kt @@ -20,8 +20,8 @@ import ac.mdiq.podcini.storage.model.EpisodeMedia import ac.mdiq.podcini.storage.model.Feed import ac.mdiq.podcini.storage.model.EpisodeFilter import ac.mdiq.podcini.storage.utils.EpisodeUtil -import ac.mdiq.podcini.storage.model.SortOrder -import ac.mdiq.podcini.storage.model.SortOrder.Companion.fromCode +import ac.mdiq.podcini.storage.model.EpisodeSortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder.Companion.fromCode import ac.mdiq.podcini.ui.actions.EpisodeMultiSelectHandler import ac.mdiq.podcini.ui.actions.menuhandler.EpisodeMenuHandler import ac.mdiq.podcini.ui.actions.menuhandler.MenuItemUtils @@ -698,13 +698,13 @@ import java.util.concurrent.Semaphore class SingleFeedSortDialog(val feed: Feed?) : EpisodeSortDialog() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - sortOrder = feed?.sortOrder ?: SortOrder.DATE_NEW_OLD + sortOrder = feed?.sortOrder ?: EpisodeSortOrder.DATE_NEW_OLD } - override fun onAddItem(title: Int, ascending: SortOrder, descending: SortOrder, ascendingIsDefault: Boolean) { - if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.PLAYED_DATE_OLD_NEW || ascending == SortOrder.COMPLETED_DATE_OLD_NEW - || ascending == SortOrder.DURATION_SHORT_LONG || ascending == SortOrder.RANDOM - || ascending == SortOrder.EPISODE_TITLE_A_Z - || (feed?.isLocalFeed == true && ascending == SortOrder.EPISODE_FILENAME_A_Z)) { + override fun onAddItem(title: Int, ascending: EpisodeSortOrder, descending: EpisodeSortOrder, ascendingIsDefault: Boolean) { + if (ascending == EpisodeSortOrder.DATE_OLD_NEW || ascending == EpisodeSortOrder.PLAYED_DATE_OLD_NEW || ascending == EpisodeSortOrder.COMPLETED_DATE_OLD_NEW + || ascending == EpisodeSortOrder.DURATION_SHORT_LONG || ascending == EpisodeSortOrder.RANDOM + || ascending == EpisodeSortOrder.EPISODE_TITLE_A_Z + || (feed?.isLocalFeed == true && ascending == EpisodeSortOrder.EPISODE_FILENAME_A_Z)) { super.onAddItem(title, ascending, descending, ascendingIsDefault) } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/HistoryFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/HistoryFragment.kt index 97a90c30..444809ab 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/HistoryFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/HistoryFragment.kt @@ -5,7 +5,7 @@ import ac.mdiq.podcini.storage.database.RealmDB.realm import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeMedia -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.actions.menuhandler.MenuItemUtils import ac.mdiq.podcini.ui.activity.MainActivity import ac.mdiq.podcini.ui.adapter.EpisodesAdapter @@ -32,7 +32,7 @@ import kotlin.math.min @UnstableApi class HistoryFragment : BaseEpisodesFragment() { - private var sortOrder : SortOrder = SortOrder.PLAYED_DATE_NEW_OLD + private var sortOrder : EpisodeSortOrder = EpisodeSortOrder.PLAYED_DATE_NEW_OLD private var startDate : Long = 0L private var endDate : Long = Date().time @@ -190,17 +190,17 @@ import kotlin.math.min } class HistorySortDialog : EpisodeSortDialog() { - override fun onAddItem(title: Int, ascending: SortOrder, descending: SortOrder, ascendingIsDefault: Boolean) { - if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.PLAYED_DATE_OLD_NEW - || ascending == SortOrder.COMPLETED_DATE_OLD_NEW - || ascending == SortOrder.DURATION_SHORT_LONG || ascending == SortOrder.EPISODE_TITLE_A_Z - || ascending == SortOrder.SIZE_SMALL_LARGE || ascending == SortOrder.FEED_TITLE_A_Z) { + override fun onAddItem(title: Int, ascending: EpisodeSortOrder, descending: EpisodeSortOrder, ascendingIsDefault: Boolean) { + if (ascending == EpisodeSortOrder.DATE_OLD_NEW || ascending == EpisodeSortOrder.PLAYED_DATE_OLD_NEW + || ascending == EpisodeSortOrder.COMPLETED_DATE_OLD_NEW + || ascending == EpisodeSortOrder.DURATION_SHORT_LONG || ascending == EpisodeSortOrder.EPISODE_TITLE_A_Z + || ascending == EpisodeSortOrder.SIZE_SMALL_LARGE || ascending == EpisodeSortOrder.FEED_TITLE_A_Z) { super.onAddItem(title, ascending, descending, ascendingIsDefault) } } override fun onSelectionChanged() { super.onSelectionChanged() - EventFlow.postEvent(FlowEvent.HistoryEvent(sortOrder?: SortOrder.PLAYED_DATE_NEW_OLD)) + EventFlow.postEvent(FlowEvent.HistoryEvent(sortOrder?: EpisodeSortOrder.PLAYED_DATE_NEW_OLD)) } } @@ -219,7 +219,7 @@ import kotlin.math.min * @return The playback history. The FeedItems are sorted by their media's playbackCompletionDate in descending order. */ fun getHistory(offset: Int, limit: Int, start: Long = 0L, end: Long = Date().time, - sortOrder: SortOrder = SortOrder.PLAYED_DATE_NEW_OLD): List { + sortOrder: EpisodeSortOrder = EpisodeSortOrder.PLAYED_DATE_NEW_OLD): List { Logd(TAG, "getHistory() called") val medias = realm.query(EpisodeMedia::class).query("lastPlayedTime > $0 AND lastPlayedTime <= $1", start, end).find() var episodes: MutableList = mutableListOf() diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/QueueFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/QueueFragment.kt index aaf7236f..729e5278 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/QueueFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/QueueFragment.kt @@ -19,7 +19,7 @@ import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeMedia import ac.mdiq.podcini.storage.model.EpisodeFilter import ac.mdiq.podcini.storage.utils.EpisodeUtil -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.actions.EpisodeMultiSelectHandler import ac.mdiq.podcini.ui.actions.menuhandler.EpisodeMenuHandler import ac.mdiq.podcini.ui.actions.menuhandler.MenuItemUtils @@ -572,14 +572,14 @@ import java.util.* binding.keepSortedCheckbox.setEnabled(UserPreferences.isQueueKeepSorted) return view } - override fun onAddItem(title: Int, ascending: SortOrder, descending: SortOrder, ascendingIsDefault: Boolean) { - if (ascending != SortOrder.EPISODE_FILENAME_A_Z && ascending != SortOrder.SIZE_SMALL_LARGE) + override fun onAddItem(title: Int, ascending: EpisodeSortOrder, descending: EpisodeSortOrder, ascendingIsDefault: Boolean) { + if (ascending != EpisodeSortOrder.EPISODE_FILENAME_A_Z && ascending != EpisodeSortOrder.SIZE_SMALL_LARGE) super.onAddItem(title, ascending, descending, ascendingIsDefault) } @UnstableApi override fun onSelectionChanged() { super.onSelectionChanged() - binding.keepSortedCheckbox.setEnabled(sortOrder != SortOrder.RANDOM) - if (sortOrder == SortOrder.RANDOM) binding.keepSortedCheckbox.setChecked(false) + binding.keepSortedCheckbox.setEnabled(sortOrder != EpisodeSortOrder.RANDOM) + if (sortOrder == EpisodeSortOrder.RANDOM) binding.keepSortedCheckbox.setChecked(false) UserPreferences.isQueueKeepSorted = binding.keepSortedCheckbox.isChecked UserPreferences.queueKeepSortedOrder = sortOrder reorderQueue(sortOrder, true) @@ -590,7 +590,7 @@ import java.util.* * QueueUpdateBroadcast. This option should be set to `false` * if the caller wants to avoid unexpected updates of the GUI. */ - private fun reorderQueue(sortOrder: SortOrder?, broadcastUpdate: Boolean) : Job { + private fun reorderQueue(sortOrder: EpisodeSortOrder?, broadcastUpdate: Boolean) : Job { Logd(TAG, "reorderQueue called") if (sortOrder == null) { Logd(TAG, "reorderQueue() - sortOrder is null. Do nothing.") @@ -664,11 +664,11 @@ import java.util.* @UnstableApi override fun afterBindViewHolder(holder: EpisodeViewHolder, pos: Int) { if (inActionMode() || !dragDropEnabled) { - holder.dragHandle.setVisibility(View.GONE) + holder.dragHandle.visibility = View.GONE holder.dragHandle.setOnTouchListener(null) // holder.coverHolder.setOnTouchListener(null) } else { - holder.dragHandle.setVisibility(View.VISIBLE) + holder.dragHandle.visibility = View.VISIBLE holder.dragHandle.setOnTouchListener { _: View?, event: MotionEvent -> if (event.actionMasked == MotionEvent.ACTION_DOWN) swipeActions.startDrag(holder) false diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/SubscriptionsFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/SubscriptionsFragment.kt index 370173fc..a7c7bd39 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/SubscriptionsFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/SubscriptionsFragment.kt @@ -4,7 +4,8 @@ import ac.mdiq.podcini.R import ac.mdiq.podcini.databinding.* import ac.mdiq.podcini.net.feed.FeedUpdateManager import ac.mdiq.podcini.preferences.UserPreferences -import ac.mdiq.podcini.preferences.UserPreferences.feedOrder +import ac.mdiq.podcini.preferences.UserPreferences.feedOrderBy +import ac.mdiq.podcini.preferences.UserPreferences.feedOrderDir import ac.mdiq.podcini.preferences.UserPreferences.useGridLayout import ac.mdiq.podcini.storage.database.Feeds.getFeedList import ac.mdiq.podcini.storage.database.Feeds.getTags @@ -17,7 +18,7 @@ import ac.mdiq.podcini.ui.actions.menuhandler.FeedMenuHandler import ac.mdiq.podcini.ui.actions.menuhandler.MenuItemUtils import ac.mdiq.podcini.ui.activity.MainActivity import ac.mdiq.podcini.ui.adapter.SelectableAdapter -import ac.mdiq.podcini.ui.dialog.FeedSortDialog +import ac.mdiq.podcini.ui.dialog.FeedSortDialogNew import ac.mdiq.podcini.ui.dialog.RemoveFeedDialog import ac.mdiq.podcini.ui.dialog.TagSettingsDialog import ac.mdiq.podcini.ui.utils.CoverLoader @@ -288,7 +289,7 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec val itemId = item.itemId when (itemId) { R.id.action_search -> (activity as MainActivity).loadChildFragment(SearchFragment.newInstance()) - R.id.subscriptions_sort -> FeedSortDialog.showDialog(requireContext()) + R.id.subscriptions_sort -> FeedSortDialogNew().show(childFragmentManager, "FeedSortDialog") R.id.refresh_item -> FeedUpdateManager.runOnceOrAsk(requireContext()) else -> return false } @@ -332,28 +333,29 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec private fun sortFeeds() { Logd(TAG, "sortFeeds() called") - val feedOrder = feedOrder + val feedOrder = feedOrderBy + val dir = 1 - 2*feedOrderDir // get from 0, 1 to 1, -1 val comparator: Comparator = when (feedOrder) { UserPreferences.FEED_ORDER_UNPLAYED -> { val episodes = realm.query(Episode::class).query("(playState == ${Episode.NEW} OR playState == ${Episode.UNPLAYED})").find() val counterMap = counterMap(episodes) - comparator(counterMap) + comparator(counterMap, dir) } UserPreferences.FEED_ORDER_ALPHABETICAL -> { Comparator { lhs: Feed, rhs: Feed -> val t1 = lhs.title val t2 = rhs.title when { - t1 == null -> 1 - t2 == null -> -1 - else -> t1.compareTo(t2, ignoreCase = true) + t1 == null -> dir + t2 == null -> -dir + else -> t1.compareTo(t2, ignoreCase = true) * dir } } } UserPreferences.FEED_ORDER_MOST_PLAYED -> { val episodes = realm.query(Episode::class).query("playState == ${Episode.PLAYED}").find() val counterMap = counterMap(episodes) - comparator(counterMap) + comparator(counterMap, dir) } UserPreferences.FEED_ORDER_LAST_UPDATED -> { val episodes = realm.query(Episode::class).sort("pubDate", Sort.DESCENDING).find() @@ -363,7 +365,7 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec val pDateOld = counterMap[feedId] ?: 0 if (pDateOld < episode.pubDate) counterMap[feedId] = episode.pubDate } - comparator(counterMap) + comparator(counterMap, dir) } UserPreferences.FEED_ORDER_LAST_UNREAD_UPDATED -> { val episodes = realm.query(Episode::class) @@ -374,24 +376,24 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec val pDateOld = counterMap[feedId] ?: 0 if (pDateOld < episode.pubDate) counterMap[feedId] = episode.pubDate } - comparator(counterMap) + comparator(counterMap, dir) } UserPreferences.FEED_ORDER_DOWNLOADED -> { val episodes = realm.query(Episode::class).query("media.downloaded == true").find() val counterMap = counterMap(episodes) - comparator(counterMap) + comparator(counterMap, dir) } UserPreferences.FEED_ORDER_DOWNLOADED_UNPLAYED -> { val episodes = realm.query(Episode::class) .query("(playState == ${Episode.NEW} OR playState == ${Episode.UNPLAYED}) AND media.downloaded == true").find() val counterMap = counterMap(episodes) - comparator(counterMap) + comparator(counterMap, dir) } // doing FEED_ORDER_NEW else -> { val episodes = realm.query(Episode::class).query("playState == ${Episode.NEW}").find() val counterMap = counterMap(episodes) - comparator(counterMap) + comparator(counterMap, dir) } } synchronized(feedList) { feedList.sortWith(comparator) } @@ -407,15 +409,15 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec return counterMap } - private fun comparator(counterMap: Map): Comparator { + private fun comparator(counterMap: Map, dir: Int): Comparator { return Comparator { lhs: Feed, rhs: Feed -> val counterLhs = counterMap[lhs.id]?:0 val counterRhs = counterMap[rhs.id]?:0 when { // reverse natural order: podcast with most unplayed episodes first - counterLhs > counterRhs -> -1 - counterLhs == counterRhs -> lhs.title?.compareTo(rhs.title!!, ignoreCase = true) ?: -1 - else -> 1 + counterLhs > counterRhs -> -dir + counterLhs == counterRhs -> (lhs.title?.compareTo(rhs.title!!, ignoreCase = true) ?: -1) * dir + else -> dir } } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/view/viewholder/EpisodeViewHolder.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/view/viewholder/EpisodeViewHolder.kt index 9db3923f..6a24f2ea 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/view/viewholder/EpisodeViewHolder.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/view/viewholder/EpisodeViewHolder.kt @@ -18,10 +18,12 @@ import ac.mdiq.podcini.ui.actions.actionbutton.TTSActionButton import ac.mdiq.podcini.ui.activity.MainActivity import ac.mdiq.podcini.ui.utils.CoverLoader import ac.mdiq.podcini.ui.utils.ThemeUtils +import ac.mdiq.podcini.ui.utils.ThemeUtils.getColorFromAttr import ac.mdiq.podcini.ui.view.CircularProgressBar import ac.mdiq.podcini.util.Converter import ac.mdiq.podcini.util.DateFormatter import ac.mdiq.podcini.util.Logd +import android.graphics.PorterDuff import android.text.Layout import android.text.format.Formatter import android.util.Log @@ -34,6 +36,7 @@ import android.widget.ProgressBar import android.widget.TextView import androidx.appcompat.content.res.AppCompatResources import androidx.cardview.widget.CardView +import androidx.core.content.ContextCompat import androidx.media3.common.util.UnstableApi import androidx.recyclerview.widget.RecyclerView import com.google.android.material.elevation.SurfaceColors @@ -93,21 +96,25 @@ open class EpisodeViewHolder(private val activity: MainActivity, parent: ViewGro this.episode = item placeholder.text = item.feed?.title title.text = item.title - container.alpha = if (item.isPlayed()) 0.75f else 1.0f - if (item.isPlayed()) { - leftPadding.contentDescription = item.title + ". " + activity.getString(R.string.is_played) - binding.playedMark.visibility = View.VISIBLE - binding.playedMark.alpha = 1.0f - } else { - leftPadding.contentDescription = item.title - binding.playedMark.visibility = View.GONE + container.alpha = if (item.isPlayed()) 0.7f else 1.0f + leftPadding.contentDescription = item.title + binding.playedMark.visibility = View.GONE + when { + item.isPlayed() -> { + leftPadding.contentDescription = item.title + ". " + activity.getString(R.string.is_played) + binding.playedMark.visibility = View.VISIBLE + binding.playedMark.alpha = 1.0f + } + item.isNew -> { + binding.txtvPubDate.setTextColor(getColorFromAttr(activity, androidx.appcompat.R.attr.colorAccent)) + } } setPubDate(item) isFavorite.visibility = if (item.isFavorite) View.VISIBLE else View.GONE isInQueue.visibility = if (curQueue.isInQueue(item)) View.VISIBLE else View.GONE - container.alpha = if (item.isPlayed()) 0.75f else 1.0f +// container.alpha = if (item.isPlayed()) 0.7f else 1.0f val newButton = EpisodeActionButton.forItem(item) // Logd(TAG, "Trying to bind button ${actionButton?.TAG} ${newButton.TAG} ${item.title}") @@ -152,6 +159,7 @@ open class EpisodeViewHolder(private val activity: MainActivity, parent: ViewGro Logd(TAG, "setting cover to ic_launcher") cover.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_launcher_foreground)) } +// if (item.isNew) cover.setColorFilter(ContextCompat.getColor(activity, R.color.gradient_100), PorterDuff.Mode.MULTIPLY) } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/util/event/FlowEvent.kt b/app/src/main/kotlin/ac/mdiq/podcini/util/event/FlowEvent.kt index ff8de5ec..9ef52ed3 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/util/event/FlowEvent.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/util/event/FlowEvent.kt @@ -5,7 +5,7 @@ import ac.mdiq.podcini.net.download.DownloadStatus import ac.mdiq.podcini.storage.model.Feed import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.Playable -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.util.Logd import android.content.Context import android.view.KeyEvent @@ -93,7 +93,7 @@ sealed class FlowEvent { } } - data class HistoryEvent(val sortOrder: SortOrder = SortOrder.PLAYED_DATE_NEW_OLD, val startDate: Long = 0, val endDate: Long = Date().time) : FlowEvent() + data class HistoryEvent(val sortOrder: EpisodeSortOrder = EpisodeSortOrder.PLAYED_DATE_NEW_OLD, val startDate: Long = 0, val endDate: Long = Date().time) : FlowEvent() data class SleepTimerUpdatedEvent(private val timeLeft: Long) : FlowEvent() { val isOver: Boolean diff --git a/app/src/main/kotlin/ac/mdiq/podcini/util/sorting/EpisodesPermutors.kt b/app/src/main/kotlin/ac/mdiq/podcini/util/sorting/EpisodesPermutors.kt index 3b4328a8..a06fe3af 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/util/sorting/EpisodesPermutors.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/util/sorting/EpisodesPermutors.kt @@ -1,7 +1,7 @@ package ac.mdiq.podcini.util.sorting import ac.mdiq.podcini.storage.model.Episode -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import java.util.* /** @@ -14,43 +14,43 @@ object EpisodesPermutors { * @return Permutor that sorts a list appropriate to the given sort order. */ @JvmStatic - fun getPermutor(sortOrder: SortOrder): Permutor { + fun getPermutor(sortOrder: EpisodeSortOrder): Permutor { var comparator: Comparator? = null var permutor: Permutor? = null when (sortOrder) { - SortOrder.EPISODE_TITLE_A_Z -> comparator = Comparator { f1: Episode?, f2: Episode? -> itemTitle(f1).compareTo(itemTitle(f2)) } - SortOrder.EPISODE_TITLE_Z_A -> comparator = Comparator { f1: Episode?, f2: Episode? -> itemTitle(f2).compareTo(itemTitle(f1)) } - SortOrder.DATE_OLD_NEW -> comparator = Comparator { f1: Episode?, f2: Episode? -> pubDate(f1).compareTo(pubDate(f2)) } - SortOrder.DATE_NEW_OLD -> comparator = Comparator { f1: Episode?, f2: Episode? -> pubDate(f2).compareTo(pubDate(f1)) } - SortOrder.DURATION_SHORT_LONG -> comparator = Comparator { f1: Episode?, f2: Episode? -> duration(f1).compareTo(duration(f2)) } - SortOrder.DURATION_LONG_SHORT -> comparator = Comparator { f1: Episode?, f2: Episode? -> duration(f2).compareTo(duration(f1)) } - SortOrder.EPISODE_FILENAME_A_Z -> comparator = Comparator { f1: Episode?, f2: Episode? -> itemLink(f1).compareTo(itemLink(f2)) } - SortOrder.EPISODE_FILENAME_Z_A -> comparator = Comparator { f1: Episode?, f2: Episode? -> itemLink(f2).compareTo(itemLink(f1)) } - SortOrder.PLAYED_DATE_OLD_NEW -> comparator = Comparator { f1: Episode?, f2: Episode? -> playDate(f1).compareTo(playDate(f2)) } - SortOrder.PLAYED_DATE_NEW_OLD -> comparator = Comparator { f1: Episode?, f2: Episode? -> playDate(f2).compareTo(playDate(f1)) } - SortOrder.COMPLETED_DATE_OLD_NEW -> comparator = Comparator { f1: Episode?, f2: Episode? -> completeDate(f1).compareTo(completeDate(f2)) } - SortOrder.COMPLETED_DATE_NEW_OLD -> comparator = Comparator { f1: Episode?, f2: Episode? -> completeDate(f2).compareTo(completeDate(f1)) } + EpisodeSortOrder.EPISODE_TITLE_A_Z -> comparator = Comparator { f1: Episode?, f2: Episode? -> itemTitle(f1).compareTo(itemTitle(f2)) } + EpisodeSortOrder.EPISODE_TITLE_Z_A -> comparator = Comparator { f1: Episode?, f2: Episode? -> itemTitle(f2).compareTo(itemTitle(f1)) } + EpisodeSortOrder.DATE_OLD_NEW -> comparator = Comparator { f1: Episode?, f2: Episode? -> pubDate(f1).compareTo(pubDate(f2)) } + EpisodeSortOrder.DATE_NEW_OLD -> comparator = Comparator { f1: Episode?, f2: Episode? -> pubDate(f2).compareTo(pubDate(f1)) } + EpisodeSortOrder.DURATION_SHORT_LONG -> comparator = Comparator { f1: Episode?, f2: Episode? -> duration(f1).compareTo(duration(f2)) } + EpisodeSortOrder.DURATION_LONG_SHORT -> comparator = Comparator { f1: Episode?, f2: Episode? -> duration(f2).compareTo(duration(f1)) } + EpisodeSortOrder.EPISODE_FILENAME_A_Z -> comparator = Comparator { f1: Episode?, f2: Episode? -> itemLink(f1).compareTo(itemLink(f2)) } + EpisodeSortOrder.EPISODE_FILENAME_Z_A -> comparator = Comparator { f1: Episode?, f2: Episode? -> itemLink(f2).compareTo(itemLink(f1)) } + EpisodeSortOrder.PLAYED_DATE_OLD_NEW -> comparator = Comparator { f1: Episode?, f2: Episode? -> playDate(f1).compareTo(playDate(f2)) } + EpisodeSortOrder.PLAYED_DATE_NEW_OLD -> comparator = Comparator { f1: Episode?, f2: Episode? -> playDate(f2).compareTo(playDate(f1)) } + EpisodeSortOrder.COMPLETED_DATE_OLD_NEW -> comparator = Comparator { f1: Episode?, f2: Episode? -> completeDate(f1).compareTo(completeDate(f2)) } + EpisodeSortOrder.COMPLETED_DATE_NEW_OLD -> comparator = Comparator { f1: Episode?, f2: Episode? -> completeDate(f2).compareTo(completeDate(f1)) } - SortOrder.FEED_TITLE_A_Z -> comparator = Comparator { f1: Episode?, f2: Episode? -> feedTitle(f1).compareTo(feedTitle(f2)) } - SortOrder.FEED_TITLE_Z_A -> comparator = Comparator { f1: Episode?, f2: Episode? -> feedTitle(f2).compareTo(feedTitle(f1)) } - SortOrder.RANDOM -> permutor = object : Permutor { + EpisodeSortOrder.FEED_TITLE_A_Z -> comparator = Comparator { f1: Episode?, f2: Episode? -> feedTitle(f1).compareTo(feedTitle(f2)) } + EpisodeSortOrder.FEED_TITLE_Z_A -> comparator = Comparator { f1: Episode?, f2: Episode? -> feedTitle(f2).compareTo(feedTitle(f1)) } + EpisodeSortOrder.RANDOM -> permutor = object : Permutor { override fun reorder(queue: MutableList?) { if (!queue.isNullOrEmpty()) queue.shuffle() } } - SortOrder.SMART_SHUFFLE_OLD_NEW -> permutor = object : Permutor { + EpisodeSortOrder.SMART_SHUFFLE_OLD_NEW -> permutor = object : Permutor { override fun reorder(queue: MutableList?) { if (!queue.isNullOrEmpty()) smartShuffle(queue as MutableList, true) } } - SortOrder.SMART_SHUFFLE_NEW_OLD -> permutor = object : Permutor { + EpisodeSortOrder.SMART_SHUFFLE_NEW_OLD -> permutor = object : Permutor { override fun reorder(queue: MutableList?) { if (!queue.isNullOrEmpty()) smartShuffle(queue as MutableList, false) } } - SortOrder.SIZE_SMALL_LARGE -> comparator = Comparator { f1: Episode?, f2: Episode? -> size(f1).compareTo(size(f2)) } - SortOrder.SIZE_LARGE_SMALL -> comparator = Comparator { f1: Episode?, f2: Episode? -> size(f2).compareTo(size(f1)) } + EpisodeSortOrder.SIZE_SMALL_LARGE -> comparator = Comparator { f1: Episode?, f2: Episode? -> size(f1).compareTo(size(f2)) } + EpisodeSortOrder.SIZE_LARGE_SMALL -> comparator = Comparator { f1: Episode?, f2: Episode? -> size(f2).compareTo(size(f1)) } } if (comparator != null) { val comparator2: Comparator = comparator diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 6f21aaf3..d8c07d79 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -60,15 +60,13 @@ افتح القائمة اغلق القائمة تفضيلات الدرج - رتب بعدد الحلقات - رتب أبجديا - رتب بتاريخ النشر - رتب بعدد الحلقات المشغلة + رتب أبجديا + رتب بتاريخ النشر + رتب بعدد الحلقات المشغلة - عدد الحلقات غير المشغلة - عدد الحلقات المنزلة - عدد الحلقات المنزلة وغير المشغلة - بدون + عدد الحلقات غير المشغلة + عدد الحلقات المنزلة + عدد الحلقات المنزلة وغير المشغلة لا يوجد برنامج متوافق اصدار سجلات مفصلة diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index 4aaf64bb..016a5e75 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -24,13 +24,11 @@ Abrir el menú Zarrar el menú - Pol contador - Alfabéticamente - Pola data d\'espublizamientu - Pol númberu d\'episodios reproducíos - Episodios ensin reproducir - Episodios baxaos - Nada + Alfabéticamente + Pola data d\'espublizamientu + Pol númberu d\'episodios reproducíos + Episodios ensin reproducir + Episodios baxaos Nun s\'atoparon aplicaciones compatibles Esportar el rexistru detalláu diff --git a/app/src/main/res/values-br/strings.xml b/app/src/main/res/values-br/strings.xml index a17b57f0..9d2574b3 100644 --- a/app/src/main/res/values-br/strings.xml +++ b/app/src/main/res/values-br/strings.xml @@ -55,15 +55,13 @@ Digeriñ al lañser Serriñ al lañser Gwellvezioù ar stalaf - Rummañ dre gonter - Rummañ dre urzh al lizherenneg - Rummañ dre an deiziad embann - Rummañ dre an niver a rannoù lennet + Rummañ dre urzh al lizherenneg + Rummañ dre an deiziad embann + Rummañ dre an niver a rannoù lennet - Niver a rannoù n\'int ket bet lennet - Niver a rannoù pellgarget - Niver a rannoù pellgarget n\'int ket bet lennet - Hini ebet + Niver a rannoù n\'int ket bet lennet + Niver a rannoù pellgarget + Niver a rannoù pellgarget n\'int ket bet lennet N\'eo ket bet kavet arloadoù keverlec\'h Ezporzhiañ ar c\'herzhlevrioù dre ar munud diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 70e3cc95..9142d8cf 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -56,15 +56,13 @@ Obre menú Tanca menú Preferències - Ordre per comptador - Ordre alfabètic - Ordre per data de publicació - Ordre per número d\'episodis reproduïts + Ordre alfabètic + Ordre per data de publicació + Ordre per número d\'episodis reproduïts - Número d\'episodis per reproduir - Número d\'episodis descarregats - Número de descàrregues i episodis sense reproduir - Cap + Número d\'episodis per reproduir + Número d\'episodis descarregats + Número de descàrregues i episodis sense reproduir No s\'han trobat aplicacions compatibles Exporta registres detallats diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 63e7f9a1..4e3b5c7a 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -57,15 +57,13 @@ Otevřít menu Zavřít menu Nastavení postranního panelu - Řadit dle čítače - Řadit abecedně - Řadit dle data zveřejnění - Řadit podle počtu poslechnutých epizod + Řadit abecedně + Řadit dle data zveřejnění + Řadit podle počtu poslechnutých epizod - Počet nepřehraných epizod - Počet stažených epizod - Počet stažených a nepřehraných epizod - Žádné + Počet nepřehraných epizod + Počet stažených epizod + Počet stažených a nepřehraných epizod Nenalezena kompatibilní aplikace Exportovat detailní záznamy diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index df8eefb6..8c682faa 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -57,15 +57,13 @@ Åbn menu Luk menu Præferencer for panel - Sorter efter tæller - Sorter alfabetisk - Sorter efter udgivelsesdato - Sorter efter antal afspillede afsnit + Sorter alfabetisk + Sorter efter udgivelsesdato + Sorter efter antal afspillede afsnit - Antal uafspillede afsnit - Antal overførte afsnit - Antal overførte og uafspillede afsnit - Ingen + Antal uafspillede afsnit + Antal overførte afsnit + Antal overførte og uafspillede afsnit Ingen kompatible apper fundet. Eksporter detaljeret log diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5a714c9e..d6595e87 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -61,15 +61,13 @@ Menü öffnen Menü schließen Seitenleisten-Einstellungen - Nach Zähler sortieren - Alphabetisch sortieren - Nach Veröffentlichungsdatum sortieren - Nach Anzahl gespielter Episoden sortieren + Alphabetisch sortieren + Nach Veröffentlichungsdatum sortieren + Nach Anzahl gespielter Episoden sortieren - Anzahl nicht abgespielter Episoden - Anzahl heruntergeladener Episoden - Anzahl heruntergeladener und nicht abgespielter Episoden - Keine + Anzahl nicht abgespielter Episoden + Anzahl heruntergeladener Episoden + Anzahl heruntergeladener und nicht abgespielter Episoden Keine kompatiblen Apps gefunden Detaillierte Logs exportieren diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 244d5cff..886146f5 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -60,15 +60,13 @@ Abrir menú Cerrar menú Preferencias del cajón - Ordenar por contador - Ordenar alfabéticamente - Ordenar por fecha de publicación - Ordenar por número de episodios reproducidos + Ordenar alfabéticamente + Ordenar por fecha de publicación + Ordenar por número de episodios reproducidos - Número de episodios no reproducidos - Número de episodios descargados - Número de episodios descargados y no reproducidos - Ninguno + Número de episodios no reproducidos + Número de episodios descargados + Número de episodios descargados y no reproducidos No se encontró ninguna aplicación compatible Exportar registros detallados diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 2f7e4f77..eafd702d 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -48,14 +48,12 @@ Ava menüü Sulge menüü - Sorteeri arvu järgi - Sorteeri tähestiku järgi - Sorteeri avaldamise kuupäeva järgi - Sorteeri kuulatud saadete järgi - Kuulamata saadete arv - Allalaaditud saadete arv - Allalaaditud kuulamata saadete arv - Pole + Sorteeri tähestiku järgi + Sorteeri avaldamise kuupäeva järgi + Sorteeri kuulatud saadete järgi + Kuulamata saadete arv + Allalaaditud saadete arv + Allalaaditud kuulamata saadete arv Ühtegi ühilduvat rakendust ei leitud Ekspordi täpne logi diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index c839a26d..8b407f23 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -55,14 +55,12 @@ Ireki menua Itxi menua - Antolatu kontagailuaren arabera - Antolatu alfabetikoki - Antolatu argitaratze dataz - Antolatu ikusitako saioen arabera + Antolatu alfabetikoki + Antolatu argitaratze dataz + Antolatu ikusitako saioen arabera - Entzun gabeko saioen zenbatekoa - Deskargatutako saio kopurua - Bat ere ez + Entzun gabeko saioen zenbatekoa + Deskargatutako saio kopurua Ez dago app bateragarririk Esportatu log zehatzak diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 6f296744..c9a8f056 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -62,15 +62,13 @@ باز کردن منو بستن منو ترجیحات کشو - مرتب‌سازی بر اساس شمارنده - مرتب‌سازی بر اساس حروف الفبا - مرتب‌سازی بر اساس تاریخ انتشار - چینش بر اساس تعداد قسمت‌های پخش شده + مرتب‌سازی بر اساس حروف الفبا + مرتب‌سازی بر اساس تاریخ انتشار + چینش بر اساس تعداد قسمت‌های پخش شده - تعداد قسمت‌های پخش‌نشده - تعداد قسمت‌های بار گرفته - تعداد قسمت‌های بار گرفته و پخش نشده - هیچ‌یک + تعداد قسمت‌های پخش‌نشده + تعداد قسمت‌های بار گرفته + تعداد قسمت‌های بار گرفته و پخش نشده هیچ اپ سازگاری پیدا نشد برون‌ریزی گزارش پرجزئیات diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index bae6daaf..2b78b6cf 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -55,15 +55,13 @@ Avaa menu Sulje menu Hyllyasetukset - Järjestä kertojen mukaan - Järjestä aakkosellisesti - Järjestä julkaisupäivän mukaan - Järjestä toistettujen jaksojen mukaan + Järjestä aakkosellisesti + Järjestä julkaisupäivän mukaan + Järjestä toistettujen jaksojen mukaan - Toistamattomia jaksoja - Ladattuja jaksoja - Ladattuja ja toistamattomia jaksoja - Ei yhtään + Toistamattomia jaksoja + Ladattuja jaksoja + Ladattuja ja toistamattomia jaksoja Yhteensopivia sovelluksia ei löytynyt Vie yksityiskohtaiset lokit diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index d094619c..90f46be9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -61,15 +61,13 @@ Ouvrir le menu Fermer le menu Préférences du volet - Trier par compteur - Trier par ordre alphabétique - Trier par date de publication - Trier par nombre lus + Trier par ordre alphabétique + Trier par date de publication + Trier par nombre lus - Épisodes non lus - Épisodes téléchargés - Épisodes téléchargés et non lus - Aucun + Épisodes non lus + Épisodes téléchargés + Épisodes téléchargés et non lus Aucune application compatible trouvée Export détaillé des logs diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 2aea2c15..0bb4e7d2 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -57,15 +57,13 @@ Abrir menú Pechar menú Preferencias do panel - Ordenar polo contador - Ordenar alfabeticamente - Ordenar por data de publicación - Ordenar por número de episodios reproducidos + Ordenar alfabeticamente + Ordenar por data de publicación + Ordenar por número de episodios reproducidos - Número de episodios non reproducidos - Número de episodios descargados - Número de episodios descargados e non escoitados - Ningún + Número de episodios non reproducidos + Número de episodios descargados + Número de episodios descargados e non escoitados Non se atopan apps compatibles Exportar rexistro detallado diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index a52fe83a..8b022b5b 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -51,15 +51,13 @@ Menü megnyitása Menü bezárása - Rendezés számláló szerint - Rendezés betűrendben - Rendezés közzététel dátuma szerint - Rendezés lejátszott epizódok szerint + Rendezés betűrendben + Rendezés közzététel dátuma szerint + Rendezés lejátszott epizódok szerint - Nem játszott epizódok száma - Letöltött epizódok száma - Letöltött és nem lejátszott epizódok száma - Nincs + Nem játszott epizódok száma + Letöltött epizódok száma + Letöltött és nem lejátszott epizódok száma Nem található kompatibilis alkalmazás Részletes naplók exportálása diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index cc0eb504..1d94587a 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -51,15 +51,13 @@ Buka menu Tutup menu Preferensi laci - Urutkan berdasarkan penghitung - Urutkan menurut abjad - Urutkan menurut tanggal publikasi - Urutkan menurut jumlah episode yang diputar + Urutkan menurut abjad + Urutkan menurut tanggal publikasi + Urutkan menurut jumlah episode yang diputar - Jumlah episode yang belum diputar - Jumlah episode yang diunduh - Jumlah episode yang terunduh dan belum terputar - Tidak ada + Jumlah episode yang belum diputar + Jumlah episode yang diunduh + Jumlah episode yang terunduh dan belum terputar Tidak ada aplikasi kompatibel yang ditemukan Ekspor log rinci diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index fdab7dc4..884819d0 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -61,15 +61,13 @@ Apri il menù Chiudi il menù Preferenze del menu - Ordina per contatore - Ordina alfabeticamente - Ordina per data di pubblicazione - Ordina per numero di episodi riprodotti + Ordina alfabeticamente + Ordina per data di pubblicazione + Ordina per numero di episodi riprodotti - Numero di episodi non riprodotti - Numero di episodi scaricati - Numero di episodi scaricati e non riprodotti - Nessuno + Numero di episodi non riprodotti + Numero di episodi scaricati + Numero di episodi scaricati e non riprodotti Nessuna applicazione compatibile trovata Esporta registri dettagliati diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index cdc49ed7..e815f098 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -57,15 +57,13 @@ פתיחת תפריט סגירת תפריט העדפות מגירה - מיון לפי מונה - מיון בסדר אלפביתי - מיון לפי תאריך פרסום - מיון לפי מספר פרקים שהושמעו + מיון בסדר אלפביתי + מיון לפי תאריך פרסום + מיון לפי מספר פרקים שהושמעו - מספר פרקים שעוד לא התנגנו - מספר פרקים שהתקבלו - מספר הפרקים שירדו אבל לא נוגנו - ללא + מספר פרקים שעוד לא התנגנו + מספר פרקים שהתקבלו + מספר הפרקים שירדו אבל לא נוגנו לא נמצאו יישומונים תואמים ייצוא יומנים מפורטים diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 79775d17..f7c6ff06 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -44,15 +44,13 @@ メニューを開く メニューを閉じる - カウンターで並べ替え - アルファベット順で並べ替え - 公開日で並べ替え - 再生したエピソードの数で並べ替え + アルファベット順で並べ替え + 公開日で並べ替え + 再生したエピソードの数で並べ替え - 未再生のエピソードの数 - ダウンロード済のエピソードの数 - ダウンロード済と未再生のエピソードの数 - なし + 未再生のエピソードの数 + ダウンロード済のエピソードの数 + ダウンロード済と未再生のエピソードの数 互換性のあるアプリが見つかりません 詳細ログを出力する diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 2f2cb7de..c2a39a45 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -55,15 +55,13 @@ 메뉴 열기 메뉴 닫기 드로어 기본 설정 - 카운터로 정렬 - 사전 순서로 정렬 - 공개 날짜 순서대로 정렬 - 재생한 에피소드 개수에 따라 정렬 + 사전 순서로 정렬 + 공개 날짜 순서대로 정렬 + 재생한 에피소드 개수에 따라 정렬 - 재생하지 않은 에피소드 수 - 다운로드한 에피소드 수 - 다운로드 개수 및 재생하지 않은 에피소드 - 없음 + 재생하지 않은 에피소드 수 + 다운로드한 에피소드 수 + 다운로드 개수 및 재생하지 않은 에피소드 호환되는 앱이 없습니다 자세한 기록 내보내기 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 84f26f00..1e9a952a 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -36,13 +36,11 @@ Atverti meniu Užverti meniu - Rikiuoti pagal skaitiklio reikšmę - Rikiuoti pagal abėcėlę - Rikiuoti pagal publikavimo datą - Rikiuoti pagal perklausytų epizodų skaičių - Neperklausytų epizodų skaičius - Atsisiųstų epizodų skaičius - Nieko + Rikiuoti pagal abėcėlę + Rikiuoti pagal publikavimo datą + Rikiuoti pagal perklausytų epizodų skaičių + Neperklausytų epizodų skaičius + Atsisiųstų epizodų skaičius Nerasta suderinamų programėlių Eksportuoti išsamų žurnalą diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 90bec733..ebf89aca 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -55,15 +55,13 @@ Åpne menyen Lukk menyen Skuff-innstillinger - Sorter på teller - Sorter alfabetisk - Sorter etter utgivelsesdato - Sorter etter antall avspilte episoder + Sorter alfabetisk + Sorter etter utgivelsesdato + Sorter etter antall avspilte episoder - Antall uavspilte episoder - Antall nedlastede episoder - Antall of nedlastede og uavspilte episoder - Ingen + Antall uavspilte episoder + Antall nedlastede episoder + Antall of nedlastede og uavspilte episoder Fant ingen kompatible apper Eksport detaljert logfiler diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 5140c1e1..20fb3956 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -61,15 +61,13 @@ Menu openen Menu sluiten Menu instellen - Op ingestelde teller - Op alfabetische volgorde - Op verschijningsdatum - Op aantal afgespeelde afleveringen + Op alfabetische volgorde + Op verschijningsdatum + Op aantal afgespeelde afleveringen - Aantal niet afgespeelde afleveringen - Aantal gedownloade afleveringen - Aantal gedownloade, onbeluisterde afleveringen - Geen + Aantal niet afgespeelde afleveringen + Aantal gedownloade afleveringen + Aantal gedownloade, onbeluisterde afleveringen Geen compatibele apps aangetroffen Uitgebreide logboeken exporteren diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index de392c3a..d25011e3 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -59,15 +59,13 @@ Otwórz menu Zamknij menu Ustawienia panelu nawigacyjnego - Sortuj wg licznika - Sortuj alfabetycznie - Sortuj wg daty publikacji - Sortuj wg liczby odtworzonych odcinków + Sortuj alfabetycznie + Sortuj wg daty publikacji + Sortuj wg liczby odtworzonych odcinków - Liczba nieodtworzonych odcinków - Liczba pobranych odcinków - Liczba pobranych i nieodtworzonych odcinków - Brak + Liczba nieodtworzonych odcinków + Liczba pobranych odcinków + Liczba pobranych i nieodtworzonych odcinków Nie znaleziono kompatybilnych aplikacji Eksportuj szczegółowe logi diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index ab831b3d..97a21d04 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -58,15 +58,13 @@ Abrir menu Fechar menu Menu de navegação - Ordenar por contador - Ordenar alfabeticamente - Ordenar por data de publicação - Ordenar pelo número de episódios reproduzidos + Ordenar alfabeticamente + Ordenar por data de publicação + Ordenar pelo número de episódios reproduzidos - Número de episódios não reproduzidos - Número de episódios baixados - Número de episódios baixados e não reproduzidos - Nenhum + Número de episódios não reproduzidos + Número de episódios baixados + Número de episódios baixados e não reproduzidos Nenhum aplicativo compatível encontrado Exportar relatórios detalhados diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 837df6f5..640e13d8 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -60,15 +60,13 @@ Abrir menu Fechar menu Preferências do menu - Ordenar por contador - Ordenar alfabeticamente - Ordenar por data de publicação - Ordenar por número de episódios reproduzidos + Ordenar alfabeticamente + Ordenar por data de publicação + Ordenar por número de episódios reproduzidos - Número de episódios não reproduzidos - Número de episódios descarregados - Número de episódios descarregados e não reproduzidos - Nenhum + Número de episódios não reproduzidos + Número de episódios descarregados + Número de episódios descarregados e não reproduzidos Não existem aplicações compatíveis Exportar registos detalhados diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 347da703..d81f15f0 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -57,15 +57,13 @@ Deschide meniul Închide meniul Preferințe Sertar - Sortează după număr - Sortează alfabetic - Sortează după data publicării - Sortează după numărul de episoade urmărite + Sortează alfabetic + Sortează după data publicării + Sortează după numărul de episoade urmărite - Numărul de episoade neredate - Numărul de episoade descărcate - Numărul de episoade descărcate și neredate - Niciunul + Numărul de episoade neredate + Numărul de episoade descărcate + Numărul de episoade descărcate și neredate Nicio aplicație compatibilă nu a fost găsită Exportă log-uri detaliate diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index cf6e7771..84c2bd01 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -55,15 +55,13 @@ Открыть меню Закрыть меню Настройка бокового меню - По количеству - По алфавиту - По дате выхода - По количеству прослушанных + По алфавиту + По дате выхода + По количеству прослушанных - Количество непрослушанных выпусков - Количество загруженных выпусков - Количество загруженных и непрослушанных выпусков - Ничего + Количество непрослушанных выпусков + Количество загруженных выпусков + Количество загруженных и непрослушанных выпусков Совместимых приложений не найдено Экспортировать подробные журналы diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 1830a6c0..59427482 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -57,15 +57,13 @@ Otvoriť menu Zatvoriť menu Nastavenie navigačného panela - Usporiadať podľa počítadla - Usporiadať abecedne - Usporiadať podľa dátumu zverejnenia - Usporiadať podľa počtu prehraných epizód + Usporiadať abecedne + Usporiadať podľa dátumu zverejnenia + Usporiadať podľa počtu prehraných epizód - Počet neprehraných epizód - Počet stiahnutých epizód - Počet stiahnutých a neprehratých epizód - Žiadne + Počet neprehraných epizód + Počet stiahnutých epizód + Počet stiahnutých a neprehratých epizód Žiadne kompatibilné aplikácie Exportovať podrobné záznamy diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 0275b3c7..6d824807 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -35,13 +35,11 @@ Odpri meni Zapri meni - Razvrsti po števcu - Razvrsti po abecedi - Razvrsti po datumu objave - Razvrsti po številu predvajanih epizod - Število nepredvajanih epizod - Število prenesenih epizod - Nič + Razvrsti po abecedi + Razvrsti po datumu objave + Razvrsti po številu predvajanih epizod + Število nepredvajanih epizod + Število prenesenih epizod Ni bilo najdenih združljivih aplikacij Izvozi podrobne dnevnike diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 214e236b..9e4da7af 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -57,15 +57,13 @@ Öppna meny Stäng meny Menyinställningar - Sortera efter antal ospelade - Sortera alfabetiskt - Sortera efter publiceringsdatum - Sortera efter antal spelade episoder + Sortera alfabetiskt + Sortera efter publiceringsdatum + Sortera efter antal spelade episoder - Antal ospelade episoder - Antal nedladdade episoder - Antal nedladdade och ospelade avsnitt - Inga + Antal ospelade episoder + Antal nedladdade episoder + Antal nedladdade och ospelade avsnitt Hittade inga kompatibla appar Exportera detaljerade loggar diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 12144861..1efae463 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -60,15 +60,13 @@ Münüyü aç Menüyü kapat İzni reddettiniz. - Sayaca göre sırala - Alfabetik olarak sırala - Yayınlanma tarihine göre sırala - Oynatılan bölüm sayısına göre sırala + Alfabetik olarak sırala + Yayınlanma tarihine göre sırala + Oynatılan bölüm sayısına göre sırala - Çalınmamış bölümlerin sayısı - İndirilen bölümlerin sayısı - İndirilen ve oynatılmamış bölümlerin sayısı - Hiçbiri + Çalınmamış bölümlerin sayısı + İndirilen bölümlerin sayısı + İndirilen ve oynatılmamış bölümlerin sayısı Uyumlu uygulama bulunamadı Ayrıntılı günlükleri dışa aktar diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 2b4c75e4..1d57d798 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -57,15 +57,13 @@ Показати меню Сховати меню Налаштування шторки - Сортувати за лічильником - Сортувати за абеткою - Сортувати за датою публікації - Сортувати за кількістю прослуханих епізодів + Сортувати за абеткою + Сортувати за датою публікації + Сортувати за кількістю прослуханих епізодів - Кількість непрослуханих епізодів - Кількість завантажених епізодів - Кількість завантажених але не прослуханих епізодів - Немає + Кількість непрослуханих епізодів + Кількість завантажених епізодів + Кількість завантажених але не прослуханих епізодів Сумісних програм не знайдено Експорт детальних журналів diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 836aa98f..132c3cc0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -61,15 +61,13 @@ 打开菜单 关闭菜单 抽屉选项 - 按数量排序 - 按名称排序 - 按出版日期排序 - 根据已播放节目的数量排序 + 按名称排序 + 按出版日期排序 + 根据已播放节目的数量排序 - 未播曲目数 - 已下载节目数 - 已下载但未播放的节目数 - + 未播曲目数 + 已下载节目数 + 已下载但未播放的节目数 没有找到兼容的应用程序 导出详细日志 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 230f9503..bf0d47bd 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -34,13 +34,11 @@ 打開選單 關閉選單 - 按計數器排序 - 按字母排序 - 按發布日期排序 - 按已播放的集數排序 - 未播放集數 - 已下載集數 - 沒有 + 按字母排序 + 按發布日期排序 + 按已播放的集數排序 + 未播放集數 + 已下載集數 找不到相容的 App 匯出詳細記錄 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 1fa1e9d0..1044b51c 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -188,38 +188,25 @@ 3 - - @string/drawer_feed_order_unplayed - @string/drawer_feed_order_alphabetical - @string/drawer_feed_order_last_update - @string/drawer_feed_order_last_unread_update - @string/drawer_feed_order_most_played - @string/drawer_feed_counter_downloaded - @string/drawer_feed_counter_downloaded_unplayed - @string/drawer_feed_order_new_episodes - - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - - - - - - - + + + + + + + + + - + + + + - + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6b81c760..18d2e2f0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -78,17 +78,15 @@ Open menu Close menu Drawer preferences - Counter - Title - Publication date - Unread publication date - Number of played episodes - Number of new episodes - Number of unplayed episodes - Number of downloaded episodes - Number of downloaded and unplayed episodes - None + Title + Publish date + Unplayed publish date + Played count + New count + Unplayed count + Download count + Unplayed download count No compatible apps found diff --git a/app/src/test/kotlin/ac/mdiq/podcini/feed/FeedTest.kt b/app/src/test/kotlin/ac/mdiq/podcini/feed/FeedTest.kt index 912932b0..03dc906e 100644 --- a/app/src/test/kotlin/ac/mdiq/podcini/feed/FeedTest.kt +++ b/app/src/test/kotlin/ac/mdiq/podcini/feed/FeedTest.kt @@ -2,7 +2,7 @@ package ac.mdiq.podcini.feed import ac.mdiq.podcini.feed.FeedMother.anyFeed import ac.mdiq.podcini.storage.model.Feed -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import junit.framework.TestCase.assertEquals import org.junit.Assert import org.junit.Before @@ -67,8 +67,8 @@ class FeedTest { @Test @Throws(Exception::class) fun testSetSortOrder_OnlyIntraFeedSortAllowed() { - for (sortOrder in SortOrder.entries) { - if (sortOrder.scope == SortOrder.Scope.INTRA_FEED) { + for (sortOrder in EpisodeSortOrder.entries) { + if (sortOrder.scope == EpisodeSortOrder.Scope.INTRA_FEED) { original!!.sortOrder = sortOrder // should be okay } else { try { diff --git a/app/src/test/kotlin/ac/mdiq/podcini/storage/DbReaderTest.kt b/app/src/test/kotlin/ac/mdiq/podcini/storage/DbReaderTest.kt index 216fd69d..6a97565a 100644 --- a/app/src/test/kotlin/ac/mdiq/podcini/storage/DbReaderTest.kt +++ b/app/src/test/kotlin/ac/mdiq/podcini/storage/DbReaderTest.kt @@ -10,7 +10,7 @@ import ac.mdiq.podcini.storage.database.Feeds.getFeedListDownloadUrls import ac.mdiq.podcini.storage.database.Queues.getInQueueEpisodeIds import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeFilter -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.fragment.HistoryFragment.Companion.getHistory import ac.mdiq.podcini.ui.fragment.HistoryFragment.Companion.getNumberOfCompleted import ac.mdiq.podcini.ui.fragment.NavDrawerFragment.Companion.getDatasetStats @@ -223,7 +223,7 @@ class DbReaderTest { fun testGetDownloadedItems() { val numItems = 10 val downloaded = saveDownloadedItems(numItems) - val downloadedSaved = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), SortOrder.DATE_NEW_OLD) + val downloadedSaved = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.DOWNLOADED), EpisodeSortOrder.DATE_NEW_OLD) Assert.assertNotNull(downloadedSaved) Assert.assertEquals(downloaded.size.toLong(), downloadedSaved.size.toLong()) for (item in downloadedSaved) { @@ -266,7 +266,7 @@ class DbReaderTest { for (i in newItems.indices) { unreadIds[i] = newItems[i].id } - val newItemsSaved = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.NEW), SortOrder.DATE_NEW_OLD) + val newItemsSaved = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.NEW), EpisodeSortOrder.DATE_NEW_OLD) Assert.assertNotNull(newItemsSaved) Assert.assertEquals(newItemsSaved.size.toLong(), newItems.size.toLong()) for (feedItem in newItemsSaved) { diff --git a/app/src/test/kotlin/ac/mdiq/podcini/util/EpisodePermutorsTest.kt b/app/src/test/kotlin/ac/mdiq/podcini/util/EpisodePermutorsTest.kt index 0e05980d..18791cfe 100644 --- a/app/src/test/kotlin/ac/mdiq/podcini/util/EpisodePermutorsTest.kt +++ b/app/src/test/kotlin/ac/mdiq/podcini/util/EpisodePermutorsTest.kt @@ -4,7 +4,7 @@ import ac.mdiq.podcini.util.sorting.EpisodesPermutors.getPermutor import ac.mdiq.podcini.storage.model.Feed import ac.mdiq.podcini.storage.model.Episode import ac.mdiq.podcini.storage.model.EpisodeMedia -import ac.mdiq.podcini.storage.model.SortOrder +import ac.mdiq.podcini.storage.model.EpisodeSortOrder import org.junit.Assert import org.junit.Test import java.util.* @@ -15,7 +15,7 @@ import java.util.* class EpisodePermutorsTest { @Test fun testEnsureNonNullPermutors() { - for (sortOrder in SortOrder.entries) { + for (sortOrder in EpisodeSortOrder.entries) { Assert.assertNotNull("The permutor for SortOrder $sortOrder is unexpectedly null", getPermutor(sortOrder)) } @@ -23,7 +23,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_EPISODE_TITLE_ASC() { - val permutor = getPermutor(SortOrder.EPISODE_TITLE_A_Z) + val permutor = getPermutor(EpisodeSortOrder.EPISODE_TITLE_A_Z) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -33,7 +33,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_EPISODE_TITLE_ASC_NullTitle() { - val permutor = getPermutor(SortOrder.EPISODE_TITLE_A_Z) + val permutor = getPermutor(EpisodeSortOrder.EPISODE_TITLE_A_Z) val itemList = testList.toMutableList() itemList[2].title = (null) @@ -45,7 +45,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_EPISODE_TITLE_DESC() { - val permutor = getPermutor(SortOrder.EPISODE_TITLE_Z_A) + val permutor = getPermutor(EpisodeSortOrder.EPISODE_TITLE_Z_A) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -55,7 +55,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_DATE_ASC() { - val permutor = getPermutor(SortOrder.DATE_OLD_NEW) + val permutor = getPermutor(EpisodeSortOrder.DATE_OLD_NEW) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -65,7 +65,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_DATE_ASC_NulPubDatel() { - val permutor = getPermutor(SortOrder.DATE_OLD_NEW) + val permutor = getPermutor(EpisodeSortOrder.DATE_OLD_NEW) val itemList = testList itemList[2] // itemId 2 @@ -77,7 +77,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_DATE_DESC() { - val permutor = getPermutor(SortOrder.DATE_NEW_OLD) + val permutor = getPermutor(EpisodeSortOrder.DATE_NEW_OLD) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -87,7 +87,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_DURATION_ASC() { - val permutor = getPermutor(SortOrder.DURATION_SHORT_LONG) + val permutor = getPermutor(EpisodeSortOrder.DURATION_SHORT_LONG) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -97,7 +97,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_DURATION_DESC() { - val permutor = getPermutor(SortOrder.DURATION_LONG_SHORT) + val permutor = getPermutor(EpisodeSortOrder.DURATION_LONG_SHORT) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -107,7 +107,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_size_asc() { - val permutor = getPermutor(SortOrder.SIZE_SMALL_LARGE) + val permutor = getPermutor(EpisodeSortOrder.SIZE_SMALL_LARGE) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -117,7 +117,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_size_desc() { - val permutor = getPermutor(SortOrder.SIZE_LARGE_SMALL) + val permutor = getPermutor(EpisodeSortOrder.SIZE_LARGE_SMALL) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -127,7 +127,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_DURATION_DESC_NullMedia() { - val permutor = getPermutor(SortOrder.DURATION_LONG_SHORT) + val permutor = getPermutor(EpisodeSortOrder.DURATION_LONG_SHORT) val itemList = testList itemList[1] // itemId 3 @@ -139,7 +139,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_FEED_TITLE_ASC() { - val permutor = getPermutor(SortOrder.FEED_TITLE_A_Z) + val permutor = getPermutor(EpisodeSortOrder.FEED_TITLE_A_Z) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -149,7 +149,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_FEED_TITLE_DESC() { - val permutor = getPermutor(SortOrder.FEED_TITLE_Z_A) + val permutor = getPermutor(EpisodeSortOrder.FEED_TITLE_Z_A) val itemList = testList Assert.assertTrue(checkIdOrder(itemList, 1, 3, 2)) // before sorting @@ -159,7 +159,7 @@ class EpisodePermutorsTest { @Test fun testPermutorForRule_FEED_TITLE_DESC_NullTitle() { - val permutor = getPermutor(SortOrder.FEED_TITLE_Z_A) + val permutor = getPermutor(EpisodeSortOrder.FEED_TITLE_Z_A) val itemList = testList itemList[1].feed!!.title = (null) diff --git a/changelog.md b/changelog.md index e8f2fbcd..5aecc5a1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,10 @@ +## 6.0.7 + +* feeds sorting is bi-directional and in the same style as episodes sorting +* feed order names changed in English (other languages need update) +* date of new episode is highlighted in episodes list views +* fixed issue of tags not being properly handled + ## 6.0.6 * minor class re-structuring diff --git a/fastlane/metadata/android/en-US/changelogs/3020207.txt b/fastlane/metadata/android/en-US/changelogs/3020207.txt new file mode 100644 index 00000000..8817aa66 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/3020207.txt @@ -0,0 +1,7 @@ + +Version 6.0.7 brings several changes: + +* feeds sorting is bi-directional and in the same style as episodes sorting +* feed order names changed in English (other languages need update) +* date of new episode is highlighted in episodes list views +* fixed issue of tags not being properly handled