Skip to content

Commit

Permalink
6.8.6 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
XilinJia committed Oct 3, 2024
1 parent caa892f commit 7c74e89
Show file tree
Hide file tree
Showing 22 changed files with 747 additions and 487 deletions.
7 changes: 3 additions & 4 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 3020262
versionName "6.8.5"
versionCode 3020263
versionName "6.8.6"

applicationId "ac.mdiq.podcini.R"
def commit = ""
Expand Down Expand Up @@ -197,8 +197,7 @@ dependencies {
implementation libs.androidx.annotation
implementation libs.androidx.appcompat
implementation libs.androidx.coordinatorlayout
//noinspection UseTomlInstead
implementation "androidx.fragment:fragment-ktx:1.8.3"
implementation libs.androidx.fragment.fragment.ktx
implementation libs.androidx.gridlayout
implementation libs.androidx.media3.exoplayer
implementation libs.androidx.media3.ui
Expand Down
338 changes: 338 additions & 0 deletions app/src/main/kotlin/ac/mdiq/podcini/net/feed/DirectSubscribe.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import ac.mdiq.podcini.preferences.UserPreferences.isSkipSilence
import ac.mdiq.podcini.preferences.UserPreferences.prefLowQualityMedia
import ac.mdiq.podcini.preferences.UserPreferences.rewindSecs
import ac.mdiq.podcini.receiver.MediaButtonReceiver
import ac.mdiq.podcini.storage.database.Episodes.addToHistory
import ac.mdiq.podcini.storage.database.Episodes.setCompletionDate
import ac.mdiq.podcini.storage.database.Episodes.deleteMediaSync
import ac.mdiq.podcini.storage.database.Episodes.getEpisodeByGuidOrUrl
import ac.mdiq.podcini.storage.database.Episodes.setPlayStateSync
Expand All @@ -58,7 +58,6 @@ 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
import ac.mdiq.podcini.ui.widget.WidgetUpdater.WidgetState
Expand Down Expand Up @@ -103,7 +102,6 @@ import android.webkit.URLUtil
import android.widget.Toast
import androidx.annotation.VisibleForTesting
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE
import androidx.core.util.Consumer
import androidx.media3.common.*
import androidx.media3.common.Player.*
Expand Down Expand Up @@ -404,7 +402,7 @@ class PlaybackService : MediaLibraryService() {
if (shouldDeleteRemoveFromQueue()) removeFromQueueSync(null, item!!)
}
}
if (playable is EpisodeMedia && (ended || skipped || playingNext)) addToHistory(item!!)
if (playable is EpisodeMedia && (ended || skipped || playingNext)) setCompletionDate(item!!)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,12 @@ object Episodes {
}

/**
* Adds a Episode object to the playback history. A Episode object is in the playback history if
* its playback completion date is set to a non-null value. This method will set the playback completion date to the
* current date regardless of the current value.
* This method will set the playback completion date to the current date regardless of the current value.
* @param episode Episode that should be added to the playback history.
* @param date PlaybackCompletionDate for `media`
*/
fun addToHistory(episode: Episode, date: Date? = Date()) : Job {
Logd(TAG, "addToHistory called played: ${episode.playState}")
fun setCompletionDate(episode: Episode, date: Date? = Date()) : Job {
Logd(TAG, "setCompletionDate called played: ${episode.playState}")
return runOnIOScope {
val episode_ = realm.query(Episode::class).query("id == $0", episode.id).first().find()
if (episode_ != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package ac.mdiq.podcini.ui.actions.swipeactions

import ac.mdiq.podcini.R
import ac.mdiq.podcini.playback.base.InTheatre.curQueue
import ac.mdiq.podcini.storage.database.Episodes.addToHistory
import ac.mdiq.podcini.storage.database.Episodes.deleteMediaSync
import ac.mdiq.podcini.storage.database.Episodes.setFavorite
import ac.mdiq.podcini.storage.database.Episodes.setPlayState
Expand All @@ -12,6 +11,7 @@ import ac.mdiq.podcini.storage.database.Feeds.shouldAutoDeleteItem
import ac.mdiq.podcini.storage.database.Queues.addToQueue
import ac.mdiq.podcini.storage.database.Queues.removeFromQueue
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.upsert
import ac.mdiq.podcini.storage.model.Episode
Expand Down Expand Up @@ -278,20 +278,30 @@ open class SwipeActions(private val fragment: Fragment, private val tag: String)
@OptIn(UnstableApi::class)
override fun performAction(item: Episode, fragment: Fragment, filter: EpisodeFilter) {
val playbackCompletionDate: Date? = item.media?.playbackCompletionDate
deleteFromHistory(item)
val lastPlayedDate = item.media?.lastPlayedTime
setHistoryDates(item)

(fragment.requireActivity() as MainActivity)
.showSnackbarAbovePlayer(R.string.removed_history_label, Snackbar.LENGTH_LONG)
.setAction(fragment.getString(R.string.undo)) {
if (playbackCompletionDate != null) addToHistory(item, playbackCompletionDate) }
if (playbackCompletionDate != null) setHistoryDates(item, lastPlayedDate?:0, playbackCompletionDate) }
}

override fun willRemove(filter: EpisodeFilter, item: Episode): Boolean {
return true
}

fun deleteFromHistory(episode: Episode) {
addToHistory(episode, Date(0))
fun setHistoryDates(episode: Episode, lastPlayed: Long = 0, completed: Date = Date(0)) {
runOnIOScope {
val episode_ = realm.query(Episode::class).query("id == $0", episode.id).first().find()
if (episode_ != null) {
upsert(episode_) {
it.media?.lastPlayedTime = lastPlayed
it.media?.playbackCompletionDate = completed
}
EventFlow.postEvent(FlowEvent.HistoryEvent())
}
}
}
}

Expand Down

This file was deleted.

9 changes: 6 additions & 3 deletions app/src/main/kotlin/ac/mdiq/podcini/ui/compose/Episodes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,11 @@ fun EpisodeLazyColumn(activity: MainActivity, episodes: SnapshotStateList<Episod
if (index < episodes.size && episodes[index].id == changes.obj.id) {
playedState = changes.obj.isPlayed()
farvoriteState = changes.obj.isFavorite
// episodes[index] = changes.obj // direct assignment doesn't update member like media??
episodes[index] = changes.obj // direct assignment doesn't update member like media??
changes.obj.copyStates(episodes[index])
episodes.removeAt(index)
episodes.add(index, changes.obj)
// remove action could possibly conflict with the one in mediaMonitor
// episodes.removeAt(index)
// episodes.add(index, changes.obj)
}
}
else -> {}
Expand Down Expand Up @@ -355,6 +356,7 @@ fun EpisodeLazyColumn(activity: MainActivity, episodes: SnapshotStateList<Episod
selected.add(episodes[index])
longPressIndex = index
} else {
selected.clear()
selectedSize = 0
longPressIndex = -1
}
Expand Down Expand Up @@ -456,6 +458,7 @@ fun EpisodeLazyColumn(activity: MainActivity, episodes: SnapshotStateList<Episod
selectAllRes = R.drawable.ic_select_none
} else {
selected.clear()
longPressIndex = -1
selectAllRes = R.drawable.ic_select_all
}
selectedSize = selected.size
Expand Down
101 changes: 101 additions & 0 deletions app/src/main/kotlin/ac/mdiq/podcini/ui/compose/OnlineFeed.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package ac.mdiq.podcini.ui.compose

import ac.mdiq.podcini.R
import ac.mdiq.podcini.net.feed.DirectSubscribe
import ac.mdiq.podcini.net.feed.discovery.PodcastSearchResult
import ac.mdiq.podcini.ui.activity.MainActivity
import ac.mdiq.podcini.ui.fragment.OnlineFeedFragment
import ac.mdiq.podcini.util.MiscFormatter.formatNumber
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import coil.compose.AsyncImage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun OnlineFeedItem(activity: MainActivity, feed: PodcastSearchResult) {
val showSubscribeDialog = remember { mutableStateOf(false) }
@Composable
fun confirmSubscribe(feed: PodcastSearchResult, showDialog: Boolean, onDismissRequest: () -> Unit) {
if (showDialog) {
Dialog(onDismissRequest = { onDismissRequest() }) {
Card(
modifier = Modifier
.wrapContentSize(align = Alignment.Center)
.padding(16.dp),
shape = RoundedCornerShape(16.dp),
) {
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.Center
) {
Text("Subscribe: \"${feed.title}\" ?")
Button(onClick = {
CoroutineScope(Dispatchers.IO).launch {
if (feed.feedUrl != null) {
val subscribe = DirectSubscribe(activity)
subscribe.feedSource = feed.source
subscribe.startFeedBuilding(feed.feedUrl)
}
}
onDismissRequest()
}) {
Text("Confirm")
}
}
}
}
}
}
if (showSubscribeDialog.value) {
confirmSubscribe(feed, showSubscribeDialog.value, onDismissRequest = {
showSubscribeDialog.value = false
})
}
Column(Modifier.padding(start = 10.dp, end = 10.dp, top = 4.dp, bottom = 4.dp).combinedClickable(
onClick = {
if (feed.feedUrl != null) {
val fragment = OnlineFeedFragment.newInstance(feed.feedUrl)
fragment.feedSource = feed.source
activity.loadChildFragment(fragment)
}
}, onLongClick = { showSubscribeDialog.value = true })) {
val textColor = MaterialTheme.colorScheme.onSurface
Text(feed.title, color = textColor, maxLines = 2, overflow = TextOverflow.Ellipsis, modifier = Modifier.padding(bottom = 4.dp))
Row {
AsyncImage(model = feed.imageUrl, contentDescription = "imgvCover", placeholder = painterResource(R.mipmap.ic_launcher), modifier = Modifier.width(65.dp).height(65.dp))
Column(Modifier.padding(start = 10.dp)) {
var authorText by remember { mutableStateOf("") }
authorText = when {
!feed.author.isNullOrBlank() -> feed.author.trim { it <= ' ' }
feed.feedUrl != null && !feed.feedUrl.contains("itunes.apple.com") -> feed.feedUrl
else -> ""
}
if (authorText.isNotEmpty()) Text(authorText, color = textColor, style = MaterialTheme.typography.bodyMedium)
if (feed.subscriberCount > 0) Text(formatNumber(feed.subscriberCount) + " subscribers", color = textColor, style = MaterialTheme.typography.bodyMedium)
Row {
if (feed.count != null && feed.count > 0) Text(feed.count.toString() + " episodes", color = textColor, style = MaterialTheme.typography.bodyMedium)
Spacer(Modifier.weight(1f))
if (feed.update != null) Text(feed.update, color = textColor, style = MaterialTheme.typography.bodyMedium)
}
Text(feed.source + ": " + feed.feedUrl, color = textColor, maxLines = 2, overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.labelSmall)
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ class SwipeActionsDialog(private val context: Context, private val tag: String)
}
QueuesFragment.TAG -> {
forFragment = context.getString(R.string.queue_label)
keys = Stream.of(keys).filter { a: SwipeAction ->
(!a.getId().equals(SwipeAction.ADD_TO_QUEUE) && !a.getId().equals(SwipeAction.REMOVE_FROM_HISTORY)) }.toList()
// keys = Stream.of(keys).filter { a: SwipeAction ->
// (!a.getId().equals(SwipeAction.ADD_TO_QUEUE) && !a.getId().equals(SwipeAction.REMOVE_FROM_HISTORY)) }.toList()
keys = Stream.of(keys).filter { a: SwipeAction -> (!a.getId().equals(SwipeAction.REMOVE_FROM_HISTORY)) }.toList()
}
HistoryFragment.TAG -> {
forFragment = context.getString(R.string.playback_history_label)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class FeedInfoFragment : Fragment(), Toolbar.OnMenuItemClickListener {
}))
Spacer(modifier = Modifier.weight(0.2f))
Button(onClick = { (activity as MainActivity).loadChildFragment(FeedEpisodesFragment.newInstance(feed.id)) }) {
Text(feed.episodes.size.toString() + stringResource(R.string.episodes_label), color = textColor)
Text(feed.episodes.size.toString() + " " + stringResource(R.string.episodes_label), color = textColor)
}
Spacer(modifier = Modifier.width(15.dp))
}
Expand Down
Loading

0 comments on commit 7c74e89

Please sign in to comment.