6.12.2 commit
This commit is contained in:
parent
79c1bf43f9
commit
d3ca132b7c
|
@ -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 3020279
|
versionCode 3020280
|
||||||
versionName "6.12.1"
|
versionName "6.12.2"
|
||||||
|
|
||||||
applicationId "ac.mdiq.podcini.R"
|
applicationId "ac.mdiq.podcini.R"
|
||||||
def commit = ""
|
def commit = ""
|
||||||
|
|
|
@ -45,7 +45,7 @@ abstract class ServiceStatusHandler(private val activity: FragmentActivity) {
|
||||||
Logd(TAG, "statusUpdate onReceive doing updates")
|
Logd(TAG, "statusUpdate onReceive doing updates")
|
||||||
MediaPlayerBase.status = info.playerStatus
|
MediaPlayerBase.status = info.playerStatus
|
||||||
prevStatus = MediaPlayerBase.status
|
prevStatus = MediaPlayerBase.status
|
||||||
curMedia = info.playable
|
// curMedia = info.playable
|
||||||
handleStatus()
|
handleStatus()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -177,7 +177,7 @@ abstract class ServiceStatusHandler(private val activity: FragmentActivity) {
|
||||||
Logd(TAG, "Querying service info")
|
Logd(TAG, "Querying service info")
|
||||||
if (playbackService != null && PlaybackService.mPlayerInfo != null) {
|
if (playbackService != null && PlaybackService.mPlayerInfo != null) {
|
||||||
MediaPlayerBase.status = PlaybackService.mPlayerInfo!!.playerStatus
|
MediaPlayerBase.status = PlaybackService.mPlayerInfo!!.playerStatus
|
||||||
curMedia = PlaybackService.mPlayerInfo!!.playable
|
// curMedia = PlaybackService.mPlayerInfo!!.playable
|
||||||
// make sure that new media is loaded if it's available
|
// make sure that new media is loaded if it's available
|
||||||
mediaInfoLoaded = false
|
mediaInfoLoaded = false
|
||||||
handleStatus()
|
handleStatus()
|
||||||
|
|
|
@ -271,11 +271,13 @@ abstract class MediaPlayerBase protected constructor(protected val context: Cont
|
||||||
Log.d(TAG, "${this.javaClass.simpleName}: Setting player status to $newStatus")
|
Log.d(TAG, "${this.javaClass.simpleName}: Setting player status to $newStatus")
|
||||||
this.oldStatus = status
|
this.oldStatus = status
|
||||||
status = newStatus
|
status = newStatus
|
||||||
if (newMedia != null) setPlayable(newMedia)
|
if (newMedia != null) {
|
||||||
if (newMedia != null && newStatus != PlayerStatus.INDETERMINATE) {
|
setPlayable(newMedia)
|
||||||
when {
|
if (newStatus != PlayerStatus.INDETERMINATE) {
|
||||||
oldStatus == PlayerStatus.PLAYING && newStatus != PlayerStatus.PLAYING -> callback.onPlaybackPause(newMedia, position)
|
when {
|
||||||
oldStatus != PlayerStatus.PLAYING && newStatus == PlayerStatus.PLAYING -> callback.onPlaybackStart(newMedia, position)
|
oldStatus == PlayerStatus.PLAYING && newStatus != PlayerStatus.PLAYING -> callback.onPlaybackPause(newMedia, position)
|
||||||
|
oldStatus != PlayerStatus.PLAYING && newStatus == PlayerStatus.PLAYING -> callback.onPlaybackStart(newMedia, position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback.statusChanged(MediaPlayerInfo(oldStatus, status, curMedia))
|
callback.statusChanged(MediaPlayerInfo(oldStatus, status, curMedia))
|
||||||
|
|
|
@ -389,15 +389,23 @@ class PlaybackService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
|
// fun shouldSkipKeepEpisode(): Boolean {
|
||||||
|
// return appPrefs.getBoolean(UserPreferences.Prefs.prefSkipKeepsEpisode.name, true)
|
||||||
|
// }
|
||||||
|
// fun shouldFavoriteKeepEpisode(): Boolean {
|
||||||
|
// return appPrefs.getBoolean(UserPreferences.Prefs.prefFavoriteKeepsEpisode.name, true)
|
||||||
|
// }
|
||||||
runOnIOScope {
|
runOnIOScope {
|
||||||
if (ended || smartMarkAsPlayed || autoSkipped || (skipped && !shouldSkipKeepEpisode())) {
|
val shouldSkipKeepEpisode = appPrefs.getBoolean(UserPreferences.Prefs.prefSkipKeepsEpisode.name, true)
|
||||||
|
val shouldFavoriteKeepEpisode = appPrefs.getBoolean(UserPreferences.Prefs.prefFavoriteKeepsEpisode.name, true)
|
||||||
|
if (ended || smartMarkAsPlayed || autoSkipped || (skipped && !shouldSkipKeepEpisode)) {
|
||||||
Logd(TAG, "onPostPlayback ended: $ended smartMarkAsPlayed: $smartMarkAsPlayed autoSkipped: $autoSkipped skipped: $skipped")
|
Logd(TAG, "onPostPlayback ended: $ended smartMarkAsPlayed: $smartMarkAsPlayed autoSkipped: $autoSkipped skipped: $skipped")
|
||||||
// only mark the item as played if we're not keeping it anyways
|
// only mark the item as played if we're not keeping it anyways
|
||||||
item = setPlayStateSync(PlayState.PLAYED.code, ended || (skipped && smartMarkAsPlayed), item!!)
|
item = setPlayStateSync(PlayState.PLAYED.code, ended || (skipped && smartMarkAsPlayed), item!!)
|
||||||
val action = item?.feed?.preferences?.autoDeleteAction
|
val action = item?.feed?.preferences?.autoDeleteAction
|
||||||
val shouldAutoDelete = (action == AutoDeleteAction.ALWAYS ||
|
val shouldAutoDelete = (action == AutoDeleteAction.ALWAYS ||
|
||||||
(action == AutoDeleteAction.GLOBAL && item?.feed != null && shouldAutoDeleteItem(item!!.feed!!)))
|
(action == AutoDeleteAction.GLOBAL && item?.feed != null && shouldAutoDeleteItem(item!!.feed!!)))
|
||||||
if (playable is EpisodeMedia && shouldAutoDelete && (item?.isFavorite != true || !shouldFavoriteKeepEpisode())) {
|
if (playable is EpisodeMedia && shouldAutoDelete && (item?.isFavorite != true || !shouldFavoriteKeepEpisode)) {
|
||||||
item = deleteMediaSync(this@PlaybackService, item!!)
|
item = deleteMediaSync(this@PlaybackService, item!!)
|
||||||
if (shouldDeleteRemoveFromQueue()) removeFromQueueSync(null, item!!)
|
if (shouldDeleteRemoveFromQueue()) removeFromQueueSync(null, item!!)
|
||||||
}
|
}
|
||||||
|
@ -407,14 +415,6 @@ class PlaybackService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shouldSkipKeepEpisode(): Boolean {
|
|
||||||
return appPrefs.getBoolean(UserPreferences.Prefs.prefSkipKeepsEpisode.name, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun shouldFavoriteKeepEpisode(): Boolean {
|
|
||||||
return appPrefs.getBoolean(UserPreferences.Prefs.prefFavoriteKeepsEpisode.name, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPlaybackStart(playable: Playable, position: Int) {
|
override fun onPlaybackStart(playable: Playable, position: Int) {
|
||||||
Logd(TAG, "onPlaybackStart position: $position")
|
Logd(TAG, "onPlaybackStart position: $position")
|
||||||
taskManager.startWidgetUpdater()
|
taskManager.startWidgetUpdater()
|
||||||
|
@ -747,12 +747,10 @@ class PlaybackService : MediaLibraryService() {
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
Logd(TAG, "Service is about to be destroyed")
|
Logd(TAG, "Service is about to be destroyed")
|
||||||
|
|
||||||
playbackService = null
|
playbackService = null
|
||||||
isRunning = false
|
isRunning = false
|
||||||
currentMediaType = MediaType.UNKNOWN
|
currentMediaType = MediaType.UNKNOWN
|
||||||
castStateListener.destroy()
|
castStateListener.destroy()
|
||||||
|
|
||||||
currentitem = null
|
currentitem = null
|
||||||
|
|
||||||
LocalMediaPlayer.cleanup()
|
LocalMediaPlayer.cleanup()
|
||||||
|
@ -1967,8 +1965,8 @@ class PlaybackService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||||
// val stat = if (isPlaying) PlayerStatus.PLAYING else PlayerStatus.PAUSED
|
// val stat = if (isPlaying) PlayerStatus.PLAYING else PlayerStatus.PAUSED
|
||||||
// TODO: test
|
// TODO: test: changing PAUSED to STOPPED or INDETERMINATE makes resume not possible if interrupted
|
||||||
val stat = if (isPlaying) PlayerStatus.PLAYING else PlayerStatus.INDETERMINATE
|
val stat = if (isPlaying) PlayerStatus.PLAYING else PlayerStatus.PAUSED
|
||||||
setPlayerStatus(stat, curMedia)
|
setPlayerStatus(stat, curMedia)
|
||||||
Logd(TAG, "onIsPlayingChanged $isPlaying")
|
Logd(TAG, "onIsPlayingChanged $isPlaying")
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ class EpisodeFilter(vararg properties: String) : Serializable {
|
||||||
val showNotAutoDownloadable: Boolean = hasProperty(States.not_auto_downloadable.name)
|
val showNotAutoDownloadable: Boolean = hasProperty(States.not_auto_downloadable.name)
|
||||||
val showHasMedia: Boolean = hasProperty(States.has_media.name)
|
val showHasMedia: Boolean = hasProperty(States.has_media.name)
|
||||||
val showNoMedia: Boolean = hasProperty(States.no_media.name)
|
val showNoMedia: Boolean = hasProperty(States.no_media.name)
|
||||||
|
val showHasComments: Boolean = hasProperty(States.has_comments.name)
|
||||||
|
val showNoComments: Boolean = hasProperty(States.no_comments.name)
|
||||||
val showIsFavorite: Boolean = hasProperty(States.is_favorite.name)
|
val showIsFavorite: Boolean = hasProperty(States.is_favorite.name)
|
||||||
val showNotFavorite: Boolean = hasProperty(States.not_favorite.name)
|
val showNotFavorite: Boolean = hasProperty(States.not_favorite.name)
|
||||||
|
|
||||||
|
@ -48,6 +50,8 @@ class EpisodeFilter(vararg properties: String) : Serializable {
|
||||||
showNotAutoDownloadable && item.isAutoDownloadEnabled -> return false
|
showNotAutoDownloadable && item.isAutoDownloadEnabled -> return false
|
||||||
showHasMedia && item.media == null -> return false
|
showHasMedia && item.media == null -> return false
|
||||||
showNoMedia && item.media != null -> return false
|
showNoMedia && item.media != null -> return false
|
||||||
|
showHasComments && item.comment.isEmpty() -> return false
|
||||||
|
showNoComments && item.comment.isNotEmpty() -> return false
|
||||||
showIsFavorite && !item.isFavorite -> return false
|
showIsFavorite && !item.isFavorite -> return false
|
||||||
showNotFavorite && item.isFavorite -> return false
|
showNotFavorite && item.isFavorite -> return false
|
||||||
showQueued && !inAnyQueue(item) -> return false
|
showQueued && !inAnyQueue(item) -> return false
|
||||||
|
@ -69,7 +73,7 @@ class EpisodeFilter(vararg properties: String) : Serializable {
|
||||||
val statements: MutableList<String> = ArrayList()
|
val statements: MutableList<String> = ArrayList()
|
||||||
when {
|
when {
|
||||||
showPlayed -> statements.add("playState >= ${PlayState.PLAYED.code}")
|
showPlayed -> statements.add("playState >= ${PlayState.PLAYED.code}")
|
||||||
showUnplayed -> statements.add(" playState < ${PlayState.PLAYED.code}> ") // Match "New" items (read = -1) as well
|
showUnplayed -> statements.add(" playState < ${PlayState.PLAYED.code} ") // Match "New" items (read = -1) as well
|
||||||
showNew -> statements.add("playState == -1 ")
|
showNew -> statements.add("playState == -1 ")
|
||||||
}
|
}
|
||||||
when {
|
when {
|
||||||
|
@ -93,8 +97,12 @@ class EpisodeFilter(vararg properties: String) : Serializable {
|
||||||
showNoMedia -> statements.add("media == nil ")
|
showNoMedia -> statements.add("media == nil ")
|
||||||
}
|
}
|
||||||
when {
|
when {
|
||||||
showIsFavorite -> statements.add("isFavorite == true ")
|
showHasComments -> statements.add(" comment != '' ")
|
||||||
showNotFavorite -> statements.add("isFavorite == false ")
|
showNoComments -> statements.add(" comment == '' ")
|
||||||
|
}
|
||||||
|
when {
|
||||||
|
showIsFavorite -> statements.add("rating == ${Rating.FAVORITE.code} ")
|
||||||
|
showNotFavorite -> statements.add("rating != ${Rating.FAVORITE.code} ")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statements.isEmpty()) return "id > 0"
|
if (statements.isEmpty()) return "id > 0"
|
||||||
|
@ -120,6 +128,8 @@ class EpisodeFilter(vararg properties: String) : Serializable {
|
||||||
not_favorite,
|
not_favorite,
|
||||||
has_media,
|
has_media,
|
||||||
no_media,
|
no_media,
|
||||||
|
has_comments,
|
||||||
|
no_comments,
|
||||||
queued,
|
queued,
|
||||||
not_queued,
|
not_queued,
|
||||||
downloaded,
|
downloaded,
|
||||||
|
|
|
@ -11,6 +11,8 @@ class FeedFilter(vararg properties: String) : Serializable {
|
||||||
val showNotKeepUpdated: Boolean = hasProperty(States.not_keepUpdated.name)
|
val showNotKeepUpdated: Boolean = hasProperty(States.not_keepUpdated.name)
|
||||||
val showGlobalPlaySpeed: Boolean = hasProperty(States.global_playSpeed.name)
|
val showGlobalPlaySpeed: Boolean = hasProperty(States.global_playSpeed.name)
|
||||||
val showCustomPlaySpeed: Boolean = hasProperty(States.custom_playSpeed.name)
|
val showCustomPlaySpeed: Boolean = hasProperty(States.custom_playSpeed.name)
|
||||||
|
val showHasComments: Boolean = hasProperty(States.has_comments.name)
|
||||||
|
val showNoComments: Boolean = hasProperty(States.no_comments.name)
|
||||||
val showHasSkips: Boolean = hasProperty(States.has_skips.name)
|
val showHasSkips: Boolean = hasProperty(States.has_skips.name)
|
||||||
val showNoSkips: Boolean = hasProperty(States.no_skips.name)
|
val showNoSkips: Boolean = hasProperty(States.no_skips.name)
|
||||||
val showAlwaysAutoDelete: Boolean = hasProperty(States.always_auto_delete.name)
|
val showAlwaysAutoDelete: Boolean = hasProperty(States.always_auto_delete.name)
|
||||||
|
@ -36,6 +38,8 @@ class FeedFilter(vararg properties: String) : Serializable {
|
||||||
showNotKeepUpdated && feed.preferences?.keepUpdated != false -> return false
|
showNotKeepUpdated && feed.preferences?.keepUpdated != false -> return false
|
||||||
showGlobalPlaySpeed && feed.preferences?.playSpeed != SPEED_USE_GLOBAL -> return false
|
showGlobalPlaySpeed && feed.preferences?.playSpeed != SPEED_USE_GLOBAL -> return false
|
||||||
showCustomPlaySpeed && feed.preferences?.playSpeed == SPEED_USE_GLOBAL -> return false
|
showCustomPlaySpeed && feed.preferences?.playSpeed == SPEED_USE_GLOBAL -> return false
|
||||||
|
showHasComments && feed.comment.isEmpty() -> return false
|
||||||
|
showNoComments && feed.comment.isEmpty() -> return false
|
||||||
showHasSkips && feed.preferences?.introSkip == 0 && feed.preferences?.endingSkip == 0 -> return false
|
showHasSkips && feed.preferences?.introSkip == 0 && feed.preferences?.endingSkip == 0 -> return false
|
||||||
showNoSkips && (feed.preferences?.introSkip != 0 || feed.preferences?.endingSkip != 0) -> return false
|
showNoSkips && (feed.preferences?.introSkip != 0 || feed.preferences?.endingSkip != 0) -> return false
|
||||||
showAlwaysAutoDelete && feed.preferences?.autoDeleteAction != FeedPreferences.AutoDeleteAction.ALWAYS -> return false
|
showAlwaysAutoDelete && feed.preferences?.autoDeleteAction != FeedPreferences.AutoDeleteAction.ALWAYS -> return false
|
||||||
|
@ -60,6 +64,10 @@ class FeedFilter(vararg properties: String) : Serializable {
|
||||||
showHasSkips -> statements.add(" preferences.introSkip != 0 OR preferences.endingSkip != 0 ")
|
showHasSkips -> statements.add(" preferences.introSkip != 0 OR preferences.endingSkip != 0 ")
|
||||||
showNoSkips -> statements.add(" preferences.introSkip == 0 AND preferences.endingSkip == 0 ")
|
showNoSkips -> statements.add(" preferences.introSkip == 0 AND preferences.endingSkip == 0 ")
|
||||||
}
|
}
|
||||||
|
when {
|
||||||
|
showHasComments -> statements.add(" comment != '' ")
|
||||||
|
showNoComments -> statements.add(" comment == '' ")
|
||||||
|
}
|
||||||
when {
|
when {
|
||||||
showAlwaysAutoDelete -> statements.add(" preferences.autoDelete == ${FeedPreferences.AutoDeleteAction.ALWAYS.code} ")
|
showAlwaysAutoDelete -> statements.add(" preferences.autoDelete == ${FeedPreferences.AutoDeleteAction.ALWAYS.code} ")
|
||||||
showNeverAutoDelete -> statements.add(" preferences.playSpeed == ${FeedPreferences.AutoDeleteAction.NEVER.code} ")
|
showNeverAutoDelete -> statements.add(" preferences.playSpeed == ${FeedPreferences.AutoDeleteAction.NEVER.code} ")
|
||||||
|
@ -89,6 +97,8 @@ class FeedFilter(vararg properties: String) : Serializable {
|
||||||
custom_playSpeed,
|
custom_playSpeed,
|
||||||
has_skips,
|
has_skips,
|
||||||
no_skips,
|
no_skips,
|
||||||
|
has_comments,
|
||||||
|
no_comments,
|
||||||
// global_auto_delete,
|
// global_auto_delete,
|
||||||
always_auto_delete,
|
always_auto_delete,
|
||||||
never_auto_delete,
|
never_auto_delete,
|
||||||
|
|
|
@ -1,92 +1,99 @@
|
||||||
package ac.mdiq.podcini.ui.dialog
|
package ac.mdiq.podcini.ui.dialog
|
||||||
|
|
||||||
import ac.mdiq.podcini.R
|
import ac.mdiq.podcini.R
|
||||||
import ac.mdiq.podcini.databinding.FilterDialogBinding
|
|
||||||
import ac.mdiq.podcini.databinding.FilterDialogRowBinding
|
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
||||||
|
import ac.mdiq.podcini.storage.model.FeedFilter
|
||||||
|
import ac.mdiq.podcini.ui.compose.CustomTheme
|
||||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.TAG
|
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.TAG
|
||||||
|
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.FeedFilterDialog.FeedFilterGroup.ItemProperties
|
||||||
import ac.mdiq.podcini.util.Logd
|
import ac.mdiq.podcini.util.Logd
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import androidx.compose.foundation.BorderStroke
|
||||||
import android.widget.LinearLayout
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.OutlinedButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.ComposeView
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import com.google.android.material.button.MaterialButtonToggleGroup
|
|
||||||
|
|
||||||
abstract class EpisodeFilterDialog : BottomSheetDialogFragment() {
|
abstract class EpisodeFilterDialog : BottomSheetDialogFragment() {
|
||||||
private lateinit var rows: LinearLayout
|
|
||||||
private var _binding: FilterDialogBinding? = null
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
var filter: EpisodeFilter? = null
|
var filter: EpisodeFilter? = null
|
||||||
private val buttonMap: MutableMap<String, Button> = mutableMapOf()
|
|
||||||
val filtersDisabled: MutableSet<FeedItemFilterGroup> = mutableSetOf()
|
val filtersDisabled: MutableSet<FeedItemFilterGroup> = mutableSetOf()
|
||||||
|
private val filterValues: MutableSet<String> = mutableSetOf()
|
||||||
private val newFilterValues: Set<String>
|
|
||||||
get() {
|
|
||||||
val newFilterValues: MutableSet<String> = HashSet()
|
|
||||||
for (i in 0 until rows.childCount) {
|
|
||||||
if (rows.getChildAt(i) !is MaterialButtonToggleGroup) continue
|
|
||||||
val group = rows.getChildAt(i) as MaterialButtonToggleGroup
|
|
||||||
if (group.checkedButtonId == View.NO_ID) continue
|
|
||||||
val tag = group.findViewById<View>(group.checkedButtonId).tag as? String ?: continue
|
|
||||||
newFilterValues.add(tag)
|
|
||||||
}
|
|
||||||
return newFilterValues
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val layout = inflater.inflate(R.layout.filter_dialog, container, false)
|
val composeView = ComposeView(requireContext()).apply {
|
||||||
_binding = FilterDialogBinding.bind(layout)
|
setContent {
|
||||||
rows = binding.filterRows
|
CustomTheme(requireContext()) {
|
||||||
Logd("EpisodeFilterDialog", "fragment onCreateView")
|
MainView()
|
||||||
|
}
|
||||||
//add filter rows
|
}
|
||||||
for (item in FeedItemFilterGroup.entries) {
|
}
|
||||||
// Logd("EpisodeFilterDialog", "FeedItemFilterGroup: ${item.values[0].filterId} ${item.values[1].filterId}")
|
return composeView
|
||||||
if (item in filtersDisabled) continue
|
}
|
||||||
|
|
||||||
val rBinding = FilterDialogRowBinding.inflate(inflater)
|
@Composable
|
||||||
rBinding.filterButton1.setOnClickListener { onFilterChanged(newFilterValues) }
|
fun MainView() {
|
||||||
rBinding.filterButton2.setOnClickListener { onFilterChanged(newFilterValues) }
|
val textColor = MaterialTheme.colorScheme.onSurface
|
||||||
|
Column {
|
||||||
rBinding.filterButton1.setText(item.values[0].displayName)
|
for (item in FeedItemFilterGroup.entries) {
|
||||||
rBinding.filterButton1.tag = item.values[0].filterId
|
if (item in filtersDisabled) continue
|
||||||
buttonMap[item.values[0].filterId] = rBinding.filterButton1
|
Row(modifier = Modifier.padding(2.dp).fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
|
||||||
rBinding.filterButton2.setText(item.values[1].displayName)
|
var selectedIndex by remember { mutableStateOf(-1) }
|
||||||
rBinding.filterButton2.tag = item.values[1].filterId
|
LaunchedEffect(Unit) {
|
||||||
buttonMap[item.values[1].filterId] = rBinding.filterButton2
|
if (filter != null) {
|
||||||
rBinding.filterButton1.maxLines = 3
|
if (item.values[0].filterId in filter!!.values) selectedIndex = 0
|
||||||
rBinding.filterButton1.isSingleLine = false
|
else if (item.values[1].filterId in filter!!.values) selectedIndex = 1
|
||||||
rBinding.filterButton2.maxLines = 3
|
}
|
||||||
rBinding.filterButton2.isSingleLine = false
|
}
|
||||||
rows.addView(rBinding.root, rows.childCount - 1)
|
OutlinedButton(modifier = Modifier.padding(2.dp), border = BorderStroke(2.dp, if (selectedIndex != 0) textColor else Color.Green),
|
||||||
}
|
onClick = {
|
||||||
|
if (selectedIndex != 0) {
|
||||||
binding.confirmFiltermenu.setOnClickListener { dismiss() }
|
selectedIndex = 0
|
||||||
binding.resetFiltermenu.setOnClickListener {
|
filterValues.add(item.values[0].filterId)
|
||||||
onFilterChanged(emptySet())
|
filterValues.remove(item.values[1].filterId)
|
||||||
for (i in 0 until rows.childCount) {
|
} else {
|
||||||
if (rows.getChildAt(i) is MaterialButtonToggleGroup) (rows.getChildAt(i) as MaterialButtonToggleGroup).clearChecked()
|
selectedIndex = -1
|
||||||
}
|
filterValues.remove(item.values[0].filterId)
|
||||||
}
|
}
|
||||||
|
onFilterChanged(filterValues)
|
||||||
if (filter != null) {
|
},
|
||||||
for (filterId in filter!!.values) {
|
) {
|
||||||
if (filterId.isNotEmpty()) {
|
Text(text = stringResource(item.values[0].displayName), color = textColor)
|
||||||
val button = buttonMap[filterId]
|
}
|
||||||
if (button != null) (button.parent as MaterialButtonToggleGroup).check(button.id)
|
Spacer(Modifier.width(5.dp))
|
||||||
|
OutlinedButton(modifier = Modifier.padding(2.dp), border = BorderStroke(2.dp, if (selectedIndex != 1) textColor else Color.Green),
|
||||||
|
onClick = {
|
||||||
|
if (selectedIndex != 1) {
|
||||||
|
selectedIndex = 1
|
||||||
|
filterValues.add(item.values[1].filterId)
|
||||||
|
filterValues.remove(item.values[0].filterId)
|
||||||
|
} else {
|
||||||
|
selectedIndex = -1
|
||||||
|
filterValues.remove(item.values[1].filterId)
|
||||||
|
}
|
||||||
|
onFilterChanged(filterValues)
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(item.values[1].displayName), color = textColor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return layout
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
Logd(TAG, "onDestroyView")
|
Logd(TAG, "onDestroyView")
|
||||||
_binding = null
|
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +104,7 @@ abstract class EpisodeFilterDialog : BottomSheetDialogFragment() {
|
||||||
PAUSED(ItemProperties(R.string.hide_paused_episodes_label, EpisodeFilter.States.paused.name), ItemProperties(R.string.not_paused, EpisodeFilter.States.not_paused.name)),
|
PAUSED(ItemProperties(R.string.hide_paused_episodes_label, EpisodeFilter.States.paused.name), ItemProperties(R.string.not_paused, EpisodeFilter.States.not_paused.name)),
|
||||||
FAVORITE(ItemProperties(R.string.hide_is_favorite_label, EpisodeFilter.States.is_favorite.name), ItemProperties(R.string.not_favorite, EpisodeFilter.States.not_favorite.name)),
|
FAVORITE(ItemProperties(R.string.hide_is_favorite_label, EpisodeFilter.States.is_favorite.name), ItemProperties(R.string.not_favorite, EpisodeFilter.States.not_favorite.name)),
|
||||||
MEDIA(ItemProperties(R.string.has_media, EpisodeFilter.States.has_media.name), ItemProperties(R.string.no_media, EpisodeFilter.States.no_media.name)),
|
MEDIA(ItemProperties(R.string.has_media, EpisodeFilter.States.has_media.name), ItemProperties(R.string.no_media, EpisodeFilter.States.no_media.name)),
|
||||||
|
OPINION(ItemProperties(R.string.has_comments, EpisodeFilter.States.has_comments.name), ItemProperties(R.string.no_comments, EpisodeFilter.States.no_comments.name)),
|
||||||
QUEUED(ItemProperties(R.string.queued_label, EpisodeFilter.States.queued.name), ItemProperties(R.string.not_queued_label, EpisodeFilter.States.not_queued.name)),
|
QUEUED(ItemProperties(R.string.queued_label, EpisodeFilter.States.queued.name), ItemProperties(R.string.not_queued_label, EpisodeFilter.States.not_queued.name)),
|
||||||
DOWNLOADED(ItemProperties(R.string.downloaded_label, EpisodeFilter.States.downloaded.name), ItemProperties(R.string.not_downloaded_label, EpisodeFilter.States.not_downloaded.name)),
|
DOWNLOADED(ItemProperties(R.string.downloaded_label, EpisodeFilter.States.downloaded.name), ItemProperties(R.string.not_downloaded_label, EpisodeFilter.States.not_downloaded.name)),
|
||||||
AUTO_DOWNLOADABLE(ItemProperties(R.string.auto_downloadable_label, EpisodeFilter.States.auto_downloadable.name), ItemProperties(R.string.not_auto_downloadable_label, EpisodeFilter.States.not_auto_downloadable.name));
|
AUTO_DOWNLOADABLE(ItemProperties(R.string.auto_downloadable_label, EpisodeFilter.States.auto_downloadable.name), ItemProperties(R.string.not_auto_downloadable_label, EpisodeFilter.States.not_auto_downloadable.name));
|
||||||
|
|
|
@ -6,6 +6,7 @@ import ac.mdiq.podcini.playback.PlaybackServiceStarter
|
||||||
import ac.mdiq.podcini.playback.ServiceStatusHandler
|
import ac.mdiq.podcini.playback.ServiceStatusHandler
|
||||||
import ac.mdiq.podcini.playback.base.InTheatre.curEpisode
|
import ac.mdiq.podcini.playback.base.InTheatre.curEpisode
|
||||||
import ac.mdiq.podcini.playback.base.InTheatre.curMedia
|
import ac.mdiq.podcini.playback.base.InTheatre.curMedia
|
||||||
|
import ac.mdiq.podcini.playback.base.InTheatre.isCurrentlyPlaying
|
||||||
import ac.mdiq.podcini.playback.base.MediaPlayerBase.Companion.status
|
import ac.mdiq.podcini.playback.base.MediaPlayerBase.Companion.status
|
||||||
import ac.mdiq.podcini.playback.base.PlayerStatus
|
import ac.mdiq.podcini.playback.base.PlayerStatus
|
||||||
import ac.mdiq.podcini.playback.base.VideoMode
|
import ac.mdiq.podcini.playback.base.VideoMode
|
||||||
|
@ -510,7 +511,7 @@ class AudioPlayerFragment : Fragment() {
|
||||||
fun onPositionUpdate(event: FlowEvent.PlaybackPositionEvent) {
|
fun onPositionUpdate(event: FlowEvent.PlaybackPositionEvent) {
|
||||||
Logd(TAG, "onPositionUpdate")
|
Logd(TAG, "onPositionUpdate")
|
||||||
if (!playButInit && playButRes == R.drawable.ic_play_48dp && curMedia is EpisodeMedia) {
|
if (!playButInit && playButRes == R.drawable.ic_play_48dp && curMedia is EpisodeMedia) {
|
||||||
playButRes = R.drawable.ic_pause
|
if (isCurrentlyPlaying(curMedia as? EpisodeMedia)) playButRes = R.drawable.ic_pause
|
||||||
playButInit = true
|
playButInit = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,14 +754,15 @@ class AudioPlayerFragment : Fragment() {
|
||||||
Logd(TAG, "loadMediaInfo() curMedia: ${curMedia?.getIdentifier()}")
|
Logd(TAG, "loadMediaInfo() curMedia: ${curMedia?.getIdentifier()}")
|
||||||
val actMain = (activity as MainActivity)
|
val actMain = (activity as MainActivity)
|
||||||
var i = 0
|
var i = 0
|
||||||
while (curMedia == null && i++ < 6) runBlocking { delay(500) }
|
// while (curMedia == null && i++ < 6) runBlocking { delay(500) }
|
||||||
if (curMedia == null) {
|
if (curMedia == null) {
|
||||||
if (actMain.isPlayerVisible()) actMain.setPlayerVisible(false)
|
if (actMain.isPlayerVisible()) actMain.setPlayerVisible(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (!actMain.isPlayerVisible()) actMain.setPlayerVisible(true)
|
||||||
if (!loadItemsRunning) {
|
if (!loadItemsRunning) {
|
||||||
loadItemsRunning = true
|
loadItemsRunning = true
|
||||||
if (!actMain.isPlayerVisible()) actMain.setPlayerVisible(true)
|
// if (!actMain.isPlayerVisible()) actMain.setPlayerVisible(true)
|
||||||
val curMediaChanged = currentMedia == null || curMedia?.getIdentifier() != currentMedia?.getIdentifier()
|
val curMediaChanged = currentMedia == null || curMedia?.getIdentifier() != currentMedia?.getIdentifier()
|
||||||
if (curMedia?.getIdentifier() != currentMedia?.getIdentifier()) updateUi(curMedia!!)
|
if (curMedia?.getIdentifier() != currentMedia?.getIdentifier()) updateUi(curMedia!!)
|
||||||
if (!isCollapsed && curMediaChanged) {
|
if (!isCollapsed && curMediaChanged) {
|
||||||
|
|
|
@ -72,6 +72,7 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
@ -650,7 +651,7 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
||||||
Dialog(onDismissRequest = onDismissRequest) {
|
Dialog(onDismissRequest = onDismissRequest) {
|
||||||
Surface(shape = RoundedCornerShape(16.dp)) {
|
Surface(shape = RoundedCornerShape(16.dp)) {
|
||||||
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
for (rating in Rating.entries) {
|
for (rating in Rating.entries.reversed()) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(4.dp).clickable {
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(4.dp).clickable {
|
||||||
for (item in selected) Feeds.setRating(item, rating.code)
|
for (item in selected) Feeds.setRating(item, rating.code)
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
|
@ -1105,77 +1106,72 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
class FeedFilterDialog : BottomSheetDialogFragment() {
|
class FeedFilterDialog : BottomSheetDialogFragment() {
|
||||||
private lateinit var rows: LinearLayout
|
|
||||||
private var _binding: FilterDialogBinding? = null
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
var filter: FeedFilter? = null
|
var filter: FeedFilter? = null
|
||||||
private val buttonMap: MutableMap<String, Button> = mutableMapOf()
|
private val filterValues: MutableSet<String> = mutableSetOf()
|
||||||
|
|
||||||
private val newFilterValues: Set<String>
|
|
||||||
get() {
|
|
||||||
val newFilterValues: MutableSet<String> = HashSet()
|
|
||||||
for (i in 0 until rows.childCount) {
|
|
||||||
if (rows.getChildAt(i) !is MaterialButtonToggleGroup) continue
|
|
||||||
val group = rows.getChildAt(i) as MaterialButtonToggleGroup
|
|
||||||
if (group.checkedButtonId == View.NO_ID) continue
|
|
||||||
val tag = group.findViewById<View>(group.checkedButtonId).tag as? String ?: continue
|
|
||||||
newFilterValues.add(tag)
|
|
||||||
}
|
|
||||||
return newFilterValues
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val layout = inflater.inflate(R.layout.filter_dialog, container, false)
|
val composeView = ComposeView(requireContext()).apply {
|
||||||
_binding = FilterDialogBinding.bind(layout)
|
setContent {
|
||||||
rows = binding.filterRows
|
CustomTheme(requireContext()) {
|
||||||
Logd("FeedFilterDialog", "fragment onCreateView")
|
MainView()
|
||||||
|
}
|
||||||
//add filter rows
|
}
|
||||||
for (item in FeedFilterGroup.entries) {
|
}
|
||||||
// Logd("EpisodeFilterDialog", "FeedItemFilterGroup: ${item.values[0].filterId} ${item.values[1].filterId}")
|
return composeView
|
||||||
val rBinding = FilterDialogRowBinding.inflate(inflater)
|
}
|
||||||
// rowBinding.root.addOnButtonCheckedListener { _: MaterialButtonToggleGroup?, _: Int, _: Boolean ->
|
|
||||||
// onFilterChanged(newFilterValues)
|
@Composable
|
||||||
// }
|
fun MainView() {
|
||||||
rBinding.filterButton1.setOnClickListener { onFilterChanged(newFilterValues) }
|
val textColor = MaterialTheme.colorScheme.onSurface
|
||||||
rBinding.filterButton2.setOnClickListener { onFilterChanged(newFilterValues) }
|
Column {
|
||||||
|
for (item in FeedFilterGroup.entries) {
|
||||||
rBinding.filterButton1.setText(item.values[0].displayName)
|
Row(modifier = Modifier.padding(2.dp).fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
|
||||||
rBinding.filterButton1.tag = item.values[0].filterId
|
var selectedIndex by remember { mutableStateOf(-1) }
|
||||||
buttonMap[item.values[0].filterId] = rBinding.filterButton1
|
LaunchedEffect(Unit) {
|
||||||
rBinding.filterButton2.setText(item.values[1].displayName)
|
if (filter != null) {
|
||||||
rBinding.filterButton2.tag = item.values[1].filterId
|
if (item.values[0].filterId in filter!!.values) selectedIndex = 0
|
||||||
buttonMap[item.values[1].filterId] = rBinding.filterButton2
|
else if (item.values[1].filterId in filter!!.values) selectedIndex = 1
|
||||||
rBinding.filterButton1.maxLines = 3
|
}
|
||||||
rBinding.filterButton1.isSingleLine = false
|
}
|
||||||
rBinding.filterButton2.maxLines = 3
|
OutlinedButton(modifier = Modifier.padding(2.dp), border = BorderStroke(2.dp, if (selectedIndex != 0) textColor else Color.Green),
|
||||||
rBinding.filterButton2.isSingleLine = false
|
onClick = {
|
||||||
rows.addView(rBinding.root, rows.childCount - 1)
|
if (selectedIndex != 0) {
|
||||||
}
|
selectedIndex = 0
|
||||||
|
filterValues.add(item.values[0].filterId)
|
||||||
binding.confirmFiltermenu.setOnClickListener { dismiss() }
|
filterValues.remove(item.values[1].filterId)
|
||||||
binding.resetFiltermenu.setOnClickListener {
|
} else {
|
||||||
onFilterChanged(emptySet())
|
selectedIndex = -1
|
||||||
for (i in 0 until rows.childCount) {
|
filterValues.remove(item.values[0].filterId)
|
||||||
if (rows.getChildAt(i) is MaterialButtonToggleGroup) (rows.getChildAt(i) as MaterialButtonToggleGroup).clearChecked()
|
}
|
||||||
}
|
onFilterChanged(filterValues)
|
||||||
}
|
},
|
||||||
|
) {
|
||||||
if (filter != null) {
|
Text(text = stringResource(item.values[0].displayName), color = textColor)
|
||||||
for (filterId in filter!!.values) {
|
}
|
||||||
if (filterId.isNotEmpty()) {
|
Spacer(Modifier.width(5.dp))
|
||||||
val button = buttonMap[filterId]
|
OutlinedButton(modifier = Modifier.padding(2.dp), border = BorderStroke(2.dp, if (selectedIndex != 1) textColor else Color.Green),
|
||||||
if (button != null) (button.parent as MaterialButtonToggleGroup).check(button.id)
|
onClick = {
|
||||||
|
if (selectedIndex != 1) {
|
||||||
|
selectedIndex = 1
|
||||||
|
filterValues.add(item.values[1].filterId)
|
||||||
|
filterValues.remove(item.values[0].filterId)
|
||||||
|
} else {
|
||||||
|
selectedIndex = -1
|
||||||
|
filterValues.remove(item.values[1].filterId)
|
||||||
|
}
|
||||||
|
onFilterChanged(filterValues)
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(item.values[1].displayName), color = textColor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return layout
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
Logd(TAG, "onDestroyView")
|
Logd(TAG, "onDestroyView")
|
||||||
_binding = null
|
// _binding = null
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1188,6 +1184,7 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
||||||
enum class FeedFilterGroup(vararg values: ItemProperties) {
|
enum class FeedFilterGroup(vararg values: ItemProperties) {
|
||||||
KEEP_UPDATED(ItemProperties(R.string.keep_updated, FeedFilter.States.keepUpdated.name), ItemProperties(R.string.not_keep_updated, FeedFilter.States.not_keepUpdated.name)),
|
KEEP_UPDATED(ItemProperties(R.string.keep_updated, FeedFilter.States.keepUpdated.name), ItemProperties(R.string.not_keep_updated, FeedFilter.States.not_keepUpdated.name)),
|
||||||
PLAY_SPEED(ItemProperties(R.string.global_speed, FeedFilter.States.global_playSpeed.name), ItemProperties(R.string.custom_speed, FeedFilter.States.custom_playSpeed.name)),
|
PLAY_SPEED(ItemProperties(R.string.global_speed, FeedFilter.States.global_playSpeed.name), ItemProperties(R.string.custom_speed, FeedFilter.States.custom_playSpeed.name)),
|
||||||
|
OPINION(ItemProperties(R.string.has_comments, FeedFilter.States.has_comments.name), ItemProperties(R.string.no_comments, FeedFilter.States.no_comments.name)),
|
||||||
SKIPS(ItemProperties(R.string.has_skips, FeedFilter.States.has_skips.name), ItemProperties(R.string.no_skips, FeedFilter.States.no_skips.name)),
|
SKIPS(ItemProperties(R.string.has_skips, FeedFilter.States.has_skips.name), ItemProperties(R.string.no_skips, FeedFilter.States.no_skips.name)),
|
||||||
AUTO_DELETE(ItemProperties(R.string.always_auto_delete, FeedFilter.States.always_auto_delete.name), ItemProperties(R.string.never_auto_delete, FeedFilter.States.never_auto_delete.name)),
|
AUTO_DELETE(ItemProperties(R.string.always_auto_delete, FeedFilter.States.always_auto_delete.name), ItemProperties(R.string.never_auto_delete, FeedFilter.States.never_auto_delete.name)),
|
||||||
AUTO_DOWNLOAD(ItemProperties(R.string.auto_download, FeedFilter.States.autoDownload.name), ItemProperties(R.string.not_auto_download, FeedFilter.States.not_autoDownload.name));
|
AUTO_DOWNLOAD(ItemProperties(R.string.auto_download, FeedFilter.States.autoDownload.name), ItemProperties(R.string.not_auto_download, FeedFilter.States.not_autoDownload.name));
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ScrollView
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:id="@+id/filter_dialog">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/filter_rows"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingLeft="24dp"
|
|
||||||
android:paddingTop="24dp"
|
|
||||||
android:paddingRight="24dp"
|
|
||||||
android:paddingBottom="8dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/resetFiltermenu"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/reset"
|
|
||||||
style="@style/Widget.MaterialComponents.Button.TextButton" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/confirmFiltermenu"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/confirm_label"
|
|
||||||
style="@style/Widget.MaterialComponents.Button.TextButton" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
|
|
@ -1,25 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/buttonGroup"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:weightSum="2"
|
|
||||||
app:singleSelection="true">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/filterButton1"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
style="@style/OutlinedButtonBetterContrast" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/filterButton2"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
style="@style/OutlinedButtonBetterContrast" />
|
|
||||||
|
|
||||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
|
|
@ -903,6 +903,8 @@
|
||||||
<string name="custom_speed">Custom play speed</string>
|
<string name="custom_speed">Custom play speed</string>
|
||||||
<string name="has_skips">Skips set</string>
|
<string name="has_skips">Skips set</string>
|
||||||
<string name="no_skips">No Skips set</string>
|
<string name="no_skips">No Skips set</string>
|
||||||
|
<string name="has_comments">Has commented</string>
|
||||||
|
<string name="no_comments">Not commented</string>
|
||||||
<string name="always_auto_delete">Always auto delete</string>
|
<string name="always_auto_delete">Always auto delete</string>
|
||||||
<string name="never_auto_delete">Never auto delete</string>
|
<string name="never_auto_delete">Never auto delete</string>
|
||||||
<string name="auto_download">Auto download enabled</string>
|
<string name="auto_download">Auto download enabled</string>
|
||||||
|
|
10
changelog.md
10
changelog.md
|
@ -1,3 +1,13 @@
|
||||||
|
# 6.12.2
|
||||||
|
|
||||||
|
* fixed play not resuming after interruption (watch for any side effects)
|
||||||
|
* fixed incorrect initial play button on PlayerUI
|
||||||
|
* fixed startup delay when curMedia is null
|
||||||
|
* rating list in popup for Subscriptions is reversed (favorite on top)
|
||||||
|
* first migration of Episodes and Feeds filters to Jetpack Compose
|
||||||
|
* added has/no comments in the filters
|
||||||
|
* fixed some errors in Episodes filter
|
||||||
|
|
||||||
# 6.12.1
|
# 6.12.1
|
||||||
|
|
||||||
* fixed circular calling functions when PlayerDetailed view is open
|
* fixed circular calling functions when PlayerDetailed view is open
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
Version 6.12.2
|
||||||
|
|
||||||
|
* fixed play not resuming after interruption (watch for any side effects)
|
||||||
|
* fixed incorrect initial play button on PlayerUI
|
||||||
|
* fixed startup delay when curMedia is null
|
||||||
|
* rating list in popup for Subscriptions is reversed (favorite on top)
|
||||||
|
* first migration of Episodes and Feeds filters to Jetpack Compose
|
||||||
|
* added has/no comments in the filters
|
||||||
|
* fixed some errors in Episodes filter
|
Loading…
Reference in New Issue