6.6.1 commit

This commit is contained in:
Xilin Jia 2024-09-13 23:34:06 +01:00
parent 7a1f2feac2
commit efd51ed6e1
14 changed files with 105 additions and 64 deletions

View File

@ -31,8 +31,8 @@ android {
testApplicationId "ac.mdiq.podcini.tests" testApplicationId "ac.mdiq.podcini.tests"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
versionCode 3020245 versionCode 3020246
versionName "6.6.0" versionName "6.6.1"
applicationId "ac.mdiq.podcini.R" applicationId "ac.mdiq.podcini.R"
def commit = "" def commit = ""

View File

@ -32,6 +32,7 @@ import ac.mdiq.podcini.preferences.UserPreferences
import ac.mdiq.podcini.preferences.UserPreferences.appPrefs import ac.mdiq.podcini.preferences.UserPreferences.appPrefs
import ac.mdiq.podcini.preferences.UserPreferences.fastForwardSecs import ac.mdiq.podcini.preferences.UserPreferences.fastForwardSecs
import ac.mdiq.podcini.preferences.UserPreferences.isSkipSilence import ac.mdiq.podcini.preferences.UserPreferences.isSkipSilence
import ac.mdiq.podcini.preferences.UserPreferences.prefLowQualityMedia
import ac.mdiq.podcini.preferences.UserPreferences.rewindSecs import ac.mdiq.podcini.preferences.UserPreferences.rewindSecs
import ac.mdiq.podcini.receiver.MediaButtonReceiver import ac.mdiq.podcini.receiver.MediaButtonReceiver
import ac.mdiq.podcini.storage.database.Episodes.addToHistory import ac.mdiq.podcini.storage.database.Episodes.addToHistory
@ -1432,7 +1433,7 @@ class PlaybackService : MediaLibraryService() {
val streamInfo = StreamInfo.getInfo(vService, url) val streamInfo = StreamInfo.getInfo(vService, url)
val audioStreamsList = getFilteredAudioStreams(streamInfo.audioStreams) val audioStreamsList = getFilteredAudioStreams(streamInfo.audioStreams)
Logd(TAG, "setDataSource1 audioStreamsList ${audioStreamsList.size}") Logd(TAG, "setDataSource1 audioStreamsList ${audioStreamsList.size}")
val audioIndex = if (isNetworkRestricted) 0 else audioStreamsList.size - 1 val audioIndex = if (isNetworkRestricted && prefLowQualityMedia) 0 else audioStreamsList.size - 1
val audioStream = audioStreamsList[audioIndex] val audioStream = audioStreamsList[audioIndex]
Logd(TAG, "setDataSource1 use audio quality: ${audioStream.bitrate}") Logd(TAG, "setDataSource1 use audio quality: ${audioStream.bitrate}")
val aSource = DefaultMediaSourceFactory(context).createMediaSource( val aSource = DefaultMediaSourceFactory(context).createMediaSource(

View File

@ -197,6 +197,12 @@ object UserPreferences {
appPrefs.edit().putBoolean(Prefs.prefStreamOverDownload.name, stream).apply() appPrefs.edit().putBoolean(Prefs.prefStreamOverDownload.name, stream).apply()
} }
var prefLowQualityMedia: Boolean
get() = appPrefs.getBoolean(Prefs.prefLowQualityOnMobile.name, false)
set(stream) {
appPrefs.edit().putBoolean(Prefs.prefLowQualityOnMobile.name, stream).apply()
}
/** /**
* Sets up the UserPreferences class. * Sets up the UserPreferences class.
* @throws IllegalArgumentException if context is null * @throws IllegalArgumentException if context is null
@ -324,6 +330,7 @@ object UserPreferences {
prefPauseForFocusLoss, prefPauseForFocusLoss,
prefPlaybackTimeRespectsSpeed, prefPlaybackTimeRespectsSpeed,
prefStreamOverDownload, prefStreamOverDownload,
prefLowQualityOnMobile,
prefSpeedforwardSpeed, prefSpeedforwardSpeed,
// Network // Network

View File

@ -1,6 +1,5 @@
package ac.mdiq.podcini.storage.database package ac.mdiq.podcini.storage.database
import ac.mdiq.podcini.BuildConfig
import ac.mdiq.podcini.net.download.DownloadError import ac.mdiq.podcini.net.download.DownloadError
import ac.mdiq.podcini.net.sync.model.EpisodeAction import ac.mdiq.podcini.net.sync.model.EpisodeAction
import ac.mdiq.podcini.net.sync.queue.SynchronizationQueueSink import ac.mdiq.podcini.net.sync.queue.SynchronizationQueueSink
@ -20,18 +19,20 @@ import ac.mdiq.podcini.storage.database.RealmDB.upsertBlk
import ac.mdiq.podcini.storage.model.* import ac.mdiq.podcini.storage.model.*
import ac.mdiq.podcini.storage.model.FeedPreferences.AutoDeleteAction import ac.mdiq.podcini.storage.model.FeedPreferences.AutoDeleteAction
import ac.mdiq.podcini.storage.model.FeedPreferences.Companion.TAG_ROOT import ac.mdiq.podcini.storage.model.FeedPreferences.Companion.TAG_ROOT
import ac.mdiq.podcini.storage.model.VolumeAdaptionSetting
import ac.mdiq.podcini.storage.utils.FilesUtils.feedfilePath import ac.mdiq.podcini.storage.utils.FilesUtils.feedfilePath
import ac.mdiq.podcini.storage.utils.FilesUtils.getFeedfileName import ac.mdiq.podcini.storage.utils.FilesUtils.getFeedfileName
import ac.mdiq.podcini.util.Logd
import ac.mdiq.podcini.util.EventFlow import ac.mdiq.podcini.util.EventFlow
import ac.mdiq.podcini.util.FlowEvent import ac.mdiq.podcini.util.FlowEvent
import ac.mdiq.podcini.util.Logd
import android.app.backup.BackupManager import android.app.backup.BackupManager
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import io.realm.kotlin.ext.asFlow import io.realm.kotlin.ext.asFlow
import io.realm.kotlin.notifications.* import io.realm.kotlin.notifications.ResultsChange
import io.realm.kotlin.notifications.SingleQueryChange
import io.realm.kotlin.notifications.UpdatedObject
import io.realm.kotlin.notifications.UpdatedResults
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.io.File import java.io.File
import java.text.DateFormat import java.text.DateFormat
@ -241,7 +242,7 @@ object Feeds {
""".trimIndent())) """.trimIndent()))
continue continue
} }
var oldItem = EpisodeAssistant.searchEpisodeByIdentifyingValue(savedFeed.episodes, episode) var oldItem = searchEpisodeByIdentifyingValue(savedFeed.episodes, episode)
if (!newFeed.isLocalFeed && oldItem == null) { if (!newFeed.isLocalFeed && oldItem == null) {
oldItem = EpisodeAssistant.searchEpisodeGuessDuplicate(savedFeed.episodes, episode) oldItem = EpisodeAssistant.searchEpisodeGuessDuplicate(savedFeed.episodes, episode)
if (oldItem != null) { if (oldItem != null) {
@ -299,7 +300,7 @@ object Feeds {
val it = savedFeed.episodes.toMutableList().iterator() val it = savedFeed.episodes.toMutableList().iterator()
while (it.hasNext()) { while (it.hasNext()) {
val feedItem = it.next() val feedItem = it.next()
if (EpisodeAssistant.searchEpisodeByIdentifyingValue(newFeed.episodes, feedItem) == null) { if (searchEpisodeByIdentifyingValue(newFeed.episodes, feedItem) == null) {
unlistedItems.add(feedItem) unlistedItems.add(feedItem)
it.remove() it.remove()
} }
@ -442,15 +443,13 @@ object Feeds {
if (searchEpisodeByIdentifyingValue(feed.episodes, episode) != null) return if (searchEpisodeByIdentifyingValue(feed.episodes, episode) != null) return
Logd(TAG, "addToYoutubeSyndicate adding new episode: ${episode.title}") Logd(TAG, "addToYoutubeSyndicate adding new episode: ${episode.title}")
runOnIOScope { episode.feed = feed
episode.feed = feed episode.id = Feed.newId()
episode.id = Feed.newId() episode.feedId = feed.id
episode.feedId = feed.id episode.media?.id = episode.id
episode.media?.id = episode.id upsertBlk(episode) {}
upsert(episode) {} feed.episodes.add(episode)
feed.episodes.add(episode) upsertBlk(feed) {}
upsert(feed) {}
}
} }
/** /**

View File

@ -3,7 +3,6 @@ package ac.mdiq.podcini.ui.activity
import ac.mdiq.podcini.R import ac.mdiq.podcini.R
import ac.mdiq.podcini.storage.database.Episodes.episodeFromStreamInfo import ac.mdiq.podcini.storage.database.Episodes.episodeFromStreamInfo
import ac.mdiq.podcini.storage.database.Feeds.addToYoutubeSyndicate import ac.mdiq.podcini.storage.database.Feeds.addToYoutubeSyndicate
import ac.mdiq.podcini.storage.model.Episode
import ac.mdiq.podcini.ui.compose.CustomTheme import ac.mdiq.podcini.ui.compose.CustomTheme
import ac.mdiq.podcini.util.Logd import ac.mdiq.podcini.util.Logd
import ac.mdiq.vista.extractor.Vista import ac.mdiq.vista.extractor.Vista
@ -13,7 +12,6 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.ViewGroup
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.annotation.OptIn import androidx.annotation.OptIn
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -23,7 +21,6 @@ import androidx.compose.material.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
@ -32,14 +29,14 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.URLDecoder import java.net.URLDecoder
class ShareReceiverActivity : AppCompatActivity() { class ShareReceiverActivity : AppCompatActivity() {
var feedUrl: String? = null
@OptIn(UnstableApi::class) override fun onCreate(savedInstanceState: Bundle?) { @OptIn(UnstableApi::class) override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
var feedUrl: String? = null
when { when {
intent.hasExtra(ARG_FEEDURL) -> feedUrl = intent.getStringExtra(ARG_FEEDURL) intent.hasExtra(ARG_FEEDURL) -> feedUrl = intent.getStringExtra(ARG_FEEDURL)
intent.action == Intent.ACTION_SEND -> feedUrl = intent.getStringExtra(Intent.EXTRA_TEXT) intent.action == Intent.ACTION_SEND -> feedUrl = intent.getStringExtra(Intent.EXTRA_TEXT)
@ -50,7 +47,7 @@ class ShareReceiverActivity : AppCompatActivity() {
showNoPodcastFoundError() showNoPodcastFoundError()
return return
} }
if (!feedUrl.startsWith("http")) { if (!feedUrl!!.startsWith("http")) {
val uri = Uri.parse(feedUrl) val uri = Uri.parse(feedUrl)
val urlString = uri?.getQueryParameter("url") val urlString = uri?.getQueryParameter("url")
if (urlString != null) feedUrl = URLDecoder.decode(urlString, "UTF-8") if (urlString != null) feedUrl = URLDecoder.decode(urlString, "UTF-8")
@ -59,32 +56,26 @@ class ShareReceiverActivity : AppCompatActivity() {
when { when {
// plain text // plain text
feedUrl!!.matches(Regex("^[^\\s<>/]+\$")) -> { feedUrl!!.matches(Regex("^[^\\s<>/]+\$")) -> {
val intent = MainActivity.showOnlineSearch(this, feedUrl) val intent = MainActivity.showOnlineSearch(this, feedUrl!!)
startActivity(intent) startActivity(intent)
finish() finish()
} }
// Youtube media // Youtube media
feedUrl.startsWith("https://youtube.com/watch?") -> { feedUrl!!.startsWith("https://youtube.com/watch?") -> {
Logd(TAG, "got youtube media") Logd(TAG, "got youtube media")
CoroutineScope(Dispatchers.IO).launch { setContent {
val info = StreamInfo.getInfo(Vista.getService(0), feedUrl) val showDialog = remember { mutableStateOf(true) }
Logd(TAG, "info: $info") CustomTheme(this@ShareReceiverActivity) {
val episode = episodeFromStreamInfo(info) confirmAddEpisode(showDialog.value, onDismissRequest = {
Logd(TAG, "episode: $episode") showDialog.value = false
withContext(Dispatchers.Main) { finish()
setContent { })
val showDialog = remember { mutableStateOf(true) }
CustomTheme(this@ShareReceiverActivity) {
confirmAddEpisode(showDialog.value, episode, onDismissRequest = { showDialog.value = false })
}
}
} }
} }
} }
else -> { else -> {
Logd(TAG, "Activity was started with url $feedUrl") Logd(TAG, "Activity was started with url $feedUrl")
val intent = MainActivity.showOnlineFeed(this, feedUrl) val intent = MainActivity.showOnlineFeed(this, feedUrl!!)
// intent.putExtra(MainActivity.Extras.started_from_share.name, getIntent().getBooleanExtra(MainActivity.Extras.started_from_share.name, false)) // intent.putExtra(MainActivity.Extras.started_from_share.name, getIntent().getBooleanExtra(MainActivity.Extras.started_from_share.name, false))
startActivity(intent) startActivity(intent)
finish() finish()
@ -93,7 +84,7 @@ class ShareReceiverActivity : AppCompatActivity() {
} }
@Composable @Composable
fun confirmAddEpisode(showDialog: Boolean, episode: Episode, onDismissRequest: () -> Unit) { fun confirmAddEpisode(showDialog: Boolean, onDismissRequest: () -> Unit) {
if (showDialog) { if (showDialog) {
Dialog(onDismissRequest = { onDismissRequest() }) { Dialog(onDismissRequest = { onDismissRequest() }) {
Card( Card(
@ -106,11 +97,11 @@ class ShareReceiverActivity : AppCompatActivity() {
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.Center verticalArrangement = Arrangement.Center
) { ) {
var checked by remember { mutableStateOf(false) } var audioOnly by remember { mutableStateOf(false) }
Row(Modifier.fillMaxWidth()) { Row(Modifier.fillMaxWidth()) {
Checkbox(checked = checked, Checkbox(checked = audioOnly,
onCheckedChange = { onCheckedChange = {
checked = it audioOnly = it
} }
) )
Text( Text(
@ -119,8 +110,14 @@ class ShareReceiverActivity : AppCompatActivity() {
) )
} }
Button(onClick = { Button(onClick = {
addToYoutubeSyndicate(episode, !checked) CoroutineScope(Dispatchers.IO).launch {
finish() val info = StreamInfo.getInfo(Vista.getService(0), feedUrl!!)
Logd(TAG, "info: $info")
val episode = episodeFromStreamInfo(info)
Logd(TAG, "episode: $episode")
addToYoutubeSyndicate(episode, !audioOnly)
}
onDismissRequest()
}) { }) {
Text("Confirm") Text("Confirm")
} }

View File

@ -71,6 +71,8 @@ import java.util.concurrent.Semaphore
private lateinit var swipeActions: SwipeActions private lateinit var swipeActions: SwipeActions
private lateinit var nextPageLoader: MoreContentListFooterUtil private lateinit var nextPageLoader: MoreContentListFooterUtil
private var infoTextFiltered = ""
private var infoTextUpdate = ""
private var displayUpArrow = false private var displayUpArrow = false
private var headerCreated = false private var headerCreated = false
private var feedID: Long = 0 private var feedID: Long = 0
@ -155,6 +157,7 @@ import java.util.concurrent.Semaphore
}) })
binding.swipeRefresh.setDistanceToTriggerSync(resources.getInteger(R.integer.swipe_refresh_distance)) binding.swipeRefresh.setDistanceToTriggerSync(resources.getInteger(R.integer.swipe_refresh_distance))
binding.swipeRefresh.setProgressViewEndTarget(false, 0)
binding.swipeRefresh.setOnRefreshListener { binding.swipeRefresh.setOnRefreshListener {
FeedUpdateManager.runOnceOrAsk(requireContext(), feed) FeedUpdateManager.runOnceOrAsk(requireContext(), feed)
} }
@ -429,6 +432,8 @@ import java.util.concurrent.Semaphore
private fun onFeedUpdateRunningEvent(event: FlowEvent.FeedUpdatingEvent) { private fun onFeedUpdateRunningEvent(event: FlowEvent.FeedUpdatingEvent) {
nextPageLoader.setLoadingState(event.isRunning) nextPageLoader.setLoadingState(event.isRunning)
if (!event.isRunning) nextPageLoader.root.visibility = View.GONE if (!event.isRunning) nextPageLoader.root.visibility = View.GONE
infoTextUpdate = if (event.isRunning) getString(R.string.refreshing_label) else ""
binding.header.txtvInformation.text = ("{gmo-info} $infoTextFiltered $infoTextUpdate")
binding.swipeRefresh.isRefreshing = event.isRunning binding.swipeRefresh.isRefreshing = event.isRunning
} }
@ -454,18 +459,20 @@ import java.util.concurrent.Semaphore
binding.header.txtvTitle.text = feed!!.title binding.header.txtvTitle.text = feed!!.title
binding.header.txtvAuthor.text = feed!!.author binding.header.txtvAuthor.text = feed!!.author
binding.header.txtvInformation.setOnClickListener {}
infoTextFiltered = ""
if (!feed?.preferences?.filterString.isNullOrEmpty()) { if (!feed?.preferences?.filterString.isNullOrEmpty()) {
val filter: EpisodeFilter = feed!!.episodeFilter val filter: EpisodeFilter = feed!!.episodeFilter
if (filter.values.isNotEmpty()) { if (filter.values.isNotEmpty()) {
binding.header.txtvInformation.text = ("{gmo-info} " + this.getString(R.string.filtered_label)) infoTextFiltered = this.getString(R.string.filtered_label)
binding.header.txtvInformation.setOnClickListener { binding.header.txtvInformation.setOnClickListener {
val dialog = FeedEpisodeFilterDialog(feed) val dialog = FeedEpisodeFilterDialog(feed)
dialog.filter = feed!!.episodeFilter dialog.filter = feed!!.episodeFilter
dialog.show(childFragmentManager, null) dialog.show(childFragmentManager, null)
} }
binding.header.txtvInformation.visibility = View.VISIBLE }
} else binding.header.txtvInformation.visibility = View.GONE }
} else binding.header.txtvInformation.visibility = View.GONE binding.header.txtvInformation.text = ("{gmo-info} $infoTextFiltered $infoTextUpdate")
} }
@UnstableApi private fun setupHeaderView() { @UnstableApi private fun setupHeaderView() {

View File

@ -110,6 +110,8 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
private lateinit var catAdapter: ArrayAdapter<String> private lateinit var catAdapter: ArrayAdapter<String>
private var infoTextFiltered = ""
private var infoTextUpdate = ""
private var tagFilterIndex = 1 private var tagFilterIndex = 1
// TODO: currently not used // TODO: currently not used
private var displayedFolder: String = "" private var displayedFolder: String = ""
@ -187,7 +189,8 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
} else false } else false
} }
binding.progressBar.visibility = View.VISIBLE // binding.progressBar.visibility = View.VISIBLE
binding.progressBar.visibility = View.GONE
val subscriptionAddButton: FloatingActionButton = binding.subscriptionsAdd val subscriptionAddButton: FloatingActionButton = binding.subscriptionsAdd
subscriptionAddButton.setOnClickListener { subscriptionAddButton.setOnClickListener {
@ -218,8 +221,10 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
private fun setSwipeRefresh() { private fun setSwipeRefresh() {
if (swipeToRefresh) { if (swipeToRefresh) {
binding.swipeRefresh.isEnabled = true binding.swipeRefresh.isEnabled = true
binding.swipeRefresh.setProgressViewEndTarget(false, 0)
binding.swipeRefresh.setDistanceToTriggerSync(resources.getInteger(R.integer.swipe_refresh_distance)) binding.swipeRefresh.setDistanceToTriggerSync(resources.getInteger(R.integer.swipe_refresh_distance))
binding.swipeRefresh.setOnRefreshListener { binding.swipeRefresh.setOnRefreshListener {
Logd(TAG, "running FeedUpdateManager")
FeedUpdateManager.runOnceOrAsk(requireContext()) FeedUpdateManager.runOnceOrAsk(requireContext())
} }
} else binding.swipeRefresh.isEnabled = false } else binding.swipeRefresh.isEnabled = false
@ -327,7 +332,9 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
when (event) { when (event) {
is FlowEvent.FeedUpdatingEvent -> { is FlowEvent.FeedUpdatingEvent -> {
Logd(TAG, "FeedUpdateRunningEvent: ${event.isRunning}") Logd(TAG, "FeedUpdateRunningEvent: ${event.isRunning}")
binding.swipeRefresh.isRefreshing = event.isRunning infoTextUpdate = if (event.isRunning) " " + this@SubscriptionsFragment.getString(R.string.refreshing_label) else ""
binding.txtvInformation.text = (infoTextFiltered + infoTextUpdate)
if (swipeToRefresh) binding.swipeRefresh.isRefreshing = event.isRunning
if (!event.isRunning && event.id != prevFeedUpdatingEvent?.id) loadSubscriptions() if (!event.isRunning && event.id != prevFeedUpdatingEvent?.id) loadSubscriptions()
prevFeedUpdatingEvent = event prevFeedUpdatingEvent = event
} }
@ -377,18 +384,20 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
// We have fewer items. This can result in items being selected that are no longer visible. // We have fewer items. This can result in items being selected that are no longer visible.
if (feedListFiltered.size > feedList.size) adapter.endSelectMode() if (feedListFiltered.size > feedList.size) adapter.endSelectMode()
filterOnTag() filterOnTag()
binding.progressBar.visibility = View.GONE // binding.progressBar.visibility = View.GONE
adapter.setItems(feedListFiltered) adapter.setItems(feedListFiltered)
binding.count.text = feedListFiltered.size.toString() + " / " + feedList.size.toString() binding.count.text = feedListFiltered.size.toString() + " / " + feedList.size.toString()
infoTextFiltered = " "
binding.txtvInformation.setOnClickListener {}
if (feedsFilter.isNotEmpty()) { if (feedsFilter.isNotEmpty()) {
val filter = FeedFilter(feedsFilter) val filter = FeedFilter(feedsFilter)
binding.txtvInformation.text = ("{gmo-info} " + getString(R.string.filtered_label)) infoTextFiltered = getString(R.string.filtered_label)
binding.txtvInformation.setOnClickListener { binding.txtvInformation.setOnClickListener {
val dialog = FeedFilterDialog.newInstance(filter) val dialog = FeedFilterDialog.newInstance(filter)
dialog.show(childFragmentManager, null) dialog.show(childFragmentManager, null)
} }
binding.txtvInformation.visibility = View.VISIBLE }
} else binding.txtvInformation.visibility = View.GONE binding.txtvInformation.text = (infoTextFiltered + infoTextUpdate)
emptyView.updateVisibility() emptyView.updateVisibility()
} }
} catch (e: Throwable) { Log.e(TAG, Log.getStackTraceString(e)) } catch (e: Throwable) { Log.e(TAG, Log.getStackTraceString(e))
@ -1187,7 +1196,7 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
} }
} }
fun onFilterChanged(newFilterValues: Set<String>) { private fun onFilterChanged(newFilterValues: Set<String>) {
feedsFilter = StringUtils.join(newFilterValues, ",") feedsFilter = StringUtils.join(newFilterValues, ",")
Logd(TAG, "onFilterChanged: $feedsFilter") Logd(TAG, "onFilterChanged: $feedsFilter")
EventFlow.postEvent(FlowEvent.FeedsFilterEvent(newFilterValues)) EventFlow.postEvent(FlowEvent.FeedsFilterEvent(newFilterValues))

View File

@ -187,7 +187,6 @@
android:padding="2dp" android:padding="2dp"
android:background="?android:attr/colorBackground" android:background="?android:attr/colorBackground"
android:foreground="?android:attr/selectableItemBackground" android:foreground="?android:attr/selectableItemBackground"
android:visibility="gone"
android:gravity="center" android:gravity="center"
android:textColor="?attr/colorAccent" android:textColor="?attr/colorAccent"
tools:visibility="visible" tools:visibility="visible"

View File

@ -50,7 +50,6 @@
android:padding="2dp" android:padding="2dp"
android:background="?android:attr/colorBackground" android:background="?android:attr/colorBackground"
android:foreground="?android:attr/selectableItemBackground" android:foreground="?android:attr/selectableItemBackground"
android:visibility="gone"
android:gravity="center" android:gravity="center"
android:textColor="?attr/colorAccent" android:textColor="?attr/colorAccent"
tools:visibility="visible" tools:visibility="visible"

View File

@ -119,6 +119,7 @@
<string name="error_label">Error</string> <string name="error_label">Error</string>
<string name="error_msg_prefix">An error occurred:</string> <string name="error_msg_prefix">An error occurred:</string>
<string name="refresh_label">Refresh</string> <string name="refresh_label">Refresh</string>
<string name="refreshing_label">Refreshing</string>
<string name="reconsile_label">Reconsile</string> <string name="reconsile_label">Reconsile</string>
<string name="chapters_label">Chapters</string> <string name="chapters_label">Chapters</string>
<string name="no_chapters_label">No chapters</string> <string name="no_chapters_label">No chapters</string>
@ -478,6 +479,8 @@
<string name="pref_audio_only_sum">Only play audio of a video media</string> <string name="pref_audio_only_sum">Only play audio of a video media</string>
<string name="pref_stream_over_download_title">Prefer streaming</string> <string name="pref_stream_over_download_title">Prefer streaming</string>
<string name="pref_stream_over_download_sum">Display stream button instead of download button in lists</string> <string name="pref_stream_over_download_sum">Display stream button instead of download button in lists</string>
<string name="pref_low_quality_on_mobile_title">Prefer low quality on mobile</string>
<string name="pref_low_quality_on_mobile_sum">On metered network, only low quality media (if available) is fetched</string>
<string name="pref_mobileUpdate_title">Mobile updates</string> <string name="pref_mobileUpdate_title">Mobile updates</string>
<string name="pref_mobileUpdate_sum">Select what should be allowed over the mobile data connection</string> <string name="pref_mobileUpdate_sum">Select what should be allowed over the mobile data connection</string>
<string name="pref_mobileUpdate_refresh">Podcast refresh</string> <string name="pref_mobileUpdate_refresh">Podcast refresh</string>

View File

@ -57,10 +57,15 @@
android:summary="@string/pref_speed_forward_sum" android:summary="@string/pref_speed_forward_sum"
android:title="@string/pref_speed_forward"/> android:title="@string/pref_speed_forward"/>
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="false"
android:key="prefStreamOverDownload" android:key="prefStreamOverDownload"
android:summary="@string/pref_stream_over_download_sum" android:summary="@string/pref_stream_over_download_sum"
android:title="@string/pref_stream_over_download_title"/> android:title="@string/pref_stream_over_download_title"/>
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="prefLowQualityOnMobile"
android:summary="@string/pref_low_quality_on_mobile_sum"
android:title="@string/pref_low_quality_on_mobile_title"/>
<Preference <Preference
android:title="@string/pref_playback_video_mode" android:title="@string/pref_playback_video_mode"
android:key="prefPlaybackVideoModeLauncher" android:key="prefPlaybackVideoModeLauncher"

View File

@ -1,3 +1,11 @@
# 6.6.1
* the confirm dialog is more responsive when receiving a youtube media share
* receiving a youtube media share can be dismissed by not pressing the confirm button
* in Subscriptions and FeedEpisodes views, swipe down to refresh no longer blocks UI, only shows "Refreshing" status on the info bar
* added preference "Prefer low quality on mobile" under Settings -> Playback -> Playback control, and default it to false,
* if set true, Youtube media will use low quality audio on mobile network (which has been the default way of handling)
# 6.6.0 # 6.6.0
* added ability to receive shared Youtube media, * added ability to receive shared Youtube media,

View File

@ -1,4 +1,4 @@
Version 6.5.10: Version 6.6.0:
* added ability to receive shared Youtube media, * added ability to receive shared Youtube media,
* once received, the user can choose to set it as "audio only" before confirm * once received, the user can choose to set it as "audio only" before confirm

View File

@ -0,0 +1,7 @@
Version 6.6.1:
* the confirm dialog is more responsive when receiving a youtube media share
* receiving a youtube media share can be dismissed by not pressing the confirm button
* in Subscriptions and FeedEpisodes views, swipe down to refresh no longer blocks UI, only shows "Refreshing" status on the info bar
* added preference "Prefer low quality on mobile" under Settings -> Playback -> Playback control, and default it to false,
* if set true, Youtube media will use low quality audio on mobile network (which has been the default way of handling)