6.12.8 commit
This commit is contained in:
parent
d87bc718d3
commit
70d4f9c70f
|
@ -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 = ""
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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!!)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 -> {}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 = ""
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
16
changelog.md
16
changelog.md
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue