6.12.8 commit

This commit is contained in:
Xilin Jia 2024-10-28 13:53:23 +01:00
parent d87bc718d3
commit 70d4f9c70f
52 changed files with 205 additions and 132 deletions

View File

@ -31,8 +31,8 @@ android {
testApplicationId "ac.mdiq.podcini.tests"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
versionCode 3020285
versionName "6.12.7"
versionCode 3020286
versionName "6.12.8"
applicationId "ac.mdiq.podcini.R"
def commit = ""

View File

@ -261,7 +261,7 @@ import kotlin.math.min
.position(media.getPosition() / 1000)
.playedDuration(media.playedDuration / 1000)
.total(media.getDuration() / 1000)
.isFavorite(item.isFavorite)
.isFavorite(item.isSUPER)
.playState(item.playState)
.build()
queuedEpisodeActions.add(played)
@ -334,7 +334,7 @@ import kotlin.math.min
it.media!!.setPosition(action.position * 1000)
it.media!!.playedDuration = action.playedDuration * 1000
it.media!!.setLastPlayedTime(action.timestamp!!.time)
it.rating = if (action.isFavorite) Rating.FAVORITE.code else Rating.UNRATED.code
it.rating = if (action.isFavorite) Rating.SUPER.code else Rating.UNRATED.code
it.playState = action.playState
if (hasAlmostEnded(it.media!!)) {
Logd(TAG, "Marking as played")

View File

@ -44,7 +44,10 @@ object NetworkUtils {
return when (networkInfo.type) {
ConnectivityManager.TYPE_WIFI -> {
if (isEnableAutodownloadWifiFilter) isInAllowedWifiNetwork
else !isNetworkMetered
else {
if (!isNetworkMetered) true
else isAllowMobileAutoDownload
}
}
ConnectivityManager.TYPE_ETHERNET -> true
else -> isAllowMobileAutoDownload || !isNetworkRestricted
@ -158,7 +161,6 @@ object NetworkUtils {
val allowed: MutableSet<String> = HashSet(getValueStringSet!!)
if (allow) allowed.add(type)
else allowed.remove(type)
appPrefs.edit().putStringSet(UserPreferences.Prefs.prefMobileUpdateTypes.name, allowed).apply()
}

View File

@ -368,7 +368,7 @@ class PlaybackService : MediaLibraryService() {
val action = item?.feed?.preferences?.autoDeleteAction
val shouldAutoDelete = (action == AutoDeleteAction.ALWAYS ||
(action == AutoDeleteAction.GLOBAL && item?.feed != null && shouldAutoDeleteItem(item!!.feed!!)))
if (playable is EpisodeMedia && shouldAutoDelete && (item?.isFavorite != true || !shouldFavoriteKeepEpisode)) {
if (playable is EpisodeMedia && shouldAutoDelete && (item?.isSUPER != true || !shouldFavoriteKeepEpisode)) {
item = deleteMediaSync(this@PlaybackService, item!!)
if (shouldDeleteRemoveFromQueue()) removeFromQueueSync(null, item!!)
}

View File

@ -938,7 +938,7 @@ class ImportExportPreferencesFragment : PreferenceFragmentCompat() {
it.media!!.setPosition(action.position * 1000)
it.media!!.playedDuration = action.playedDuration * 1000
it.media!!.setLastPlayedTime(action.timestamp!!.time)
it.rating = if (action.isFavorite) Rating.FAVORITE.code else Rating.UNRATED.code
it.rating = if (action.isFavorite) Rating.SUPER.code else Rating.UNRATED.code
it.playState = action.playState
if (hasAlmostEnded(it.media!!)) {
Logd(TAG, "Marking as played: $action")
@ -973,7 +973,7 @@ class ImportExportPreferencesFragment : PreferenceFragmentCompat() {
.position(media.getPosition() / 1000)
.playedDuration(media.playedDuration / 1000)
.total(media.getDuration() / 1000)
.isFavorite(item.isFavorite)
.isFavorite(item.isSUPER)
.playState(item.playState)
.build()
queuedEpisodeActions.add(played)

View File

@ -64,7 +64,7 @@ object AutoCleanups {
val candidates: MutableList<Episode> = ArrayList()
val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.States.downloaded.name), EpisodeSortOrder.DATE_NEW_OLD)
for (item in downloadedItems) {
if (item.media != null && item.media!!.downloaded && !item.isFavorite) candidates.add(item)
if (item.media != null && item.media!!.downloaded && !item.isSUPER) candidates.add(item)
}
return candidates
}
@ -117,7 +117,7 @@ object AutoCleanups {
val downloadedItems = getEpisodes(0, Int.MAX_VALUE, EpisodeFilter(EpisodeFilter.States.downloaded.name), EpisodeSortOrder.DATE_NEW_OLD)
val idsInQueues = getInQueueEpisodeIds()
for (item in downloadedItems) {
if (item.media != null && item.media!!.downloaded && !idsInQueues.contains(item.id) && !item.isFavorite)
if (item.media != null && item.media!!.downloaded && !idsInQueues.contains(item.id) && !item.isSUPER)
candidates.add(item)
}
return candidates
@ -183,7 +183,7 @@ object AutoCleanups {
val idsInQueues = getInQueueEpisodeIds()
val mostRecentDateForDeletion = calcMostRecentDateForDeletion(Date())
for (item in downloadedItems) {
if (item.media != null && item.media!!.downloaded && !idsInQueues.contains(item.id) && item.playState >= PlayState.PLAYED.code && !item.isFavorite) {
if (item.media != null && item.media!!.downloaded && !idsInQueues.contains(item.id) && item.playState >= PlayState.PLAYED.code && !item.isSUPER) {
val media = item.media
// make sure this candidate was played at least the proper amount of days prior to now
if (media?.playbackCompletionDate != null && media.playbackCompletionDate!!.before(mostRecentDateForDeletion)) candidates.add(item)

View File

@ -123,11 +123,11 @@ object AutoDownloads {
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
}
FeedPreferences.AutoDownloadPolicy.NEWER -> {
queryString += " AND playState < ${PlayState.SKIPPED.code} SORT(pubDate DESC) LIMIT(${3*allowedDLCount})"
queryString += " AND playState <= ${PlayState.SOON.code} SORT(pubDate DESC) LIMIT(${3*allowedDLCount})"
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
}
FeedPreferences.AutoDownloadPolicy.OLDER -> {
queryString += " AND playState < ${PlayState.SKIPPED.code} SORT(pubDate ASC) LIMIT(${3*allowedDLCount})"
queryString += " AND playState <= ${PlayState.SOON.code} SORT(pubDate ASC) LIMIT(${3*allowedDLCount})"
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
}
else -> {}

View File

@ -129,7 +129,9 @@ object Episodes {
episode = upsertBlk(episode) {
it.media?.setfileUrlOrNull(null)
if (media.downloadUrl.isNullOrEmpty()) it.media = null
it.playState = PlayState.SKIPPED.code
}
EventFlow.postEvent(FlowEvent.EpisodePlayedEvent(episode))
localDelete = true
}
url != null -> {
@ -145,8 +147,10 @@ object Episodes {
it.media?.downloaded = false
it.media?.setfileUrlOrNull(null)
it.media?.hasEmbeddedPicture = false
it.playState = PlayState.SKIPPED.code
if (media.downloadUrl.isNullOrEmpty()) it.media = null
}
EventFlow.postEvent(FlowEvent.EpisodePlayedEvent(episode))
}
}

View File

@ -287,7 +287,6 @@ object Feeds {
episode.feed = savedFeed
episode.id = idLong++
episode.feedId = savedFeed.id
episode.playState = PlayState.NEW.code
if (episode.media != null) {
episode.media!!.id = episode.id
if (!savedFeed.hasVideoMedia && episode.media!!.getMediaType() == MediaType.VIDEO) savedFeed.hasVideoMedia = true
@ -298,7 +297,8 @@ object Feeds {
val pubDate = episode.getPubDate()
if (pubDate == null || priorMostRecentDate == null || priorMostRecentDate.before(pubDate) || priorMostRecentDate == pubDate) {
Logd(TAG, "Marking episode published on $pubDate new, prior most recent date = $priorMostRecentDate")
episode.setNew()
episode.playState = PlayState.NEW.code
// episode.setNew()
if (savedFeed.preferences?.autoAddNewToQueue == true) {
val q = savedFeed.preferences?.queue
if (q != null) runOnIOScope { addToQueueSync(episode, q) }

View File

@ -86,7 +86,7 @@ class Episode : RealmObject {
var rating: Int = Rating.UNRATED.code
@Ignore
var isFavorite: Boolean = (rating == Rating.FAVORITE.code)
var isSUPER: Boolean = (rating == Rating.SUPER.code)
private set
@FullText
@ -172,7 +172,8 @@ class Episode : RealmObject {
media == null -> {
setMedia(other.media)
// reset to new if feed item did link to a file before
setNew()
// setNew()
playState = PlayState.NEW.code
}
media!!.compareWithOther(other.media!!) -> media!!.updateFromOther(other.media!!)
}
@ -206,9 +207,9 @@ class Episode : RealmObject {
this.media = media
}
fun setNew() {
playState = PlayState.NEW.code
}
// fun setNew() {
// playState = PlayState.NEW.code
// }
fun isPlayed(): Boolean {
return playState >= PlayState.SKIPPED.code
@ -218,9 +219,9 @@ class Episode : RealmObject {
playState = if (played) PlayState.PLAYED.code else PlayState.UNPLAYED.code
}
fun setBuilding() {
playState = PlayState.BUILDING.code
}
// fun setBuilding() {
// playState = PlayState.BUILDING.code
// }
/**
* Updates this item's description property if the given argument is longer than the already stored description

View File

@ -56,9 +56,9 @@ class EpisodeFilter(vararg properties_: String) : Serializable {
if (properties.contains(States.unrated.name)) ratingQuerys.add(" rating == ${Rating.UNRATED.code} ")
if (properties.contains(States.trash.name)) ratingQuerys.add(" rating == ${Rating.TRASH.code} ")
if (properties.contains(States.bad.name)) ratingQuerys.add(" rating == ${Rating.BAD.code} ")
if (properties.contains(States.neutral.name)) ratingQuerys.add(" rating == ${Rating.NEUTRAL.code} ")
if (properties.contains(States.neutral.name)) ratingQuerys.add(" rating == ${Rating.OK.code} ")
if (properties.contains(States.good.name)) ratingQuerys.add(" rating == ${Rating.GOOD.code} ")
if (properties.contains(States.favorite.name)) ratingQuerys.add(" rating == ${Rating.FAVORITE.code} ")
if (properties.contains(States.favorite.name)) ratingQuerys.add(" rating == ${Rating.SUPER.code} ")
if (ratingQuerys.isNotEmpty()) {
val query = StringBuilder(" (" + ratingQuerys[0])
if (ratingQuerys.size > 1) for (r in ratingQuerys.subList(1, ratingQuerys.size)) {
@ -183,9 +183,9 @@ class EpisodeFilter(vararg properties_: String) : Serializable {
RATING(R.string.rating_label, ItemProperties(R.string.unrated, States.unrated.name),
ItemProperties(R.string.trash, States.trash.name),
ItemProperties(R.string.bad, States.bad.name),
ItemProperties(R.string.neutral, States.neutral.name),
ItemProperties(R.string.OK, States.neutral.name),
ItemProperties(R.string.good, States.good.name),
ItemProperties(R.string.favorite, States.favorite.name),
ItemProperties(R.string.Super, States.favorite.name),
),
PLAY_STATE(R.string.playstate, ItemProperties(R.string.unspecified, States.unspecified.name),
ItemProperties(R.string.building, States.building.name),

View File

@ -97,7 +97,7 @@ class Feed : RealmObject {
var hasVideoMedia: Boolean = false
var rating: Int = Rating.NEUTRAL.code
var rating: Int = Rating.OK.code
@FullText
var comment: String = ""

View File

@ -51,9 +51,9 @@ class FeedFilter(vararg properties_: String) : Serializable {
if (properties.contains(States.unrated.name)) ratingQuerys.add(" rating == ${Rating.UNRATED.code} ")
if (properties.contains(States.trash.name)) ratingQuerys.add(" rating == ${Rating.TRASH.code} ")
if (properties.contains(States.bad.name)) ratingQuerys.add(" rating == ${Rating.BAD.code} ")
if (properties.contains(States.neutral.name)) ratingQuerys.add(" rating == ${Rating.NEUTRAL.code} ")
if (properties.contains(States.OK.name)) ratingQuerys.add(" rating == ${Rating.OK.code} ")
if (properties.contains(States.good.name)) ratingQuerys.add(" rating == ${Rating.GOOD.code} ")
if (properties.contains(States.favorite.name)) ratingQuerys.add(" rating == ${Rating.FAVORITE.code} ")
if (properties.contains(States.Super.name)) ratingQuerys.add(" rating == ${Rating.SUPER.code} ")
if (ratingQuerys.isNotEmpty()) {
val query = StringBuilder(" (" + ratingQuerys[0])
if (ratingQuerys.size > 1) for (r in ratingQuerys.subList(1, ratingQuerys.size)) {
@ -120,9 +120,9 @@ class FeedFilter(vararg properties_: String) : Serializable {
unrated,
trash,
bad,
neutral,
OK,
good,
favorite,
Super,
}
enum class FeedFilterGroup(val nameRes: Int, vararg values_: ItemProperties) {
@ -131,9 +131,9 @@ class FeedFilter(vararg properties_: String) : Serializable {
RATING(R.string.rating_label, ItemProperties(R.string.unrated, States.unrated.name),
ItemProperties(R.string.trash, States.trash.name),
ItemProperties(R.string.bad, States.bad.name),
ItemProperties(R.string.neutral, States.neutral.name),
ItemProperties(R.string.OK, States.OK.name),
ItemProperties(R.string.good, States.good.name),
ItemProperties(R.string.favorite, States.favorite.name),
ItemProperties(R.string.Super, States.Super.name),
),
HAS_VIDEO(R.string.has_video, ItemProperties(R.string.yes, States.has_video.name), ItemProperties(R.string.no, States.no_video.name)),
PLAY_SPEED(R.string.play_speed, ItemProperties(R.string.global_speed, States.global_playSpeed.name), ItemProperties(R.string.custom_speed, States.custom_playSpeed.name)),

View File

@ -1,19 +1,20 @@
package ac.mdiq.podcini.storage.model
import ac.mdiq.podcini.R
import androidx.compose.ui.graphics.Color
enum class PlayState(val code: Int, val res: Int, val userSet: Boolean) {
UNSPECIFIED(-10, R.drawable.ic_questionmark, false),
BUILDING(-2, R.drawable.baseline_build_24, false),
NEW(-1, R.drawable.baseline_fiber_new_24, false),
UNPLAYED(0, R.drawable.baseline_new_label_24, true),
LATER(1, R.drawable.baseline_watch_later_24, true),
SOON(2, R.drawable.baseline_local_play_24, true),
INQUEUE(3, R.drawable.ic_playlist_play_black, false),
INPROGRESS(5, R.drawable.baseline_play_circle_outline_24, false),
SKIPPED(6, R.drawable.ic_skip_24dp, true),
PLAYED(10, R.drawable.ic_mark_played, true), // was 1
IGNORED(20, R.drawable.baseline_visibility_off_24, true);
enum class PlayState(val code: Int, val res: Int, color: Color?, val userSet: Boolean) {
UNSPECIFIED(-10, R.drawable.ic_questionmark, null, false),
BUILDING(-2, R.drawable.baseline_build_24, null, false),
NEW(-1, R.drawable.baseline_fiber_new_24, Color.Green, false),
UNPLAYED(0, R.drawable.baseline_new_label_24, null, true),
LATER(1, R.drawable.baseline_watch_later_24, Color.Green, true),
SOON(2, R.drawable.baseline_local_play_24, Color.Green, true),
INQUEUE(3, R.drawable.ic_playlist_play_black, Color.Green, false),
INPROGRESS(5, R.drawable.baseline_play_circle_outline_24, Color.Green, false),
SKIPPED(6, R.drawable.ic_skip_24dp, null, true),
PLAYED(10, R.drawable.ic_mark_played, null, true), // was 1
IGNORED(20, R.drawable.baseline_visibility_off_24, null, true);
companion object {
fun fromCode(code: Int): PlayState {

View File

@ -6,13 +6,13 @@ enum class Rating(val code: Int, val res: Int) {
UNRATED(-3, R.drawable.ic_questionmark),
TRASH(-2, R.drawable.ic_delete),
BAD(-1, androidx.media3.session.R.drawable.media3_icon_thumb_down_filled),
NEUTRAL(0, R.drawable.baseline_sentiment_neutral_24),
OK(0, R.drawable.baseline_sentiment_neutral_24),
GOOD(1, androidx.media3.session.R.drawable.media3_icon_thumb_up_filled),
FAVORITE(2, R.drawable.ic_star);
SUPER(2, R.drawable.ic_star);
companion object {
fun fromCode(code: Int): Rating {
return enumValues<Rating>().firstOrNull { it.code == code } ?: NEUTRAL
return enumValues<Rating>().firstOrNull { it.code == code } ?: OK
}
}
}

View File

@ -81,6 +81,24 @@ abstract class EpisodeActionButton internal constructor(@JvmField var item: Epis
abstract fun onClick(context: Context)
fun forItem(): EpisodeActionButton {
val media = item.media ?: return TTSActionButton(item)
val isDownloadingMedia = when (media.downloadUrl) {
null -> false
else -> DownloadServiceInterface.get()?.isDownloadingEpisode(media.downloadUrl!!)?:false
}
Logd("ItemActionButton", "forItem: local feed: ${item.feed?.isLocalFeed} downloaded: ${media.downloaded} playing: ${isCurrentlyPlaying(media)} ${item.title} ")
return when {
isCurrentlyPlaying(media) -> PauseActionButton(item)
item.feed != null && item.feed!!.isLocalFeed -> PlayLocalActionButton(item)
media.downloaded -> PlayActionButton(item)
isDownloadingMedia -> CancelDownloadActionButton(item)
isStreamOverDownload || item.feed == null || item.feedId == null || item.feed?.type == Feed.FeedType.YOUTUBE.name
|| item.feed?.preferences?.prefStreamOverDownload == true -> StreamActionButton(item)
else -> DownloadActionButton(item)
}
}
@Composable
fun AltActionsDialog(context: Context, showDialog: Boolean, onDismiss: () -> Unit) {
if (showDialog) {
@ -127,23 +145,23 @@ abstract class EpisodeActionButton internal constructor(@JvmField var item: Epis
@UnstableApi
companion object {
fun forItem(episode: Episode): EpisodeActionButton {
val media = episode.media ?: return TTSActionButton(episode)
val isDownloadingMedia = when (media.downloadUrl) {
null -> false
else -> DownloadServiceInterface.get()?.isDownloadingEpisode(media.downloadUrl!!)?:false
}
Logd("ItemActionButton", "forItem: local feed: ${episode.feed?.isLocalFeed} downloaded: ${media.downloaded} playing: ${isCurrentlyPlaying(media)} ${episode.title} ")
return when {
isCurrentlyPlaying(media) -> PauseActionButton(episode)
episode.feed != null && episode.feed!!.isLocalFeed -> PlayLocalActionButton(episode)
media.downloaded -> PlayActionButton(episode)
isDownloadingMedia -> CancelDownloadActionButton(episode)
isStreamOverDownload || episode.feed == null || episode.feedId == null || episode.feed?.type == Feed.FeedType.YOUTUBE.name
|| episode.feed?.preferences?.prefStreamOverDownload == true -> StreamActionButton(episode)
else -> DownloadActionButton(episode)
}
}
// fun forItem(episode: Episode): EpisodeActionButton {
// val media = episode.media ?: return TTSActionButton(episode)
// val isDownloadingMedia = when (media.downloadUrl) {
// null -> false
// else -> DownloadServiceInterface.get()?.isDownloadingEpisode(media.downloadUrl!!)?:false
// }
// Logd("ItemActionButton", "forItem: local feed: ${episode.feed?.isLocalFeed} downloaded: ${media.downloaded} playing: ${isCurrentlyPlaying(media)} ${episode.title} ")
// return when {
// isCurrentlyPlaying(media) -> PauseActionButton(episode)
// episode.feed != null && episode.feed!!.isLocalFeed -> PlayLocalActionButton(episode)
// media.downloaded -> PlayActionButton(episode)
// isDownloadingMedia -> CancelDownloadActionButton(episode)
// isStreamOverDownload || episode.feed == null || episode.feedId == null || episode.feed?.type == Feed.FeedType.YOUTUBE.name
// || episode.feed?.preferences?.prefStreamOverDownload == true -> StreamActionButton(episode)
// else -> DownloadActionButton(episode)
// }
// }
fun playVideoIfNeeded(context: Context, media: Playable) {
val item = (media as? EpisodeMedia)?.episode
@ -255,7 +273,6 @@ class PlayActionButton(item: Episode) : EpisodeActionButton(item) {
}
class DeleteActionButton(item: Episode) : EpisodeActionButton(item) {
override val visibility: Boolean
get() {
return item.media != null && (item.media!!.downloaded || item.feed?.isLocalFeed == true)
@ -274,6 +291,17 @@ class DeleteActionButton(item: Episode) : EpisodeActionButton(item) {
}
}
class NullActionButton(item: Episode) : EpisodeActionButton(item) {
override fun getLabel(): Int {
return R.string.null_label
}
override fun getDrawable(): Int {
return R.drawable.ic_questionmark
}
@UnstableApi
override fun onClick(context: Context) {}
}
class PauseActionButton(item: Episode) : EpisodeActionButton(item) {
override fun getLabel(): Int {
return R.string.pause_label
@ -405,7 +433,7 @@ class TTSActionButton(item: Episode) : EpisodeActionButton(item) {
return
}
processing = 0.01f
item.setBuilding()
item.playState = PlayState.BUILDING.code
EventFlow.postEvent(FlowEvent.EpisodeEvent.updated(item))
RealmDB.runOnIOScope {
if (item.transcript == null) {

View File

@ -728,7 +728,7 @@ class VideoplayerActivity : CastEnabledActivity() {
withContext(Dispatchers.Main) {
Logd(TAG, "load() item ${episode?.id}")
if (episode != null) {
val isFav = episode!!.isFavorite
val isFav = episode!!.isSUPER
if (isFavorite != isFav) {
isFavorite = isFav
invalidateOptionsMenu(activity)

View File

@ -32,8 +32,10 @@ import ac.mdiq.podcini.storage.model.Feed.Companion.newId
import ac.mdiq.podcini.storage.utils.DurationConverter
import ac.mdiq.podcini.storage.utils.EpisodeUtil.hasAlmostEnded
import ac.mdiq.podcini.storage.utils.ImageResourceUtils
import ac.mdiq.podcini.ui.actions.DownloadActionButton
import ac.mdiq.podcini.ui.actions.EpisodeActionButton
import ac.mdiq.podcini.ui.actions.EpisodeActionButton.Companion.forItem
//import ac.mdiq.podcini.ui.actions.EpisodeActionButton.Companion.forItem
import ac.mdiq.podcini.ui.actions.NullActionButton
import ac.mdiq.podcini.ui.actions.SwipeAction
import ac.mdiq.podcini.ui.activity.MainActivity
import ac.mdiq.podcini.ui.fragment.EpisodeInfoFragment
@ -140,11 +142,12 @@ class EpisodeVM(var episode: Episode) {
var ratingState by mutableIntStateOf(episode.rating)
var inProgressState by mutableStateOf(episode.isInProgress)
var downloadState by mutableIntStateOf(if (episode.media?.downloaded == true) DownloadStatus.State.COMPLETED.ordinal else DownloadStatus.State.UNKNOWN.ordinal)
var actionButton by mutableStateOf(forItem(episode))
// var actionButton by mutableStateOf(forItem(episode))
var actionButton by mutableStateOf<EpisodeActionButton>(NullActionButton(episode))
var actionRes by mutableIntStateOf(actionButton.getDrawable())
var showAltActionsDialog by mutableStateOf(false)
var dlPercent by mutableIntStateOf(0)
var inQueueState by mutableStateOf(curQueue.contains(episode))
// var inQueueState by mutableStateOf(curQueue.contains(episode))
var isSelected by mutableStateOf(false)
var prog by mutableFloatStateOf(0f)
@ -196,6 +199,7 @@ class EpisodeVM(var episode: Episode) {
withContext(Dispatchers.Main) {
positionState = changes.obj.media?.position ?: 0
inProgressState = changes.obj.isInProgress
downloadState = if (changes.obj.media?.downloaded == true) DownloadStatus.State.COMPLETED.ordinal else DownloadStatus.State.UNKNOWN.ordinal
Logd("EpisodeVM", "mediaMonitor $positionState $inProgressState ${episode.title}")
episode = changes.obj
// Logd("EpisodeVM", "mediaMonitor downloaded: ${changes.obj.media?.downloaded} ${episode.media?.downloaded}")
@ -711,10 +715,10 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: MutableList<EpisodeVM>, feed:
}
Logd(TAG, "long clicked: ${vm.episode.title}")
})) {
LaunchedEffect(key1 = queueChanged) {
if (index >= vms.size) return@LaunchedEffect
vms[index].inQueueState = curQueue.contains(vms[index].episode)
}
// LaunchedEffect(key1 = queueChanged) {
// if (index >= vms.size) return@LaunchedEffect
// vms[index].inQueueState = curQueue.contains(vms[index].episode)
// }
Row(verticalAlignment = Alignment.CenterVertically) {
// Logd(TAG, "info row")
val ratingIconRes = Rating.fromCode(vm.ratingState).res
@ -735,6 +739,7 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: MutableList<EpisodeVM>, feed:
}
Text(vm.episode.title ?: "", color = textColor, maxLines = 2, overflow = TextOverflow.Ellipsis)
}
var actionButton by remember(vm.episode.id) { mutableStateOf(vm.actionButton.forItem()) }
fun isDownloading(): Boolean {
return vms[index].downloadState > DownloadStatus.State.UNKNOWN.ordinal && vms[index].downloadState < DownloadStatus.State.COMPLETED.ordinal
}
@ -744,28 +749,32 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: MutableList<EpisodeVM>, feed:
if (isDownloading()) vm.dlPercent = dls?.getProgress(vms[index].episode.media?.downloadUrl ?: "") ?: 0
Logd(TAG, "LaunchedEffect $index isPlayingState: ${vms[index].isPlayingState} ${vms[index].episode.title}")
Logd(TAG, "LaunchedEffect $index downloadState: ${vms[index].downloadState} ${vm.episode.media?.downloaded} ${vm.dlPercent}")
vm.actionButton = forItem(vm.episode)
// vm.actionRes = vm.actionButton!!.getDrawable()
vm.actionButton = vm.actionButton.forItem()
actionButton = vm.actionButton
}
} else {
LaunchedEffect(Unit) {
Logd(TAG, "LaunchedEffect init actionButton")
vm.actionButton = actionButton_(vm.episode)
actionButton = vm.actionButton
// vm.actionRes = vm.actionButton!!.getDrawable()
}
}
Box(contentAlignment = Alignment.Center, modifier = Modifier.width(40.dp).height(40.dp).padding(end = 10.dp).align(Alignment.CenterVertically)
.pointerInput(Unit) {
detectTapGestures(onLongPress = { vms[index].showAltActionsDialog = true },
onTap = { vms[index].actionButton.onClick(activity) })
onTap = {
// vms[index].actionButton.onClick(activity)
actionButton.onClick(activity)
})
}, ) {
// Logd(TAG, "button box")
vm.actionRes = vm.actionButton.getDrawable()
vm.actionRes = actionButton.getDrawable()
Icon(imageVector = ImageVector.vectorResource(vm.actionRes), tint = textColor, contentDescription = null, modifier = Modifier.width(28.dp).height(32.dp))
if (isDownloading() && vm.dlPercent >= 0) CircularProgressIndicator(progress = { 0.01f * vm.dlPercent },
strokeWidth = 4.dp, color = textColor, modifier = Modifier.width(30.dp).height(35.dp))
}
if (vm.showAltActionsDialog) vm.actionButton.AltActionsDialog(activity, vm.showAltActionsDialog,
if (vm.showAltActionsDialog) actionButton.AltActionsDialog(activity, vm.showAltActionsDialog,
onDismiss = { vm.showAltActionsDialog = false })
}
}

View File

@ -69,7 +69,7 @@ class AllEpisodesFragment : BaseEpisodesFragment() {
loadItemsRunning = false
}
if (allEpisodes.isEmpty()) return listOf()
allEpisodes = allEpisodes.filter { filter.matchesForQueues(it) }
// allEpisodes = allEpisodes.filter { filter.matchesForQueues(it) }
return allEpisodes
}

View File

@ -369,7 +369,7 @@ import java.util.*
episodes.clear()
episodes.addAll(currentDownloads)
}
episodes.retainAll { filter.matchesForQueues(it) }
// episodes.retainAll { filter.matchesForQueues(it) }
withContext(Dispatchers.Main) {
vms.clear()
for (e in episodes) vms.add(EpisodeVM(e))

View File

@ -220,7 +220,7 @@ class EpisodeInfoFragment : Fragment(), Toolbar.OnMenuItemClickListener {
// }
// }
}))
if (episode?.media != null) {
if (episode?.media != null && !inQueue) {
Spacer(modifier = Modifier.weight(0.2f))
val inQueueIconRes = if (inQueue) R.drawable.ic_playlist_play else R.drawable.ic_playlist_remove
Icon(imageVector = ImageVector.vectorResource(inQueueIconRes), tint = MaterialTheme.colorScheme.tertiary, contentDescription = "inQueue",

View File

@ -172,7 +172,7 @@ import java.util.concurrent.Semaphore
requireActivity().supportFragmentManager.executePendingTransactions()
}
if (showFilterDialog) EpisodesFilterDialog(filter = feed!!.episodeFilter,
filtersDisabled = mutableSetOf(EpisodeFilter.EpisodesFilterGroup.DOWNLOADED, EpisodeFilter.EpisodesFilterGroup.MEDIA),
// filtersDisabled = mutableSetOf(EpisodeFilter.EpisodesFilterGroup.DOWNLOADED, EpisodeFilter.EpisodesFilterGroup.MEDIA),
onDismissRequest = { showFilterDialog = false } ) { filterValues ->
if (feed != null) {
Logd(TAG, "persist Episode Filter(): feedId = [${feed?.id}], filterValues = [$filterValues]")
@ -238,7 +238,7 @@ import java.util.concurrent.Semaphore
cancelFlowEvents()
}
@kotlin.OptIn(ExperimentalFoundationApi::class)
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun FeedEpisodesHeader(activity: MainActivity, filterButColor: Color, filterClickCB: ()->Unit, filterLongClickCB: ()->Unit) {
val textColor = MaterialTheme.colorScheme.onSurface

View File

@ -375,6 +375,20 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener {
val feedList_ = getFeedList(fQueryStr).toMutableList()
val feedOrder = feedOrderBy
val dir = 1 - 2*feedOrderDir // get from 0, 1 to 1, -1
fun comparator(counterMap: Map<Long, Long>, dir: Int): Comparator<Feed> {
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 -> -dir
counterLhs == counterRhs -> (lhs.title?.compareTo(rhs.title!!, ignoreCase = true) ?: -1) * dir
else -> dir
}
}
}
val comparator: Comparator<Feed> = when (feedOrder) {
FeedSortOrder.UNPLAYED_NEW_OLD.index -> {
// val queryString = "feedId == $0 AND (playState == ${PlayState.NEW.code} OR playState == ${PlayState.UNPLAYED.code})"
@ -483,19 +497,6 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener {
return feedList_.sortedWith(comparator)
}
private fun comparator(counterMap: Map<Long, Long>, dir: Int): Comparator<Feed> {
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 -> -dir
counterLhs == counterRhs -> (lhs.title?.compareTo(rhs.title!!, ignoreCase = true) ?: -1) * dir
else -> dir
}
}
}
@Composable
fun InforBar() {
Row(Modifier.padding(start = 20.dp, end = 20.dp)) {
@ -903,8 +904,8 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener {
if (feed.rating != Rating.UNRATED.code)
Icon(imageVector = ImageVector.vectorResource(Rating.fromCode(feed.rating).res), tint = MaterialTheme.colorScheme.tertiary, contentDescription = "rating",
modifier = Modifier.background(MaterialTheme.colorScheme.tertiaryContainer).constrainAs(rating) {
start.linkTo(parent.start)
centerVerticallyTo(coverImage)
start.linkTo(coverImage.start)
bottom.linkTo(coverImage.bottom)
})
// TODO: need to use state
if (feed.lastUpdateFailed) Icon(imageVector = ImageVector.vectorResource(R.drawable.ic_error), tint = Color.Red, contentDescription = "error",

View File

@ -165,7 +165,7 @@ sealed class FlowEvent {
// TODO: need better handling at receving end
data class EpisodePlayedEvent(val episode: Episode? = null) : FlowEvent()
data class RatingEvent(val episode: Episode, val rating: Int = Rating.FAVORITE.code) : FlowEvent()
data class RatingEvent(val episode: Episode, val rating: Int = Rating.SUPER.code) : FlowEvent()
// data class AllEpisodesFilterEvent(val filterValues: Set<String?>?) : FlowEvent()

View File

@ -422,7 +422,7 @@
<string name="pref_unpauseOnHeadsetReconnect_title">إعادة توصيل سماعات الرأس</string>
<string name="pref_unpauseOnBluetoothReconnect_title">إعادة توصيل البلوتوث</string>
<string name="pref_stream_over_download_title">أفضّل البث التدفقي</string>
<string name="pref_mobileUpdate_title">التحديث باستخدام شبكة الجوال</string>
<string name="pref_mobileUpdate_sum">حدد ما يجب السماح به أثناء الاتصال على شبكة الجوال</string>
<string name="pref_mobileUpdate_refresh">تحديث البودكاست</string>
<string name="pref_mobileUpdate_images">صور الغلاف</string>

View File

@ -372,7 +372,7 @@
<string name="pref_unpauseOnHeadsetReconnect_title">Reconnexió d\'auriculars</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Reconnexió de Bluetooth</string>
<string name="pref_stream_over_download_title">Preferir escoltar en directe</string>
<string name="pref_mobileUpdate_title">Actualitza fent servir dades mòbils</string>
<string name="pref_mobileUpdate_sum">Selecciona què és permès a la connexió de la xarxa mòbil</string>
<string name="pref_mobileUpdate_refresh">Refrescar podcast</string>
<string name="pref_mobileUpdate_images">Cobre images</string>

View File

@ -414,7 +414,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Opětovné připojení Bluetooth</string>
<string name="pref_stream_over_download_title">Upřednostnit streamování</string>
<string name="pref_stream_over_download_sum">Zobrazit tlačítko streamovat místo tlačítka stáhnout v seznamech.</string>
<string name="pref_mobileUpdate_title">Aktualizace přes mobilní data</string>
<string name="pref_mobileUpdate_sum">Vyberte, co by mělo být povoleno přes mobilní data</string>
<string name="pref_mobileUpdate_refresh">Obnovit podcast</string>
<string name="pref_mobileUpdate_images">Obrázky podcastů/epizod</string>

View File

@ -389,7 +389,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth forbundet igen</string>
<string name="pref_stream_over_download_title">Foretræk streaming</string>
<string name="pref_stream_over_download_sum">Vis stream-knap i stedet for overfør-knap i lister</string>
<string name="pref_mobileUpdate_title">Mobilopdateringer</string>
<string name="pref_mobileUpdate_sum">Vælg hvad der skal være tilladt via mobil dataforbindelse</string>
<string name="pref_mobileUpdate_refresh">Opdatering af podcast</string>
<string name="pref_mobileUpdate_images">Billeder</string>

View File

@ -393,7 +393,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth wieder verbunden</string>
<string name="pref_stream_over_download_title">Streaming bevorzugen</string>
<string name="pref_stream_over_download_sum">Stream-Button anstatt Download-Button in Listen anzeigen</string>
<string name="pref_mobileUpdate_title">Mobile Aktualisierungen</string>
<string name="pref_mobileUpdate_sum">Auswählen, was über mobile Daten erlaubt sein soll</string>
<string name="pref_mobileUpdate_refresh">Aktualisierung der Podcasts</string>
<string name="pref_mobileUpdate_images">Titelbilder</string>

View File

@ -404,7 +404,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Reconectar con Bluetooth</string>
<string name="pref_stream_over_download_title">Preferir escuchar en directo</string>
<string name="pref_stream_over_download_sum">Mostrar el botón de escuchar en directo en vez del botón de descarga en las listas</string>
<string name="pref_mobileUpdate_title">Actualizaciones vía datos móviles</string>
<string name="pref_mobileUpdate_sum">Seleccionar lo que se debe permitir descargar con datos móviles</string>
<string name="pref_mobileUpdate_refresh">Actualizar podcast</string>
<string name="pref_mobileUpdate_images">Imágenes de portada</string>

View File

@ -376,7 +376,7 @@
<string name="pref_unpauseOnHeadsetReconnect_title">وصل دوبارهٔ گوشی</string>
<string name="pref_unpauseOnBluetoothReconnect_title">وصل دوبارهٔ بلوتوث</string>
<string name="pref_stream_over_download_title">ترجیح جریان</string>
<string name="pref_mobileUpdate_title">به‌روز رسانی‌های همراه</string>
<string name="pref_mobileUpdate_sum">آنچه که باید از طریق اتصال داده تلفن همراه مجاز است را انتخاب کنید</string>
<string name="pref_mobileUpdate_refresh">تازه سازی پادکست</string>
<string name="pref_mobileUpdate_images">تصویر جلد</string>

View File

@ -366,7 +366,7 @@
<string name="pref_unpauseOnHeadsetReconnect_title">Kuulokkeiden uudelleenyhdistyminen</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetoothin uudelleenyhdistyminen</string>
<string name="pref_stream_over_download_title">Suosi suoratoistoa</string>
<string name="pref_mobileUpdate_title">Mobiilipäivitykset</string>
<string name="pref_mobileUpdate_sum">Valitse, mikä on sallittua mobiiliyhteydellä</string>
<string name="pref_mobileUpdate_refresh">Podcastien päivitys</string>
<string name="pref_mobileUpdate_images">Kansikuvat</string>

View File

@ -405,7 +405,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Connexion du Bluetooth</string>
<string name="pref_stream_over_download_title">Préférer le streaming</string>
<string name="pref_stream_over_download_sum">Afficher dans les listes le bouton du streaming au lieu de celui du téléchargement</string>
<string name="pref_mobileUpdate_title">Utilisation de la connexion mobile</string>
<string name="pref_mobileUpdate_sum">Choisir ce qui est autorisé lorsque la connexion mobile est utilisée</string>
<string name="pref_mobileUpdate_refresh">Mise à jour des podcasts</string>
<string name="pref_mobileUpdate_images">Récupération des images</string>

View File

@ -388,7 +388,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Reconexión bluetooth</string>
<string name="pref_stream_over_download_title">Preferir retransmisión</string>
<string name="pref_stream_over_download_sum">Nas listas, mostrar botón de difusión no lugar do botón de descarga</string>
<string name="pref_mobileUpdate_title">Actualización con móbil</string>
<string name="pref_mobileUpdate_sum">Escolle o que estará permitido utilizando conexión de datos do móbil</string>
<string name="pref_mobileUpdate_refresh">Actualizar podcast</string>
<string name="pref_mobileUpdate_images">Imaxes de portadas</string>

View File

@ -405,7 +405,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Riconnessione Bluetooth</string>
<string name="pref_stream_over_download_title">Preferisci streaming</string>
<string name="pref_stream_over_download_sum">Negli elenchi mostra il tasto stream al posto del tasto download</string>
<string name="pref_mobileUpdate_title">Aggiornamenti su rete mobile</string>
<string name="pref_mobileUpdate_sum">Seleziona quali operazioni sono consentite su reti mobili</string>
<string name="pref_mobileUpdate_refresh">Aggiornamento podcast</string>
<string name="pref_mobileUpdate_images">Copertine</string>

View File

@ -413,7 +413,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">חיבור Bluetooth מחדש</string>
<string name="pref_stream_over_download_title">העדפת הזרמה</string>
<string name="pref_stream_over_download_sum">הצגת כפתור הזרמה במקום כפתור הורדה ברשימות</string>
<string name="pref_mobileUpdate_title">עדכונים דרך רשת סלולרית</string>
<string name="pref_mobileUpdate_sum">לבחור מה מותר דרך חיבור רשת סלולרית</string>
<string name="pref_mobileUpdate_refresh">רענון פודקאסטים</string>
<string name="pref_mobileUpdate_images">תמונות נושא</string>

View File

@ -357,7 +357,7 @@
<string name="pref_unpauseOnHeadsetReconnect_title">헤드폰 재연결</string>
<string name="pref_unpauseOnBluetoothReconnect_title">블루투스 다시 연결</string>
<string name="pref_stream_over_download_title">스트리밍 선호</string>
<string name="pref_mobileUpdate_title">휴대전화 망 업데이트</string>
<string name="pref_mobileUpdate_sum">휴대전화 데이터 연결을 통해 무엇을 허용할지 선택합니다.</string>
<string name="pref_mobileUpdate_refresh">팟캐스트 새로 고침</string>
<string name="pref_mobileUpdate_images">커버 이미지</string>

View File

@ -364,7 +364,7 @@
<string name="pref_unpauseOnHeadsetReconnect_title">Gjeninnkopling av hodetelefoner</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Blutetooth tilkoblet igjen</string>
<string name="pref_stream_over_download_title">Foretrekk strømming</string>
<string name="pref_mobileUpdate_title">Mobiloppdateringer</string>
<string name="pref_mobileUpdate_sum">Velg hva som skal tillates over mobildata</string>
<string name="pref_mobileUpdate_refresh">Last podkast på nytt</string>
<string name="pref_mobileUpdate_images">Cover-bilder</string>

View File

@ -380,7 +380,7 @@
<string name="pref_pauseOnHeadsetDisconnect_title">Fones de ouvido ou Bluetooth desconectado</string>
<string name="pref_unpauseOnHeadsetReconnect_title">Fones de ouvido reconectados</string>
<string name="pref_stream_over_download_title">Preferir streaming</string>
<string name="pref_mobileUpdate_title">Atualização usando dados móveis</string>
<string name="pref_mobileUpdate_sum">Selecione o que deve ser permitido na conexão de dados móveis</string>
<string name="pref_mobileUpdate_refresh">Atualizar podcast</string>
<string name="pref_mobileUpdate_images">Imagens de capa</string>

View File

@ -404,7 +404,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Ligação bluetooth</string>
<string name="pref_stream_over_download_title">Preferir emissão</string>
<string name="pref_stream_over_download_sum">Mostrar botão de emissão em vez do botão para descarregar</string>
<string name="pref_mobileUpdate_title">Dados móveis</string>
<string name="pref_mobileUpdate_sum">Selecione o que pode ser permitido através de dados móveis</string>
<string name="pref_mobileUpdate_refresh">Atualização de podcasts</string>
<string name="pref_mobileUpdate_images">Descarga de imagens</string>

View File

@ -401,7 +401,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Reconectare Bluetooth</string>
<string name="pref_stream_over_download_title">Preferă streamingul</string>
<string name="pref_stream_over_download_sum">Afișează butonul de stream în locul butonului de descărcare</string>
<string name="pref_mobileUpdate_title">Actualizări mobile</string>
<string name="pref_mobileUpdate_sum">Selectează ce ar trebui să fie permis să folosească conexiunea de date mobile</string>
<string name="pref_mobileUpdate_refresh">Reîmprospătare podcast</string>
<string name="pref_mobileUpdate_images">Imagine de copertă</string>

View File

@ -393,7 +393,7 @@
<string name="pref_unpauseOnHeadsetReconnect_title">При подключении наушников</string>
<string name="pref_unpauseOnBluetoothReconnect_title">При подключении Bluetooth</string>
<string name="pref_stream_over_download_title">Трансляция вместо загрузки</string>
<string name="pref_mobileUpdate_title">Обновления в мобильной сети</string>
<string name="pref_mobileUpdate_sum">Выберите, что разрешено загружать через мобильное подключение</string>
<string name="pref_mobileUpdate_refresh">Обновление подкастов</string>
<string name="pref_mobileUpdate_images">Обложки</string>

View File

@ -413,7 +413,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth znovu pripojené</string>
<string name="pref_stream_over_download_title">Uprednostniť streamovanie</string>
<string name="pref_stream_over_download_sum">V zoznamoch zobraziť tlačidlo streamovať namiesto tlačidla stiahnuť</string>
<string name="pref_mobileUpdate_title">Mobilná aktualizácia</string>
<string name="pref_mobileUpdate_sum">Vyberte, co by malo byť povolené cez mobilné dáta</string>
<string name="pref_mobileUpdate_refresh">Obnoviť podcast</string>
<string name="pref_mobileUpdate_images">Obrázky podcastov/epizód</string>

View File

@ -389,7 +389,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Blutetooth återansluts</string>
<string name="pref_stream_over_download_title">Föredra strömmning</string>
<string name="pref_stream_over_download_sum">Visa knappen för strömming iställer för nedladdning i listor</string>
<string name="pref_mobileUpdate_title">Mobila uppdateringar</string>
<string name="pref_mobileUpdate_sum">Välj vad som ska tillåtas över mobila dataanslutningar</string>
<string name="pref_mobileUpdate_refresh">Uppdatera podcasts</string>
<string name="pref_mobileUpdate_images">Omslagsbilder</string>

View File

@ -374,7 +374,7 @@
<string name="pref_unpauseOnHeadsetReconnect_title">Kulaklıklar yeniden bağlanıyor</string>
<string name="pref_unpauseOnBluetoothReconnect_title">Bluetooth yeniden bağlanıyor</string>
<string name="pref_stream_over_download_title">İndirmeden dinle</string>
<string name="pref_mobileUpdate_title">Mobil güncellemeler</string>
<string name="pref_mobileUpdate_sum">Mobil veri üzerinden nelere izin verileceğini seçiniz</string>
<string name="pref_mobileUpdate_refresh">Podcast yenileme</string>
<string name="pref_mobileUpdate_images">Kapak görselleri</string>

View File

@ -413,7 +413,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">Повторне підключення через Bluetooth</string>
<string name="pref_stream_over_download_title">Надавати перевагу стрімінгу</string>
<string name="pref_stream_over_download_sum">Відображати кнопку стріму замість кнопки завантаження у списках</string>
<string name="pref_mobileUpdate_title">Оновлення через мобільні дані</string>
<string name="pref_mobileUpdate_sum">Виберіть, що має бути дозволено через мобільне з\'єднання для передачі даних</string>
<string name="pref_mobileUpdate_refresh">Оновлення подкасту</string>
<string name="pref_mobileUpdate_images">Обкладинки зображень</string>

View File

@ -381,7 +381,7 @@
<string name="pref_unpauseOnBluetoothReconnect_title">蓝牙重连</string>
<string name="pref_stream_over_download_title">偏好在线</string>
<string name="pref_stream_over_download_sum">在列表中显示在线播放按钮而不是下载按钮</string>
<string name="pref_mobileUpdate_title">移动数据更新</string>
<string name="pref_mobileUpdate_sum">选择使用移动数据连接时应当允许的内容</string>
<string name="pref_mobileUpdate_refresh">播客刷新 </string>
<string name="pref_mobileUpdate_images">封面图片</string>

View File

@ -68,7 +68,6 @@
<item>@string/pref_mobileUpdate_images</item>
<item>@string/synchronization_pref</item>
</string-array>
<string-array name="mobile_update_values">
<item>feed_refresh</item>
<item>episode_download</item>

View File

@ -256,6 +256,7 @@
<string name="stream_label">Stream</string>
<string name="erase_episodes_label">Erase episodes</string>
<string name="reserve_episodes_label">Reserve episodes</string>
<string name="null_label">Null</string>
<string name="delete_label">Delete</string>
<string name="delete_failed">Unable to delete file. Rebooting the device could help.</string>
<string name="delete_local_failed">Unable to delete file. Try re-connecting the local folder from the podcast info screen.</string>
@ -303,9 +304,9 @@
<string name="unrated">Unrated</string>
<string name="trash">Trash</string>
<string name="bad">Bad</string>
<string name="neutral">Neutral</string>
<string name="OK">OK</string>
<string name="good">Good</string>
<string name="favorite">Favorite</string>
<string name="Super">Super</string>
<string name="set_rating_label">Set rating</string>
<string name="playstate">Play state</string>
<string name="unspecified">Unspecified</string>
@ -520,7 +521,7 @@
<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_metered_network_title">Metered network settings</string>
<string name="pref_mobileUpdate_sum">Select what should be allowed over the mobile data connection</string>
<string name="pref_mobileUpdate_refresh">Podcast refresh</string>
<string name="pref_mobileUpdate_images">Cover images</string>

View File

@ -53,7 +53,7 @@
android:entryValues="@array/mobile_update_values"
android:key="prefMobileUpdateTypes"
android:summary="@string/pref_mobileUpdate_sum"
android:title="@string/pref_mobileUpdate_title"/>
android:title="@string/pref_metered_network_title"/>
<Preference
android:key="prefProxy"
android:summary="@string/pref_proxy_sum"

View File

@ -1,7 +1,21 @@
# 6.12.8
* set episode's playState to Skipped when its media file is removed
* in AutoDownloadPolicy, Newer or Older now include episodes with playState of New, Unplayed, Later and Soon
* naming change in Rating: Neutral -> OK, Favorite -> Super
* in EpisodeInfo header, only show "add to queue" icon when the episode is not in queue
* in-queue icon is no longer shown on episodes lists
* reduced start lag when opening a large episodes list
* likely fixed the action button not updating issue after download in episodes lists
* in grid layout of Subscriptions view, moved the rating icon to the lower left corner
* in FeedEpisodes view, enabled Downloaded and HasMedia filters
* changed in Settings -> Downloads, "Mobile updates" to "Metered network settings"
* the setting applies to metered mobile and wifi networks
# 6.12.7
* fixed issue in auto-download where number of played is not correctly counted
* in AutoDownloadPolicy, Newer or Older now means include episodes with playState not being Skipped, Played, and Ignored
* in AutoDownloadPolicy, Newer or Older now include episodes with playState not being Skipped, Played, and Ignored
* in Subscriptions sorting, Played means Skipped, Played, or Ignored, Unplayed means any state lower than Skipped
* fixed high CPU usage in Download view
* removed a few useless classes and the useless test modules

View File

@ -0,0 +1,13 @@
Version 6.12.8
* set episode's playState to Skipped when its media file is removed
* in AutoDownloadPolicy, Newer or Older now include episodes with playState of New, Unplayed, Later and Soon
* naming change in Rating: Neutral -> OK, Favorite -> Super
* in EpisodeInfo header, only show "add to queue" icon when the episode is not in queue
* in-queue icon is no longer shown on episodes lists
* reduced start lag when opening a large episodes list
* likely fixed the action button not updating issue after download in episodes lists
* in grid layout of Subscriptions view, moved the rating icon to the lower left corner
* in FeedEpisodes view, enabled Downloaded and HasMedia filters
* changed in Settings -> Downloads, "Mobile updates" to "Metered network settings"
* the setting applies to metered mobile and wifi networks