Skip to content

Commit

Permalink
6.1.4 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
XilinJia committed Jul 23, 2024
1 parent fab805b commit 08dfdf8
Show file tree
Hide file tree
Showing 18 changed files with 288 additions and 77 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ android {
buildConfig true
}
defaultConfig {
versionCode 3020217
versionName "6.1.3"
versionCode 3020218
versionName "6.1.4"

applicationId "ac.mdiq.podcini.R"
def commit = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ abstract class MediaPlayerBase protected constructor(protected val context: Cont
*
* @return a Future, just for the purpose of tracking its execution.
*/
protected abstract fun endPlayback(hasEnded: Boolean, wasSkipped: Boolean, shouldContinue: Boolean, toStoppedState: Boolean)
internal abstract fun endPlayback(hasEnded: Boolean, wasSkipped: Boolean, shouldContinue: Boolean, toStoppedState: Boolean)

/**
* @return `true` if the WifiLock feature should be used, `false` otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ac.mdiq.podcini.net.utils.NetworkUtils.isAllowMobileStreaming
import ac.mdiq.podcini.net.utils.NetworkUtils.isStreamingAllowed
import ac.mdiq.podcini.playback.PlaybackServiceStarter
import ac.mdiq.podcini.playback.base.InTheatre
import ac.mdiq.podcini.playback.base.InTheatre.curEpisode
import ac.mdiq.podcini.playback.base.InTheatre.curMedia
import ac.mdiq.podcini.playback.base.InTheatre.curQueue
import ac.mdiq.podcini.playback.base.InTheatre.curState
Expand Down Expand Up @@ -37,8 +38,8 @@ import ac.mdiq.podcini.storage.database.Episodes.shouldDeleteRemoveFromQueue
import ac.mdiq.podcini.storage.database.Feeds.shouldAutoDeleteItem
import ac.mdiq.podcini.storage.database.Queues.addToQueue
import ac.mdiq.podcini.storage.database.Queues.removeFromQueueSync
import ac.mdiq.podcini.storage.database.RealmDB.realm
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
import ac.mdiq.podcini.storage.database.RealmDB.upsertBlk
import ac.mdiq.podcini.storage.model.*
import ac.mdiq.podcini.storage.model.CurrentState.Companion.NO_MEDIA_PLAYING
Expand Down Expand Up @@ -81,7 +82,6 @@ import androidx.work.impl.utils.futures.SettableFuture
import com.google.common.collect.ImmutableList
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import io.realm.kotlin.ext.isManaged
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collectLatest
import java.util.*
Expand Down Expand Up @@ -361,8 +361,17 @@ class PlaybackService : MediaSessionService() {
writeNoMediaPlaying()
return null
}
val nextItem = getNextInQueue(item)
if (nextItem?.media == null) {
// val nextItem = getNextInQueue(item)
if (curQueue.episodes.isEmpty()) {
Logd(TAG, "getNextInQueue queue is empty")
writeNoMediaPlaying()
return null
}
val i = curQueue.episodes.indexOf(item)
var j = 0
if (i >= 0 && i < curQueue.episodes.size-1) j = i+1
val nextItem = unmanaged(curQueue.episodes[j])
if (nextItem.media == null) {
Logd(TAG, "getNextInQueue nextItem: $nextItem media is null")
writeNoMediaPlaying()
return null
Expand All @@ -384,17 +393,17 @@ class PlaybackService : MediaSessionService() {
return nextItem.media
}

private fun getNextInQueue(episode: Episode): Episode? {
Logd(TAG, "getNextInQueue() with: itemId ${episode.id}")
if (curQueue.episodes.isEmpty()) return null

val i = curQueue.episodes.indexOf(episode)
var j = 0
if (i >= 0 && i < curQueue.episodes.size-1) j = i+1

val itemNew = curQueue.episodes[j]
return if (itemNew.isManaged()) realm.copyFromRealm(itemNew) else itemNew
}
// private fun getNextInQueue(episode: Episode): Episode? {
// Logd(TAG, "getNextInQueue() with: itemId ${episode.id}")
// if (curQueue.episodes.isEmpty()) return null
//
// val i = curQueue.episodes.indexOf(episode)
// var j = 0
// if (i >= 0 && i < curQueue.episodes.size-1) j = i+1
//
// val itemNew = curQueue.episodes[j]
// return unmanaged(itemNew)
// }

override fun findMedia(url: String): Playable? {
val item = getEpisodeByGuidOrUrl(null, url)
Expand Down Expand Up @@ -918,19 +927,61 @@ class PlaybackService : MediaSessionService() {
EventFlow.events.collectLatest { event ->
Logd(TAG, "Received event: ${event.TAG}")
when (event) {
is FlowEvent.QueueEvent -> onQueueEvent(event)
is FlowEvent.PlayerErrorEvent -> onPlayerError(event)
is FlowEvent.BufferUpdateEvent -> onBufferUpdate(event)
is FlowEvent.SleepTimerUpdatedEvent -> onSleepTimerUpdate(event)
// is FlowEvent.VolumeAdaptionChangedEvent -> onVolumeAdaptionChanged(event)
is FlowEvent.FeedPrefsChangeEvent -> onFeedPrefsChanged(event)
// is FlowEvent.SkipIntroEndingChangedEvent -> skipIntroEndingPresetChanged(event)
is FlowEvent.PlayEvent -> currentitem = event.episode
is FlowEvent.EpisodeMediaEvent -> onEpisodeMediaEvent(event)
else -> {}
}
}
}
}

private fun onEpisodeMediaEvent(event: FlowEvent.EpisodeMediaEvent) {
if (event.action == FlowEvent.EpisodeMediaEvent.Action.REMOVED) {
for (e in event.episodes) {
if (e.id == curEpisode?.id) {
curEpisode = unmanaged(e)
curMedia = curEpisode!!.media
mPlayer?.endPlayback(hasEnded = false, wasSkipped = true, shouldContinue = true, toStoppedState = true)
break
}
}
}
}

private fun onQueueEvent(event: FlowEvent.QueueEvent) {
if (event.action == FlowEvent.QueueEvent.Action.REMOVED) {
for (e in event.episodes) {
if (e.id == curEpisode?.id) {
mPlayer?.endPlayback(hasEnded = false, wasSkipped = true, shouldContinue = true, toStoppedState = true)
break
}
}
}
}

// private fun onVolumeAdaptionChanged(event: FlowEvent.VolumeAdaptionChangedEvent) {
// if (mPlayer != null) updateVolumeIfNecessary(mPlayer!!, event.feedId, event.volumeAdaptionSetting)
// }

private fun onFeedPrefsChanged(event: FlowEvent.FeedPrefsChangeEvent) {
val item = (curMedia as? EpisodeMedia)?.episode ?: currentitem
if (item?.feed?.id == event.feed.id) {
item.feed = null
// seems no need to pause??
// if (MediaPlayerBase.status == PlayerStatus.PLAYING) {
// mPlayer?.pause(abandonFocus = false, reinit = false)
// mPlayer?.resume()
// }
}
}

private fun onPlayerError(event: FlowEvent.PlayerErrorEvent) {
if (MediaPlayerBase.status == PlayerStatus.PLAYING || MediaPlayerBase.status == PlayerStatus.FALLBACK)
mPlayer!!.pause(abandonFocus = true, reinit = false)
Expand Down Expand Up @@ -1062,22 +1113,6 @@ class PlaybackService : MediaSessionService() {
}
}

// private fun onVolumeAdaptionChanged(event: FlowEvent.VolumeAdaptionChangedEvent) {
// if (mPlayer != null) updateVolumeIfNecessary(mPlayer!!, event.feedId, event.volumeAdaptionSetting)
// }

private fun onFeedPrefsChanged(event: FlowEvent.FeedPrefsChangeEvent) {
val item = (curMedia as? EpisodeMedia)?.episode ?: currentitem
if (item?.feed?.id == event.feed.id) {
item.feed = null
// seems no need to pause??
// if (MediaPlayerBase.status == PlayerStatus.PLAYING) {
// mPlayer?.pause(abandonFocus = false, reinit = false)
// mPlayer?.resume()
// }
}
}

enum class NotificationCustomButton(val customAction: String, val commandButton: CommandButton) {
SKIP(
customAction = CUSTOM_COMMAND_SKIP_ACTION_ID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ object Episodes {
val action = EpisodeAction.Builder(episode, EpisodeAction.DELETE).currentTimestamp().build()
SynchronizationQueueSink.enqueueEpisodeActionIfSyncActive(context, action)
}
EventFlow.postEvent(FlowEvent.EpisodeEvent.updated(episode))
EventFlow.postEvent(FlowEvent.EpisodeMediaEvent.removed(episode))
}
return episode
}
Expand Down Expand Up @@ -223,7 +223,7 @@ object Episodes {
if (episode != null) {
episode.media = media
episode = upsert(episode) {}
EventFlow.postEvent(FlowEvent.EpisodeEvent.updated(episode))
EventFlow.postEvent(FlowEvent.EpisodeMediaEvent.updated(episode))
} else Log.e(TAG, "persistEpisodeMedia media.episode is null")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
hasEmbeddedPicture = false
}
}
upsertBlk(episode!!) {}
if (episode != null) upsertBlk(episode!!) {}
}

override fun equals(other: Any?): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import android.app.Activity
import android.content.DialogInterface
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.RadioButton
import androidx.annotation.PluralsRes
import androidx.media3.common.util.UnstableApi
Expand Down Expand Up @@ -118,6 +119,8 @@ class EpisodeMultiSelectHandler(private val activity: MainActivity, private val
fun show() {
val activity = activityRef.get() ?: return
val binding = SelectQueueDialogBinding.inflate(LayoutInflater.from(activity))
binding.removeCheckbox.visibility = View.VISIBLE

val queues = realm.query(PlayQueue::class).find()
for (i in queues.indices) {
val radioButton = RadioButton(activity)
Expand All @@ -137,21 +140,23 @@ class EpisodeMultiSelectHandler(private val activity: MainActivity, private val
.setTitle(R.string.put_in_queue_label)
.setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int ->
val queues = realm.query(PlayQueue::class).find()
val toRemove = mutableSetOf<Long>()
val toRemoveCur = mutableListOf<Episode>()
items.forEach { e ->
if (curQueue.isInQueue(e)) toRemoveCur.add(e)
}
items.forEach { e ->
for (q in queues) {
if (q.isInQueue(e)) {
toRemove.add(e.id)
break
if (binding.removeCheckbox.isChecked) {
val toRemove = mutableSetOf<Long>()
val toRemoveCur = mutableListOf<Episode>()
items.forEach { e ->
if (curQueue.isInQueue(e)) toRemoveCur.add(e)
}
items.forEach { e ->
for (q in queues) {
if (q.isInQueue(e)) {
toRemove.add(e.id)
break
}
}
}
if (toRemove.isNotEmpty()) runBlocking { removeFromAllQueuesQuiet(toRemove.toList()) }
if (toRemoveCur.isNotEmpty()) EventFlow.postEvent(FlowEvent.QueueEvent.removed(toRemoveCur))
}
if (toRemove.isNotEmpty()) runBlocking { removeFromAllQueuesQuiet(toRemove.toList()) }
if (toRemoveCur.isNotEmpty()) EventFlow.postEvent(FlowEvent.QueueEvent.removed(toRemoveCur))
items.forEach { e ->
runBlocking { addToQueueSync(false, e, toQueue) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class PlayActionButton(item: Episode) : EpisodeActionButton(item) {
episode.media?.downloaded = false
episode.media?.fileUrl = null
upsertBlk(episode) {}
EventFlow.postEvent(FlowEvent.EpisodeEvent.updated(episode))
EventFlow.postEvent(FlowEvent.EpisodeMediaEvent.removed(episode))
}
EventFlow.postEvent(FlowEvent.MessageEvent(context.getString(R.string.error_file_not_found)))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
override fun onResume() {
Logd(TAG, "onResume() isCollapsed: $isCollapsed")
super.onResume()
loadMediaInfo(false)
}

override fun onStart() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,30 @@ import kotlinx.coroutines.flow.collectLatest
for (item in event.episodes) {
val pos: Int = EpisodeUtil.indexOfItemWithId(episodes, item.id)
if (pos >= 0) {
episodes.removeAt(pos)
if (getFilter().matches(item)) {
episodes.add(pos, item)
episodes[pos] = item
adapter.notifyItemChangedCompat(pos)
} else adapter.notifyItemRemoved(pos)
} else {
episodes.removeAt(pos)
adapter.notifyItemRemoved(pos)
}
}
}
}

private fun onEpisodeMediaEvent(event: FlowEvent.EpisodeMediaEvent) {
// Logd(TAG, "onEventMainThread() called with ${event.TAG}")
for (item in event.episodes) {
val pos: Int = EpisodeUtil.indexOfItemWithId(episodes, item.id)
if (pos >= 0) {
episodes[pos] = unmanaged(episodes[pos])
episodes[pos].media = item.media
if (getFilter().matches(item)) {
adapter.notifyItemChangedCompat(pos)
} else {
// episodes.removeAt(pos)
// adapter.notifyItemRemoved(pos)
}
}
}
}
Expand Down Expand Up @@ -387,6 +406,7 @@ import kotlinx.coroutines.flow.collectLatest
is FlowEvent.FeedListEvent, is FlowEvent.EpisodePlayedEvent, is FlowEvent.PlayerSettingsEvent, is FlowEvent.FavoritesEvent -> loadItems()
is FlowEvent.PlaybackPositionEvent -> onPlaybackPositionEvent(event)
is FlowEvent.EpisodeEvent -> onEpisodeEvent(event)
is FlowEvent.EpisodeMediaEvent -> onEpisodeMediaEvent(event)
else -> {}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ import java.util.*
Logd(TAG, "Received event: ${event.TAG}")
when (event) {
is FlowEvent.EpisodeEvent -> onEpisodeEvent(event)
is FlowEvent.EpisodeMediaEvent -> onEpisodeMediaEvent(event)
is FlowEvent.PlaybackPositionEvent -> onPlaybackPositionEvent(event)
is FlowEvent.FavoritesEvent -> onFavoriteEvent(event)
is FlowEvent.PlayerSettingsEvent -> loadItems()
Expand Down Expand Up @@ -290,12 +291,28 @@ import java.util.*
if (pos >= 0) {
episodes.removeAt(pos)
val media = item.media
if (media != null && media.downloaded) {
episodes.add(pos, item)
// adapter.notifyItemChangedCompat(pos)
} else {
// adapter.notifyItemRemoved(pos)
}
if (media != null && media.downloaded) episodes.add(pos, item)
}
}
// have to do this as adapter.notifyItemRemoved(pos) when pos == 0 causes crash
if (size > 0) {
// adapter.setDummyViews(0)
adapter.updateItems(episodes)
}
refreshInfoBar()
}

private fun onEpisodeMediaEvent(event: FlowEvent.EpisodeMediaEvent) {
// Logd(TAG, "onEpisodeEvent() called with ${event.TAG}")
var i = 0
val size: Int = event.episodes.size
while (i < size) {
val item: Episode = event.episodes[i++]
val pos = EpisodeUtil.indexOfItemWithId(episodes, item.id)
if (pos >= 0) {
episodes.removeAt(pos)
val media = item.media
if (media != null && media.downloaded) episodes.add(pos, item)
}
}
// have to do this as adapter.notifyItemRemoved(pos) when pos == 0 causes crash
Expand Down
Loading

0 comments on commit 08dfdf8

Please sign in to comment.