Skip to content

Commit

Permalink
6.8.4 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
XilinJia committed Oct 1, 2024
1 parent 03cb641 commit 06b5d2d
Show file tree
Hide file tree
Showing 24 changed files with 690 additions and 1,060 deletions.
6 changes: 4 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ android {
testApplicationId "ac.mdiq.podcini.tests"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

versionCode 3020260
versionName "6.8.3"
versionCode 3020261
versionName "6.8.4"

applicationId "ac.mdiq.podcini.R"
def commit = ""
Expand Down Expand Up @@ -172,6 +172,8 @@ android {
dependencies {
implementation libs.androidx.material3.android
implementation libs.androidx.material3
// implementation libs.androidx.ui.viewbinding
implementation libs.androidx.fragment.compose

/** Desugaring for using VistaGuide **/
coreLibraryDesugaring libs.desugar.jdk.libs.nio
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ac.mdiq.podcini.storage.model.EpisodeMedia
import ac.mdiq.podcini.storage.model.FeedPreferences
import ac.mdiq.podcini.storage.model.MediaType
import ac.mdiq.podcini.storage.model.Playable
import ac.mdiq.podcini.util.showStackTrace
import android.content.Context
import android.media.AudioManager
import android.net.Uri
Expand All @@ -18,6 +19,9 @@ import android.net.wifi.WifiManager.WifiLock
import android.util.Log
import android.util.Pair
import android.view.SurfaceHolder
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -286,9 +290,9 @@ abstract class MediaPlayerBase protected constructor(protected val context: Cont
private val TAG: String = MediaPlayerBase::class.simpleName ?: "Anonymous"

@get:Synchronized
@Volatile
// @Volatile
@JvmStatic
var status: PlayerStatus = PlayerStatus.STOPPED
var status by mutableStateOf(PlayerStatus.STOPPED)

@JvmField
val ELAPSED_TIME_FOR_SHORT_REWIND: Long = TimeUnit.MINUTES.toMillis(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import ac.mdiq.podcini.storage.utils.EpisodeUtil
import ac.mdiq.podcini.storage.utils.EpisodeUtil.hasAlmostEnded
import ac.mdiq.podcini.ui.activity.starter.MainActivityStarter
import ac.mdiq.podcini.ui.activity.starter.VideoPlayerActivityStarter
import ac.mdiq.podcini.ui.compose.queueChanged
import ac.mdiq.podcini.ui.fragment.AudioPlayerFragment.Companion.media3Controller
import ac.mdiq.podcini.ui.utils.NotificationUtils
import ac.mdiq.podcini.ui.widget.WidgetUpdater
Expand Down Expand Up @@ -1076,6 +1077,7 @@ class PlaybackService : MediaLibraryService() {
if (e.id == curEpisode?.id) {
Logd(TAG, "onQueueEvent: queue event removed ${e.title}")
mPlayer?.endPlayback(hasEnded = false, wasSkipped = true, shouldContinue = true, toStoppedState = true)
queueChanged++
break
}
}
Expand Down Expand Up @@ -1964,12 +1966,14 @@ class PlaybackService : MediaLibraryService() {
}
}
override fun onIsPlayingChanged(isPlaying: Boolean) {
val stat = if (isPlaying) PlayerStatus.PLAYING else PlayerStatus.PAUSED
// val stat = if (isPlaying) PlayerStatus.PLAYING else PlayerStatus.PAUSED
// TODO: test
val stat = if (isPlaying) PlayerStatus.PLAYING else PlayerStatus.INDETERMINATE
setPlayerStatus(stat, curMedia)
Logd(TAG, "onIsPlayingChanged $isPlaying")
}
override fun onPlayerError(error: PlaybackException) {
Logd(TAG, "onPlayerError ${error.message}")
Log.d(TAG, "onPlayerError ${error.message}")
if (wasDownloadBlocked(error)) audioErrorListener?.accept(context.getString(R.string.download_error_blocked))
else {
var cause = error.cause
Expand Down
80 changes: 66 additions & 14 deletions app/src/main/kotlin/ac/mdiq/podcini/storage/model/Episode.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package ac.mdiq.podcini.storage.model

import ac.mdiq.podcini.net.download.DownloadStatus
import ac.mdiq.podcini.playback.base.InTheatre.curQueue
import ac.mdiq.podcini.playback.base.InTheatre.isCurrentlyPlaying
import ac.mdiq.podcini.storage.database.Feeds.getFeed
import ac.mdiq.vista.extractor.Vista
import ac.mdiq.vista.extractor.stream.StreamInfo
Expand Down Expand Up @@ -95,7 +93,7 @@ class Episode : RealmObject {

@Ignore
val isInProgress: Boolean
get() = (media != null && media!!.isInProgress)
get() = (media != null && media!!.position > 0)

@Ignore
val isDownloaded: Boolean
Expand Down Expand Up @@ -137,12 +135,6 @@ class Episode : RealmObject {
return field
}

@Ignore
val inQueueState = mutableStateOf(curQueue.contains(this))

@Ignore
val isPlayingState = mutableStateOf(isCurrentlyPlaying(media))

@Ignore
val downloadState = mutableIntStateOf(if (media?.downloaded == true) DownloadStatus.State.COMPLETED.ordinal else DownloadStatus.State.UNKNOWN.ordinal)

Expand All @@ -168,8 +160,8 @@ class Episode : RealmObject {
}

fun copyStates(other: Episode) {
inQueueState.value = other.inQueueState.value
isPlayingState.value = other.isPlayingState.value
// inQueueState.value = other.inQueueState.value
// isPlayingState.value = other.isPlayingState.value
downloadState.value = other.downloadState.value
stopMonitoring.value = other.stopMonitoring.value
}
Expand Down Expand Up @@ -278,15 +270,75 @@ class Episode : RealmObject {

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Episode) return false
return id == other.id
if (javaClass != other?.javaClass) return false

other as Episode

if (id != other.id) return false
if (identifier != other.identifier) return false
if (title != other.title) return false
if (description != other.description) return false
if (transcript != other.transcript) return false
if (link != other.link) return false
if (pubDate != other.pubDate) return false
if (media != other.media) return false
if (feedId != other.feedId) return false
if (podcastIndexChapterUrl != other.podcastIndexChapterUrl) return false
if (playState != other.playState) return false
if (paymentLink != other.paymentLink) return false
if (imageUrl != other.imageUrl) return false
if (isAutoDownloadEnabled != other.isAutoDownloadEnabled) return false
if (tags != other.tags) return false
if (chapters != other.chapters) return false
if (isFavorite != other.isFavorite) return false
if (isInProgress != other.isInProgress) return false
if (isDownloaded != other.isDownloaded) return false
// if (inQueueState != other.inQueueState) return false
// if (isPlayingState != other.isPlayingState) return false
if (downloadState != other.downloadState) return false
if (stopMonitoring != other.stopMonitoring) return false

return true
}

override fun hashCode(): Int {
val result = (id xor (id ushr 32)).toInt()
var result = id.hashCode()
result = 31 * result + (identifier?.hashCode() ?: 0)
result = 31 * result + (title?.hashCode() ?: 0)
result = 31 * result + (description?.hashCode() ?: 0)
result = 31 * result + (transcript?.hashCode() ?: 0)
result = 31 * result + (link?.hashCode() ?: 0)
result = 31 * result + pubDate.hashCode()
result = 31 * result + (media?.hashCode() ?: 0)
result = 31 * result + (feedId?.hashCode() ?: 0)
result = 31 * result + (podcastIndexChapterUrl?.hashCode() ?: 0)
result = 31 * result + playState
result = 31 * result + (paymentLink?.hashCode() ?: 0)
result = 31 * result + (imageUrl?.hashCode() ?: 0)
result = 31 * result + isAutoDownloadEnabled.hashCode()
result = 31 * result + tags.hashCode()
result = 31 * result + chapters.hashCode()
result = 31 * result + isFavorite.hashCode()
result = 31 * result + isInProgress.hashCode()
result = 31 * result + isDownloaded.hashCode()
// result = 31 * result + inQueueState.hashCode()
// result = 31 * result + isPlayingState.hashCode()
result = 31 * result + downloadState.hashCode()
result = 31 * result + stopMonitoring.hashCode()
return result
}

// override fun equals(other: Any?): Boolean {
// if (this === other) return true
// if (other !is Episode) return false
// return id == other.id
// }
//
// override fun hashCode(): Int {
// val result = (id xor (id ushr 32)).toInt()
// return result
// }

enum class PlayState(val code: Int) {
UNSPECIFIED(-2),
NEW(-1),
Expand Down
71 changes: 48 additions & 23 deletions app/src/main/kotlin/ac/mdiq/podcini/storage/model/EpisodeMedia.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
// var episodeId: Long = 0
// private set

@Ignore
val isInProgress: Boolean
get() = (this.position > 0)
// @Ignore
// val isInProgress: Boolean
// get() = (this.position > 0)

constructor() {}

Expand Down Expand Up @@ -326,43 +326,68 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
if (persist && episode != null) upsertBlk(episode!!) {}
}

fun episodeOrFetch(): Episode? {
return if (episode != null) episode else {
var item = realm.query(Episode::class).query("id == $id").first().find()
Logd(TAG, "episodeOrFetch warning: episode of media is null: $id ${item?.title}")
if (item != null) {
item = upsertBlk(item) {
it.media = this@EpisodeMedia
it.media!!.episode = it
}
}
if (item == null || isManaged()) item else unmanaged(item)
}
}

override fun equals(other: Any?): Boolean {
if (other == null) return false
if (other is RemoteMedia) return other == this
return super.equals(other)
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as EpisodeMedia

if (id != other.id) return false
if (fileUrl != other.fileUrl) return false
if (downloadUrl != other.downloadUrl) return false
if (downloaded != other.downloaded) return false
if (downloadTime != other.downloadTime) return false
if (duration != other.duration) return false
if (position != other.position) return false
if (lastPlayedTime != other.lastPlayedTime) return false
if (playedDuration != other.playedDuration) return false
if (size != other.size) return false
if (mimeType != other.mimeType) return false
if (playbackCompletionDate != other.playbackCompletionDate) return false
if (playbackCompletionTime != other.playbackCompletionTime) return false
if (startPosition != other.startPosition) return false
if (playedDurationWhenStarted != other.playedDurationWhenStarted) return false
if (hasEmbeddedPicture != other.hasEmbeddedPicture) return false
// if (isInProgress != other.isInProgress) return false

return true
}

override fun hashCode(): Int {
var result = super.hashCode()
var result = id.hashCode()
result = 31 * result + (fileUrl?.hashCode() ?: 0)
result = 31 * result + (downloadUrl?.hashCode() ?: 0)
result = 31 * result + downloaded.hashCode()
result = 31 * result + downloadTime.hashCode()
result = 31 * result + duration
result = 31 * result + position
result = 31 * result + lastPlayedTime.hashCode()
result = 31 * result + playedDuration
result = 31 * result + size.hashCode()
result = 31 * result + (mimeType?.hashCode() ?: 0)
result = 31 * result + (episode?.hashCode() ?: 0)
result = 31 * result + (playbackCompletionDate?.hashCode() ?: 0)
result = 31 * result + playbackCompletionTime.hashCode()
result = 31 * result + startPosition
result = 31 * result + playedDurationWhenStarted
result = 31 * result + (hasEmbeddedPicture?.hashCode() ?: 0)
// result = 31 * result + episodeId.hashCode()
// result = 31 * result + isInProgress.hashCode()
return result
}

fun episodeOrFetch(): Episode? {
return if (episode != null) episode else {
var item = realm.query(Episode::class).query("id == $id").first().find()
Logd(TAG, "episodeOrFetch warning: episode of media is null: $id ${item?.title}")
if (item != null) {
item = upsertBlk(item) {
it.media = this@EpisodeMedia
it.media!!.episode = it
}
}
if (item == null || isManaged()) item else unmanaged(item)
}
}

companion object {
private val TAG: String = EpisodeMedia::class.simpleName ?: "Anonymous"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ac.mdiq.podcini.preferences.UserPreferences.videoPlayMode
import ac.mdiq.podcini.storage.model.*
import ac.mdiq.podcini.ui.activity.VideoplayerActivity.Companion.videoMode
import ac.mdiq.podcini.ui.compose.CustomTheme
import ac.mdiq.podcini.util.Logd
import android.content.Context
import android.view.View
import android.view.ViewGroup
Expand Down Expand Up @@ -111,7 +112,7 @@ abstract class EpisodeActionButton internal constructor(@JvmField var item: Epis
null -> false
else -> DownloadServiceInterface.get()?.isDownloadingEpisode(media.downloadUrl!!)?:false
}
// Logd("ItemActionButton", "forItem: ${episode.feedId} ${episode.feed?.isLocalFeed} ${media.downloaded} ${isCurrentlyPlaying(media)} ${episode.title} ")
Logd("ItemActionButton", "forItem: ${episode.feedId} ${episode.feed?.isLocalFeed} ${media.downloaded} ${isCurrentlyPlaying(media)} ${episode.title} ")
return when {
isCurrentlyPlaying(media) -> PauseActionButton(episode)
episode.feed != null && episode.feed!!.isLocalFeed -> PlayLocalActionButton(episode)
Expand Down
Loading

0 comments on commit 06b5d2d

Please sign in to comment.