6.1.1 commit
This commit is contained in:
parent
76e350ff72
commit
d47bdab971
|
@ -126,8 +126,8 @@ android {
|
||||||
buildConfig true
|
buildConfig true
|
||||||
}
|
}
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
versionCode 3020214
|
versionCode 3020215
|
||||||
versionName "6.1.0"
|
versionName "6.1.1"
|
||||||
|
|
||||||
applicationId "ac.mdiq.podcini.R"
|
applicationId "ac.mdiq.podcini.R"
|
||||||
def commit = ""
|
def commit = ""
|
||||||
|
|
|
@ -95,7 +95,8 @@ class OpmlBackupAgent : BackupAgentHelper() {
|
||||||
IOUtils.closeQuietly(writer)
|
IOUtils.closeQuietly(writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@OptIn(UnstableApi::class) override fun restoreEntity(data: BackupDataInputStream) {
|
@OptIn(UnstableApi::class)
|
||||||
|
override fun restoreEntity(data: BackupDataInputStream) {
|
||||||
Logd(TAG, "Backup restore")
|
Logd(TAG, "Backup restore")
|
||||||
if (OPML_ENTITY_KEY != data.key) {
|
if (OPML_ENTITY_KEY != data.key) {
|
||||||
Logd(TAG, "Unknown entity key: " + data.key)
|
Logd(TAG, "Unknown entity key: " + data.key)
|
||||||
|
@ -103,6 +104,7 @@ class OpmlBackupAgent : BackupAgentHelper() {
|
||||||
}
|
}
|
||||||
var digester: MessageDigest? = null
|
var digester: MessageDigest? = null
|
||||||
var reader: Reader
|
var reader: Reader
|
||||||
|
var linesRead = 0
|
||||||
try {
|
try {
|
||||||
digester = MessageDigest.getInstance("MD5")
|
digester = MessageDigest.getInstance("MD5")
|
||||||
reader = InputStreamReader(DigestInputStream(data, digester), Charset.forName("UTF-8"))
|
reader = InputStreamReader(DigestInputStream(data, digester), Charset.forName("UTF-8"))
|
||||||
|
@ -112,25 +114,30 @@ class OpmlBackupAgent : BackupAgentHelper() {
|
||||||
try {
|
try {
|
||||||
mChecksum = digester?.digest() ?: byteArrayOf()
|
mChecksum = digester?.digest() ?: byteArrayOf()
|
||||||
BufferedReader(reader).use { bufferedReader ->
|
BufferedReader(reader).use { bufferedReader ->
|
||||||
val tempFile = File.createTempFile("opml_restored", ".tmp", mContext.filesDir)
|
val tempFile = File(mContext.filesDir, "opml_restored.txt")
|
||||||
|
// val tempFile = File.createTempFile("opml_restored", ".tmp", mContext.filesDir)
|
||||||
FileWriter(tempFile).use { fileWriter ->
|
FileWriter(tempFile).use { fileWriter ->
|
||||||
while (true) {
|
while (true) {
|
||||||
val line = bufferedReader.readLine() ?: break
|
val line = bufferedReader.readLine() ?: break
|
||||||
|
Logd(TAG, "restoreEntity: $linesRead $line")
|
||||||
|
linesRead++
|
||||||
fileWriter.write(line)
|
fileWriter.write(line)
|
||||||
fileWriter.write(System.lineSeparator()) // Write a newline character
|
fileWriter.write(System.lineSeparator()) // Write a newline character
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext)
|
|
||||||
with(sharedPreferences.edit()) {
|
|
||||||
putBoolean(UserPreferences.Prefs.prefOPMLRestore.name, true)
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
} catch (e: XmlPullParserException) {
|
} catch (e: XmlPullParserException) {
|
||||||
Log.e(TAG, "Error while parsing the OPML file", e)
|
Log.e(TAG, "Error while parsing the OPML file", e)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.e(TAG, "Failed to restore OPML backup", e)
|
Log.e(TAG, "Failed to restore OPML backup", e)
|
||||||
} finally {
|
} finally {
|
||||||
|
if (linesRead > 0) {
|
||||||
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||||
|
with(sharedPreferences.edit()) {
|
||||||
|
putBoolean(UserPreferences.Prefs.prefOPMLRestore.name, true)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
IOUtils.closeQuietly(reader)
|
IOUtils.closeQuietly(reader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,11 +173,12 @@ class OpmlBackupAgent : BackupAgentHelper() {
|
||||||
private const val OPML_BACKUP_KEY = "opml"
|
private const val OPML_BACKUP_KEY = "opml"
|
||||||
|
|
||||||
val isOPMLRestared: Boolean
|
val isOPMLRestared: Boolean
|
||||||
get() = appPrefs.getBoolean(UserPreferences.Prefs.prefOPMLRestore.name, true)
|
get() = appPrefs.getBoolean(UserPreferences.Prefs.prefOPMLRestore.name, false)
|
||||||
|
|
||||||
fun performRestore(context: Context) {
|
fun performRestore(context: Context) {
|
||||||
Logd(TAG, "performRestore")
|
Logd(TAG, "performRestore")
|
||||||
val tempFile = File.createTempFile("opml_restored", ".tmp", context.filesDir)
|
val tempFile = File(context.filesDir, "opml_restored.txt")
|
||||||
|
// val tempFile = File.createTempFile("opml_restored", ".tmp", context.filesDir)
|
||||||
if (tempFile.exists()) {
|
if (tempFile.exists()) {
|
||||||
val reader = FileReader(tempFile)
|
val reader = FileReader(tempFile)
|
||||||
val opmlElements = OpmlReader().readDocument(reader)
|
val opmlElements = OpmlReader().readDocument(reader)
|
||||||
|
@ -179,6 +187,7 @@ class OpmlBackupAgent : BackupAgentHelper() {
|
||||||
feed.episodes.clear()
|
feed.episodes.clear()
|
||||||
updateFeed(context, feed, false)
|
updateFeed(context, feed, false)
|
||||||
}
|
}
|
||||||
|
Toast.makeText(context, "${opmlElements.size} feeds were restored", Toast.LENGTH_SHORT).show()
|
||||||
runOnce(context)
|
runOnce(context)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(context, "No backup data found", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "No backup data found", Toast.LENGTH_SHORT).show()
|
||||||
|
|
|
@ -12,6 +12,7 @@ import ac.mdiq.podcini.storage.database.Queues.getInQueueEpisodeIds
|
||||||
import ac.mdiq.podcini.storage.model.Episode
|
import ac.mdiq.podcini.storage.model.Episode
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeSortOrder
|
import ac.mdiq.podcini.storage.model.EpisodeSortOrder
|
||||||
|
import ac.mdiq.podcini.util.Logd
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
|
@ -68,7 +69,8 @@ object AutoCleanups {
|
||||||
override fun getReclaimableItems(): Int {
|
override fun getReclaimableItems(): Int {
|
||||||
return candidates.size
|
return candidates.size
|
||||||
}
|
}
|
||||||
@OptIn(UnstableApi::class) public override fun performCleanup(context: Context, numToRemove: Int): Int {
|
@OptIn(UnstableApi::class)
|
||||||
|
public override fun performCleanup(context: Context, numToRemove: Int): Int {
|
||||||
var candidates = candidates
|
var candidates = candidates
|
||||||
// in the absence of better data, we'll sort by item publication date
|
// in the absence of better data, we'll sort by item publication date
|
||||||
candidates = candidates.sortedWith { lhs: Episode, rhs: Episode ->
|
candidates = candidates.sortedWith { lhs: Episode, rhs: Episode ->
|
||||||
|
@ -250,8 +252,12 @@ object AutoCleanups {
|
||||||
* @return The number of episodes that were deleted.
|
* @return The number of episodes that were deleted.
|
||||||
*/
|
*/
|
||||||
protected abstract fun performCleanup(context: Context, numToRemove: Int): Int
|
protected abstract fun performCleanup(context: Context, numToRemove: Int): Int
|
||||||
|
|
||||||
|
// only used in tests
|
||||||
fun performCleanup(context: Context): Int {
|
fun performCleanup(context: Context): Int {
|
||||||
return performCleanup(context, getDefaultCleanupParameter())
|
val numToRemove = getDefaultCleanupParameter()
|
||||||
|
if (numToRemove <= 0) return 0
|
||||||
|
return performCleanup(context, numToRemove)
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Returns a parameter for performCleanup. The implementation of this interface should decide how much
|
* Returns a parameter for performCleanup. The implementation of this interface should decide how much
|
||||||
|
@ -266,7 +272,10 @@ object AutoCleanups {
|
||||||
* @return The number of epiosdes that were deleted
|
* @return The number of epiosdes that were deleted
|
||||||
*/
|
*/
|
||||||
fun makeRoomForEpisodes(context: Context, amountOfRoomNeeded: Int): Int {
|
fun makeRoomForEpisodes(context: Context, amountOfRoomNeeded: Int): Int {
|
||||||
return performCleanup(context, getNumEpisodesToCleanup(amountOfRoomNeeded))
|
val numToRemove = getNumEpisodesToCleanup(amountOfRoomNeeded)
|
||||||
|
Logd("EpisodeCleanupAlgorithm", "makeRoomForEpisodes: $numToRemove")
|
||||||
|
if (numToRemove <= 0) return 0
|
||||||
|
return performCleanup(context, numToRemove)
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return the number of episodes/items that *could* be cleaned up, if needed
|
* @return the number of episodes/items that *could* be cleaned up, if needed
|
||||||
|
|
|
@ -10,20 +10,17 @@ import ac.mdiq.podcini.preferences.UserPreferences.isEnableAutodownload
|
||||||
import ac.mdiq.podcini.preferences.UserPreferences.isEnableAutodownloadOnBattery
|
import ac.mdiq.podcini.preferences.UserPreferences.isEnableAutodownloadOnBattery
|
||||||
import ac.mdiq.podcini.storage.database.Episodes.getEpisodes
|
import ac.mdiq.podcini.storage.database.Episodes.getEpisodes
|
||||||
import ac.mdiq.podcini.storage.database.Episodes.getEpisodesCount
|
import ac.mdiq.podcini.storage.database.Episodes.getEpisodesCount
|
||||||
import ac.mdiq.podcini.storage.database.Episodes.setPlayState
|
|
||||||
import ac.mdiq.podcini.storage.database.Feeds.getFeedList
|
import ac.mdiq.podcini.storage.database.Feeds.getFeedList
|
||||||
import ac.mdiq.podcini.storage.database.RealmDB.realm
|
import ac.mdiq.podcini.storage.database.RealmDB.realm
|
||||||
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
|
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
|
||||||
import ac.mdiq.podcini.storage.database.RealmDB.upsertBlk
|
import ac.mdiq.podcini.storage.database.RealmDB.upsertBlk
|
||||||
import ac.mdiq.podcini.storage.model.*
|
import ac.mdiq.podcini.storage.model.*
|
||||||
import ac.mdiq.podcini.storage.utils.EpisodesPermutors.getPermutor
|
|
||||||
import ac.mdiq.podcini.util.Logd
|
import ac.mdiq.podcini.util.Logd
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.os.BatteryManager
|
import android.os.BatteryManager
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import io.realm.kotlin.Realm
|
|
||||||
import io.realm.kotlin.UpdatePolicy
|
import io.realm.kotlin.UpdatePolicy
|
||||||
import java.util.concurrent.ExecutorService
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
@ -149,27 +146,28 @@ object AutoDownloads {
|
||||||
if (networkShouldAutoDl && powerShouldAutoDl) {
|
if (networkShouldAutoDl && powerShouldAutoDl) {
|
||||||
Logd(Companion.TAG, "autoDownloadEpisodeMedia Performing auto-dl of undownloaded episodes")
|
Logd(Companion.TAG, "autoDownloadEpisodeMedia Performing auto-dl of undownloaded episodes")
|
||||||
val candidates: MutableSet<Episode> = mutableSetOf()
|
val candidates: MutableSet<Episode> = mutableSetOf()
|
||||||
val queueItems = curQueue.episodes.filter { it.media?.downloaded != true }
|
val queueItems = realm.query(Episode::class).query("id IN $0 AND media.downloaded == false", curQueue.episodeIds).find()
|
||||||
|
Logd(TAG, "autoDownloadEpisodeMedia add from queue: ${queueItems.size}")
|
||||||
if (queueItems.isNotEmpty()) candidates.addAll(queueItems)
|
if (queueItems.isNotEmpty()) candidates.addAll(queueItems)
|
||||||
val feeds = feeds ?: getFeedList()
|
val feeds = feeds ?: getFeedList()
|
||||||
feeds.forEach { f ->
|
feeds.forEach { f ->
|
||||||
if (f.preferences?.autoDownload == true && !f.isLocalFeed) {
|
if (f.preferences?.autoDownload == true && !f.isLocalFeed) {
|
||||||
var episodes = mutableListOf<Episode>()
|
var episodes = mutableListOf<Episode>()
|
||||||
val downloadedCount = getEpisodesCount(EpisodeFilter(EpisodeFilter.States.downloaded.name), f.id)
|
val downloadedCount = getEpisodesCount(EpisodeFilter(EpisodeFilter.States.downloaded.name), f.id)
|
||||||
val toDLCount = (f.preferences?.autoDLMaxEpisodes?:0) - downloadedCount
|
val allowedDLCount = (f.preferences?.autoDLMaxEpisodes?:0) - downloadedCount
|
||||||
if (toDLCount > 0) {
|
if (allowedDLCount > 0) {
|
||||||
var queryString = "feedId == ${f.id} AND isAutoDownloadEnabled == true AND media != nil AND media.downloaded == false"
|
var queryString = "feedId == ${f.id} AND isAutoDownloadEnabled == true AND media != nil AND media.downloaded == false"
|
||||||
when (f.preferences?.autoDLPolicy) {
|
when (f.preferences?.autoDLPolicy) {
|
||||||
FeedPreferences.AutoDLPolicy.ONLY_NEW -> {
|
FeedPreferences.AutoDLPolicy.ONLY_NEW -> {
|
||||||
queryString += " AND playState == -1 SORT(pubDate DESC) LIMIT(${3*toDLCount})"
|
queryString += " AND playState == -1 SORT(pubDate DESC) LIMIT(${3*allowedDLCount})"
|
||||||
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
|
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
|
||||||
}
|
}
|
||||||
FeedPreferences.AutoDLPolicy.NEWER -> {
|
FeedPreferences.AutoDLPolicy.NEWER -> {
|
||||||
queryString += " AND playState != 1 SORT(pubDate DESC) LIMIT(${3*toDLCount})"
|
queryString += " AND playState != 1 SORT(pubDate DESC) LIMIT(${3*allowedDLCount})"
|
||||||
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
|
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
|
||||||
}
|
}
|
||||||
FeedPreferences.AutoDLPolicy.OLDER -> {
|
FeedPreferences.AutoDLPolicy.OLDER -> {
|
||||||
queryString += " AND playState != 1 SORT(pubDate ASC) LIMIT(${3*toDLCount})"
|
queryString += " AND playState != 1 SORT(pubDate ASC) LIMIT(${3*allowedDLCount})"
|
||||||
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
|
episodes = realm.query(Episode::class).query(queryString).find().toMutableList()
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
|
@ -177,9 +175,11 @@ object AutoDownloads {
|
||||||
if (episodes.isNotEmpty()) {
|
if (episodes.isNotEmpty()) {
|
||||||
var count = 0
|
var count = 0
|
||||||
for (e in episodes) {
|
for (e in episodes) {
|
||||||
|
if (isCurMedia(e.media)) continue
|
||||||
if (f.preferences?.autoDownloadFilter?.shouldAutoDownload(e) == true) {
|
if (f.preferences?.autoDownloadFilter?.shouldAutoDownload(e) == true) {
|
||||||
|
Logd(TAG, "autoDownloadEpisodeMedia add to cadidates: ${e.title} ${e.isDownloaded}")
|
||||||
candidates.add(e)
|
candidates.add(e)
|
||||||
if (++count >= toDLCount) break
|
if (++count >= allowedDLCount) break
|
||||||
} else upsertBlk(e) { it.setPlayed(true)}
|
} else upsertBlk(e) { it.setPlayed(true)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,7 @@ class AddFeedFragment : Fragment() {
|
||||||
.setPositiveButton("Yes") { dialog, _ ->
|
.setPositiveButton("Yes") { dialog, _ ->
|
||||||
performRestore(requireContext())
|
performRestore(requireContext())
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
parentFragmentManager.popBackStack()
|
||||||
}
|
}
|
||||||
.setNegativeButton("No") { dialog, _ ->
|
.setNegativeButton("No") { dialog, _ ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
|
|
@ -324,6 +324,17 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
||||||
(activity as MainActivity).setPlayerVisible(true)
|
(activity as MainActivity).setPlayerVisible(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onPlaybackPositionEvent(event: FlowEvent.PlaybackPositionEvent) {
|
||||||
|
// Logd(TAG, "onPlayEvent ${event.episode.title}")
|
||||||
|
val media = event.media
|
||||||
|
if (currentMedia?.getIdentifier() == null || media?.getIdentifier() != currentMedia?.getIdentifier()) {
|
||||||
|
currentMedia = media
|
||||||
|
playerDetailsFragment?.setItem(curEpisode!!)
|
||||||
|
}
|
||||||
|
playerUI?.onPositionUpdate(event)
|
||||||
|
if (!isCollapsed) playerDetailsFragment?.onPlaybackPositionEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
private var eventSink: Job? = null
|
private var eventSink: Job? = null
|
||||||
private fun cancelFlowEvents() {
|
private fun cancelFlowEvents() {
|
||||||
Logd(TAG, "cancelFlowEvents")
|
Logd(TAG, "cancelFlowEvents")
|
||||||
|
@ -346,10 +357,7 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
||||||
is FlowEvent.FavoritesEvent -> onFavoriteEvent(event)
|
is FlowEvent.FavoritesEvent -> onFavoriteEvent(event)
|
||||||
is FlowEvent.PlayerErrorEvent -> MediaPlayerErrorDialog.show(activity as Activity, event)
|
is FlowEvent.PlayerErrorEvent -> MediaPlayerErrorDialog.show(activity as Activity, event)
|
||||||
is FlowEvent.SleepTimerUpdatedEvent -> if (event.isCancelled || event.wasJustEnabled()) loadMediaInfo(false)
|
is FlowEvent.SleepTimerUpdatedEvent -> if (event.isCancelled || event.wasJustEnabled()) loadMediaInfo(false)
|
||||||
is FlowEvent.PlaybackPositionEvent -> {
|
is FlowEvent.PlaybackPositionEvent -> onPlaybackPositionEvent(event)
|
||||||
playerUI?.onPositionUpdate(event)
|
|
||||||
if (!isCollapsed) playerDetailsFragment?.onPlaybackPositionEvent(event)
|
|
||||||
}
|
|
||||||
is FlowEvent.SpeedChangedEvent -> playerUI?.updatePlaybackSpeedButton(event)
|
is FlowEvent.SpeedChangedEvent -> playerUI?.updatePlaybackSpeedButton(event)
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import ac.mdiq.podcini.databinding.BaseEpisodesListFragmentBinding
|
||||||
import ac.mdiq.podcini.databinding.MultiSelectSpeedDialBinding
|
import ac.mdiq.podcini.databinding.MultiSelectSpeedDialBinding
|
||||||
import ac.mdiq.podcini.net.feed.FeedUpdateManager
|
import ac.mdiq.podcini.net.feed.FeedUpdateManager
|
||||||
import ac.mdiq.podcini.playback.base.InTheatre.isCurMedia
|
import ac.mdiq.podcini.playback.base.InTheatre.isCurMedia
|
||||||
|
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
|
||||||
import ac.mdiq.podcini.storage.model.Episode
|
import ac.mdiq.podcini.storage.model.Episode
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeMedia
|
import ac.mdiq.podcini.storage.model.EpisodeMedia
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
||||||
|
@ -343,7 +344,8 @@ import kotlinx.coroutines.flow.collectLatest
|
||||||
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
||||||
|
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
episodes[pos] = item
|
episodes[pos] = unmanaged(episodes[pos])
|
||||||
|
episodes[pos].media?.position = event.media.position
|
||||||
curIndex = pos
|
curIndex = pos
|
||||||
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import ac.mdiq.podcini.preferences.UserPreferences
|
||||||
import ac.mdiq.podcini.preferences.UserPreferences.appPrefs
|
import ac.mdiq.podcini.preferences.UserPreferences.appPrefs
|
||||||
import ac.mdiq.podcini.storage.database.Episodes.getEpisodes
|
import ac.mdiq.podcini.storage.database.Episodes.getEpisodes
|
||||||
import ac.mdiq.podcini.storage.database.RealmDB.realm
|
import ac.mdiq.podcini.storage.database.RealmDB.realm
|
||||||
|
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
|
||||||
import ac.mdiq.podcini.storage.model.Episode
|
import ac.mdiq.podcini.storage.model.Episode
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeMedia
|
import ac.mdiq.podcini.storage.model.EpisodeMedia
|
||||||
|
@ -310,7 +311,8 @@ import java.util.*
|
||||||
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
||||||
|
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
episodes[pos] = item
|
episodes[pos] = unmanaged(episodes[pos])
|
||||||
|
episodes[pos].media?.position = event.media.position
|
||||||
curIndex = pos
|
curIndex = pos
|
||||||
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
||||||
}
|
}
|
||||||
|
|
|
@ -421,7 +421,8 @@ import java.util.concurrent.Semaphore
|
||||||
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
curIndex else EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
||||||
|
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
episodes[pos] = item
|
episodes[pos] = unmanaged(episodes[pos])
|
||||||
|
episodes[pos].media?.position = event.media.position
|
||||||
curIndex = pos
|
curIndex = pos
|
||||||
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import ac.mdiq.podcini.storage.database.Queues.moveInQueueSync
|
||||||
import ac.mdiq.podcini.storage.database.Queues.queueKeepSortedOrder
|
import ac.mdiq.podcini.storage.database.Queues.queueKeepSortedOrder
|
||||||
import ac.mdiq.podcini.storage.database.RealmDB.realm
|
import ac.mdiq.podcini.storage.database.RealmDB.realm
|
||||||
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
|
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
|
||||||
|
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
|
||||||
import ac.mdiq.podcini.storage.database.RealmDB.upsert
|
import ac.mdiq.podcini.storage.database.RealmDB.upsert
|
||||||
import ac.mdiq.podcini.storage.model.Episode
|
import ac.mdiq.podcini.storage.model.Episode
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
||||||
|
@ -337,7 +338,8 @@ import java.util.*
|
||||||
curIndex else EpisodeUtil.indexOfItemWithId(queueItems, item.id)
|
curIndex else EpisodeUtil.indexOfItemWithId(queueItems, item.id)
|
||||||
|
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
queueItems[pos] = item
|
queueItems[pos] = unmanaged(queueItems[pos])
|
||||||
|
queueItems[pos].media?.position = event.media.position
|
||||||
curIndex = pos
|
curIndex = pos
|
||||||
adapter?.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
adapter?.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import ac.mdiq.podcini.databinding.SearchFragmentBinding
|
||||||
import ac.mdiq.podcini.net.feed.discovery.CombinedSearcher
|
import ac.mdiq.podcini.net.feed.discovery.CombinedSearcher
|
||||||
import ac.mdiq.podcini.playback.base.InTheatre.isCurMedia
|
import ac.mdiq.podcini.playback.base.InTheatre.isCurMedia
|
||||||
import ac.mdiq.podcini.storage.database.RealmDB.realm
|
import ac.mdiq.podcini.storage.database.RealmDB.realm
|
||||||
|
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
|
||||||
import ac.mdiq.podcini.storage.model.Episode
|
import ac.mdiq.podcini.storage.model.Episode
|
||||||
import ac.mdiq.podcini.storage.model.EpisodeMedia
|
import ac.mdiq.podcini.storage.model.EpisodeMedia
|
||||||
import ac.mdiq.podcini.storage.model.Feed
|
import ac.mdiq.podcini.storage.model.Feed
|
||||||
|
@ -300,7 +301,8 @@ import java.lang.ref.WeakReference
|
||||||
curIndex else EpisodeUtil.indexOfItemWithId(results, item.id)
|
curIndex else EpisodeUtil.indexOfItemWithId(results, item.id)
|
||||||
|
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
results[pos] = item
|
results[pos] = unmanaged(results[pos])
|
||||||
|
results[pos].media?.position = event.media.position
|
||||||
curIndex = pos
|
curIndex = pos
|
||||||
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
adapter.notifyItemChanged(pos, Bundle().apply { putString("PositionUpdate", "PlaybackPositionEvent") })
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
# 6.1.1
|
||||||
|
|
||||||
|
* fixed player UI not updating on change of episode
|
||||||
|
* fixed the mal-function of restoring previously backed-up OPML
|
||||||
|
* reduced reactions to PlaybackPositionEvent
|
||||||
|
* tuned AutoCleanup a bit
|
||||||
|
* tuned and fixed some some issues in audo-downloaded
|
||||||
|
|
||||||
# 6.1.0
|
# 6.1.0
|
||||||
|
|
||||||
* in FeedEpisode view fixed filtering after an episode's play state is changed
|
* in FeedEpisode view fixed filtering after an episode's play state is changed
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Version 6.0.14 brings several changes:
|
Version 6.1.0 brings several changes:
|
||||||
|
|
||||||
* in FeedEpisode view fixed filtering after an episode's play state is changed
|
* in FeedEpisode view fixed filtering after an episode's play state is changed
|
||||||
* fixed refreshing a feed causes duplicate episodes in FeedEpisodes view
|
* fixed refreshing a feed causes duplicate episodes in FeedEpisodes view
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
Version 6.1.1 brings several changes:
|
||||||
|
|
||||||
|
* fixed player UI not updating on change of episode
|
||||||
|
* fixed the mal-function of restoring previously backed-up OPML
|
||||||
|
* reduced reactions to PlaybackPositionEvent
|
||||||
|
* tuned AutoCleanup a bit
|
||||||
|
* tuned and fixed some some issues in audo-downloaded
|
Loading…
Reference in New Issue