Skip to content

Commit

Permalink
6.13.8 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
XilinJia committed Nov 10, 2024
1 parent 50dc8e1 commit 08822bd
Show file tree
Hide file tree
Showing 43 changed files with 897 additions and 1,545 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ android {
vectorDrawables.useSupportLibrary false
vectorDrawables.generatedDensities = []

versionCode 3020294
versionName "6.13.7"
versionCode 3020295
versionName "6.13.8"

applicationId "ac.mdiq.podcini.R"
def commit = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1157,8 +1157,10 @@ class PlaybackService : MediaLibraryService() {
media.setPosition(position)
media.setLastPlayedTime(System.currentTimeMillis())
if (it.isNew) it.playState = PlayState.UNPLAYED.code
if (media.startPosition >= 0 && media.getPosition() > media.startPosition)
if (media.startPosition >= 0 && media.getPosition() > media.startPosition) {
media.playedDuration = (media.playedDurationWhenStarted + media.getPosition() - media.startPosition)
media.timeSpent = (System.currentTimeMillis() - media.startTime).toInt()
}
}
}
// This appears not too useful
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ class AboutFragment : PreferenceFragmentCompat() {
else -> DevelopersFragment()
}
}

override fun getItemCount(): Int {
return TOTAL_COUNT
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,43 +36,51 @@ object LogsAndStats {
* Searches the DB for statistics.
* @return The list of statistics objects
*/
fun getStatistics(includeMarkedAsPlayed: Boolean, timeFilterFrom: Long, timeFilterTo: Long): StatisticsResult {
fun getStatistics(includeMarkedAsPlayed: Boolean, timeFilterFrom: Long, timeFilterTo: Long, feedId: Long = 0L): StatisticsResult {
Logd(TAG, "getStatistics called")
val medias = if (feedId == 0L) realm.query(EpisodeMedia::class).find() else realm.query(EpisodeMedia::class).query("episode.feedId == $feedId").find()

val medias = realm.query(EpisodeMedia::class).find()
val groupdMedias = medias.groupBy { it.episodeOrFetch()?.feedId ?: 0L }
val result = StatisticsResult()
result.oldestDate = Long.MAX_VALUE
for ((fid, feedMedias) in groupdMedias) {
val feed = getFeed(fid, false) ?: continue
val numEpisodes = feed.episodes.size.toLong()
var feedPlayedTime = 0L
var timeSpent = 0L
var durationWithSkip = 0L
var feedTotalTime = 0L
var episodesStarted = 0L
var totalDownloadSize = 0L
var episodesDownloadCount = 0L
for (m in feedMedias) {
if (m.lastPlayedTime > 0 && m.lastPlayedTime < result.oldestDate) result.oldestDate = m.lastPlayedTime
feedTotalTime += m.duration
if (m.lastPlayedTime in timeFilterFrom..<timeFilterTo) {
if (m.lastPlayedTime in (timeFilterFrom + 1)..<timeFilterTo) {
if (includeMarkedAsPlayed) {
if ((m.playbackCompletionTime > 0 && m.playedDuration > 0) || (m.episodeOrFetch()?.playState?:-10) > PlayState.SKIPPED.code || m.position > 0) {
episodesStarted += 1
feedPlayedTime += m.duration
timeSpent += m.timeSpent
}
} else {
feedPlayedTime += m.playedDuration
timeSpent += m.timeSpent
Logd(TAG, "m.playedDuration: ${m.playedDuration} m.timeSpent: ${m.timeSpent}")
if (m.playbackCompletionTime > 0 && m.playedDuration > 0) episodesStarted += 1
}
durationWithSkip += m.duration
}
if (m.downloaded) {
episodesDownloadCount += 1
totalDownloadSize += m.size
}
}
feedPlayedTime /= 1000
durationWithSkip /= 1000
timeSpent /= 1000
feedTotalTime /= 1000
result.statsItems.add(StatisticsItem(feed, feedTotalTime, feedPlayedTime, numEpisodes, episodesStarted, totalDownloadSize, episodesDownloadCount))
result.statsItems.add(StatisticsItem(feed, feedTotalTime, feedPlayedTime, timeSpent, durationWithSkip, numEpisodes, episodesStarted, totalDownloadSize, episodesDownloadCount))
}
return result
}
Expand Down
23 changes: 20 additions & 3 deletions app/src/main/kotlin/ac/mdiq/podcini/storage/database/RealmDB.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ object RealmDB {
SubscriptionLog::class,
Chapter::class))
.name("Podcini.realm")
.schemaVersion(29)
.schemaVersion(30)
.migration({ mContext ->
val oldRealm = mContext.oldRealm // old realm using the previous schema
val newRealm = mContext.newRealm // new realm using the new schema
Expand Down Expand Up @@ -105,20 +105,37 @@ object RealmDB {
// }
}
if (oldRealm.schemaVersion() < 28) {
Logd(TAG, "migrating DB from below 27")
Logd(TAG, "migrating DB from below 28")
mContext.enumerate(className = "Episode") { oldObject: DynamicRealmObject, newObject: DynamicMutableRealmObject? ->
newObject?.run {
if (oldObject.getValue<Long>(fieldName = "playState") == 1L) {
set("playState", 10L)
} else {
val media = oldObject.getObject(propertyName = "media")
var position = 0L
if (media != null) position = media.getValue(propertyName = "position", Long::class) ?: 0
if (media != null) position = media.getValue(propertyName = "position", Long::class)
if (position > 0) set("playState", 5L)
}
}
}
}
if (oldRealm.schemaVersion() < 30) {
Logd(TAG, "migrating DB from below 30")
mContext.enumerate(className = "Episode") { oldObject: DynamicRealmObject, newObject: DynamicMutableRealmObject? ->
newObject?.run {
val media = oldObject.getObject(propertyName = "media")
var playedDuration = 0L
if (media != null) {
playedDuration = media.getValue(propertyName = "playedDuration", Long::class)
Logd(TAG, "position: $playedDuration")
if (playedDuration > 0L) {
val newMedia = newObject.getObject(propertyName = "media")
newMedia?.set("timeSpent", playedDuration)
}
}
}
}
}
}).build()
realm = Realm.open(config)
}
Expand Down
3 changes: 0 additions & 3 deletions app/src/main/kotlin/ac/mdiq/podcini/storage/model/Episode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ import org.apache.commons.lang3.builder.ToStringBuilder
import org.apache.commons.lang3.builder.ToStringStyle
import java.util.*

/**
* Episode within a feed.
*/
class Episode : RealmObject {
@PrimaryKey
var id: Long = 0L // increments from Date().time * 100 at time of creation
Expand Down
16 changes: 11 additions & 5 deletions app/src/main/kotlin/ac/mdiq/podcini/storage/model/EpisodeMedia.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,17 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
@set:JvmName("setLastPlayedTimeProperty")
var lastPlayedTime: Long = 0 // Last time this media was played (in ms)

var startPosition: Int = -1

var playedDurationWhenStarted: Int = 0
private set

var playedDuration: Int = 0 // How many ms of this file have been played

var startTime: Long = 0 // time in ms when start playing

var timeSpent: Int = 0 // How many ms of this file have been played in actual time

// File size in Byte
var size: Long = 0L

Expand All @@ -64,11 +73,6 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
}
var playbackCompletionTime: Long = 0

var startPosition: Int = -1

var playedDurationWhenStarted: Int = 0
private set

@Ignore
var volumeAdaptionSetting: VolumeAdaptionSetting = VolumeAdaptionSetting.OFF
get() = fromInteger(volumeAdaption)
Expand Down Expand Up @@ -286,6 +290,7 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
override fun onPlaybackStart() {
startPosition = max(position.toDouble(), 0.0).toInt()
playedDurationWhenStarted = playedDuration
startTime = System.currentTimeMillis()
}

override fun onPlaybackPause(context: Context) {
Expand All @@ -294,6 +299,7 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
playedDuration = playedDurationWhenStarted + position - startPosition
playedDurationWhenStarted = playedDuration
}
timeSpent = (System.currentTimeMillis() - startTime).toInt()
startPosition = position
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class FeedFilter(vararg properties_: String) : Serializable {
query.append(r)
}
query.append(") ")
Logd("FeedFilter", "audoDeleteQueues: ${query}")
Logd("FeedFilter", "audoDeleteQueues: $query")
statements.add(query.toString())
}
when {
Expand All @@ -90,7 +90,7 @@ class FeedFilter(vararg properties_: String) : Serializable {
query.append(r)
}
query.append(") ")
Logd("queryString", "${query}")
Logd("queryString", "$query")
return query.toString()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import java.util.ArrayList
class StatisticsItem(val feed: Feed,
val time: Long, // total time, in seconds
val timePlayed: Long, // in seconds, Respects speed, listening twice, ...
val timeSpent: Long, // in seconds, actual time spent playing
val durationOfStarted: Long, // in seconds, total duration of episodes started playing
val numEpisodes: Long, // Number of episodes.
val episodesStarted: Long, // Episodes that are actually played.
val totalDownloadSize: Long, // Simply sums up the size of download podcasts.
Expand All @@ -15,6 +17,7 @@ class MonthlyStatisticsItem {
var year: Int = 0
var month: Int = 0
var timePlayed: Long = 0
var timeSpent: Long = 0
}

class StatisticsResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ object DurationConverter {
* @return "HH:MM hours"
*/
@JvmStatic
fun shortLocalizedDuration(context: Context, time: Long): String {
fun shortLocalizedDuration(context: Context, time: Long, showHoursText: Boolean = true): String {
val hours = time.toFloat() / 3600f
return String.format(Locale.getDefault(), "%.2f ", hours) + context.getString(R.string.time_hours)
return String.format(Locale.getDefault(), "%.2f ", hours) + if (showHoursText) context.getString(R.string.time_hours) else ""
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import java.util.*
object EpisodesPermutors {
/**
* Returns a Permutor that sorts a list appropriate to the given sort order.
*
* @return Permutor that sorts a list appropriate to the given sort order.
*/
@JvmStatic
Expand Down Expand Up @@ -100,20 +99,16 @@ object EpisodesPermutors {
}

/**
* Implements a reordering by pubdate that avoids consecutive episodes from the same feed in
* the queue.
*
* Implements a reordering by pubdate that avoids consecutive episodes from the same feed in the queue.
* A listener might want to hear episodes from any given feed in pubdate order, but would
* prefer a more balanced ordering that avoids having to listen to clusters of consecutive
* episodes from the same feed. This is what "Smart Shuffle" tries to accomplish.
*
* Assume the queue looks like this: `ABCDDEEEEEEEEEE`.
* This method first starts with a queue of the final size, where each slot is empty (null).
* It takes the podcast with most episodes (`E`) and places the episodes spread out in the queue: `EE_E_EE_E_EE_EE`.
* The podcast with the second-most number of episodes (`D`) is then
* placed spread-out in the *available* slots: `EE_EDEE_EDEE_EE`.
* This continues, until we end up with: `EEBEDEECEDEEAEE`.
*
* Note that episodes aren't strictly ordered in terms of pubdate, but episodes of each feed are.
*
* @param queue A (modifiable) list of FeedItem elements to be reordered.
Expand Down Expand Up @@ -172,8 +167,7 @@ object EpisodesPermutors {

/**
* Interface for passing around list permutor method. This is used for cases where a simple comparator
* won't work (e.g. Random, Smart Shuffle, etc).
*
* won't work (e.g. Random, Smart Shuffle, etc)
* @param <E> the type of elements in the list
</E> */
interface Permutor<E> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import android.view.KeyEvent
import android.widget.Toast
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
Expand All @@ -47,6 +48,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -102,7 +104,7 @@ abstract class EpisodeActionButton internal constructor(@JvmField var item: Epis
fun AltActionsDialog(context: Context, showDialog: Boolean, onDismiss: () -> Unit) {
if (showDialog) {
Dialog(onDismissRequest = onDismiss) {
Card(modifier = Modifier.wrapContentSize(align = Alignment.Center).padding(16.dp), shape = RoundedCornerShape(16.dp)) {
Card(modifier = Modifier.wrapContentSize(align = Alignment.Center).padding(16.dp), shape = RoundedCornerShape(16.dp), border = BorderStroke(1.dp, Color.Yellow)) {
Row(modifier = Modifier.padding(16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
val label = getLabel()
Logd(TAG, "button label: $label")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import android.content.Context
import android.content.SharedPreferences
import android.util.TypedValue
import android.view.ViewGroup
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
Expand Down Expand Up @@ -151,7 +152,7 @@ open class SwipeActions(private val fragment: Fragment, private val tag: String)
(fragment.view as? ViewGroup)?.removeView(this@apply)
}) {
val context = LocalContext.current
Surface(shape = RoundedCornerShape(16.dp)) {
Surface(shape = RoundedCornerShape(16.dp), border = BorderStroke(1.dp, Color.Yellow)) {
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
for (action in swipeActions) {
if (action.getId() == NO_ACTION.name || action.getId() == ActionTypes.COMBO.name) continue
Expand Down Expand Up @@ -614,7 +615,7 @@ open class SwipeActions(private val fragment: Fragment, private val tag: String)
var showPickerDialog by remember { mutableStateOf(false) }
if (showPickerDialog) {
Dialog(onDismissRequest = { showPickerDialog = false }) {
Card(modifier = Modifier.wrapContentSize(align = Alignment.Center).fillMaxWidth().padding(16.dp), shape = RoundedCornerShape(16.dp)) {
Card(modifier = Modifier.wrapContentSize(align = Alignment.Center).fillMaxWidth().padding(16.dp), shape = RoundedCornerShape(16.dp), border = BorderStroke(1.dp, Color.Yellow)) {
LazyVerticalGrid(columns = GridCells.Fixed(2), modifier = Modifier.padding(16.dp)) {
items(keys.size) { index ->
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(16.dp).clickable {
Expand Down Expand Up @@ -663,7 +664,7 @@ open class SwipeActions(private val fragment: Fragment, private val tag: String)
else -> {}
}
if (tag != QueuesFragment.TAG) keys = keys.filter { a: SwipeAction -> !a.getId().equals(ActionTypes.REMOVE_FROM_QUEUE.name) }
Card(modifier = Modifier.wrapContentSize(align = Alignment.Center).fillMaxWidth().padding(16.dp), shape = RoundedCornerShape(16.dp)) {
Card(modifier = Modifier.wrapContentSize(align = Alignment.Center).fillMaxWidth().padding(16.dp), shape = RoundedCornerShape(16.dp), border = BorderStroke(1.dp, Color.Yellow)) {
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(20.dp)) {
Text(stringResource(R.string.swipeactions_label) + " - " + forFragment)
Text(stringResource(R.string.swipe_left))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import ac.mdiq.podcini.ui.activity.starter.MainActivityStarter
import ac.mdiq.podcini.ui.dialog.RatingDialog
import ac.mdiq.podcini.ui.fragment.*
import ac.mdiq.podcini.ui.fragment.AudioPlayerFragment.Companion.media3Controller
import ac.mdiq.podcini.ui.statistics.StatisticsFragment
import ac.mdiq.podcini.ui.fragment.StatisticsFragment
import ac.mdiq.podcini.ui.utils.ThemeUtils.getDrawableFromAttr
import ac.mdiq.podcini.ui.utils.TransitionEffect
import ac.mdiq.podcini.util.EventFlow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ac.mdiq.podcini.playback.service.PlaybackService.Companion.seekTo
import ac.mdiq.podcini.storage.model.Playable
import ac.mdiq.podcini.storage.utils.DurationConverter.getDurationStringLocalized
import ac.mdiq.podcini.storage.utils.DurationConverter.getDurationStringLong
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
Expand All @@ -20,6 +21,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
Expand All @@ -35,7 +37,7 @@ fun ChaptersDialog(media: Playable, onDismissRequest: () -> Unit) {
val chapters = media.getChapters()
val textColor = MaterialTheme.colorScheme.onSurface
Dialog(onDismissRequest = onDismissRequest) {
Surface(shape = RoundedCornerShape(16.dp)) {
Surface(shape = RoundedCornerShape(16.dp), border = BorderStroke(1.dp, Color.Yellow)) {
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
Text(stringResource(R.string.chapters_label))
var currentChapterIndex by remember { mutableIntStateOf(-1) }
Expand Down
Loading

0 comments on commit 08822bd

Please sign in to comment.