4.5.4 commit
This commit is contained in:
parent
15321d51e5
commit
9233a443de
|
@ -149,8 +149,8 @@ android {
|
|||
// Version code schema (not used):
|
||||
// "1.2.3-beta4" -> 1020304
|
||||
// "1.2.3" -> 1020395
|
||||
versionCode 3020123
|
||||
versionName "4.5.3"
|
||||
versionCode 3020124
|
||||
versionName "4.5.4"
|
||||
|
||||
def commit = ""
|
||||
try {
|
||||
|
|
|
@ -31,6 +31,8 @@ class TypeGetter {
|
|||
reader = createReader(feed)
|
||||
xpp.setInput(reader)
|
||||
var eventType = xpp.eventType
|
||||
// TODO: need to check about handling webpage
|
||||
// return return Type.ATOM
|
||||
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
|
@ -63,7 +65,9 @@ class TypeGetter {
|
|||
Log.d(TAG, "Recognized type RSS 0.91/0.92")
|
||||
return Type.RSS091
|
||||
}
|
||||
else -> throw UnsupportedFeedtypeException("Unsupported rss version")
|
||||
else -> {
|
||||
throw UnsupportedFeedtypeException("Unsupported rss version")
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
|
|
@ -26,8 +26,7 @@ object PlaybackSpeedUtils {
|
|||
mediaType = media.getMediaType()
|
||||
playbackSpeed = PlaybackPreferences.currentlyPlayingTemporaryPlaybackSpeed
|
||||
|
||||
// if (playbackSpeed == FeedPreferences.SPEED_USE_GLOBAL && media is FeedMedia) {
|
||||
if (media is FeedMedia) {
|
||||
if (playbackSpeed == FeedPreferences.SPEED_USE_GLOBAL && media is FeedMedia) {
|
||||
val item = media.item
|
||||
if (item != null) {
|
||||
val feed = item.feed
|
||||
|
|
|
@ -13,6 +13,7 @@ import ac.mdiq.podcini.storage.model.feed.FeedMedia
|
|||
import ac.mdiq.podcini.storage.model.playback.MediaType
|
||||
import ac.mdiq.podcini.storage.model.playback.Playable
|
||||
import ac.mdiq.podcini.playback.base.PlayerStatus
|
||||
import ac.mdiq.podcini.preferences.UserPreferences
|
||||
import android.content.*
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
|
@ -152,6 +153,7 @@ abstract class PlaybackController(private val activity: FragmentActivity) {
|
|||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
if (service is LocalBinder) {
|
||||
playbackService = service.service
|
||||
onPlaybackServiceConnected()
|
||||
if (!released) {
|
||||
queryService()
|
||||
Log.d(TAG, "Connection to Service established")
|
||||
|
@ -243,6 +245,8 @@ abstract class PlaybackController(private val activity: FragmentActivity) {
|
|||
|
||||
abstract fun loadMediaInfo()
|
||||
|
||||
open fun onPlaybackServiceConnected() { }
|
||||
|
||||
/**
|
||||
* Called when connection to playback service has been established or
|
||||
* information has to be refreshed
|
||||
|
@ -342,10 +346,11 @@ abstract class PlaybackController(private val activity: FragmentActivity) {
|
|||
playbackService?.setVideoSurface(holder)
|
||||
}
|
||||
|
||||
fun setPlaybackSpeed(speed: Float, codeArray: Array<Int>? = null) {
|
||||
fun setPlaybackSpeed(speed: Float, codeArray: BooleanArray? = null) {
|
||||
if (playbackService != null) {
|
||||
playbackService!!.setSpeed(speed, codeArray)
|
||||
} else {
|
||||
UserPreferences.setPlaybackSpeed(speed)
|
||||
EventBus.getDefault().post(SpeedChangedEvent(speed))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1617,18 +1617,18 @@ class PlaybackService : MediaBrowserServiceCompat() {
|
|||
val playable: Playable?
|
||||
get() = mediaPlayer?.getPlayable()
|
||||
|
||||
fun setSpeed(speed: Float, codeArray: Array<Int>? = null) {
|
||||
fun setSpeed(speed: Float, codeArray: BooleanArray? = null) {
|
||||
isSpeedForward = false
|
||||
isFallbackSpeed = false
|
||||
|
||||
currentlyPlayingTemporaryPlaybackSpeed = speed
|
||||
|
||||
if (currentMediaType == MediaType.VIDEO) {
|
||||
currentlyPlayingTemporaryPlaybackSpeed = speed
|
||||
videoPlaybackSpeed = speed
|
||||
mediaPlayer?.setPlaybackParams(speed, isSkipSilence)
|
||||
} else {
|
||||
if (codeArray != null && codeArray.size == 3) {
|
||||
if (codeArray[2] == 1) setPlaybackSpeed(speed)
|
||||
if (codeArray[1] == 1 && playable is FeedMedia) {
|
||||
if (codeArray[2]) setPlaybackSpeed(speed)
|
||||
if (codeArray[1] && playable is FeedMedia) {
|
||||
var item = (playable as FeedMedia).item
|
||||
if (item == null) {
|
||||
val itemId = (playable as FeedMedia).itemId
|
||||
|
@ -1651,11 +1651,16 @@ class PlaybackService : MediaBrowserServiceCompat() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (codeArray[0]) {
|
||||
currentlyPlayingTemporaryPlaybackSpeed = speed
|
||||
mediaPlayer?.setPlaybackParams(speed, isSkipSilence)
|
||||
}
|
||||
} else {
|
||||
currentlyPlayingTemporaryPlaybackSpeed = speed
|
||||
mediaPlayer?.setPlaybackParams(speed, isSkipSilence)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun speedForward(speed: Float) {
|
||||
if (mediaPlayer == null || isFallbackSpeed) return
|
||||
|
|
|
@ -11,8 +11,8 @@ class PlaybackSpeedDialogActivity : AppCompatActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setTheme(getTranslucentTheme(this))
|
||||
super.onCreate(savedInstanceState)
|
||||
val speedDialog: VariableSpeedDialog = InnerVariableSpeedDialog()
|
||||
speedDialog.show(supportFragmentManager, null)
|
||||
val speedDialog: VariableSpeedDialog? = VariableSpeedDialog.newInstance(booleanArrayOf(false, false, true), 2)
|
||||
speedDialog?.show(supportFragmentManager, null)
|
||||
}
|
||||
|
||||
class InnerVariableSpeedDialog : VariableSpeedDialog() {
|
||||
|
|
|
@ -609,7 +609,7 @@ class VideoplayerActivity : CastEnabledActivity(), OnSeekBarChangeListener {
|
|||
shareDialog.show(supportFragmentManager, "ShareEpisodeDialog")
|
||||
}
|
||||
item.itemId == R.id.playback_speed -> {
|
||||
VariableSpeedDialog().show(supportFragmentManager, null)
|
||||
VariableSpeedDialog.newInstance(booleanArrayOf(true, false, true))?.show(supportFragmentManager, null)
|
||||
}
|
||||
else -> {
|
||||
return false
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.view.LayoutInflater
|
|||
import androidx.media3.common.util.UnstableApi
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.math.round
|
||||
|
||||
@UnstableApi
|
||||
class EditFallbackSpeedDialog(activity: Activity) {
|
||||
|
@ -32,7 +33,7 @@ import java.lang.ref.WeakReference
|
|||
speed < 0.0f -> speed = 0.0f
|
||||
speed > 3.0f -> speed = 3.0f
|
||||
}
|
||||
fallbackSpeed = String.format("%.2f", speed).toFloat()
|
||||
fallbackSpeed = round(100 * speed) / 100
|
||||
}
|
||||
.setNegativeButton(R.string.cancel_label, null)
|
||||
.show()
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.view.LayoutInflater
|
|||
import androidx.media3.common.util.UnstableApi
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.math.round
|
||||
|
||||
@UnstableApi
|
||||
class EditForwardSpeedDialog(activity: Activity) {
|
||||
|
@ -33,7 +34,7 @@ import java.lang.ref.WeakReference
|
|||
speed < 0.0f -> speed = 0.0f
|
||||
speed > 10.0f -> speed = 10.0f
|
||||
}
|
||||
speedforwardSpeed = String.format("%.1f", speed).toFloat()
|
||||
speedforwardSpeed = round(10 * speed) / 10
|
||||
}
|
||||
.setNegativeButton(R.string.cancel_label, null)
|
||||
.show()
|
||||
|
|
|
@ -11,6 +11,7 @@ import ac.mdiq.podcini.ui.view.PlaybackSpeedSeekBar
|
|||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -40,7 +41,7 @@ open class VariableSpeedDialog : BottomSheetDialogFragment() {
|
|||
private var controller: PlaybackController? = null
|
||||
private val selectedSpeeds: MutableList<Float>
|
||||
|
||||
private val settingCode: Array<Int> = Array(3) { 0 }
|
||||
private lateinit var settingCode: BooleanArray
|
||||
|
||||
init {
|
||||
val format = DecimalFormatSymbols(Locale.US)
|
||||
|
@ -50,14 +51,23 @@ open class VariableSpeedDialog : BottomSheetDialogFragment() {
|
|||
|
||||
@UnstableApi override fun onStart() {
|
||||
super.onStart()
|
||||
if (controller == null) {
|
||||
controller = object : PlaybackController(requireActivity()) {
|
||||
override fun loadMediaInfo() {
|
||||
if (controller != null) updateSpeed(SpeedChangedEvent(controller!!.currentPlaybackSpeedMultiplier))
|
||||
}
|
||||
|
||||
override fun onPlaybackServiceConnected() {
|
||||
super.onPlaybackServiceConnected()
|
||||
binding.currentAudio.visibility = View.VISIBLE
|
||||
binding.currentPodcast.visibility = View.VISIBLE
|
||||
|
||||
if (!settingCode[0]) binding.currentAudio.visibility = View.INVISIBLE
|
||||
if (!settingCode[1]) binding.currentPodcast.visibility = View.INVISIBLE
|
||||
if (!settingCode[2]) binding.global.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
controller?.init()
|
||||
}
|
||||
|
||||
EventBus.getDefault().register(this)
|
||||
if (controller != null) updateSpeed(SpeedChangedEvent(controller!!.currentPlaybackSpeedMultiplier))
|
||||
}
|
||||
|
@ -80,23 +90,28 @@ open class VariableSpeedDialog : BottomSheetDialogFragment() {
|
|||
): View? {
|
||||
_binding = SpeedSelectDialogBinding.inflate(inflater)
|
||||
|
||||
val argument = arguments?.getString("default_setting")
|
||||
settingCode = (arguments?.getBooleanArray("settingCode") ?: BooleanArray(3) {true})
|
||||
val index_default = arguments?.getInt("index_default")
|
||||
|
||||
when (argument) {
|
||||
null, "Current" -> {
|
||||
when (index_default) {
|
||||
null, 0 -> {
|
||||
binding.currentAudio.isChecked = true
|
||||
}
|
||||
"Feed" -> {
|
||||
1 -> {
|
||||
binding.currentPodcast.isChecked = true
|
||||
}
|
||||
else -> {
|
||||
binding.global.isChecked = true
|
||||
}
|
||||
}
|
||||
// if (!settingCode[0]) binding.currentAudio.visibility = View.INVISIBLE
|
||||
// if (!settingCode[1]) binding.currentPodcast.visibility = View.INVISIBLE
|
||||
// if (!settingCode[2]) binding.global.visibility = View.INVISIBLE
|
||||
|
||||
speedSeekBar = binding.speedSeekBar
|
||||
speedSeekBar.setProgressChangedListener { multiplier: Float ->
|
||||
controller?.setPlaybackSpeed(multiplier)
|
||||
addCurrentSpeedChip.text = String.format(Locale.getDefault(), "%1$.2f", multiplier)
|
||||
// controller?.setPlaybackSpeed(multiplier)
|
||||
}
|
||||
val selectedSpeedsGrid = binding.selectedSpeedsGrid
|
||||
selectedSpeedsGrid.layoutManager = GridLayoutManager(context, 3)
|
||||
|
@ -124,9 +139,13 @@ open class VariableSpeedDialog : BottomSheetDialogFragment() {
|
|||
|
||||
@OptIn(UnstableApi::class) override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
// if (controller == null || !controller!!.isPlaybackServiceReady()) {
|
||||
// binding.currentPodcast.visibility = View.INVISIBLE
|
||||
// } else binding.currentPodcast.visibility = View.VISIBLE
|
||||
if (controller == null || !controller!!.isPlaybackServiceReady()) {
|
||||
binding.currentAudio.visibility = View.INVISIBLE
|
||||
binding.currentPodcast.visibility = View.INVISIBLE
|
||||
} else {
|
||||
binding.currentAudio.visibility = View.VISIBLE
|
||||
binding.currentPodcast.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -165,9 +184,9 @@ open class VariableSpeedDialog : BottomSheetDialogFragment() {
|
|||
true
|
||||
}
|
||||
holder.chip.setOnClickListener { Handler(Looper.getMainLooper()).postDelayed({
|
||||
if (binding.currentAudio.isChecked) settingCode[0] = 1
|
||||
if (binding.currentPodcast.isChecked) settingCode[1] = 1
|
||||
if (binding.global.isChecked) settingCode[2] = 1
|
||||
if (binding.currentAudio.isChecked) settingCode[0] = true
|
||||
if (binding.currentPodcast.isChecked) settingCode[1] = true
|
||||
if (binding.global.isChecked) settingCode[2] = true
|
||||
|
||||
if (controller != null) {
|
||||
dismiss()
|
||||
|
@ -189,13 +208,18 @@ open class VariableSpeedDialog : BottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(argument: String? = null): VariableSpeedDialog {
|
||||
val dialog = VariableSpeedDialog()
|
||||
if (argument != null) {
|
||||
val args = Bundle()
|
||||
args.putString("default_setting", argument)
|
||||
dialog.arguments = args
|
||||
fun newInstance(settingCode_: BooleanArray? = null, index_default: Int? = null): VariableSpeedDialog? {
|
||||
val settingCode = settingCode_ ?: BooleanArray(3){false}
|
||||
if (settingCode.size != 3) {
|
||||
Log.e("VariableSpeedDialog", "wrong settingCode dimension")
|
||||
return null
|
||||
}
|
||||
val dialog = VariableSpeedDialog()
|
||||
val args = Bundle()
|
||||
args.putBooleanArray("settingCode", settingCode)
|
||||
if (index_default != null) args.putInt("index_default", index_default)
|
||||
dialog.arguments = args
|
||||
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
|
|
|
@ -500,7 +500,7 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
|||
setupLengthTextView()
|
||||
setupControlButtons()
|
||||
butPlaybackSpeed.setOnClickListener {
|
||||
VariableSpeedDialog.newInstance(null).show(childFragmentManager, null)
|
||||
VariableSpeedDialog.newInstance(booleanArrayOf(true, true, true), null)?.show(childFragmentManager, null)
|
||||
}
|
||||
sbPosition.setOnSeekBarChangeListener(this)
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ import io.reactivex.schedulers.Schedulers
|
|||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import org.jsoup.Jsoup
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import kotlin.concurrent.Volatile
|
||||
|
@ -330,6 +331,16 @@ class OnlineFeedViewFragment : Fragment() {
|
|||
Log.d(TAG, "Unsupported feed type detected")
|
||||
if ("html".equals(e.rootElement, ignoreCase = true)) {
|
||||
if (selectedDownloadUrl != null) {
|
||||
val doc = Jsoup.connect(selectedDownloadUrl).get()
|
||||
val linkElements = doc.select("link[type=application/rss+xml]")
|
||||
for (element in linkElements) {
|
||||
val rssUrl = element.attr("href")
|
||||
Log.d(TAG, "RSS URL: $rssUrl")
|
||||
val rc = destinationFile.delete()
|
||||
Log.d(TAG, "Deleted feed source file. Result: $rc")
|
||||
startFeedDownload(rssUrl)
|
||||
return null
|
||||
}
|
||||
val dialogShown = showFeedDiscoveryDialog(destinationFile, selectedDownloadUrl!!)
|
||||
if (dialogShown) {
|
||||
null // Should not display an error message
|
||||
|
|
|
@ -39,7 +39,7 @@ class PlaybackPreferencesFragment : PreferenceFragmentCompat() {
|
|||
|
||||
findPreference<Preference>(PREF_PLAYBACK_SPEED_LAUNCHER)!!.onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
VariableSpeedDialog.newInstance("Global").show(childFragmentManager, null)
|
||||
VariableSpeedDialog.newInstance(booleanArrayOf(false, false, true),2)?.show(childFragmentManager, null)
|
||||
true
|
||||
}
|
||||
findPreference<Preference>(PREF_PLAYBACK_REWIND_DELTA_LAUNCHER)!!.onPreferenceClickListener =
|
||||
|
|
|
@ -64,12 +64,12 @@
|
|||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="75dp"
|
||||
android:layout_height="80dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvCover"
|
||||
android:layout_width="75dp"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="match_parent"
|
||||
android:cropToPadding="true"
|
||||
android:scaleType="fitCenter"
|
||||
|
@ -127,9 +127,8 @@
|
|||
android:layout_alignLeft="@id/butRev"
|
||||
android:layout_alignEnd="@id/butRev"
|
||||
android:layout_alignRight="@id/butRev"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="30"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="12sp" />
|
||||
|
@ -158,7 +157,6 @@
|
|||
android:layout_alignLeft="@id/butPlaybackSpeed"
|
||||
android:layout_alignEnd="@id/butPlaybackSpeed"
|
||||
android:layout_alignRight="@id/butPlaybackSpeed"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:text="1.00"
|
||||
|
@ -191,7 +189,6 @@
|
|||
android:layout_alignLeft="@id/butFF"
|
||||
android:layout_alignEnd="@id/butFF"
|
||||
android:layout_alignRight="@id/butFF"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:text="30"
|
||||
|
@ -224,7 +221,6 @@
|
|||
android:layout_alignLeft="@id/butSkip"
|
||||
android:layout_alignEnd="@id/butSkip"
|
||||
android:layout_alignRight="@id/butSkip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<dimen name="drawer_corner_size">16dp</dimen>
|
||||
<dimen name="widget_margin">0dp</dimen>
|
||||
<dimen name="widget_inner_radius">4dp</dimen>
|
||||
<dimen name="external_player_height">130dp</dimen>
|
||||
<dimen name="external_player_height">135dp</dimen>
|
||||
<dimen name="text_size_micro">12sp</dimen>
|
||||
<dimen name="text_size_small">14sp</dimen>
|
||||
<dimen name="text_size_navdrawer">16sp</dimen>
|
||||
|
|
|
@ -216,3 +216,12 @@
|
|||
* adjusted layout and button dimension and alignments in the bottom player control
|
||||
* fallback speed setting is now capped at 0.0 and 3.0 and allows for 2-digit precision
|
||||
* corrected episode count display in subscriptions list when the feed has 0 episodes
|
||||
|
||||
## 4.5.4
|
||||
|
||||
* fixed crash bug when setting fallback or fast-forward speeds with some Locales
|
||||
* further enlarged height of the bottom player control to improve on missing pixels at the bottom
|
||||
* on speed setting dialog, only tap on a preset chip sets the speed, only selected options will be set
|
||||
* corrected the handling of current audio speed:
|
||||
* when speed for current audio is not set, podcast speed takes precedence
|
||||
* when speed for current audio is set, it takes precedence for the current audio (episode), even with pause/re-play
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
Version 4.5.3 brings several changes:
|
||||
|
||||
* fixed crash bug when setting fallback or fast-forward speeds with some Locales
|
||||
* further enlarged height of the bottom player control to improve on missing pixels at the bottom
|
||||
* on speed setting dialog, only tap on a preset chip sets the speed, only selected options will be set
|
||||
* corrected the handling of current audio speed:
|
||||
* when speed for current audio is not set, podcast speed takes precedence
|
||||
* when speed for current audio is set, it takes precedence for the current audio (episode), even with pause/re-play
|
Loading…
Reference in New Issue