6.13.1 commit

This commit is contained in:
Xilin Jia 2024-10-30 11:57:08 +01:00
parent 69de20fd35
commit fc902569cd
15 changed files with 72 additions and 26 deletions

View File

@ -46,6 +46,8 @@ While podcast subscriptions' OPML files (from AntennaPod or any other sources) c
* More convenient player control displayed on all pages * More convenient player control displayed on all pages
* Revamped and more efficient expanded player view showing episode description on the front * Revamped and more efficient expanded player view showing episode description on the front
* Playback speed setting has been straightened up, three speed can be set separately or combined: current audio, podcast, and global * Playback speed setting has been straightened up, three speed can be set separately or combined: current audio, podcast, and global
* There are two mechanisms in updating playback progress (configurable in Settings): every 5 seconds or adaptively at the interval of 2 percent of the media duration
* Volume adaptation control is added to player detailed view to set for current media and it takes precedence over that in feed settings
* Added preference "Fast Forward Speed" under "Playback" in settings with default value of 0.0, dialog allows setting a number between 0.0 and 10.0 * Added preference "Fast Forward Speed" under "Playback" in settings with default value of 0.0, dialog allows setting a number between 0.0 and 10.0
* The "Skip to next episode" button on the player * The "Skip to next episode" button on the player
* long-press moves to the next episode * long-press moves to the next episode
@ -95,6 +97,7 @@ While podcast subscriptions' OPML files (from AntennaPod or any other sources) c
* List info is shown in Queue and Downloads views * List info is shown in Queue and Downloads views
* Local search for feeds or episodes can be separately specified on title, author(feed only), description(including transcript in episodes), and comment (My opinion) * Local search for feeds or episodes can be separately specified on title, author(feed only), description(including transcript in episodes), and comment (My opinion)
* Left and right swipe actions on lists now have telltales and can be configured on the spot * Left and right swipe actions on lists now have telltales and can be configured on the spot
* Swipe actions are brought to perform anything on the multi-select menu, and there is a Combo swipe action
* Played or new episodes have clearer markings * Played or new episodes have clearer markings
* Sort dialog no longer dims the main view * Sort dialog no longer dims the main view
* An all new way of filtering for both podcasts and episodes with expanded criteria * An all new way of filtering for both podcasts and episodes with expanded criteria
@ -113,9 +116,9 @@ While podcast subscriptions' OPML files (from AntennaPod or any other sources) c
* Every feed (podcast) can be associated with a queue allowing downloaded media to be added to the queue * Every feed (podcast) can be associated with a queue allowing downloaded media to be added to the queue
* FeedInfo view offers a link for direct search of feeds related to author * FeedInfo view offers a link for direct search of feeds related to author
* FeedInfo view has button showing number of episodes to open the FeedEpisodes view * FeedInfo view has button showing number of episodes to open the FeedEpisodes view
* instead of isFavorite, there is a new rating system for every episode: Trash, Bad, Neutral, Good, Favorite * instead of isFavorite, there is a new rating system for every episode: Trash, Bad, OK, Good, Super
* instead of Played or Unplayed, there is a new play state system Unspecified, Building, New, Unplayed, Later, Soon, InQueue, InProgress, Skipped, Played, Ignored * instead of Played or Unplayed, there is a new play state system Unspecified, Building, New, Unplayed, Later, Soon, InQueue, InProgress, Skipped, Played, Again, Forever, Ignored
* among which Unplayed, Later, Soon, Skipped, Played, Ignored are settable by the user * among which Unplayed, Later, Soon, Skipped, Played, Again, Forever, Ignored are settable by the user
* when an episode is started to play, its state is set to InProgress * when an episode is started to play, its state is set to InProgress
* when episode is added to a queue, its state is set to InQueue, when it's removed from a queue, the state (if lower than Skipped) is set to Skipped * when episode is added to a queue, its state is set to InQueue, when it's removed from a queue, the state (if lower than Skipped) is set to Skipped
* in EpisodeInfo view, one can enter personal comments/notes under "My opinion" for the episode * in EpisodeInfo view, one can enter personal comments/notes under "My opinion" for the episode
@ -155,7 +158,7 @@ While podcast subscriptions' OPML files (from AntennaPod or any other sources) c
* auto download algorithm is changed to individual feed based. * auto download algorithm is changed to individual feed based.
* When auto download is enabled in the Settings, feeds to be auto-downloaded need to be separately enabled in the feed settings. * When auto download is enabled in the Settings, feeds to be auto-downloaded need to be separately enabled in the feed settings.
* Each feed also has its own download policy (only new episodes, newest episodes, and oldest episodes. "newest episodes" meaning most recent episodes, new or old) * Each feed also has its own download policy (only new episodes, newest episodes, oldest episodes or episodes marked as Soon. "newest episodes" meaning most recent episodes, new or old)
* Each feed has its own limit (Episode cache) for number of episodes downloaded, this limit rules in combination of the overall limit for the app. * Each feed has its own limit (Episode cache) for number of episodes downloaded, this limit rules in combination of the overall limit for the app.
* Auto downloads run feeds or feed refreshes, scheduled or manual * Auto downloads run feeds or feed refreshes, scheduled or manual
* auto download always includes any undownloaded episodes (regardless of feeds) added in the Default queue * auto download always includes any undownloaded episodes (regardless of feeds) added in the Default queue

View File

@ -31,8 +31,8 @@ android {
// testApplicationId "ac.mdiq.podcini.tests" // testApplicationId "ac.mdiq.podcini.tests"
// testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
versionCode 3020287 versionCode 3020288
versionName "6.13.0" versionName "6.13.1"
applicationId "ac.mdiq.podcini.R" applicationId "ac.mdiq.podcini.R"
def commit = "" def commit = ""

View File

@ -384,7 +384,8 @@ class PlaybackService : MediaLibraryService() {
Logd(TAG, "onPlaybackStart position: $position") Logd(TAG, "onPlaybackStart position: $position")
val delayInterval = positionUpdateInterval(playable.getDuration()) val delayInterval = positionUpdateInterval(playable.getDuration())
taskManager.startWidgetUpdater(delayInterval) taskManager.startWidgetUpdater(delayInterval)
if (position != Playable.INVALID_TIME) playable.setPosition(position + (delayInterval/2).toInt()) // if (position != Playable.INVALID_TIME) playable.setPosition(position + (delayInterval/2).toInt())
if (position != Playable.INVALID_TIME) playable.setPosition(position)
else skipIntro(playable) else skipIntro(playable)
playable.onPlaybackStart() playable.onPlaybackStart()
taskManager.startPositionSaver(delayInterval) taskManager.startPositionSaver(delayInterval)

View File

@ -6,14 +6,16 @@ import androidx.compose.ui.graphics.Color
enum class PlayState(val code: Int, val res: Int, color: Color?, val userSet: Boolean) { enum class PlayState(val code: Int, val res: Int, color: Color?, val userSet: Boolean) {
UNSPECIFIED(-10, R.drawable.ic_questionmark, null, false), UNSPECIFIED(-10, R.drawable.ic_questionmark, null, false),
BUILDING(-2, R.drawable.baseline_build_24, null, false), BUILDING(-2, R.drawable.baseline_build_24, null, false),
NEW(-1, R.drawable.baseline_fiber_new_24, Color.Green, false), NEW(-1, R.drawable.outline_new_releases_24, Color.Green, false),
UNPLAYED(0, R.drawable.baseline_new_label_24, null, true), UNPLAYED(0, R.drawable.baseline_new_label_24, null, true),
LATER(1, R.drawable.baseline_watch_later_24, Color.Green, true), LATER(1, R.drawable.baseline_watch_later_24, Color.Green, true),
SOON(2, R.drawable.baseline_local_play_24, Color.Green, true), SOON(2, R.drawable.baseline_access_alarms_24, Color.Green, true),
INQUEUE(3, R.drawable.ic_playlist_play_black, Color.Green, false), INQUEUE(3, R.drawable.ic_playlist_play_black, Color.Green, false),
INPROGRESS(5, R.drawable.baseline_play_circle_outline_24, Color.Green, false), INPROGRESS(5, R.drawable.baseline_play_circle_outline_24, Color.Green, false),
SKIPPED(6, R.drawable.ic_skip_24dp, null, true), SKIPPED(6, R.drawable.ic_skip_24dp, null, true),
PLAYED(10, R.drawable.ic_mark_played, null, true), // was 1 PLAYED(10, R.drawable.ic_check, null, true), // was 1
AGAIN(12, R.drawable.baseline_replay_24, null, true),
FOREVER(15, R.drawable.baseline_light_mode_24, null, true),
IGNORED(20, R.drawable.baseline_visibility_off_24, null, true); IGNORED(20, R.drawable.baseline_visibility_off_24, null, true);
companion object { companion object {

View File

@ -27,15 +27,15 @@ interface SwipeAction {
enum class ActionTypes { enum class ActionTypes {
NO_ACTION, NO_ACTION,
COMBO, COMBO,
RATING,
SET_PLAY_STATE,
ADD_TO_QUEUE, ADD_TO_QUEUE,
PUT_TO_QUEUE, PUT_TO_QUEUE,
START_DOWNLOAD,
MARK_FAV,
SET_PLAY_STATE,
SHELVE,
ERASE,
REMOVE_FROM_QUEUE, REMOVE_FROM_QUEUE,
START_DOWNLOAD,
DELETE, DELETE,
REMOVE_FROM_HISTORY REMOVE_FROM_HISTORY,
SHELVE,
ERASE
} }
} }

View File

@ -163,6 +163,7 @@ open class SwipeActions(private val fragment: Fragment, private val tag: String)
Surface(shape = RoundedCornerShape(16.dp)) { Surface(shape = RoundedCornerShape(16.dp)) {
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) { Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
for (action in swipeActions) { for (action in swipeActions) {
if (action.getId() == NO_ACTION.name || action.getId() == ActionTypes.COMBO.name) continue
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(4.dp).clickable { Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(4.dp).clickable {
action.performAction(item, fragment, filter) action.performAction(item, fragment, filter)
showDialog = false showDialog = false
@ -212,7 +213,7 @@ open class SwipeActions(private val fragment: Fragment, private val tag: String)
class SetRatingSwipeAction : SwipeAction { class SetRatingSwipeAction : SwipeAction {
override fun getId(): String { override fun getId(): String {
return ActionTypes.MARK_FAV.name return ActionTypes.RATING.name
} }
override fun getActionIcon(): Int { override fun getActionIcon(): Int {
return R.drawable.ic_star return R.drawable.ic_star
@ -221,7 +222,7 @@ open class SwipeActions(private val fragment: Fragment, private val tag: String)
return R.attr.icon_yellow return R.attr.icon_yellow
} }
override fun getTitle(context: Context): String { override fun getTitle(context: Context): String {
return context.getString(R.string.switch_rating_label) return context.getString(R.string.set_rating_label)
} }
@OptIn(UnstableApi::class) @OptIn(UnstableApi::class)
override fun performAction(item: Episode, fragment: Fragment, filter: EpisodeFilter) { override fun performAction(item: Episode, fragment: Fragment, filter: EpisodeFilter) {

View File

@ -30,6 +30,7 @@ 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.model.Feed.Companion.MAX_SYNTHETIC_ID import ac.mdiq.podcini.storage.model.Feed.Companion.MAX_SYNTHETIC_ID
import ac.mdiq.podcini.storage.model.Feed.Companion.newId import ac.mdiq.podcini.storage.model.Feed.Companion.newId
import ac.mdiq.podcini.storage.model.PlayState.Companion.fromCode
import ac.mdiq.podcini.storage.utils.DurationConverter import ac.mdiq.podcini.storage.utils.DurationConverter
import ac.mdiq.podcini.storage.utils.EpisodeUtil.hasAlmostEnded import ac.mdiq.podcini.storage.utils.EpisodeUtil.hasAlmostEnded
import ac.mdiq.podcini.storage.utils.ImageResourceUtils import ac.mdiq.podcini.storage.utils.ImageResourceUtils
@ -692,14 +693,15 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: MutableList<EpisodeVM>, feed:
if (selectMode) toggleSelected() if (selectMode) toggleSelected()
else if (vm.episode.feed != null) activity.loadChildFragment(FeedInfoFragment.newInstance(vm.episode.feed!!)) else if (vm.episode.feed != null) activity.loadChildFragment(FeedInfoFragment.newInstance(vm.episode.feed!!))
})) }))
val alpha = if (vm.playedState >= PlayState.SKIPPED.code) 1.0f else 0f if (vm.playedState >= PlayState.SKIPPED.code) {
if (vm.playedState >= PlayState.SKIPPED.code) Icon(imageVector = ImageVector.vectorResource(R.drawable.ic_check), tint = textColor, contentDescription = "played_mark", Icon(imageVector = ImageVector.vectorResource(fromCode(vm.playedState).res), tint = textColor, contentDescription = "play state",
modifier = Modifier.background(Color.Green).alpha(alpha) modifier = Modifier.background(Color.Green.copy(alpha = 0.6f)).width(20.dp).height(20.dp)
.constrainAs(checkMark) { .constrainAs(checkMark) {
bottom.linkTo(parent.bottom) bottom.linkTo(parent.bottom)
end.linkTo(parent.end) end.linkTo(parent.end)
}) })
} }
}
Column(Modifier.weight(1f).padding(start = 6.dp, end = 6.dp) Column(Modifier.weight(1f).padding(start = 6.dp, end = 6.dp)
.combinedClickable(onClick = { .combinedClickable(onClick = {
Logd(TAG, "clicked: ${vm.episode.title}") Logd(TAG, "clicked: ${vm.episode.title}")

View File

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M22,5.7l-4.6,-3.9 -1.3,1.5 4.6,3.9L22,5.7zM7.9,3.4L6.6,1.9 2,5.7l1.3,1.5 4.6,-3.8zM12.5,8L11,8v6l4.7,2.9 0.8,-1.2 -4,-2.4L12.5,8zM12,4c-5,0 -9,4 -9,9s4,9 9,9 9,-4 9,-9 -4,-9 -9,-9zM12,20c-3.9,0 -7,-3.1 -7,-7s3.1,-7 7,-7 7,3.1 7,7 -3.1,7 -7,7z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M11,17c0,0.55 0.45,1 1,1s1,-0.45 1,-1 -0.45,-1 -1,-1 -1,0.45 -1,1zM11,3v4h2L13,5.08c3.39,0.49 6,3.39 6,6.92 0,3.87 -3.13,7 -7,7s-7,-3.13 -7,-7c0,-1.68 0.59,-3.22 1.58,-4.42L12,13l1.41,-1.41 -6.8,-6.8v0.02C4.42,6.45 3,9.05 3,12c0,4.97 4.02,9 9,9 4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9h-1zM18,12c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1 0.45,1 1,1 1,-0.45 1,-1zM6,12c0,0.55 0.45,1 1,1s1,-0.45 1,-1 -0.45,-1 -1,-1 -1,0.45 -1,1z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S14.76,7 12,7L12,7zM2,13l2,0c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1l-2,0c-0.55,0 -1,0.45 -1,1S1.45,13 2,13zM20,13l2,0c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1l-2,0c-0.55,0 -1,0.45 -1,1S19.45,13 20,13zM11,2v2c0,0.55 0.45,1 1,1s1,-0.45 1,-1V2c0,-0.55 -0.45,-1 -1,-1S11,1.45 11,2zM11,20v2c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-2c0,-0.55 -0.45,-1 -1,-1C11.45,19 11,19.45 11,20zM5.99,4.58c-0.39,-0.39 -1.03,-0.39 -1.41,0c-0.39,0.39 -0.39,1.03 0,1.41l1.06,1.06c0.39,0.39 1.03,0.39 1.41,0s0.39,-1.03 0,-1.41L5.99,4.58zM18.36,16.95c-0.39,-0.39 -1.03,-0.39 -1.41,0c-0.39,0.39 -0.39,1.03 0,1.41l1.06,1.06c0.39,0.39 1.03,0.39 1.41,0c0.39,-0.39 0.39,-1.03 0,-1.41L18.36,16.95zM19.42,5.99c0.39,-0.39 0.39,-1.03 0,-1.41c-0.39,-0.39 -1.03,-0.39 -1.41,0l-1.06,1.06c-0.39,0.39 -0.39,1.03 0,1.41s1.03,0.39 1.41,0L19.42,5.99zM7.05,18.36c0.39,-0.39 0.39,-1.03 0,-1.41c-0.39,-0.39 -1.03,-0.39 -1.41,0l-1.06,1.06c-0.39,0.39 -0.39,1.03 0,1.41s1.03,0.39 1.41,0L7.05,18.36z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M12,5V1L7,6l5,5V7c3.31,0 6,2.69 6,6s-2.69,6 -6,6 -6,-2.69 -6,-6H4c0,4.42 3.58,8 8,8s8,-3.58 8,-8 -3.58,-8 -8,-8z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM18.49,14.11l0.26,2.79 -2.74,0.62 -1.43,2.41L12,18.82l-2.58,1.11 -1.43,-2.41 -2.74,-0.62 0.26,-2.8L3.66,12l1.85,-2.12 -0.26,-2.78 2.74,-0.61 1.43,-2.41L12,5.18l2.58,-1.11 1.43,2.41 2.74,0.62 -0.26,2.79L20.34,12l-1.85,2.11zM11,15h2v2h-2zM11,7h2v6h-2z"/>
</vector>

View File

@ -298,7 +298,6 @@
</plurals> </plurals>
<string name="show_video_label">Play video</string> <string name="show_video_label">Play video</string>
<string name="add_to_favorite_label">Add to favorites</string> <string name="add_to_favorite_label">Add to favorites</string>
<string name="switch_rating_label">Swtich rating</string>
<string name="toggle_favorite_label">Toggle favorites</string> <string name="toggle_favorite_label">Toggle favorites</string>
<string name="media_type">Media type</string> <string name="media_type">Media type</string>
<string name="unknown">Unknown</string> <string name="unknown">Unknown</string>

View File

@ -1,3 +1,10 @@
# 6.13.1
* fixed the misbehavior (from 6.13.0) of rewind/forward/progress in PlayerUI
* added Again and Forever in PlayState, and changed some PlayState icons
* in episodes list, when an episode's play state is higher than Skipped, state icon (rather than only a check) is on the cover image
* in Combo swipe actions, removed NoAction and ComboAction
# 6.13.0 # 6.13.0
* updates playback position adaptively (in app and in widget) in an interval being the longer of 5 seconds and 2 percent of the media duration * updates playback position adaptively (in app and in widget) in an interval being the longer of 5 seconds and 2 percent of the media duration

View File

@ -0,0 +1,6 @@
Version 6.13.1
* fixed the misbehavior (from 6.13.0) of rewind/forward/progress in PlayerUI
* added Again and Forever in PlayState, and changed some PlayState icons
* in episodes list, when an episode's play state is higher than Skipped, state icon (rather than only a check) is on the cover image
* in Combo swipe actions, removed NoAction and ComboAction