minor improvements
This commit is contained in:
parent
824893cbfc
commit
31624b7797
|
@ -171,7 +171,7 @@ object EspressoTestUtils {
|
|||
init(InstrumentationRegistry.getInstrumentation().targetContext)
|
||||
deleteDatabase()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.close()
|
||||
}
|
||||
|
||||
|
|
|
@ -108,11 +108,11 @@ class PlaybackServiceMediaPlayerTest {
|
|||
f.preferences = prefs
|
||||
f.items = mutableListOf()
|
||||
val i = FeedItem(0, "t", "i", "l", Date(), FeedItem.UNPLAYED, f)
|
||||
f.items!!.add(i)
|
||||
f.items.add(i)
|
||||
val media = FeedMedia(0, i, 0, 0, 0, "audio/wav", fileUrl, downloadUrl, fileUrl != null, null, 0, 0)
|
||||
i.setMedia(media)
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(f)
|
||||
Assert.assertTrue(media.id != 0L)
|
||||
adapter.close()
|
||||
|
@ -130,14 +130,18 @@ class PlaybackServiceMediaPlayerTest {
|
|||
try {
|
||||
checkPSMPInfo(newInfo)
|
||||
check(newInfo!!.playerStatus != PlayerStatus.ERROR) { "MediaPlayer error" }
|
||||
if (countDownLatch.count == 0L) {
|
||||
Assert.fail()
|
||||
} else if (countDownLatch.count == 2L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
} else {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
when (countDownLatch.count) {
|
||||
0L -> {
|
||||
Assert.fail()
|
||||
}
|
||||
2L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
else -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
}
|
||||
} catch (e: AssertionFailedError) {
|
||||
if (assertionError == null) assertionError = e
|
||||
|
@ -168,14 +172,18 @@ class PlaybackServiceMediaPlayerTest {
|
|||
try {
|
||||
checkPSMPInfo(newInfo)
|
||||
check(newInfo!!.playerStatus != PlayerStatus.ERROR) { "MediaPlayer error" }
|
||||
if (countDownLatch.count == 0L) {
|
||||
Assert.fail()
|
||||
} else if (countDownLatch.count == 2L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
} else {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
when (countDownLatch.count) {
|
||||
0L -> {
|
||||
Assert.fail()
|
||||
}
|
||||
2L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
else -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
}
|
||||
} catch (e: AssertionFailedError) {
|
||||
if (assertionError == null) assertionError = e
|
||||
|
@ -207,16 +215,22 @@ class PlaybackServiceMediaPlayerTest {
|
|||
try {
|
||||
checkPSMPInfo(newInfo)
|
||||
check(newInfo!!.playerStatus != PlayerStatus.ERROR) { "MediaPlayer error" }
|
||||
if (countDownLatch.count == 0L) {
|
||||
Assert.fail()
|
||||
} else if (countDownLatch.count == 4L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 3L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 2L) {
|
||||
Assert.assertEquals(PlayerStatus.PREPARING, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 1L) {
|
||||
Assert.assertEquals(PlayerStatus.PREPARED, newInfo.playerStatus)
|
||||
when (countDownLatch.count) {
|
||||
0L -> {
|
||||
Assert.fail()
|
||||
}
|
||||
4L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
}
|
||||
3L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
}
|
||||
2L -> {
|
||||
Assert.assertEquals(PlayerStatus.PREPARING, newInfo.playerStatus)
|
||||
}
|
||||
1L -> {
|
||||
Assert.assertEquals(PlayerStatus.PREPARED, newInfo.playerStatus)
|
||||
}
|
||||
}
|
||||
countDownLatch.countDown()
|
||||
} catch (e: AssertionFailedError) {
|
||||
|
@ -247,18 +261,25 @@ class PlaybackServiceMediaPlayerTest {
|
|||
try {
|
||||
checkPSMPInfo(newInfo)
|
||||
check(newInfo!!.playerStatus != PlayerStatus.ERROR) { "MediaPlayer error" }
|
||||
if (countDownLatch.count == 0L) {
|
||||
Assert.fail()
|
||||
} else if (countDownLatch.count == 5L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 4L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 3L) {
|
||||
Assert.assertEquals(PlayerStatus.PREPARING, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 2L) {
|
||||
Assert.assertEquals(PlayerStatus.PREPARED, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 1L) {
|
||||
Assert.assertEquals(PlayerStatus.PLAYING, newInfo.playerStatus)
|
||||
when (countDownLatch.count) {
|
||||
0L -> {
|
||||
Assert.fail()
|
||||
}
|
||||
5L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
}
|
||||
4L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
}
|
||||
3L -> {
|
||||
Assert.assertEquals(PlayerStatus.PREPARING, newInfo.playerStatus)
|
||||
}
|
||||
2L -> {
|
||||
Assert.assertEquals(PlayerStatus.PREPARED, newInfo.playerStatus)
|
||||
}
|
||||
1L -> {
|
||||
Assert.assertEquals(PlayerStatus.PLAYING, newInfo.playerStatus)
|
||||
}
|
||||
}
|
||||
countDownLatch.countDown()
|
||||
} catch (e: AssertionFailedError) {
|
||||
|
@ -288,14 +309,18 @@ class PlaybackServiceMediaPlayerTest {
|
|||
try {
|
||||
checkPSMPInfo(newInfo)
|
||||
check(newInfo!!.playerStatus != PlayerStatus.ERROR) { "MediaPlayer error" }
|
||||
if (countDownLatch.count == 0L) {
|
||||
Assert.fail()
|
||||
} else if (countDownLatch.count == 2L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
} else {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
when (countDownLatch.count) {
|
||||
0L -> {
|
||||
Assert.fail()
|
||||
}
|
||||
2L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
else -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
}
|
||||
} catch (e: AssertionFailedError) {
|
||||
if (assertionError == null) assertionError = e
|
||||
|
@ -325,14 +350,18 @@ class PlaybackServiceMediaPlayerTest {
|
|||
try {
|
||||
checkPSMPInfo(newInfo)
|
||||
check(newInfo!!.playerStatus != PlayerStatus.ERROR) { "MediaPlayer error" }
|
||||
if (countDownLatch.count == 0L) {
|
||||
Assert.fail()
|
||||
} else if (countDownLatch.count == 2L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
} else {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
when (countDownLatch.count) {
|
||||
0L -> {
|
||||
Assert.fail()
|
||||
}
|
||||
2L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
else -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
countDownLatch.countDown()
|
||||
}
|
||||
}
|
||||
} catch (e: AssertionFailedError) {
|
||||
if (assertionError == null) assertionError = e
|
||||
|
@ -362,16 +391,22 @@ class PlaybackServiceMediaPlayerTest {
|
|||
try {
|
||||
checkPSMPInfo(newInfo)
|
||||
check(newInfo!!.playerStatus != PlayerStatus.ERROR) { "MediaPlayer error" }
|
||||
if (countDownLatch.count == 0L) {
|
||||
Assert.fail()
|
||||
} else if (countDownLatch.count == 4L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 3L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 2L) {
|
||||
Assert.assertEquals(PlayerStatus.PREPARING, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 1L) {
|
||||
Assert.assertEquals(PlayerStatus.PREPARED, newInfo.playerStatus)
|
||||
when (countDownLatch.count) {
|
||||
0L -> {
|
||||
Assert.fail()
|
||||
}
|
||||
4L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
}
|
||||
3L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
}
|
||||
2L -> {
|
||||
Assert.assertEquals(PlayerStatus.PREPARING, newInfo.playerStatus)
|
||||
}
|
||||
1L -> {
|
||||
Assert.assertEquals(PlayerStatus.PREPARED, newInfo.playerStatus)
|
||||
}
|
||||
}
|
||||
countDownLatch.countDown()
|
||||
} catch (e: AssertionFailedError) {
|
||||
|
@ -401,18 +436,25 @@ class PlaybackServiceMediaPlayerTest {
|
|||
try {
|
||||
checkPSMPInfo(newInfo)
|
||||
check(newInfo!!.playerStatus != PlayerStatus.ERROR) { "MediaPlayer error" }
|
||||
if (countDownLatch.count == 0L) {
|
||||
Assert.fail()
|
||||
} else if (countDownLatch.count == 5L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 4L) {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 3L) {
|
||||
Assert.assertEquals(PlayerStatus.PREPARING, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 2L) {
|
||||
Assert.assertEquals(PlayerStatus.PREPARED, newInfo.playerStatus)
|
||||
} else if (countDownLatch.count == 1L) {
|
||||
Assert.assertEquals(PlayerStatus.PLAYING, newInfo.playerStatus)
|
||||
when (countDownLatch.count) {
|
||||
0L -> {
|
||||
Assert.fail()
|
||||
}
|
||||
5L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZING, newInfo.playerStatus)
|
||||
}
|
||||
4L -> {
|
||||
Assert.assertEquals(PlayerStatus.INITIALIZED, newInfo.playerStatus)
|
||||
}
|
||||
3L -> {
|
||||
Assert.assertEquals(PlayerStatus.PREPARING, newInfo.playerStatus)
|
||||
}
|
||||
2L -> {
|
||||
Assert.assertEquals(PlayerStatus.PREPARED, newInfo.playerStatus)
|
||||
}
|
||||
1L -> {
|
||||
Assert.assertEquals(PlayerStatus.PLAYING, newInfo.playerStatus)
|
||||
}
|
||||
}
|
||||
} catch (e: AssertionFailedError) {
|
||||
if (assertionError == null) assertionError = e
|
||||
|
|
|
@ -43,7 +43,7 @@ class PlaybackServiceTaskManagerTest {
|
|||
init(context)
|
||||
deleteDatabase()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.close()
|
||||
setShakeToReset(false)
|
||||
setVibrate(false)
|
||||
|
@ -61,15 +61,15 @@ class PlaybackServiceTaskManagerTest {
|
|||
val f = Feed(0, null, "title", "link", "d", null, null, null, null, "id", null, "null", "url", false)
|
||||
f.items = mutableListOf()
|
||||
for (i in 0 until NUM_ITEMS) {
|
||||
f.items!!.add(FeedItem(0, pref + i, pref + i, "link", Date(), FeedItem.PLAYED, f))
|
||||
f.items.add(FeedItem(0, pref + i, pref + i, "link", Date(), FeedItem.PLAYED, f))
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(f)
|
||||
adapter.setQueue(f.items!!)
|
||||
adapter.setQueue(f.items)
|
||||
adapter.close()
|
||||
|
||||
for (item in f.items!!) {
|
||||
for (item in f.items) {
|
||||
Assert.assertTrue(item.id != 0L)
|
||||
}
|
||||
return f.items
|
||||
|
|
|
@ -189,7 +189,7 @@ class UITestUtils(private val context: Context) {
|
|||
localFeedDataAdded = true
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(*hostedFeeds.toTypedArray<Feed>())
|
||||
adapter.setQueue(queue)
|
||||
adapter.close()
|
||||
|
|
|
@ -35,6 +35,7 @@ import com.google.android.material.snackbar.Snackbar
|
|||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.core.preferences.ThemeSwitcher.getNoTitleTheme
|
||||
import ac.mdiq.podcini.core.receiver.MediaButtonReceiver.Companion.createIntent
|
||||
import ac.mdiq.podcini.core.storage.DBReader
|
||||
import ac.mdiq.podcini.core.sync.queue.SynchronizationQueueSink
|
||||
import ac.mdiq.podcini.core.util.download.FeedUpdateManager
|
||||
import ac.mdiq.podcini.core.util.download.FeedUpdateManager.restartUpdateAlarm
|
||||
|
@ -103,6 +104,8 @@ class MainActivity : CastEnabledActivity() {
|
|||
.build()
|
||||
}
|
||||
|
||||
DBReader.updateFeedList()
|
||||
|
||||
val fm = supportFragmentManager
|
||||
if (fm.findFragmentByTag(MAIN_FRAGMENT_TAG) == null) {
|
||||
if (UserPreferences.DEFAULT_PAGE_REMEMBER != defaultPage) {
|
||||
|
|
|
@ -423,7 +423,7 @@ class OnlineFeedViewActivity : AppCompatActivity() {
|
|||
|
||||
viewBinding.titleLabel.text = feed.title
|
||||
viewBinding.authorLabel.text = feed.author
|
||||
headerBinding.txtvDescription.text = HtmlToPlainText.getPlainText(feed.description)
|
||||
headerBinding.txtvDescription.text = HtmlToPlainText.getPlainText(feed.description?:"")
|
||||
|
||||
viewBinding.subscribeButton.setOnClickListener { v: View? ->
|
||||
if (feedInFeedlist()) {
|
||||
|
|
|
@ -1,28 +1,7 @@
|
|||
package ac.mdiq.podcini.activity
|
||||
|
||||
import ac.mdiq.podcini.activity.MainActivity
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.view.View.OnTouchListener
|
||||
import android.view.animation.*
|
||||
import android.widget.EditText
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.SeekBar
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.activity.MainActivity
|
||||
import ac.mdiq.podcini.core.service.playback.PlaybackService.Companion.getPlayerActivityIntent
|
||||
import ac.mdiq.podcini.core.service.playback.PlaybackService.Companion.isCasting
|
||||
import ac.mdiq.podcini.core.storage.DBReader
|
||||
|
@ -53,6 +32,27 @@ import ac.mdiq.podcini.storage.preferences.UserPreferences.rewindSecs
|
|||
import ac.mdiq.podcini.storage.preferences.UserPreferences.setShowRemainTimeSetting
|
||||
import ac.mdiq.podcini.storage.preferences.UserPreferences.shouldShowRemainingTime
|
||||
import ac.mdiq.podcini.ui.appstartintent.MainActivityStarter
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.view.View.OnTouchListener
|
||||
import android.view.animation.*
|
||||
import android.widget.EditText
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.SeekBar
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
|
|
|
@ -49,10 +49,10 @@ class FeedItemlistDescriptionAdapter(context: Context, resource: Int, objects: L
|
|||
holder.title!!.text = item!!.title
|
||||
holder.pubDate!!.text = formatAbbrev(context, item.pubDate)
|
||||
if (item.description != null) {
|
||||
val description = HtmlToPlainText.getPlainText(item.description)
|
||||
?.replace("\n".toRegex(), " ")
|
||||
?.replace("\\s+".toRegex(), " ")
|
||||
?.trim { it <= ' ' }
|
||||
val description = HtmlToPlainText.getPlainText(item.description!!)
|
||||
.replace("\n".toRegex(), " ")
|
||||
.replace("\\s+".toRegex(), " ")
|
||||
.trim { it <= ' ' }
|
||||
holder.description!!.text = description
|
||||
holder.description!!.maxLines = MAX_LINES_COLLAPSED
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class PlaybackControlsDialog : DialogFragment() {
|
|||
|
||||
@UnstableApi override fun onStart() {
|
||||
super.onStart()
|
||||
controller = object : PlaybackController(activity) {
|
||||
controller = object : PlaybackController(requireActivity()) {
|
||||
override fun loadMediaInfo() {
|
||||
setupAudioTracks()
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class SleepTimerDialog : DialogFragment() {
|
|||
|
||||
@UnstableApi override fun onStart() {
|
||||
super.onStart()
|
||||
controller = object : PlaybackController(activity) {
|
||||
controller = object : PlaybackController(requireActivity()) {
|
||||
override fun loadMediaInfo() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ open class VariableSpeedDialog : BottomSheetDialogFragment() {
|
|||
|
||||
@UnstableApi override fun onStart() {
|
||||
super.onStart()
|
||||
controller = object : PlaybackController(activity) {
|
||||
controller = object : PlaybackController(requireActivity()) {
|
||||
override fun loadMediaInfo() {
|
||||
updateSpeed(SpeedChangedEvent(controller!!.currentPlaybackSpeedMultiplier))
|
||||
}
|
||||
|
|
|
@ -279,7 +279,7 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
|||
}
|
||||
|
||||
private fun newPlaybackController(): PlaybackController {
|
||||
return object : PlaybackController(activity) {
|
||||
return object : PlaybackController(requireActivity()) {
|
||||
override fun updatePlayButtonShowsPlay(showPlay: Boolean) {
|
||||
butPlay.setIsShowPlay(showPlay)
|
||||
}
|
||||
|
@ -295,10 +295,10 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
|||
}
|
||||
|
||||
private fun updateUi(media: Playable?) {
|
||||
if (controller == null || media == null) {
|
||||
if (controller != null) duration = controller!!.duration
|
||||
if (media == null) {
|
||||
return
|
||||
}
|
||||
duration = controller!!.duration
|
||||
updatePosition(PlaybackPositionEvent(media.getPosition(), media.getDuration()))
|
||||
updatePlaybackSpeedButton(SpeedChangedEvent(PlaybackSpeedUtils.getCurrentPlaybackSpeed(media)))
|
||||
setChapterDividers(media)
|
||||
|
@ -460,7 +460,7 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
|||
|
||||
val isFeedMedia = media is FeedMedia
|
||||
toolbar.menu?.findItem(R.id.open_feed_item)?.setVisible(isFeedMedia)
|
||||
if (isFeedMedia) {
|
||||
if (media != null && isFeedMedia) {
|
||||
FeedItemMenuHandler.onPrepareMenu(toolbar.menu, (media as FeedMedia).getItem())
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ class ChaptersFragment : AppCompatDialogFragment() {
|
|||
CoordinatorLayout.LayoutParams.MATCH_PARENT, CoordinatorLayout.LayoutParams.WRAP_CONTENT)
|
||||
recyclerView.layoutParams = wrapHeight
|
||||
|
||||
controller = object : PlaybackController(activity) {
|
||||
controller = object : PlaybackController(requireActivity()) {
|
||||
override fun loadMediaInfo() {
|
||||
this@ChaptersFragment.loadMediaInfo(false)
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.greenrobot.eventbus.ThreadMode
|
|||
*/
|
||||
class CoverFragment : Fragment() {
|
||||
private lateinit var viewBinding: CoverFragmentBinding
|
||||
|
||||
private var controller: PlaybackController? = null
|
||||
private var disposable: Disposable? = null
|
||||
private var displayedChapterIndex = -1
|
||||
|
@ -80,7 +81,7 @@ class CoverFragment : Fragment() {
|
|||
viewBinding.butPrevChapter.setOnClickListener { v: View? -> seekToPrevChapter() }
|
||||
viewBinding.butNextChapter.setOnClickListener { v: View? -> seekToNextChapter() }
|
||||
|
||||
controller = object : PlaybackController(activity) {
|
||||
controller = object : PlaybackController(requireActivity()) {
|
||||
override fun loadMediaInfo() {
|
||||
this@CoverFragment.loadMediaInfo(false)
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ class ExternalPlayerFragment : Fragment() {
|
|||
if (controller == null) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (controller!!.getMedia() != null && controller!!.getMedia()!!.getMediaType() == MediaType.VIDEO && controller!!.status != PlayerStatus.PLAYING) {
|
||||
if (controller!!.getMedia()?.getMediaType() == MediaType.VIDEO && controller!!.status != PlayerStatus.PLAYING) {
|
||||
controller!!.playPause()
|
||||
requireContext().startActivity(getPlayerActivityIntent(requireContext(), controller!!.getMedia()!!))
|
||||
} else {
|
||||
|
@ -101,7 +101,7 @@ class ExternalPlayerFragment : Fragment() {
|
|||
|
||||
@UnstableApi
|
||||
private fun setupPlaybackController(): PlaybackController {
|
||||
return object : PlaybackController(activity) {
|
||||
return object : PlaybackController(requireActivity()) {
|
||||
override fun updatePlayButtonShowsPlay(showPlay: Boolean) {
|
||||
butPlay.setIsShowPlay(showPlay)
|
||||
}
|
||||
|
|
|
@ -195,7 +195,7 @@ class FeedInfoFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
|||
txtvTitle.text = feed!!.title
|
||||
txtvTitle.setMaxLines(6)
|
||||
|
||||
val description: String = HtmlToPlainText.getPlainText(feed!!.description)?:""
|
||||
val description: String = HtmlToPlainText.getPlainText(feed!!.description?:"")
|
||||
|
||||
txtvDescription.text = description
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class ItemDescriptionFragment : Fragment() {
|
|||
}
|
||||
})
|
||||
registerForContextMenu(webvDescription)
|
||||
controller = object : PlaybackController(activity) {
|
||||
controller = object : PlaybackController(requireActivity()) {
|
||||
override fun loadMediaInfo() {
|
||||
load()
|
||||
}
|
||||
|
@ -91,10 +91,12 @@ class ItemDescriptionFragment : Fragment() {
|
|||
return@create
|
||||
}
|
||||
if (media is FeedMedia) {
|
||||
if (media.getItem() == null) {
|
||||
media.setItem(DBReader.getFeedItem(media.itemId))
|
||||
var item = media.getItem()
|
||||
if (item == null) {
|
||||
item = DBReader.getFeedItem(media.itemId)
|
||||
media.setItem(item)
|
||||
}
|
||||
if (media.getItem() != null) DBReader.loadDescriptionOfFeedItem(media.getItem()!!)
|
||||
if (item != null && item.description == null) DBReader.loadDescriptionOfFeedItem(item)
|
||||
}
|
||||
val shownotesCleaner = ShownotesCleaner(context, media.getDescription()?:"", media.getDuration())
|
||||
emitter.onSuccess(shownotesCleaner.processShownotes())
|
||||
|
|
|
@ -156,7 +156,7 @@ class ItemFragment : Fragment() {
|
|||
})
|
||||
|
||||
EventBus.getDefault().register(this)
|
||||
controller = object : PlaybackController(activity) {
|
||||
controller = object : PlaybackController(requireActivity()) {
|
||||
override fun loadMediaInfo() {
|
||||
// Do nothing
|
||||
}
|
||||
|
|
|
@ -459,7 +459,7 @@ class QueueFragment : Fragment(), Toolbar.OnMenuItemClickListener, SelectableAda
|
|||
}
|
||||
|
||||
private fun loadItems(restoreScrollPosition: Boolean) {
|
||||
Log.d(TAG, "loadItems()")
|
||||
Log.d(TAG, "loadItems() called")
|
||||
disposable?.dispose()
|
||||
|
||||
if (queue.isEmpty()) {
|
||||
|
|
|
@ -97,10 +97,11 @@ class HomeFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
|||
}
|
||||
|
||||
private fun addSection(section: Fragment?) {
|
||||
if (section == null) return
|
||||
val containerView = FragmentContainerView(requireContext())
|
||||
containerView.id = View.generateViewId()
|
||||
viewBinding.homeContainer.addView(containerView)
|
||||
if (section != null) childFragmentManager.beginTransaction().add(containerView.id, section).commit()
|
||||
childFragmentManager.beginTransaction().add(containerView.id, section).commit()
|
||||
}
|
||||
|
||||
private fun getSection(tag: String): Fragment? {
|
||||
|
|
|
@ -31,7 +31,8 @@ import org.greenrobot.eventbus.Subscribe
|
|||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class DownloadsSection : HomeSection() {
|
||||
private var adapter: EpisodeItemListAdapter? = null
|
||||
private lateinit var adapter: EpisodeItemListAdapter
|
||||
|
||||
private var disposable: Disposable? = null
|
||||
|
||||
@UnstableApi override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
|
@ -50,7 +51,7 @@ class DownloadsSection : HomeSection() {
|
|||
}
|
||||
}
|
||||
}
|
||||
adapter?.setDummyViews(NUM_EPISODES)
|
||||
adapter.setDummyViews(NUM_EPISODES)
|
||||
viewBinding.recyclerView.adapter = adapter
|
||||
|
||||
val swipeActions = SwipeActions(this, CompletedDownloadsFragment.TAG)
|
||||
|
@ -75,10 +76,7 @@ class DownloadsSection : HomeSection() {
|
|||
|
||||
@UnstableApi @Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(event: PlaybackPositionEvent) {
|
||||
if (adapter == null) {
|
||||
return
|
||||
}
|
||||
for (i in 0 until adapter!!.itemCount) {
|
||||
for (i in 0 until adapter.itemCount) {
|
||||
val holder: EpisodeItemViewHolder? = viewBinding.recyclerView.findViewHolderForAdapterPosition(i) as? EpisodeItemViewHolder
|
||||
if (holder != null && holder.isCurrentlyPlayingItem) {
|
||||
holder.notifyPlaybackPositionUpdated(event)
|
||||
|
@ -117,8 +115,8 @@ class DownloadsSection : HomeSection() {
|
|||
if (downloads.size > NUM_EPISODES) {
|
||||
downloads = downloads.subList(0, NUM_EPISODES)
|
||||
}
|
||||
adapter?.setDummyViews(0)
|
||||
adapter?.updateItems(downloads)
|
||||
adapter.setDummyViews(0)
|
||||
adapter.updateItems(downloads)
|
||||
}, { error: Throwable? -> Log.e(TAG, Log.getStackTraceString(error)) })
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ import org.greenrobot.eventbus.ThreadMode
|
|||
import java.util.*
|
||||
|
||||
class EpisodesSurpriseSection : HomeSection() {
|
||||
private var listAdapter: HorizontalItemListAdapter? = null
|
||||
private lateinit var listAdapter: HorizontalItemListAdapter
|
||||
|
||||
private var disposable: Disposable? = null
|
||||
private var episodes: MutableList<FeedItem> = ArrayList<FeedItem>()
|
||||
|
||||
|
@ -52,7 +53,7 @@ class EpisodesSurpriseSection : HomeSection() {
|
|||
}
|
||||
}
|
||||
}
|
||||
listAdapter?.setDummyViews(NUM_EPISODES)
|
||||
listAdapter.setDummyViews(NUM_EPISODES)
|
||||
viewBinding.recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
|
||||
viewBinding.recyclerView.adapter = listAdapter
|
||||
val paddingHorizontal: Int = (12 * resources.displayMetrics.density).toInt()
|
||||
|
@ -94,7 +95,7 @@ class EpisodesSurpriseSection : HomeSection() {
|
|||
if (pos >= 0) {
|
||||
episodes.removeAt(pos)
|
||||
episodes.add(pos, item)
|
||||
listAdapter?.notifyItemChangedCompat(pos)
|
||||
listAdapter.notifyItemChangedCompat(pos)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
@ -104,17 +105,14 @@ class EpisodesSurpriseSection : HomeSection() {
|
|||
fun onEventMainThread(event: EpisodeDownloadEvent) {
|
||||
for (downloadUrl in event.urls) {
|
||||
val pos: Int = FeedItemUtil.indexOfItemWithDownloadUrl(episodes, downloadUrl)
|
||||
if (pos >= 0) listAdapter?.notifyItemChangedCompat(pos)
|
||||
if (pos >= 0) listAdapter.notifyItemChangedCompat(pos)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(event: PlaybackPositionEvent) {
|
||||
if (listAdapter == null) {
|
||||
return
|
||||
}
|
||||
for (i in 0 until listAdapter!!.itemCount) {
|
||||
for (i in 0 until listAdapter.itemCount) {
|
||||
val holder: HorizontalItemViewHolder? = viewBinding.recyclerView.findViewHolderForAdapterPosition(i) as? HorizontalItemViewHolder
|
||||
if (holder != null && holder.isCurrentlyPlayingItem) {
|
||||
holder.notifyPlaybackPositionUpdated(event)
|
||||
|
@ -131,8 +129,8 @@ class EpisodesSurpriseSection : HomeSection() {
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ episodes: List<FeedItem> ->
|
||||
this.episodes = episodes.toMutableList()
|
||||
listAdapter?.setDummyViews(0)
|
||||
listAdapter?.updateData(episodes)
|
||||
listAdapter.setDummyViews(0)
|
||||
listAdapter.updateData(episodes)
|
||||
}, { error: Throwable? -> Log.e(TAG, Log.getStackTraceString(error)) })
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ import org.greenrobot.eventbus.ThreadMode
|
|||
import java.util.*
|
||||
|
||||
class InboxSection : HomeSection() {
|
||||
private var adapter: EpisodeItemListAdapter? = null
|
||||
private lateinit var adapter: EpisodeItemListAdapter
|
||||
|
||||
private var items: List<FeedItem> = ArrayList<FeedItem>()
|
||||
private var disposable: Disposable? = null
|
||||
|
||||
|
@ -51,7 +52,7 @@ class InboxSection : HomeSection() {
|
|||
) { item: MenuItem -> this@InboxSection.onContextItemSelected(item) }
|
||||
}
|
||||
}
|
||||
adapter?.setDummyViews(NUM_EPISODES)
|
||||
adapter.setDummyViews(NUM_EPISODES)
|
||||
viewBinding.recyclerView.adapter = adapter
|
||||
|
||||
val swipeActions = SwipeActions(this, InboxFragment.TAG)
|
||||
|
@ -89,7 +90,7 @@ class InboxSection : HomeSection() {
|
|||
for (downloadUrl in event.urls) {
|
||||
val pos: Int = FeedItemUtil.indexOfItemWithDownloadUrl(items, downloadUrl)
|
||||
if (pos >= 0) {
|
||||
adapter?.notifyItemChangedCompat(pos)
|
||||
adapter.notifyItemChangedCompat(pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,8 +113,8 @@ class InboxSection : HomeSection() {
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ data: Pair<List<FeedItem>, Int> ->
|
||||
items = data.first
|
||||
adapter?.setDummyViews(0)
|
||||
adapter?.updateItems(items)
|
||||
adapter.setDummyViews(0)
|
||||
adapter.updateItems(items)
|
||||
viewBinding.numNewItemsLabel.visibility = View.VISIBLE
|
||||
if (data.second >= 100) {
|
||||
viewBinding.numNewItemsLabel.text = String.format(Locale.getDefault(), "%d+", 99)
|
||||
|
|
|
@ -29,9 +29,10 @@ import org.greenrobot.eventbus.Subscribe
|
|||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class QueueSection : HomeSection() {
|
||||
private var listAdapter: HorizontalItemListAdapter? = null
|
||||
private var disposable: Disposable? = null
|
||||
private var queue: MutableList<FeedItem>? = ArrayList()
|
||||
|
||||
private lateinit var listAdapter: HorizontalItemListAdapter
|
||||
private var queue: MutableList<FeedItem> = ArrayList()
|
||||
|
||||
@UnstableApi override fun onCreateView(inflater: LayoutInflater,
|
||||
container: ViewGroup?, savedInstanceState: Bundle?
|
||||
|
@ -44,7 +45,7 @@ class QueueSection : HomeSection() {
|
|||
) { item: MenuItem -> this@QueueSection.onContextItemSelected(item) }
|
||||
}
|
||||
}
|
||||
listAdapter?.setDummyViews(NUM_EPISODES)
|
||||
listAdapter.setDummyViews(NUM_EPISODES)
|
||||
viewBinding.recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
|
||||
viewBinding.recyclerView.adapter = listAdapter
|
||||
val paddingHorizontal: Int = (12 * resources.displayMetrics.density).toInt()
|
||||
|
@ -74,18 +75,18 @@ class QueueSection : HomeSection() {
|
|||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(event: FeedItemEvent) {
|
||||
Log.d(TAG, "onEventMainThread() called with: event = [$event]")
|
||||
if (queue == null) {
|
||||
if (queue.isEmpty()) {
|
||||
return
|
||||
}
|
||||
var i = 0
|
||||
val size: Int = event.items.size
|
||||
while (i < size) {
|
||||
val item: FeedItem = event.items[i]
|
||||
val pos: Int = FeedItemUtil.indexOfItemWithId(queue!!, item.id)
|
||||
val pos: Int = FeedItemUtil.indexOfItemWithId(queue, item.id)
|
||||
if (pos >= 0) {
|
||||
queue!!.removeAt(pos)
|
||||
queue!!.add(pos, item)
|
||||
listAdapter?.notifyItemChangedCompat(pos)
|
||||
queue.removeAt(pos)
|
||||
queue.add(pos, item)
|
||||
listAdapter.notifyItemChangedCompat(pos)
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
@ -93,23 +94,20 @@ class QueueSection : HomeSection() {
|
|||
|
||||
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(event: EpisodeDownloadEvent) {
|
||||
if (queue == null) return
|
||||
if (queue.isEmpty()) return
|
||||
for (downloadUrl in event.urls) {
|
||||
val pos: Int = FeedItemUtil.indexOfItemWithDownloadUrl(queue!!, downloadUrl)
|
||||
val pos: Int = FeedItemUtil.indexOfItemWithDownloadUrl(queue, downloadUrl)
|
||||
if (pos >= 0) {
|
||||
listAdapter?.notifyItemChangedCompat(pos)
|
||||
listAdapter.notifyItemChangedCompat(pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(event: PlaybackPositionEvent) {
|
||||
if (listAdapter == null) {
|
||||
return
|
||||
}
|
||||
var foundCurrentlyPlayingItem = false
|
||||
var currentlyPlayingItemIsFirst = true
|
||||
for (i in 0 until listAdapter!!.itemCount) {
|
||||
for (i in 0 until listAdapter.itemCount) {
|
||||
val holder: HorizontalItemViewHolder =
|
||||
viewBinding.recyclerView.findViewHolderForAdapterPosition(i) as? HorizontalItemViewHolder ?: continue
|
||||
if (holder.isCurrentlyPlayingItem) {
|
||||
|
@ -140,8 +138,8 @@ class QueueSection : HomeSection() {
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ queue: List<FeedItem> ->
|
||||
this.queue = queue.toMutableList()
|
||||
listAdapter?.setDummyViews(0)
|
||||
listAdapter?.updateData(queue)
|
||||
listAdapter.setDummyViews(0)
|
||||
listAdapter.updateData(queue)
|
||||
}, { error: Throwable? -> Log.e(TAG, Log.getStackTraceString(error)) })
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.greenrobot.eventbus.Subscribe
|
|||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
class SubscriptionsSection : HomeSection() {
|
||||
private var listAdapter: HorizontalFeedListAdapter? = null
|
||||
private lateinit var listAdapter: HorizontalFeedListAdapter
|
||||
private var disposable: Disposable? = null
|
||||
|
||||
@UnstableApi override fun onCreateView(inflater: LayoutInflater,
|
||||
|
@ -45,7 +45,7 @@ class SubscriptionsSection : HomeSection() {
|
|||
}
|
||||
}
|
||||
}
|
||||
listAdapter?.setDummyViews(NUM_FEEDS)
|
||||
listAdapter.setDummyViews(NUM_FEEDS)
|
||||
viewBinding.recyclerView.adapter = listAdapter
|
||||
val paddingHorizontal: Int = (12 * resources.displayMetrics.density).toInt()
|
||||
viewBinding.recyclerView.setPadding(paddingHorizontal, 0, paddingHorizontal, 0)
|
||||
|
@ -93,8 +93,8 @@ class SubscriptionsSection : HomeSection() {
|
|||
feeds.add(stats[i].feed)
|
||||
i++
|
||||
}
|
||||
listAdapter?.setDummyViews(0)
|
||||
listAdapter?.updateData(feeds)
|
||||
listAdapter.setDummyViews(0)
|
||||
listAdapter.updateData(feeds)
|
||||
}, { error: Throwable? -> Log.e(TAG, Log.getStackTraceString(error)) })
|
||||
}
|
||||
|
||||
|
|
|
@ -33,13 +33,13 @@ object ChapterMerger {
|
|||
return if (score(chapters1) > score(chapters2)) chapters1 else chapters2
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(chapterTarget.imageUrl)) {
|
||||
if (chapterTarget.imageUrl.isNullOrEmpty()) {
|
||||
chapterTarget.imageUrl = chapterOther.imageUrl
|
||||
}
|
||||
if (TextUtils.isEmpty(chapterTarget.link)) {
|
||||
if (chapterTarget.link.isNullOrEmpty()) {
|
||||
chapterTarget.link = chapterOther.link
|
||||
}
|
||||
if (TextUtils.isEmpty(chapterTarget.title)) {
|
||||
if (chapterTarget.title.isNullOrEmpty()) {
|
||||
chapterTarget.title = chapterOther.title
|
||||
}
|
||||
}
|
||||
|
@ -54,9 +54,9 @@ object ChapterMerger {
|
|||
var score = 0
|
||||
for (chapter in chapters) {
|
||||
score = (score
|
||||
+ (if (TextUtils.isEmpty(chapter.title)) 0 else 1)
|
||||
+ (if (TextUtils.isEmpty(chapter.link)) 0 else 1)
|
||||
+ (if (TextUtils.isEmpty(chapter.imageUrl)) 0 else 1))
|
||||
+ (if (chapter.title.isNullOrEmpty()) 0 else 1)
|
||||
+ (if (chapter.link.isNullOrEmpty()) 0 else 1)
|
||||
+ (if (chapter.imageUrl.isNullOrEmpty()) 0 else 1))
|
||||
}
|
||||
return score
|
||||
}
|
||||
|
|
|
@ -38,9 +38,8 @@ import kotlin.concurrent.Volatile
|
|||
* Manages the MediaPlayer object of the PlaybackService.
|
||||
*/
|
||||
@UnstableApi
|
||||
class LocalPSMP(context: Context,
|
||||
callback: PSMPCallback
|
||||
) : PlaybackServiceMediaPlayer(context, callback) {
|
||||
class LocalPSMP(context: Context, callback: PSMPCallback) : PlaybackServiceMediaPlayer(context, callback) {
|
||||
|
||||
private val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
|
||||
@Volatile
|
||||
|
|
|
@ -1863,7 +1863,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
|
|||
private const val TAG = "PlaybackService"
|
||||
|
||||
// TODO: need to experiment this value
|
||||
private const val POSITION_EVENT_INTERVAL = 10L
|
||||
private const val POSITION_EVENT_INTERVAL = 5L
|
||||
|
||||
const val ACTION_PLAYER_STATUS_CHANGED: String = "action.ac.mdiq.podcini.core.service.playerStatusChanged"
|
||||
private const val AVRCP_ACTION_PLAYER_STATUS_CHANGED = "com.android.music.playstatechanged"
|
||||
|
|
|
@ -212,12 +212,10 @@ class PlaybackServiceTaskManager(private val context: Context,
|
|||
*/
|
||||
@Synchronized
|
||||
fun startChapterLoader(media: Playable) {
|
||||
if (chapterLoaderFuture != null) {
|
||||
chapterLoaderFuture!!.dispose()
|
||||
chapterLoaderFuture = null
|
||||
}
|
||||
chapterLoaderFuture?.dispose()
|
||||
chapterLoaderFuture = null
|
||||
|
||||
if (media.getChapters().isEmpty()) {
|
||||
if (!media.chaptersLoaded()) {
|
||||
chapterLoaderFuture = Completable.create { emitter: CompletableEmitter ->
|
||||
ChapterUtils.loadChapters(media, context, false)
|
||||
emitter.onComplete()
|
||||
|
|
|
@ -30,6 +30,7 @@ import kotlin.math.min
|
|||
*/
|
||||
object DBReader {
|
||||
private const val TAG = "DBReader"
|
||||
private var feeds: MutableList<Feed> = mutableListOf()
|
||||
|
||||
/**
|
||||
* Maximum size of the list returned by [.getDownloadLog].
|
||||
|
@ -38,36 +39,52 @@ object DBReader {
|
|||
|
||||
@JvmStatic
|
||||
fun getFeedList(): List<Feed> {
|
||||
Log.d(TAG, "Extracting Feedlist")
|
||||
return feeds
|
||||
|
||||
// Log.d(TAG, "Extracting Feedlist")
|
||||
|
||||
// val adapter = getInstance()
|
||||
// adapter.open()
|
||||
// try {
|
||||
// return getFeedList(adapter)
|
||||
// } finally {
|
||||
// adapter.close()
|
||||
// }
|
||||
}
|
||||
|
||||
// fun getFeedList(adapter: PodDBAdapter): List<Feed> {
|
||||
// if (feeds != null) return feeds!!
|
||||
// updateFeedList(adapter)
|
||||
// return feeds!!
|
||||
// }
|
||||
|
||||
fun updateFeedList() {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
return getFeedList(adapter)
|
||||
updateFeedList(adapter)
|
||||
} finally {
|
||||
adapter.close()
|
||||
}
|
||||
}
|
||||
|
||||
fun getFeedList(adapter: PodDBAdapter?): List<Feed> {
|
||||
adapter!!.allFeedsCursor.use { cursor ->
|
||||
val feeds: MutableList<Feed> = ArrayList(cursor.count)
|
||||
fun updateFeedList(adapter: PodDBAdapter) {
|
||||
adapter.allFeedsCursor.use { cursor ->
|
||||
feeds = ArrayList(cursor.count)
|
||||
while (cursor.moveToNext()) {
|
||||
val feed = extractFeedFromCursorRow(cursor)
|
||||
feeds.add(feed)
|
||||
}
|
||||
return feeds
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getFeedListDownloadUrls(): List<String> {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.feedCursorDownloadUrls.use { cursor ->
|
||||
val result: MutableList<String> =
|
||||
ArrayList(cursor.count)
|
||||
val result: MutableList<String> = ArrayList(cursor.count)
|
||||
while (cursor.moveToNext()) {
|
||||
val url = cursor.getString(1)
|
||||
if (url != null && !url.startsWith(Feed.PREFIX_LOCAL_FOLDER)) {
|
||||
|
@ -113,8 +130,6 @@ object DBReader {
|
|||
* @param items The FeedItems whose Feed-objects should be loaded.
|
||||
*/
|
||||
private fun loadFeedDataOfFeedItemList(items: List<FeedItem>) {
|
||||
val feeds = getFeedList()
|
||||
|
||||
val feedIndex: MutableMap<Long, Feed> = ArrayMap(feeds.size)
|
||||
for (feed in feeds) {
|
||||
feedIndex[feed.id] = feed
|
||||
|
@ -150,7 +165,7 @@ object DBReader {
|
|||
Log.d(TAG, "getFeedItemList() called with: feed = [$feed]")
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getItemsOfFeedCursor(feed!!, filter).use { cursor ->
|
||||
val items = extractItemlistFromCursor(adapter, cursor).toMutableList()
|
||||
|
@ -170,7 +185,7 @@ object DBReader {
|
|||
fun extractItemlistFromCursor(itemlistCursor: Cursor): List<FeedItem> {
|
||||
Log.d(TAG, "extractItemlistFromCursor() called with: itemlistCursor = [$itemlistCursor]")
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
return extractItemlistFromCursor(adapter, itemlistCursor)
|
||||
} finally {
|
||||
|
@ -202,7 +217,7 @@ object DBReader {
|
|||
|
||||
@JvmStatic
|
||||
fun getQueue(adapter: PodDBAdapter?): List<FeedItem> {
|
||||
Log.d(TAG, "getQueue()")
|
||||
// Log.d(TAG, "getQueue()")
|
||||
adapter!!.queueCursor.use { cursor ->
|
||||
val items = extractItemlistFromCursor(adapter, cursor)
|
||||
loadAdditionalFeedItemListData(items)
|
||||
|
@ -213,8 +228,13 @@ object DBReader {
|
|||
@JvmStatic
|
||||
fun getQueueIDList(): LongList {
|
||||
Log.d(TAG, "getQueueIDList() called")
|
||||
// val stackTraceElements = Thread.currentThread().stackTrace
|
||||
// stackTraceElements.forEach { element ->
|
||||
// println(element)
|
||||
// }
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
return getQueueIDList(adapter)
|
||||
} finally {
|
||||
|
@ -237,7 +257,7 @@ object DBReader {
|
|||
Log.d(TAG, "getQueue() called")
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
return getQueue(adapter)
|
||||
} finally {
|
||||
|
@ -249,7 +269,7 @@ object DBReader {
|
|||
Log.d(TAG, "getFavoriteIDList() called")
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getFavoritesIdsCursor(0, Int.MAX_VALUE).use { cursor ->
|
||||
val favoriteIDs = LongList(cursor.count)
|
||||
|
@ -273,7 +293,7 @@ object DBReader {
|
|||
fun getEpisodes(offset: Int, limit: Int, filter: FeedItemFilter?, sortOrder: SortOrder?): List<FeedItem> {
|
||||
Log.d(TAG, "getRecentlyPublishedEpisodes() called with: offset=$offset, limit=$limit")
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getEpisodesCursor(offset, limit, filter, sortOrder).use { cursor ->
|
||||
val items = extractItemlistFromCursor(adapter, cursor)
|
||||
|
@ -288,7 +308,7 @@ object DBReader {
|
|||
@JvmStatic
|
||||
fun getTotalEpisodeCount(filter: FeedItemFilter?): Int {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getEpisodeCountCursor(filter).use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
|
@ -303,7 +323,7 @@ object DBReader {
|
|||
|
||||
fun getRandomEpisodes(limit: Int, seed: Int): List<FeedItem> {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getRandomEpisodesCursor(limit, seed).use { cursor ->
|
||||
val items = extractItemlistFromCursor(adapter, cursor)
|
||||
|
@ -328,7 +348,7 @@ object DBReader {
|
|||
Log.d(TAG, "getPlaybackHistory() called")
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
|
||||
var mediaCursor: Cursor? = null
|
||||
var itemCursor: Cursor? = null
|
||||
|
@ -356,7 +376,7 @@ object DBReader {
|
|||
@JvmStatic
|
||||
fun getPlaybackHistoryLength(): Long {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
|
||||
try {
|
||||
return adapter.completedMediaLength
|
||||
|
@ -370,7 +390,7 @@ object DBReader {
|
|||
Log.d(TAG, "getDownloadLog() called")
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getDownloadLogCursor(DOWNLOAD_LOG_SIZE).use { cursor ->
|
||||
val downloadLog: MutableList<DownloadResult> =
|
||||
|
@ -397,7 +417,7 @@ object DBReader {
|
|||
Log.d(TAG, "getFeedDownloadLog() called with: feed = [$feedId]")
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getDownloadLog(Feed.FEEDFILETYPE_FEED, feedId).use { cursor ->
|
||||
val downloadLog: MutableList<DownloadResult> = ArrayList(cursor.count)
|
||||
|
@ -434,7 +454,7 @@ object DBReader {
|
|||
*/
|
||||
fun getFeed(feedId: Long, filtered: Boolean): Feed? {
|
||||
Log.d(TAG, "getFeed() called with: feedId = [$feedId]")
|
||||
val adapter = getInstance() ?: return null
|
||||
val adapter = getInstance()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getFeedCursor(feedId).use { cursor ->
|
||||
|
@ -484,7 +504,7 @@ object DBReader {
|
|||
Log.d(TAG, "getFeedItem() called with: itemId = [$itemId]")
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
return getFeedItem(itemId, adapter)
|
||||
} finally {
|
||||
|
@ -501,7 +521,7 @@ object DBReader {
|
|||
fun getNextInQueue(item: FeedItem): FeedItem? {
|
||||
Log.d(TAG, "getNextInQueue() called with: " + "itemId = [" + item.id + "]")
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
var nextItem: FeedItem? = null
|
||||
try {
|
||||
|
@ -524,7 +544,7 @@ object DBReader {
|
|||
fun getPausedQueue(limit: Int): List<FeedItem> {
|
||||
Log.d(TAG, "getPausedQueue() called ")
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getPausedQueueCursor(limit).use { cursor ->
|
||||
val items = extractItemlistFromCursor(adapter, cursor)
|
||||
|
@ -569,7 +589,7 @@ object DBReader {
|
|||
Log.d(TAG, "getImageAuthentication() called with: imageUrl = [$imageUrl]")
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
return getImageAuthentication(imageUrl, adapter)
|
||||
} finally {
|
||||
|
@ -606,7 +626,7 @@ object DBReader {
|
|||
@JvmStatic
|
||||
fun getFeedItemByGuidOrEpisodeUrl(guid: String?, episodeUrl: String): FeedItem? {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
return getFeedItemByGuidOrEpisodeUrl(guid, episodeUrl, adapter)
|
||||
} finally {
|
||||
|
@ -627,7 +647,7 @@ object DBReader {
|
|||
// println(element)
|
||||
// }
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getDescriptionOfItem(item).use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
|
@ -650,14 +670,14 @@ object DBReader {
|
|||
*/
|
||||
@JvmStatic
|
||||
fun loadChaptersOfFeedItem(item: FeedItem): List<Chapter>? {
|
||||
Log.d(TAG, "loadChaptersOfFeedItem() called with: item = [$item]")
|
||||
Log.d(TAG, "loadChaptersOfFeedItem() called with: item = [${item.title}]")
|
||||
// TODO: need to find out who are often calling this
|
||||
// val stackTraceElements = Thread.currentThread().stackTrace
|
||||
// stackTraceElements.forEach { element ->
|
||||
// println(element)
|
||||
// }
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
return loadChaptersOfFeedItem(adapter, item)
|
||||
} finally {
|
||||
|
@ -689,7 +709,7 @@ object DBReader {
|
|||
@JvmStatic
|
||||
fun getFeedMedia(mediaId: Long): FeedMedia? {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
|
||||
try {
|
||||
adapter.getSingleFeedMediaCursor(mediaId).use { mediaCursor ->
|
||||
|
@ -714,7 +734,7 @@ object DBReader {
|
|||
fun getFeedItemsWithUrl(urls: List<String?>?): List<FeedItem> {
|
||||
Log.d(TAG, "getFeedItemsWithUrl() called ")
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
adapter.getFeedItemCursorByUrl(urls!!).use { itemCursor ->
|
||||
val items = extractItemlistFromCursor(adapter, itemCursor).toMutableList()
|
||||
|
@ -730,7 +750,7 @@ object DBReader {
|
|||
fun getMonthlyTimeStatistics(): List<MonthlyStatisticsItem> {
|
||||
val months: MutableList<MonthlyStatisticsItem> = ArrayList()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.monthlyStatisticsCursor.use { cursor ->
|
||||
val indexMonth = cursor.getColumnIndexOrThrow("month")
|
||||
val indexYear = cursor.getColumnIndexOrThrow("year")
|
||||
|
@ -756,7 +776,7 @@ object DBReader {
|
|||
timeFilterFrom: Long, timeFilterTo: Long
|
||||
): StatisticsResult {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
|
||||
val result = StatisticsResult()
|
||||
adapter.getFeedStatisticsCursor(includeMarkedAsPlayed, timeFilterFrom, timeFilterTo).use { cursor ->
|
||||
|
@ -792,7 +812,7 @@ object DBReader {
|
|||
|
||||
fun getTimeBetweenReleaseAndPlayback(timeFilterFrom: Long, timeFilterTo: Long): Long {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.getTimeBetweenReleaseAndPlayback(timeFilterFrom, timeFilterTo).use { cursor ->
|
||||
cursor.moveToFirst()
|
||||
val result = cursor.getString(0).toLong()
|
||||
|
@ -810,13 +830,13 @@ object DBReader {
|
|||
fun getNavDrawerData(subscriptionsFilter: SubscriptionsFilter?): NavDrawerData {
|
||||
Log.d(TAG, "getNavDrawerData() called with: " + "")
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
|
||||
val feedCounters: Map<Long, Int> = adapter.getFeedCounters(feedCounterSetting)
|
||||
var feeds = getFeedList(adapter)
|
||||
// getFeedList(adapter)
|
||||
|
||||
if (subscriptionsFilter != null) {
|
||||
feeds = subscriptionsFilter.filter(feeds, feedCounters as Map<Long?, Int>)
|
||||
feeds = subscriptionsFilter.filter(feeds, feedCounters as Map<Long?, Int>).toMutableList()
|
||||
}
|
||||
|
||||
val comparator: Comparator<Feed>
|
||||
|
@ -875,7 +895,7 @@ object DBReader {
|
|||
}
|
||||
}
|
||||
|
||||
feeds = feeds.sortedWith(comparator)
|
||||
feeds.sortWith(comparator)
|
||||
val queueSize = adapter.queueSize
|
||||
val numNewItems = getTotalEpisodeCount(FeedItemFilter(FeedItemFilter.NEW))
|
||||
val numDownloadedItems = getTotalEpisodeCount(FeedItemFilter(FeedItemFilter.DOWNLOADED))
|
||||
|
|
|
@ -58,7 +58,7 @@ import java.util.concurrent.*
|
|||
@UnstableApi @JvmStatic
|
||||
fun removeFeedWithDownloadUrl(context: Context?, downloadUrl: String) {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
val cursor = adapter.feedCursorDownloadUrls
|
||||
var feedID: Long = 0
|
||||
if (cursor.moveToFirst()) {
|
||||
|
@ -200,7 +200,7 @@ import java.util.concurrent.*
|
|||
val unlistedItems: MutableList<FeedItem> = ArrayList()
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
|
||||
// Look up feed in the feedslist
|
||||
val savedFeed = searchFeedByIdentifyingValueOrID(newFeed)
|
||||
|
@ -339,6 +339,7 @@ import java.util.concurrent.*
|
|||
} else {
|
||||
DBWriter.setCompleteFeed(savedFeed).get()
|
||||
}
|
||||
DBReader.updateFeedList(adapter)
|
||||
if (removeUnlistedItems) {
|
||||
DBWriter.deleteFeedItems(context, unlistedItems).get()
|
||||
}
|
||||
|
@ -420,7 +421,7 @@ import java.util.concurrent.*
|
|||
@Throws(Exception::class)
|
||||
override fun call(): T? {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
execute(adapter)
|
||||
adapter.close()
|
||||
return result
|
||||
|
|
|
@ -126,9 +126,9 @@ import java.util.concurrent.TimeUnit
|
|||
media.setFile_url(null)
|
||||
media.setHasEmbeddedPicture(false)
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setMedia(media)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.setMedia(media)
|
||||
adapter.close()
|
||||
}
|
||||
|
||||
if (media.id == currentlyPlayingFeedMediaId) {
|
||||
|
@ -174,9 +174,9 @@ import java.util.concurrent.TimeUnit
|
|||
|
||||
// delete feed
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.removeFeed(feed)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.removeFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
if (!feed.isLocalFeed && feed.download_url != null) {
|
||||
SynchronizationQueueSink.enqueueFeedRemovedIfSynchronizationIsActive(context, feed.download_url!!)
|
||||
|
@ -220,12 +220,12 @@ import java.util.concurrent.TimeUnit
|
|||
}
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter.open()
|
||||
if (removedFromQueue.isNotEmpty()) {
|
||||
adapter?.setQueue(queue)
|
||||
adapter.setQueue(queue)
|
||||
}
|
||||
adapter?.removeFeedItems(items)
|
||||
adapter?.close()
|
||||
adapter.removeFeedItems(items)
|
||||
adapter.close()
|
||||
|
||||
for (item in removedFromQueue) {
|
||||
EventBus.getDefault().post(irreversibleRemoved(item))
|
||||
|
@ -246,9 +246,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun clearPlaybackHistory(): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.clearPlaybackHistory()
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.clearPlaybackHistory()
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(PlaybackHistoryEvent.listUpdated())
|
||||
}
|
||||
}
|
||||
|
@ -259,9 +259,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun clearDownloadLog(): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.clearDownloadLog()
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.clearDownloadLog()
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(DownloadLogEvent.listUpdated())
|
||||
}
|
||||
}
|
||||
|
@ -292,9 +292,9 @@ import java.util.concurrent.TimeUnit
|
|||
media!!.setPlaybackCompletionDate(date)
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setFeedMediaPlaybackCompletionDate(media)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.setFeedMediaPlaybackCompletionDate(media)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(PlaybackHistoryEvent.listUpdated())
|
||||
}
|
||||
}
|
||||
|
@ -307,9 +307,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun addDownloadStatus(status: DownloadResult?): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setDownloadStatus(status!!)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.setDownloadStatus(status!!)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(DownloadLogEvent.listUpdated())
|
||||
}
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ import java.util.concurrent.TimeUnit
|
|||
): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter.open()
|
||||
val queue = getQueue(adapter).toMutableList()
|
||||
val item: FeedItem?
|
||||
|
||||
|
@ -337,7 +337,7 @@ import java.util.concurrent.TimeUnit
|
|||
item = getFeedItem(itemId)
|
||||
if (item != null) {
|
||||
queue.add(index, item)
|
||||
adapter?.setQueue(queue)
|
||||
adapter.setQueue(queue)
|
||||
item.addTag(FeedItem.TAG_QUEUE)
|
||||
EventBus.getDefault().post(added(item, index))
|
||||
EventBus.getDefault().post(updated(item))
|
||||
|
@ -347,7 +347,7 @@ import java.util.concurrent.TimeUnit
|
|||
}
|
||||
}
|
||||
|
||||
adapter?.close()
|
||||
adapter.close()
|
||||
if (performAutoDownload) {
|
||||
autodownloadUndownloadedItems(context)
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ import java.util.concurrent.TimeUnit
|
|||
return@runOnDbThread
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter.open()
|
||||
val queue = getQueue(adapter).toMutableList()
|
||||
|
||||
var queueModified = false
|
||||
|
@ -432,7 +432,7 @@ import java.util.concurrent.TimeUnit
|
|||
}
|
||||
if (queueModified) {
|
||||
applySortOrder(queue, events)
|
||||
adapter?.setQueue(queue)
|
||||
adapter.setQueue(queue)
|
||||
for (event in events) {
|
||||
EventBus.getDefault().post(event)
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ import java.util.concurrent.TimeUnit
|
|||
markItemPlayed(FeedItem.UNPLAYED, *markAsUnplayedIds.toArray())
|
||||
}
|
||||
}
|
||||
adapter?.close()
|
||||
adapter.close()
|
||||
if (performAutoDownload) {
|
||||
autodownloadUndownloadedItems(context)
|
||||
}
|
||||
|
@ -482,9 +482,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun clearQueue(): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.clearQueue()
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.clearQueue()
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(cleared())
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +518,7 @@ import java.util.concurrent.TimeUnit
|
|||
return
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter.open()
|
||||
val queue = getQueue(adapter).toMutableList()
|
||||
|
||||
var queueModified = false
|
||||
|
@ -543,7 +543,7 @@ import java.util.concurrent.TimeUnit
|
|||
}
|
||||
}
|
||||
if (queueModified) {
|
||||
adapter?.setQueue(queue)
|
||||
adapter.setQueue(queue)
|
||||
for (event in events) {
|
||||
EventBus.getDefault().post(event)
|
||||
}
|
||||
|
@ -551,7 +551,7 @@ import java.util.concurrent.TimeUnit
|
|||
} else {
|
||||
Log.w(TAG, "Queue was not modified by call to removeQueueItem")
|
||||
}
|
||||
adapter?.close()
|
||||
adapter.close()
|
||||
if (performAutoDownload) {
|
||||
autodownloadUndownloadedItems(context)
|
||||
}
|
||||
|
@ -567,9 +567,9 @@ import java.util.concurrent.TimeUnit
|
|||
|
||||
fun addFavoriteItem(item: FeedItem): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()?.open()
|
||||
adapter?.addFavoriteItem(item)
|
||||
adapter?.close()
|
||||
val adapter = getInstance().open()
|
||||
adapter.addFavoriteItem(item)
|
||||
adapter.close()
|
||||
item.addTag(FeedItem.TAG_FAVORITE)
|
||||
EventBus.getDefault().post(FavoritesEvent())
|
||||
EventBus.getDefault().post(updated(item))
|
||||
|
@ -578,9 +578,9 @@ import java.util.concurrent.TimeUnit
|
|||
|
||||
fun removeFavoriteItem(item: FeedItem): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()?.open()
|
||||
adapter?.removeFavoriteItem(item)
|
||||
adapter?.close()
|
||||
val adapter = getInstance().open()
|
||||
adapter.removeFavoriteItem(item)
|
||||
adapter.close()
|
||||
item.removeTag(FeedItem.TAG_FAVORITE)
|
||||
EventBus.getDefault().post(FavoritesEvent())
|
||||
EventBus.getDefault().post(updated(item))
|
||||
|
@ -658,7 +658,7 @@ import java.util.concurrent.TimeUnit
|
|||
to: Int, broadcastUpdate: Boolean
|
||||
) {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter.open()
|
||||
val queue = getQueue(adapter).toMutableList()
|
||||
|
||||
if (queue.isNotEmpty()) {
|
||||
|
@ -666,7 +666,7 @@ import java.util.concurrent.TimeUnit
|
|||
val item: FeedItem = queue.removeAt(from)
|
||||
queue.add(to, item)
|
||||
|
||||
adapter?.setQueue(queue)
|
||||
adapter.setQueue(queue)
|
||||
if (broadcastUpdate) {
|
||||
EventBus.getDefault().post(moved(item, to))
|
||||
}
|
||||
|
@ -674,15 +674,15 @@ import java.util.concurrent.TimeUnit
|
|||
} else {
|
||||
Log.e(TAG, "moveQueueItemHelper: Could not load queue")
|
||||
}
|
||||
adapter?.close()
|
||||
adapter.close()
|
||||
}
|
||||
|
||||
fun resetPagedFeedPage(feed: Feed?): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.resetPagedFeedPage(feed!!)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.resetPagedFeedPage(feed!!)
|
||||
adapter.close()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -711,9 +711,9 @@ import java.util.concurrent.TimeUnit
|
|||
): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setFeedItemRead(played, *itemIds)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.setFeedItemRead(played, *itemIds)
|
||||
adapter.close()
|
||||
if (broadcastUpdate) {
|
||||
EventBus.getDefault().post(UnreadItemsUpdateEvent())
|
||||
}
|
||||
|
@ -740,10 +740,10 @@ import java.util.concurrent.TimeUnit
|
|||
): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setFeedItemRead(played, itemId, mediaId,
|
||||
adapter.open()
|
||||
adapter.setFeedItemRead(played, itemId, mediaId,
|
||||
resetMediaPosition)
|
||||
adapter?.close()
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(UnreadItemsUpdateEvent())
|
||||
}
|
||||
}
|
||||
|
@ -756,9 +756,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun removeFeedNewFlag(feedId: Long): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setFeedItems(FeedItem.NEW, FeedItem.UNPLAYED, feedId)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.setFeedItems(FeedItem.NEW, FeedItem.UNPLAYED, feedId)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(UnreadItemsUpdateEvent())
|
||||
}
|
||||
}
|
||||
|
@ -770,9 +770,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun removeAllNewFlags(): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setFeedItems(FeedItem.NEW, FeedItem.UNPLAYED)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.setFeedItems(FeedItem.NEW, FeedItem.UNPLAYED)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(UnreadItemsUpdateEvent())
|
||||
}
|
||||
}
|
||||
|
@ -780,9 +780,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun addNewFeed(context: Context, vararg feeds: Feed): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setCompleteFeed(*feeds)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(*feeds)
|
||||
adapter.close()
|
||||
|
||||
for (feed in feeds) {
|
||||
if (!feed.isLocalFeed && feed.download_url != null) {
|
||||
|
@ -798,18 +798,18 @@ import java.util.concurrent.TimeUnit
|
|||
fun setCompleteFeed(vararg feeds: Feed): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.setCompleteFeed(*feeds)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(*feeds)
|
||||
adapter.close()
|
||||
}
|
||||
}
|
||||
|
||||
fun setItemList(items: List<FeedItem>): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter?.open()
|
||||
adapter?.storeFeedItemlist(items)
|
||||
adapter?.close()
|
||||
adapter.open()
|
||||
adapter.storeFeedItemlist(items)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(updated(items))
|
||||
}
|
||||
}
|
||||
|
@ -823,7 +823,7 @@ import java.util.concurrent.TimeUnit
|
|||
fun setFeedMedia(media: FeedMedia?): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setMedia(media)
|
||||
adapter.close()
|
||||
}
|
||||
|
@ -838,7 +838,7 @@ import java.util.concurrent.TimeUnit
|
|||
fun setFeedMediaPlaybackInformation(media: FeedMedia?): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setFeedMediaPlaybackInformation(media!!)
|
||||
adapter.close()
|
||||
}
|
||||
|
@ -854,7 +854,7 @@ import java.util.concurrent.TimeUnit
|
|||
fun setFeedItem(item: FeedItem?): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setSingleFeedItem(item!!)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(updated(item))
|
||||
|
@ -868,7 +868,7 @@ import java.util.concurrent.TimeUnit
|
|||
Log.d(TAG, "updateFeedDownloadURL(original: $original, updated: $updated)")
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setFeedDownloadUrl(original, updated)
|
||||
adapter.close()
|
||||
}
|
||||
|
@ -882,7 +882,7 @@ import java.util.concurrent.TimeUnit
|
|||
fun setFeedPreferences(preferences: FeedPreferences): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setFeedPreferences(preferences)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(FeedListUpdateEvent(preferences.feedID))
|
||||
|
@ -913,7 +913,7 @@ import java.util.concurrent.TimeUnit
|
|||
): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setFeedLastUpdateFailed(feedId, lastUpdateFailed)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(FeedListUpdateEvent(feedId))
|
||||
|
@ -923,7 +923,7 @@ import java.util.concurrent.TimeUnit
|
|||
fun setFeedCustomTitle(feed: Feed): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setFeedCustomTitle(feed.id, feed.getCustomTitle())
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(FeedListUpdateEvent(feed))
|
||||
|
@ -945,7 +945,7 @@ import java.util.concurrent.TimeUnit
|
|||
val permutor = getPermutor(sortOrder)
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
val queue = getQueue(adapter).toMutableList()
|
||||
|
||||
permutor.reorder(queue)
|
||||
|
@ -969,7 +969,7 @@ import java.util.concurrent.TimeUnit
|
|||
Log.d(TAG, "setFeedItemsFilter() called with: feedId = [$feedId], filterValues = [$filterValues]")
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setFeedItemFilter(feedId, filterValues)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(FeedEvent(FeedEvent.Action.FILTER_CHANGED, feedId))
|
||||
|
@ -983,7 +983,7 @@ import java.util.concurrent.TimeUnit
|
|||
fun setFeedItemSortOrder(feedId: Long, sortOrder: SortOrder?): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setFeedItemSortOrder(feedId, sortOrder)
|
||||
adapter.close()
|
||||
EventBus.getDefault().post(FeedEvent(FeedEvent.Action.SORT_ORDER_CHANGED, feedId))
|
||||
|
@ -996,7 +996,7 @@ import java.util.concurrent.TimeUnit
|
|||
fun resetStatistics(): Future<*> {
|
||||
return runOnDbThread {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.resetAllMediaPlayedDuration()
|
||||
adapter.close()
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ object ChapterUtils {
|
|||
|
||||
@JvmStatic
|
||||
fun loadChapters(playable: Playable, context: Context, forceRefresh: Boolean) {
|
||||
if (playable.getChapters().isNotEmpty() && !forceRefresh) {
|
||||
if (playable.chaptersLoaded() && !forceRefresh) {
|
||||
// Already loaded
|
||||
return
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ object ChapterUtils {
|
|||
val chaptersFromMediaFile = loadChaptersFromMediaFile(playable, context)
|
||||
val chaptersMergePhase1 = merge(chaptersFromDatabase, chaptersFromMediaFile)
|
||||
val chapters = merge(chaptersMergePhase1, chaptersFromPodcastIndex)
|
||||
Log.d(TAG, "loadChapters chapters size: ${chapters?.size?:0} ${playable.getEpisodeTitle()}")
|
||||
if (chapters == null) {
|
||||
// Do not try loading again. There are no chapters.
|
||||
playable.setChapters(listOf())
|
||||
|
@ -135,19 +136,19 @@ object ChapterUtils {
|
|||
}
|
||||
}
|
||||
|
||||
fun loadChaptersFromUrl(url: String, forceRefresh: Boolean): List<Chapter>? {
|
||||
fun loadChaptersFromUrl(url: String, forceRefresh: Boolean): List<Chapter> {
|
||||
if (forceRefresh) {
|
||||
return loadChaptersFromUrl(url, CacheControl.FORCE_NETWORK)
|
||||
}
|
||||
val cachedChapters = loadChaptersFromUrl(url, CacheControl.FORCE_CACHE)
|
||||
if (cachedChapters == null || cachedChapters.size <= 1) {
|
||||
if (cachedChapters.size <= 1) {
|
||||
// Some publishers use one dummy chapter before actual chapters are available
|
||||
return loadChaptersFromUrl(url, CacheControl.FORCE_NETWORK)
|
||||
}
|
||||
return cachedChapters
|
||||
}
|
||||
|
||||
private fun loadChaptersFromUrl(url: String, cacheControl: CacheControl): List<Chapter>? {
|
||||
private fun loadChaptersFromUrl(url: String, cacheControl: CacheControl): List<Chapter> {
|
||||
var response: Response? = null
|
||||
try {
|
||||
val request: Request = Builder().url(url).cacheControl(cacheControl).build()
|
||||
|
@ -160,7 +161,7 @@ object ChapterUtils {
|
|||
} finally {
|
||||
response?.close()
|
||||
}
|
||||
return null
|
||||
return listOf()
|
||||
}
|
||||
|
||||
@Throws(IOException::class, ID3ReaderException::class)
|
||||
|
|
|
@ -249,7 +249,7 @@ class LongList @JvmOverloads constructor(initialCapacity: Int = 4) {
|
|||
|
||||
companion object {
|
||||
fun of(vararg values: Long): LongList {
|
||||
if (values == null || values.size == 0) {
|
||||
if (values == null || values.isEmpty()) {
|
||||
return LongList(0)
|
||||
}
|
||||
val result = LongList(values.size)
|
||||
|
|
|
@ -111,7 +111,7 @@ object NetworkUtils {
|
|||
private val isInAllowedWifiNetwork: Boolean
|
||||
get() {
|
||||
val wm = context!!.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
val selectedNetworks = Arrays.asList(*UserPreferences.autodownloadSelectedNetworks)
|
||||
val selectedNetworks = listOf(*UserPreferences.autodownloadSelectedNetworks)
|
||||
return selectedNetworks.contains(wm.connectionInfo.networkId.toString())
|
||||
}
|
||||
|
||||
|
|
|
@ -87,8 +87,11 @@ object ShareUtils {
|
|||
|
||||
@JvmStatic
|
||||
fun shareFeedItemFile(context: Context, media: FeedMedia) {
|
||||
val lurl = media.getLocalMediaUrl()
|
||||
if (lurl.isNullOrEmpty()) return
|
||||
|
||||
val fileUri = FileProvider.getUriForFile(context, context.getString(R.string.provider_authority),
|
||||
File(media.getLocalMediaUrl()))
|
||||
File(lurl))
|
||||
|
||||
IntentBuilder(context)
|
||||
.setType(media.mime_type)
|
||||
|
|
|
@ -4,6 +4,6 @@ import ac.mdiq.podcini.model.feed.Chapter
|
|||
|
||||
class ChapterStartTimeComparator : Comparator<Chapter> {
|
||||
override fun compare(lhs: Chapter, rhs: Chapter): Int {
|
||||
return java.lang.Long.compare(lhs.start, rhs.start)
|
||||
return lhs.start.compareTo(rhs.start)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,11 +175,11 @@ class ShownotesCleaner(context: Context, private val rawShownotes: String, priva
|
|||
@JvmStatic
|
||||
fun getTimecodeLinkTime(link: String?): Int {
|
||||
if (isTimecodeLink(link)) {
|
||||
val m = TIMECODE_LINK_REGEX.matcher(link)
|
||||
val m = TIMECODE_LINK_REGEX.matcher(link!!)
|
||||
|
||||
try {
|
||||
if (m.find()) {
|
||||
return m.group(1).toInt()
|
||||
return m.group(1)?.toInt()?:0
|
||||
}
|
||||
} catch (e: NumberFormatException) {
|
||||
e.printStackTrace()
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
package ac.mdiq.podcini.core.util.playback
|
||||
|
||||
import android.content.Context
|
||||
import android.media.MediaPlayer
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.exoplayer.ExoPlaybackException
|
||||
import ac.mdiq.podcini.core.R
|
||||
import ac.mdiq.podcini.core.service.playback.ExoPlayerWrapper
|
||||
|
||||
/** Utility class for MediaPlayer errors. */
|
||||
@UnstableApi
|
||||
object MediaPlayerError {
|
||||
/** Get a human-readable string for a specific error code. */
|
||||
fun getErrorString(context: Context, code: Int): String {
|
||||
val resId = when (code) {
|
||||
MediaPlayer.MEDIA_ERROR_SERVER_DIED -> R.string.playback_error_server_died
|
||||
MediaPlayer.MEDIA_ERROR_UNSUPPORTED, ExoPlayerWrapper.ERROR_CODE_OFFSET + ExoPlaybackException.TYPE_RENDERER -> R.string.playback_error_unsupported
|
||||
MediaPlayer.MEDIA_ERROR_TIMED_OUT -> R.string.playback_error_timeout
|
||||
ExoPlayerWrapper.ERROR_CODE_OFFSET + ExoPlaybackException.TYPE_SOURCE -> R.string.playback_error_source
|
||||
else -> R.string.playback_error_unknown
|
||||
}
|
||||
return context.getString(resId) + " (" + code + ")"
|
||||
}
|
||||
}
|
|
@ -30,9 +30,9 @@ import org.greenrobot.eventbus.ThreadMode
|
|||
* control playback instead of communicating with the PlaybackService directly.
|
||||
*/
|
||||
@UnstableApi
|
||||
abstract class PlaybackController(private val activity: FragmentActivity?) {
|
||||
abstract class PlaybackController(private val activity: FragmentActivity) {
|
||||
private var playbackService: PlaybackService? = null
|
||||
private var media: Playable? = null
|
||||
|
||||
var status: PlayerStatus = PlayerStatus.STOPPED
|
||||
private set
|
||||
|
||||
|
@ -73,16 +73,16 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
initialized = true
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
activity?.registerReceiver(statusUpdate, IntentFilter(
|
||||
activity.registerReceiver(statusUpdate, IntentFilter(
|
||||
PlaybackService.ACTION_PLAYER_STATUS_CHANGED), Context.RECEIVER_NOT_EXPORTED)
|
||||
activity?.registerReceiver(notificationReceiver, IntentFilter(
|
||||
activity.registerReceiver(notificationReceiver, IntentFilter(
|
||||
PlaybackServiceInterface.ACTION_PLAYER_NOTIFICATION), Context.RECEIVER_NOT_EXPORTED)
|
||||
} else {
|
||||
activity?.registerReceiver(statusUpdate, IntentFilter(PlaybackService.ACTION_PLAYER_STATUS_CHANGED))
|
||||
activity?.registerReceiver(notificationReceiver, IntentFilter(PlaybackServiceInterface.ACTION_PLAYER_NOTIFICATION))
|
||||
activity.registerReceiver(statusUpdate, IntentFilter(PlaybackService.ACTION_PLAYER_STATUS_CHANGED))
|
||||
activity.registerReceiver(notificationReceiver, IntentFilter(PlaybackServiceInterface.ACTION_PLAYER_NOTIFICATION))
|
||||
}
|
||||
// activity?.registerReceiver(statusUpdate, IntentFilter(PlaybackService.ACTION_PLAYER_STATUS_CHANGED))
|
||||
// activity?.registerReceiver(notificationReceiver, IntentFilter(PlaybackServiceInterface.ACTION_PLAYER_NOTIFICATION))
|
||||
// activity.registerReceiver(statusUpdate, IntentFilter(PlaybackService.ACTION_PLAYER_STATUS_CHANGED))
|
||||
// activity.registerReceiver(notificationReceiver, IntentFilter(PlaybackServiceInterface.ACTION_PLAYER_NOTIFICATION))
|
||||
|
||||
if (!released) {
|
||||
bindToService()
|
||||
|
@ -100,13 +100,13 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
Log.d(TAG, "Releasing PlaybackController")
|
||||
|
||||
try {
|
||||
activity?.unregisterReceiver(statusUpdate)
|
||||
activity.unregisterReceiver(statusUpdate)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
try {
|
||||
activity?.unregisterReceiver(notificationReceiver)
|
||||
activity.unregisterReceiver(notificationReceiver)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// ignore
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
|
||||
private fun unbind() {
|
||||
try {
|
||||
activity?.unbindService(mConnection)
|
||||
activity.unbindService(mConnection)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// ignore
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
private fun bindToService() {
|
||||
Log.d(TAG, "Trying to connect to service")
|
||||
check(PlaybackService.isRunning) { "Trying to bind but service is not running" }
|
||||
val bound = activity?.bindService(Intent(activity, PlaybackService::class.java), mConnection, 0)
|
||||
val bound = activity.bindService(Intent(activity, PlaybackService::class.java), mConnection, 0)
|
||||
Log.d(TAG, "Result for service binding: $bound")
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
|
||||
private val statusUpdate: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
Log.d(TAG, "Received statusUpdate Intent.")
|
||||
// Log.d(TAG, "Received statusUpdate Intent.")
|
||||
if (playbackService != null) {
|
||||
val info = playbackService!!.pSMPInfo
|
||||
status = info.playerStatus
|
||||
|
@ -218,7 +218,7 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
* should be used to update the GUI or start/cancel background threads.
|
||||
*/
|
||||
private fun handleStatus() {
|
||||
Log.d(TAG, "status: $status")
|
||||
Log.d(TAG, "handleStatus() called status: $status")
|
||||
checkMediaInfoLoaded()
|
||||
when (status) {
|
||||
PlayerStatus.PLAYING -> updatePlayButtonShowsPlay(false)
|
||||
|
@ -267,7 +267,7 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
fun playPause() {
|
||||
if (media == null) return
|
||||
if (playbackService == null) {
|
||||
if (activity != null) PlaybackServiceStarter(activity, media!!).start()
|
||||
PlaybackServiceStarter(activity, media!!).start()
|
||||
Log.w(TAG, "Play/Pause button was pressed, but playbackservice was null!")
|
||||
return
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
playbackService!!.prepare()
|
||||
}
|
||||
else -> {
|
||||
if (activity != null) PlaybackServiceStarter(activity, media!!)
|
||||
PlaybackServiceStarter(activity, media!!)
|
||||
.callEvenIfRunning(true)
|
||||
.start()
|
||||
Log.w(TAG, "Play/Pause button was pressed and PlaybackService state was unknown")
|
||||
|
@ -289,46 +289,28 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
}
|
||||
|
||||
val position: Int
|
||||
get() = if (playbackService != null) {
|
||||
playbackService!!.currentPosition
|
||||
} else if (getMedia() != null) {
|
||||
getMedia()!!.getPosition()
|
||||
} else {
|
||||
Playable.INVALID_TIME
|
||||
}
|
||||
get() = playbackService?.currentPosition ?: getMedia()?.getPosition()?:Playable.INVALID_TIME
|
||||
|
||||
val duration: Int
|
||||
get() = if (playbackService != null) {
|
||||
playbackService!!.duration
|
||||
} else if (getMedia() != null) {
|
||||
getMedia()!!.getDuration()
|
||||
} else {
|
||||
Playable.INVALID_TIME
|
||||
}
|
||||
get() = playbackService?.duration ?: getMedia()?.getDuration()?:Playable.INVALID_TIME
|
||||
|
||||
fun getMedia(): Playable? {
|
||||
if (media == null && activity != null) {
|
||||
media = PlaybackPreferences.createInstanceFromPreferences(activity)
|
||||
}
|
||||
if (media == null && playbackService != null) media = playbackService!!.pSMPInfo.playable
|
||||
if (media == null) media = PlaybackPreferences.createInstanceFromPreferences(activity)
|
||||
|
||||
return media
|
||||
}
|
||||
|
||||
fun sleepTimerActive(): Boolean {
|
||||
return playbackService != null && playbackService!!.sleepTimerActive()
|
||||
return playbackService?.sleepTimerActive() ?: false
|
||||
}
|
||||
|
||||
fun disableSleepTimer() {
|
||||
if (playbackService != null) {
|
||||
playbackService!!.disableSleepTimer()
|
||||
}
|
||||
playbackService?.disableSleepTimer()
|
||||
}
|
||||
|
||||
val sleepTimerTimeLeft: Long
|
||||
get() = if (playbackService != null) {
|
||||
playbackService!!.sleepTimerTimeLeft
|
||||
} else {
|
||||
Playable.INVALID_TIME.toLong()
|
||||
}
|
||||
get() = playbackService?.sleepTimerTimeLeft ?: Playable.INVALID_TIME.toLong()
|
||||
|
||||
fun extendSleepTimer(extendTime: Long) {
|
||||
val timeLeft = sleepTimerTimeLeft
|
||||
|
@ -338,26 +320,24 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
}
|
||||
|
||||
fun setSleepTimer(time: Long) {
|
||||
if (playbackService != null) {
|
||||
playbackService!!.setSleepTimer(time)
|
||||
}
|
||||
playbackService?.setSleepTimer(time)
|
||||
}
|
||||
|
||||
fun seekTo(time: Int) {
|
||||
if (playbackService != null) {
|
||||
playbackService!!.seekTo(time)
|
||||
} else if (getMedia() is FeedMedia) {
|
||||
val media = getMedia() as FeedMedia?
|
||||
media!!.setPosition(time)
|
||||
DBWriter.setFeedItem(media.getItem())
|
||||
EventBus.getDefault().post(PlaybackPositionEvent(time, getMedia()!!.getDuration()))
|
||||
} else {
|
||||
val media = getMedia()
|
||||
if (media is FeedMedia) {
|
||||
media.setPosition(time)
|
||||
DBWriter.setFeedItem(media.getItem())
|
||||
EventBus.getDefault().post(PlaybackPositionEvent(time, media.getDuration()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setVideoSurface(holder: SurfaceHolder?) {
|
||||
if (playbackService != null) {
|
||||
playbackService!!.setVideoSurface(holder)
|
||||
}
|
||||
playbackService?.setVideoSurface(holder)
|
||||
}
|
||||
|
||||
fun setPlaybackSpeed(speed: Float) {
|
||||
|
@ -369,21 +349,15 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
}
|
||||
|
||||
fun setSkipSilence(skipSilence: Boolean) {
|
||||
if (playbackService != null) {
|
||||
playbackService!!.skipSilence(skipSilence)
|
||||
}
|
||||
playbackService?.skipSilence(skipSilence)
|
||||
}
|
||||
|
||||
val currentPlaybackSpeedMultiplier: Float
|
||||
get() = if (playbackService != null) {
|
||||
playbackService!!.currentPlaybackSpeed
|
||||
} else {
|
||||
getCurrentPlaybackSpeed(getMedia())
|
||||
}
|
||||
get() = playbackService?.currentPlaybackSpeed ?: getCurrentPlaybackSpeed(getMedia())
|
||||
|
||||
val audioTracks: List<String>
|
||||
get() {
|
||||
if (playbackService == null || playbackService!!.audioTracks.isNullOrEmpty()) {
|
||||
if (playbackService == null || playbackService!!.audioTracks.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
return playbackService!!.audioTracks.filterNotNull().map { it }
|
||||
|
@ -391,16 +365,11 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
|
||||
val selectedAudioTrack: Int
|
||||
get() {
|
||||
if (playbackService == null) {
|
||||
return -1
|
||||
}
|
||||
return playbackService!!.selectedAudioTrack
|
||||
return playbackService?.selectedAudioTrack?: -1
|
||||
}
|
||||
|
||||
fun setAudioTrack(track: Int) {
|
||||
if (playbackService != null) {
|
||||
playbackService!!.setAudioTrack(track)
|
||||
}
|
||||
playbackService?.setAudioTrack(track)
|
||||
}
|
||||
|
||||
val isPlayingVideoLocally: Boolean
|
||||
|
@ -409,20 +378,14 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
} else if (playbackService != null) {
|
||||
PlaybackService.currentMediaType == MediaType.VIDEO
|
||||
} else {
|
||||
getMedia() != null && getMedia()!!.getMediaType() == MediaType.VIDEO
|
||||
getMedia()?.getMediaType() == MediaType.VIDEO
|
||||
}
|
||||
|
||||
val videoSize: Pair<Int, Int>?
|
||||
get() = if (playbackService != null) {
|
||||
playbackService!!.videoSize
|
||||
} else {
|
||||
null
|
||||
}
|
||||
get() = playbackService?.videoSize
|
||||
|
||||
fun notifyVideoSurfaceAbandoned() {
|
||||
if (playbackService != null) {
|
||||
playbackService!!.notifyVideoSurfaceAbandoned()
|
||||
}
|
||||
playbackService?.notifyVideoSurfaceAbandoned()
|
||||
}
|
||||
|
||||
val isStreaming: Boolean
|
||||
|
@ -430,5 +393,7 @@ abstract class PlaybackController(private val activity: FragmentActivity?) {
|
|||
|
||||
companion object {
|
||||
private const val TAG = "PlaybackController"
|
||||
|
||||
private var media: Playable? = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import ac.mdiq.podcini.model.playback.Playable
|
|||
|
||||
@UnstableApi
|
||||
class PlaybackServiceStarter(private val context: Context, private val media: Playable) {
|
||||
|
||||
private var shouldStreamThisTime = false
|
||||
private var callEvenIfRunning = false
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class FeedDiscoverer {
|
|||
val uri = Uri.parse(strUrl)
|
||||
if (uri.isRelative) {
|
||||
val res = Uri.parse(baseUrl).buildUpon().path(strUrl).build()
|
||||
return if ((res != null)) res.toString() else null
|
||||
return res?.toString()
|
||||
} else {
|
||||
return strUrl
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ac.mdiq.podcini.core.util.syndication
|
||||
|
||||
import android.text.TextUtils
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.internal.StringUtil
|
||||
|
@ -37,7 +36,7 @@ class HtmlToPlainText {
|
|||
* @param element the root element to format
|
||||
* @return formatted text
|
||||
*/
|
||||
fun getPlainText(element: Element?): String {
|
||||
fun getPlainText(element: Element): String {
|
||||
val formatter = FormattingVisitor()
|
||||
// walk the DOM, and call .head() and .tail() for each node
|
||||
NodeTraversor.traverse(formatter, element)
|
||||
|
@ -52,14 +51,19 @@ class HtmlToPlainText {
|
|||
// hit when the node is first seen
|
||||
override fun head(node: Node, depth: Int) {
|
||||
val name = node.nodeName()
|
||||
if (node is TextNode) {
|
||||
append(node.text()) // TextNodes carry all user-readable text in the DOM.
|
||||
} else if (name == "li") {
|
||||
append("\n * ")
|
||||
} else if (name == "dt") {
|
||||
append(" ")
|
||||
} else if (StringUtil.`in`(name, "p", "h1", "h2", "h3", "h4", "h5", "tr")) {
|
||||
append("\n")
|
||||
when {
|
||||
node is TextNode -> {
|
||||
append(node.text()) // TextNodes carry all user-readable text in the DOM.
|
||||
}
|
||||
name == "li" -> {
|
||||
append("\n * ")
|
||||
}
|
||||
name == "dt" -> {
|
||||
append(" ")
|
||||
}
|
||||
StringUtil.`in`(name, "p", "h1", "h2", "h3", "h4", "h5", "tr") -> {
|
||||
append("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,13 +99,13 @@ class HtmlToPlainText {
|
|||
* @param str String with any encoding
|
||||
* @return Human readable text with minimal HTML formatting
|
||||
*/
|
||||
fun getPlainText(str: String?): String? {
|
||||
fun getPlainText(str: String): String {
|
||||
var str = str
|
||||
if (!TextUtils.isEmpty(str) && isHtml(str)) {
|
||||
if (str.isNotEmpty() && isHtml(str)) {
|
||||
val formatter = HtmlToPlainText()
|
||||
val feedDescription = Jsoup.parse(str)
|
||||
str = StringUtils.trim(formatter.getPlainText(feedDescription))
|
||||
} else if (TextUtils.isEmpty(str)) {
|
||||
} else if (str.isEmpty()) {
|
||||
str = ""
|
||||
}
|
||||
|
||||
|
@ -116,7 +120,7 @@ class HtmlToPlainText {
|
|||
*/
|
||||
private fun isHtml(str: String?): Boolean {
|
||||
val htmlTagPattern = "<(\"[^\"]*\"|'[^']*'|[^'\">])*>"
|
||||
return Pattern.compile(htmlTagPattern).matcher(str).find()
|
||||
return Pattern.compile(htmlTagPattern).matcher(str.toString()).find()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class LocalFeedUpdaterTest {
|
|||
PodDBAdapter.init(context!!)
|
||||
deleteDatabase()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.close()
|
||||
|
||||
mapDummyMetadata(LOCAL_FEED_DIR1)
|
||||
|
|
|
@ -60,7 +60,7 @@ open class DbCleanupTests {
|
|||
PodDBAdapter.init(context!!)
|
||||
deleteDatabase()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.close()
|
||||
|
||||
val prefEdit = PreferenceManager
|
||||
|
@ -136,7 +136,7 @@ open class DbCleanupTests {
|
|||
}
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
if (addToQueue) {
|
||||
adapter.setQueue(items)
|
||||
|
@ -200,11 +200,11 @@ open class DbCleanupTests {
|
|||
|
||||
// add candidate for performAutoCleanup
|
||||
val feeds = DbTestUtils.saveFeedlist(1, 1, true)
|
||||
val m: FeedMedia = feeds[0].items!!.get(0).media!!
|
||||
val m: FeedMedia = feeds[0].items[0].media!!
|
||||
m.setDownloaded(true)
|
||||
m.setFile_url("file")
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setMedia(m)
|
||||
adapter.close()
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class DbNullCleanupAlgorithmTest {
|
|||
PodDBAdapter.init(context!!)
|
||||
deleteDatabase()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.close()
|
||||
|
||||
val prefEdit = PreferenceManager.getDefaultSharedPreferences(context!!.applicationContext).edit()
|
||||
|
@ -95,7 +95,7 @@ class DbNullCleanupAlgorithmTest {
|
|||
}
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class DbReaderTest {
|
|||
PodDBAdapter.init(context)
|
||||
deleteDatabase()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.close()
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ class DbReaderTest {
|
|||
@Test
|
||||
fun testGetFeedListSortOrder() {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
|
||||
val feed1 = Feed(0, null, "A", "link", "d", null, null, null, "rss", "A", null, "", "", true)
|
||||
val feed2 = Feed(0, null, "b", "link", "d", null, null, null, "rss", "b", null, "", "", true)
|
||||
|
@ -167,7 +167,7 @@ class DbReaderTest {
|
|||
}
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setQueue(queue)
|
||||
adapter.close()
|
||||
return queue
|
||||
|
@ -219,7 +219,7 @@ class DbReaderTest {
|
|||
}
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.storeFeedItemlist(downloaded)
|
||||
adapter.close()
|
||||
return downloaded
|
||||
|
@ -258,7 +258,7 @@ class DbReaderTest {
|
|||
}
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.storeFeedItemlist(newItems)
|
||||
adapter.close()
|
||||
return newItems
|
||||
|
@ -298,7 +298,7 @@ class DbReaderTest {
|
|||
|
||||
val adapter = getInstance()
|
||||
for (playedItems in mutableListOf(0, 1, 20, 100)) {
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
for (i in 0 until playedItems) {
|
||||
val m: FeedMedia = feed.items[i].media!!
|
||||
m.setPlaybackCompletionDate(Date((i + 1).toLong()))
|
||||
|
@ -331,7 +331,7 @@ class DbReaderTest {
|
|||
val numNew = 2
|
||||
val feeds = DbTestUtils.saveFeedlist(numFeeds, numItems, true)
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
for (i in 0 until numNew) {
|
||||
val item: FeedItem = feeds[0].items[i]
|
||||
item.setNew()
|
||||
|
@ -445,7 +445,7 @@ class DbReaderTest {
|
|||
val ids = LongArray(playedItems)
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
for (i in 0 until playedItems) {
|
||||
val m: FeedMedia = feed.items[i].media!!
|
||||
m.setPlaybackCompletionDate(Date((i + 1).toLong()))
|
||||
|
|
|
@ -46,7 +46,7 @@ class DbTasksTest {
|
|||
PodDBAdapter.init(context!!)
|
||||
deleteDatabase()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.close()
|
||||
}
|
||||
|
||||
|
@ -63,14 +63,14 @@ class DbTasksTest {
|
|||
val feed = Feed("url", null, "title")
|
||||
feed.items = mutableListOf()
|
||||
for (i in 0 until numItems) {
|
||||
feed.items?.add(FeedItem(0, "item $i", "id $i", "link $i",
|
||||
feed.items.add(FeedItem(0, "item $i", "id $i", "link $i",
|
||||
Date(), FeedItem.UNPLAYED, feed))
|
||||
}
|
||||
val newFeed = updateFeed(context!!, feed, false)
|
||||
|
||||
Assert.assertEquals(feed.id, newFeed!!.id)
|
||||
Assert.assertTrue(feed.id != 0L)
|
||||
for (item in feed.items!!) {
|
||||
for (item in feed.items) {
|
||||
Assert.assertFalse(item.isPlayed())
|
||||
Assert.assertTrue(item.id != 0L)
|
||||
}
|
||||
|
@ -99,11 +99,11 @@ class DbTasksTest {
|
|||
val feed = Feed("url", null, "title")
|
||||
feed.items = mutableListOf()
|
||||
for (i in 0 until numItemsOld) {
|
||||
feed.items?.add(FeedItem(0, "item $i", "id $i", "link $i",
|
||||
feed.items.add(FeedItem(0, "item $i", "id $i", "link $i",
|
||||
Date(i.toLong()), FeedItem.PLAYED, feed))
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -112,14 +112,14 @@ class DbTasksTest {
|
|||
val feedID = feed.id
|
||||
feed.id = 0
|
||||
val itemIDs: MutableList<Long> = ArrayList()
|
||||
for (item in feed.items!!) {
|
||||
for (item in feed.items) {
|
||||
Assert.assertTrue(item.id != 0L)
|
||||
itemIDs.add(item.id)
|
||||
item.id = 0
|
||||
}
|
||||
|
||||
for (i in numItemsOld until numItemsNew + numItemsOld) {
|
||||
feed.items?.add(0, FeedItem(0, "item $i", "id $i", "link $i",
|
||||
feed.items.add(0, FeedItem(0, "item $i", "id $i", "link $i",
|
||||
Date(i.toLong()), FeedItem.UNPLAYED, feed))
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ class DbTasksTest {
|
|||
feed.items = (mutableListOf(item))
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -159,7 +159,7 @@ class DbTasksTest {
|
|||
Assert.assertNotSame(newFeed, feed)
|
||||
|
||||
val feedFromDB = getFeed(newFeed!!.id)
|
||||
val feedItemFromDB: FeedItem = feedFromDB!!.items!![0]
|
||||
val feedItemFromDB: FeedItem = feedFromDB!!.items[0]
|
||||
Assert.assertTrue(feedItemFromDB.isNew)
|
||||
}
|
||||
|
||||
|
@ -168,16 +168,16 @@ class DbTasksTest {
|
|||
val feed = Feed("url", null, "title")
|
||||
feed.items = mutableListOf()
|
||||
for (i in 0..9) {
|
||||
feed.items?.add(
|
||||
feed.items.add(
|
||||
FeedItem(0, "item $i", "id $i", "link $i", Date(i.toLong()), FeedItem.PLAYED, feed))
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
// delete some items
|
||||
feed.items?.subList(0, 2)?.clear()
|
||||
feed.items.subList(0, 2).clear()
|
||||
val newFeed = updateFeed(context!!, feed, true)
|
||||
assertEquals(8, newFeed?.items?.size) // 10 - 2 = 8 items
|
||||
|
||||
|
@ -194,10 +194,10 @@ class DbTasksTest {
|
|||
FeedItem(0, "item $i", "id $i", "link $i", Date(i.toLong()), FeedItem.PLAYED, feed)
|
||||
val media = FeedMedia(item, "download url $i", 123, "media/mp3")
|
||||
item.setMedia(media)
|
||||
feed.items?.add(item)
|
||||
feed.items.add(item)
|
||||
}
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -219,11 +219,11 @@ class DbTasksTest {
|
|||
|
||||
private fun updatedFeedTest(newFeed: Feed?, feedID: Long, itemIDs: List<Long>, numItemsOld: Int, numItemsNew: Int) {
|
||||
Assert.assertEquals(feedID, newFeed!!.id)
|
||||
assertEquals(numItemsNew + numItemsOld, newFeed.items?.size)
|
||||
newFeed.items?.reverse()
|
||||
assertEquals(numItemsNew + numItemsOld, newFeed.items.size)
|
||||
newFeed.items.reverse()
|
||||
var lastDate = Date(0)
|
||||
for (i in 0 until numItemsOld) {
|
||||
val item: FeedItem = newFeed.items!![i]
|
||||
val item: FeedItem = newFeed.items[i]
|
||||
Assert.assertSame(newFeed, item.feed)
|
||||
Assert.assertEquals(itemIDs[i], item.id)
|
||||
Assert.assertTrue(item.isPlayed())
|
||||
|
@ -231,7 +231,7 @@ class DbTasksTest {
|
|||
lastDate = item.pubDate!!
|
||||
}
|
||||
for (i in numItemsOld until numItemsNew + numItemsOld) {
|
||||
val item: FeedItem = newFeed.items!![i]
|
||||
val item: FeedItem = newFeed.items[i]
|
||||
Assert.assertSame(newFeed, item.feed)
|
||||
Assert.assertTrue(item.id != 0L)
|
||||
Assert.assertFalse(item.isPlayed())
|
||||
|
@ -254,7 +254,7 @@ class DbTasksTest {
|
|||
}
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
return feed
|
||||
|
|
|
@ -28,7 +28,7 @@ internal object DbTestUtils {
|
|||
|
||||
val feeds: MutableList<Feed> = ArrayList()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
for (i in 0 until numFeeds) {
|
||||
val f = Feed(0, null, "feed $i", "link$i", "descr", null, null,
|
||||
null, null, "id$i", null, null, "url$i", false)
|
||||
|
@ -53,7 +53,7 @@ internal object DbTestUtils {
|
|||
f.items.sortWith(FeedItemPubdateComparator())
|
||||
adapter.setCompleteFeed(f)
|
||||
Assert.assertTrue(f.id != 0L)
|
||||
for (item in f.items!!) {
|
||||
for (item in f.items) {
|
||||
Assert.assertTrue(item.id != 0L)
|
||||
}
|
||||
feeds.add(f)
|
||||
|
|
|
@ -71,7 +71,7 @@ class DbWriterTest {
|
|||
PodDBAdapter.init(context!!)
|
||||
deleteDatabase()
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.close()
|
||||
|
||||
val prefEdit = PreferenceManager.getDefaultSharedPreferences(
|
||||
|
@ -144,7 +144,7 @@ class DbWriterTest {
|
|||
items.add(item)
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
Assert.assertTrue(media!!.id != 0L)
|
||||
|
@ -181,7 +181,7 @@ class DbWriterTest {
|
|||
queue.add(item)
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.setQueue(queue)
|
||||
adapter.close()
|
||||
|
@ -225,7 +225,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -243,7 +243,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
var c = adapter.getFeedCursor(feed.id)
|
||||
Assert.assertEquals(0, c.count.toLong())
|
||||
c.close()
|
||||
|
@ -269,7 +269,7 @@ class DbWriterTest {
|
|||
feed.imageUrl = ("url")
|
||||
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -278,7 +278,7 @@ class DbWriterTest {
|
|||
deleteFeed(context!!, feed.id)[TIMEOUT, TimeUnit.SECONDS]
|
||||
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
val c = adapter.getFeedCursor(feed.id)
|
||||
Assert.assertEquals(0, c.count.toLong())
|
||||
c.close()
|
||||
|
@ -303,7 +303,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -315,7 +315,7 @@ class DbWriterTest {
|
|||
deleteFeed(context!!, feed.id)[TIMEOUT, TimeUnit.SECONDS]
|
||||
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
var c = adapter.getFeedCursor(feed.id)
|
||||
Assert.assertEquals(0, c.count.toLong())
|
||||
c.close()
|
||||
|
@ -349,7 +349,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -410,7 +410,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -423,7 +423,7 @@ class DbWriterTest {
|
|||
deleteFeed(context!!, feed.id)[TIMEOUT, TimeUnit.SECONDS]
|
||||
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
var c = adapter.getFeedCursor(feed.id)
|
||||
Assert.assertEquals(0, c.count.toLong())
|
||||
c.close()
|
||||
|
@ -453,7 +453,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -461,7 +461,7 @@ class DbWriterTest {
|
|||
deleteFeedItems(context!!, itemsToDelete)[TIMEOUT, TimeUnit.SECONDS]
|
||||
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
for (i in 0 until feed.items.size) {
|
||||
val feedItem: FeedItem = feed.items[i]
|
||||
val c = adapter.getFeedItemCursor(feedItem.id.toString())
|
||||
|
@ -484,7 +484,7 @@ class DbWriterTest {
|
|||
feed.items.add(item)
|
||||
item.setMedia(media)
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
Assert.assertTrue(media.id != 0L)
|
||||
|
@ -497,7 +497,7 @@ class DbWriterTest {
|
|||
var media: FeedMedia? = playbackHistorySetup(null)
|
||||
addItemToPlaybackHistory(media)[TIMEOUT, TimeUnit.SECONDS]
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
media = getFeedMedia(media!!.id)
|
||||
adapter.close()
|
||||
|
||||
|
@ -513,7 +513,7 @@ class DbWriterTest {
|
|||
var media: FeedMedia? = playbackHistorySetup(Date(oldDate))
|
||||
addItemToPlaybackHistory(media)[TIMEOUT, TimeUnit.SECONDS]
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
media = getFeedMedia(media!!.id)
|
||||
adapter.close()
|
||||
|
||||
|
@ -534,7 +534,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -561,7 +561,7 @@ class DbWriterTest {
|
|||
feed.items.add(item)
|
||||
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -569,7 +569,7 @@ class DbWriterTest {
|
|||
addQueueItem(context, item)[TIMEOUT, TimeUnit.SECONDS]
|
||||
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
val cursor = adapter.queueIDCursor
|
||||
Assert.assertTrue(cursor.moveToFirst())
|
||||
Assert.assertEquals(item.id, cursor.getLong(0))
|
||||
|
@ -587,7 +587,7 @@ class DbWriterTest {
|
|||
feed.items.add(item)
|
||||
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -595,7 +595,7 @@ class DbWriterTest {
|
|||
addQueueItem(context, item)[TIMEOUT, TimeUnit.SECONDS]
|
||||
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
var cursor = adapter.queueIDCursor
|
||||
Assert.assertTrue(cursor.moveToFirst())
|
||||
Assert.assertEquals(item.id, cursor.getLong(0))
|
||||
|
@ -604,7 +604,7 @@ class DbWriterTest {
|
|||
|
||||
addQueueItem(context, item)[TIMEOUT, TimeUnit.SECONDS]
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
cursor = adapter.queueIDCursor
|
||||
Assert.assertTrue(cursor.moveToFirst())
|
||||
Assert.assertEquals(item.id, cursor.getLong(0))
|
||||
|
@ -619,7 +619,7 @@ class DbWriterTest {
|
|||
val numItems = 10
|
||||
val feed = queueTestSetupMultipleItems(numItems)
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
val cursor = adapter.queueIDCursor
|
||||
Assert.assertTrue(cursor.moveToFirst())
|
||||
Assert.assertEquals(numItems.toLong(), cursor.count.toLong())
|
||||
|
@ -643,7 +643,7 @@ class DbWriterTest {
|
|||
queueTestSetupMultipleItems(numItems)
|
||||
clearQueue()[TIMEOUT, TimeUnit.SECONDS]
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
val cursor = adapter.queueIDCursor
|
||||
Assert.assertFalse(cursor.moveToFirst())
|
||||
cursor.close()
|
||||
|
@ -659,13 +659,13 @@ class DbWriterTest {
|
|||
for (removeIndex in 0 until numItems) {
|
||||
val item: FeedItem = feed.items[removeIndex]
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setQueue(feed.items.toList())
|
||||
adapter.close()
|
||||
|
||||
removeQueueItem(context!!, false, item)[TIMEOUT, TimeUnit.SECONDS]
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
val queue = adapter.queueIDCursor
|
||||
Assert.assertEquals((numItems - 1).toLong(), queue.count.toLong())
|
||||
for (i in 0 until queue.count) {
|
||||
|
@ -732,7 +732,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
var adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -748,13 +748,13 @@ class DbWriterTest {
|
|||
val fromID: Long = feed.items[from].id
|
||||
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setQueue(feed.items)
|
||||
adapter.close()
|
||||
|
||||
moveQueueItem(from, to, false)[TIMEOUT, TimeUnit.SECONDS]
|
||||
adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
val queue = adapter.queueIDCursor
|
||||
Assert.assertEquals(numItems.toLong(), queue.count.toLong())
|
||||
Assert.assertTrue(queue.moveToPosition(from))
|
||||
|
@ -782,7 +782,7 @@ class DbWriterTest {
|
|||
}
|
||||
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
adapter.setCompleteFeed(feed)
|
||||
adapter.close()
|
||||
|
||||
|
@ -824,10 +824,10 @@ class DbWriterTest {
|
|||
private fun withPodDB(action: Consumer<PodDBAdapter?>) {
|
||||
val adapter = getInstance()
|
||||
try {
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
action.accept(adapter)
|
||||
} finally {
|
||||
adapter!!.close()
|
||||
adapter.close()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import ac.mdiq.podcini.model.feed.FeedItem
|
|||
|
||||
class QueueEvent private constructor(@JvmField val action: Action,
|
||||
@JvmField val item: FeedItem?,
|
||||
@JvmField val items: List<FeedItem>?,
|
||||
@JvmField val items: List<FeedItem>,
|
||||
@JvmField val position: Int
|
||||
) {
|
||||
enum class Action {
|
||||
|
@ -14,38 +14,38 @@ class QueueEvent private constructor(@JvmField val action: Action,
|
|||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun added(item: FeedItem?, position: Int): QueueEvent {
|
||||
return QueueEvent(Action.ADDED, item, null, position)
|
||||
fun added(item: FeedItem, position: Int): QueueEvent {
|
||||
return QueueEvent(Action.ADDED, item, listOf(), position)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setQueue(queue: List<FeedItem>?): QueueEvent {
|
||||
fun setQueue(queue: List<FeedItem>): QueueEvent {
|
||||
return QueueEvent(Action.SET_QUEUE, null, queue, -1)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun removed(item: FeedItem?): QueueEvent {
|
||||
return QueueEvent(Action.REMOVED, item, null, -1)
|
||||
fun removed(item: FeedItem): QueueEvent {
|
||||
return QueueEvent(Action.REMOVED, item, listOf(), -1)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun irreversibleRemoved(item: FeedItem?): QueueEvent {
|
||||
return QueueEvent(Action.IRREVERSIBLE_REMOVED, item, null, -1)
|
||||
fun irreversibleRemoved(item: FeedItem): QueueEvent {
|
||||
return QueueEvent(Action.IRREVERSIBLE_REMOVED, item, listOf(), -1)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun cleared(): QueueEvent {
|
||||
return QueueEvent(Action.CLEARED, null, null, -1)
|
||||
return QueueEvent(Action.CLEARED, null, listOf(), -1)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun sorted(sortedQueue: List<FeedItem>?): QueueEvent {
|
||||
fun sorted(sortedQueue: List<FeedItem>): QueueEvent {
|
||||
return QueueEvent(Action.SORTED, null, sortedQueue, -1)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun moved(item: FeedItem?, newPosition: Int): QueueEvent {
|
||||
return QueueEvent(Action.MOVED, item, null, newPosition)
|
||||
fun moved(item: FeedItem, newPosition: Int): QueueEvent {
|
||||
return QueueEvent(Action.MOVED, item, listOf(), newPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ class FeedItem : FeedComponent, Serializable {
|
|||
this.title = title
|
||||
this.itemIdentifier = itemIdentifier
|
||||
this.link = link
|
||||
this.pubDate = if ((pubDate != null)) pubDate.clone() as Date else null
|
||||
this.pubDate = if (pubDate != null) pubDate.clone() as Date else null
|
||||
this.playState = state
|
||||
this.feed = feed
|
||||
this.hasChapters = false
|
||||
|
@ -145,7 +145,7 @@ class FeedItem : FeedComponent, Serializable {
|
|||
this.title = title
|
||||
this.itemIdentifier = itemIdentifier
|
||||
this.link = link
|
||||
this.pubDate = if ((pubDate != null)) pubDate.clone() as Date else null
|
||||
this.pubDate = if (pubDate != null) pubDate.clone() as Date else null
|
||||
this.playState = state
|
||||
this.feed = feed
|
||||
this.hasChapters = hasChapters
|
||||
|
@ -246,7 +246,7 @@ class FeedItem : FeedComponent, Serializable {
|
|||
}
|
||||
|
||||
fun isPlayed(): Boolean {
|
||||
return playState === PLAYED
|
||||
return playState == PLAYED
|
||||
}
|
||||
|
||||
fun setPlayed(played: Boolean) {
|
||||
|
@ -299,7 +299,7 @@ class FeedItem : FeedComponent, Serializable {
|
|||
}
|
||||
|
||||
fun hasChapters(): Boolean {
|
||||
return hasChapters
|
||||
return chapters?.isNotEmpty() ?: hasChapters
|
||||
}
|
||||
|
||||
fun disableAutoDownload() {
|
||||
|
|
|
@ -274,6 +274,10 @@ class FeedMedia : FeedFile, Playable {
|
|||
return item!!.chapters!!
|
||||
}
|
||||
|
||||
override fun chaptersLoaded(): Boolean {
|
||||
return item?.chapters != null
|
||||
}
|
||||
|
||||
override fun getWebsiteLink(): String? {
|
||||
if (item == null) {
|
||||
return null
|
||||
|
|
|
@ -29,6 +29,8 @@ interface Playable : Parcelable, Serializable {
|
|||
*/
|
||||
fun getChapters(): List<Chapter>
|
||||
|
||||
fun chaptersLoaded(): Boolean
|
||||
|
||||
/**
|
||||
* Returns a link to a website that is meant to be shown in a browser
|
||||
*/
|
||||
|
|
|
@ -124,6 +124,10 @@ class RemoteMedia : Playable {
|
|||
return chapters ?: listOf()
|
||||
}
|
||||
|
||||
override fun chaptersLoaded(): Boolean {
|
||||
return chapters != null
|
||||
}
|
||||
|
||||
override fun getEpisodeTitle(): String {
|
||||
return episodeTitle!!
|
||||
}
|
||||
|
|
|
@ -30,34 +30,43 @@ object UrlChecker {
|
|||
var url = url
|
||||
url = url.trim { it <= ' ' }
|
||||
val lowerCaseUrl = url.lowercase() // protocol names are case insensitive
|
||||
if (lowerCaseUrl.startsWith("feed://")) {
|
||||
Log.d(TAG, "Replacing feed:// with http://")
|
||||
return prepareUrl(url.substring("feed://".length))
|
||||
} else if (lowerCaseUrl.startsWith("pcast://")) {
|
||||
Log.d(TAG, "Removing pcast://")
|
||||
return prepareUrl(url.substring("pcast://".length))
|
||||
} else if (lowerCaseUrl.startsWith("pcast:")) {
|
||||
Log.d(TAG, "Removing pcast:")
|
||||
return prepareUrl(url.substring("pcast:".length))
|
||||
} else if (lowerCaseUrl.startsWith("itpc")) {
|
||||
Log.d(TAG, "Replacing itpc:// with http://")
|
||||
return prepareUrl(url.substring("itpc://".length))
|
||||
} else if (lowerCaseUrl.startsWith(AP_SUBSCRIBE)) {
|
||||
Log.d(TAG, "Removing podcini-subscribe://")
|
||||
return prepareUrl(url.substring(AP_SUBSCRIBE.length))
|
||||
} else if (lowerCaseUrl.contains(AP_SUBSCRIBE_DEEPLINK)) {
|
||||
Log.d(TAG, "Removing $AP_SUBSCRIBE_DEEPLINK")
|
||||
val removedWebsite = url.substring(url.indexOf("?url=") + "?url=".length)
|
||||
return try {
|
||||
prepareUrl(URLDecoder.decode(removedWebsite, "UTF-8"))
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
prepareUrl(removedWebsite)
|
||||
when {
|
||||
lowerCaseUrl.startsWith("feed://") -> {
|
||||
Log.d(TAG, "Replacing feed:// with http://")
|
||||
return prepareUrl(url.substring("feed://".length))
|
||||
}
|
||||
lowerCaseUrl.startsWith("pcast://") -> {
|
||||
Log.d(TAG, "Removing pcast://")
|
||||
return prepareUrl(url.substring("pcast://".length))
|
||||
}
|
||||
lowerCaseUrl.startsWith("pcast:") -> {
|
||||
Log.d(TAG, "Removing pcast:")
|
||||
return prepareUrl(url.substring("pcast:".length))
|
||||
}
|
||||
lowerCaseUrl.startsWith("itpc") -> {
|
||||
Log.d(TAG, "Replacing itpc:// with http://")
|
||||
return prepareUrl(url.substring("itpc://".length))
|
||||
}
|
||||
lowerCaseUrl.startsWith(AP_SUBSCRIBE) -> {
|
||||
Log.d(TAG, "Removing podcini-subscribe://")
|
||||
return prepareUrl(url.substring(AP_SUBSCRIBE.length))
|
||||
}
|
||||
lowerCaseUrl.contains(AP_SUBSCRIBE_DEEPLINK) -> {
|
||||
Log.d(TAG, "Removing $AP_SUBSCRIBE_DEEPLINK")
|
||||
val removedWebsite = url.substring(url.indexOf("?url=") + "?url=".length)
|
||||
return try {
|
||||
prepareUrl(URLDecoder.decode(removedWebsite, "UTF-8"))
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
prepareUrl(removedWebsite)
|
||||
}
|
||||
}
|
||||
!(lowerCaseUrl.startsWith("http://") || lowerCaseUrl.startsWith("https://")) -> {
|
||||
Log.d(TAG, "Adding http:// at the beginning of the URL")
|
||||
return "http://$url"
|
||||
}
|
||||
else -> {
|
||||
return url
|
||||
}
|
||||
} else if (!(lowerCaseUrl.startsWith("http://") || lowerCaseUrl.startsWith("https://"))) {
|
||||
Log.d(TAG, "Adding http:// at the beginning of the URL")
|
||||
return "http://$url"
|
||||
} else {
|
||||
return url
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.*
|
|||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
class CombinedSearcher : PodcastSearcher {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?>? {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?> {
|
||||
val disposables = ArrayList<Disposable>()
|
||||
val singleResults: MutableList<List<PodcastSearchResult?>?> = ArrayList(
|
||||
Collections.nCopies<List<PodcastSearchResult?>?>(PodcastSearcherRegistry.searchProviders.size, null))
|
||||
|
@ -23,9 +23,8 @@ class CombinedSearcher : PodcastSearcher {
|
|||
latch.countDown()
|
||||
continue
|
||||
}
|
||||
val index = i
|
||||
disposables.add(searcher.search(query)!!.subscribe({ e: List<PodcastSearchResult?>? ->
|
||||
singleResults[index] = e
|
||||
disposables.add(searcher.search(query).subscribe({ e: List<PodcastSearchResult?>? ->
|
||||
singleResults[i] = e
|
||||
latch.countDown()
|
||||
}, { throwable: Throwable? ->
|
||||
Log.d(TAG, Log.getStackTraceString(throwable))
|
||||
|
@ -79,7 +78,7 @@ class CombinedSearcher : PodcastSearcher {
|
|||
return results
|
||||
}
|
||||
|
||||
override fun lookupUrl(url: String): Single<String>? {
|
||||
override fun lookupUrl(url: String): Single<String> {
|
||||
return PodcastSearcherRegistry.lookupUrl(url)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import io.reactivex.schedulers.Schedulers
|
|||
class FyydPodcastSearcher : PodcastSearcher {
|
||||
private val client = FyydClient(getHttpClient())
|
||||
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?>? {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?> {
|
||||
return Single.create { subscriber: SingleEmitter<List<PodcastSearchResult?>?> ->
|
||||
val response = client.searchPodcasts(
|
||||
query, 10)
|
||||
|
@ -30,7 +30,7 @@ class FyydPodcastSearcher : PodcastSearcher {
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
override fun lookupUrl(url: String): Single<String>? {
|
||||
override fun lookupUrl(url: String): Single<String> {
|
||||
return Single.just(url)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
|||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
class GpodnetPodcastSearcher : PodcastSearcher {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?>? {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?> {
|
||||
return Single.create { subscriber: SingleEmitter<List<PodcastSearchResult?>?> ->
|
||||
try {
|
||||
val service = GpodnetService(getHttpClient(),
|
||||
|
@ -31,7 +31,7 @@ class GpodnetPodcastSearcher : PodcastSearcher {
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
override fun lookupUrl(url: String): Single<String>? {
|
||||
override fun lookupUrl(url: String): Single<String> {
|
||||
return Single.just(url)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import java.net.URLEncoder
|
|||
import java.util.regex.Pattern
|
||||
|
||||
class ItunesPodcastSearcher : PodcastSearcher {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?>? {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?> {
|
||||
return Single.create<List<PodcastSearchResult?>?> { subscriber: SingleEmitter<List<PodcastSearchResult?>?> ->
|
||||
val encodedQuery = try {
|
||||
URLEncoder.encode(query, "UTF-8")
|
||||
|
@ -58,7 +58,7 @@ class ItunesPodcastSearcher : PodcastSearcher {
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
override fun lookupUrl(url: String): Single<String>? {
|
||||
override fun lookupUrl(url: String): Single<String> {
|
||||
val pattern = Pattern.compile(PATTERN_BY_ID)
|
||||
val matcher = pattern.matcher(url)
|
||||
val lookupUrl = if (matcher.find()) ("https://itunes.apple.com/lookup?id=" + matcher.group(1)) else url
|
||||
|
|
|
@ -18,7 +18,7 @@ class ItunesTopListLoader(private val context: Context) {
|
|||
@Throws(JSONException::class, IOException::class)
|
||||
fun loadToplist(country: String, limit: Int, subscribed: List<Feed>): List<PodcastSearchResult> {
|
||||
val client = getHttpClient()
|
||||
var feedString: String
|
||||
val feedString: String
|
||||
var loadCountry = country
|
||||
if (COUNTRY_CODE_UNSET == country) {
|
||||
loadCountry = Locale.getDefault().country
|
||||
|
|
|
@ -17,9 +17,9 @@ import java.security.MessageDigest
|
|||
import java.util.*
|
||||
|
||||
class PodcastIndexPodcastSearcher : PodcastSearcher {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?>? {
|
||||
override fun search(query: String): Single<List<PodcastSearchResult?>?> {
|
||||
return Single.create { subscriber: SingleEmitter<List<PodcastSearchResult?>?> ->
|
||||
var encodedQuery = try {
|
||||
val encodedQuery = try {
|
||||
URLEncoder.encode(query, "UTF-8")
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
// this won't ever be thrown
|
||||
|
@ -57,7 +57,7 @@ class PodcastIndexPodcastSearcher : PodcastSearcher {
|
|||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
override fun lookupUrl(url: String): Single<String>? {
|
||||
override fun lookupUrl(url: String): Single<String> {
|
||||
return Single.just(url)
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ class PodcastSearchResult private constructor(
|
|||
*/
|
||||
fun fromItunes(json: JSONObject): PodcastSearchResult {
|
||||
val title = json.optString("collectionName", "")
|
||||
val imageUrl = json.optString("artworkUrl100", null)
|
||||
val feedUrl = json.optString("feedUrl", null)
|
||||
val author = json.optString("artistName", null)
|
||||
val imageUrl: String? = json.optString("artworkUrl100").takeIf { it.isNotEmpty() }
|
||||
val feedUrl: String? = json.optString("feedUrl").takeIf { it.isNotEmpty() }
|
||||
val author: String? = json.optString("artistName").takeIf { it.isNotEmpty() }
|
||||
return PodcastSearchResult(title, imageUrl, feedUrl, author)
|
||||
}
|
||||
|
||||
|
@ -90,9 +90,9 @@ class PodcastSearchResult private constructor(
|
|||
|
||||
fun fromPodcastIndex(json: JSONObject): PodcastSearchResult {
|
||||
val title = json.optString("title", "")
|
||||
val imageUrl = json.optString("image", null)
|
||||
val feedUrl = json.optString("url", null)
|
||||
val author = json.optString("author", null)
|
||||
val imageUrl: String? = json.optString("image").takeIf { it.isNotEmpty() }
|
||||
val feedUrl: String? = json.optString("url").takeIf { it.isNotEmpty() }
|
||||
val author: String? = json.optString("author").takeIf { it.isNotEmpty() }
|
||||
return PodcastSearchResult(title, imageUrl, feedUrl, author)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ package ac.mdiq.podcini.net.discovery
|
|||
import io.reactivex.Single
|
||||
|
||||
interface PodcastSearcher {
|
||||
fun search(query: String): Single<List<PodcastSearchResult?>?>?
|
||||
fun search(query: String): Single<List<PodcastSearchResult?>?>
|
||||
|
||||
fun lookupUrl(resultUrl: String): Single<String>?
|
||||
fun lookupUrl(resultUrl: String): Single<String>
|
||||
|
||||
fun urlNeedsLookup(resultUrl: String): Boolean
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ object PodcastSearcherRegistry {
|
|||
}
|
||||
private set
|
||||
|
||||
fun lookupUrl(url: String): Single<String>? {
|
||||
fun lookupUrl(url: String): Single<String> {
|
||||
for (searchProviderInfo in searchProviders) {
|
||||
if (searchProviderInfo.searcher.javaClass != CombinedSearcher::class.java
|
||||
&& searchProviderInfo.searcher.urlNeedsLookup(url)) {
|
||||
|
|
|
@ -15,7 +15,7 @@ import javax.net.ssl.TrustManager
|
|||
* This fixes issues with old Android versions that abort if the server does not know TLS 1.0
|
||||
*/
|
||||
class PodciniSslSocketFactory(trustManager: TrustManager) : SSLSocketFactory() {
|
||||
private var factory: SSLSocketFactory? = null
|
||||
private lateinit var factory: SSLSocketFactory
|
||||
|
||||
init {
|
||||
try {
|
||||
|
@ -37,51 +37,51 @@ class PodciniSslSocketFactory(trustManager: TrustManager) : SSLSocketFactory() {
|
|||
}
|
||||
|
||||
override fun getDefaultCipherSuites(): Array<String> {
|
||||
return factory!!.defaultCipherSuites
|
||||
return factory.defaultCipherSuites
|
||||
}
|
||||
|
||||
override fun getSupportedCipherSuites(): Array<String> {
|
||||
return factory!!.supportedCipherSuites
|
||||
return factory.supportedCipherSuites
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(): Socket {
|
||||
val result = factory!!.createSocket() as SSLSocket
|
||||
val result = factory.createSocket() as SSLSocket
|
||||
configureSocket(result)
|
||||
return result
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(var1: String, var2: Int): Socket {
|
||||
val result = factory!!.createSocket(var1, var2) as SSLSocket
|
||||
val result = factory.createSocket(var1, var2) as SSLSocket
|
||||
configureSocket(result)
|
||||
return result
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(var1: Socket, var2: String, var3: Int, var4: Boolean): Socket {
|
||||
val result = factory!!.createSocket(var1, var2, var3, var4) as SSLSocket
|
||||
val result = factory.createSocket(var1, var2, var3, var4) as SSLSocket
|
||||
configureSocket(result)
|
||||
return result
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(var1: InetAddress, var2: Int): Socket {
|
||||
val result = factory!!.createSocket(var1, var2) as SSLSocket
|
||||
val result = factory.createSocket(var1, var2) as SSLSocket
|
||||
configureSocket(result)
|
||||
return result
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(var1: String, var2: Int, var3: InetAddress, var4: Int): Socket {
|
||||
val result = factory!!.createSocket(var1, var2, var3, var4) as SSLSocket
|
||||
val result = factory.createSocket(var1, var2, var3, var4) as SSLSocket
|
||||
configureSocket(result)
|
||||
return result
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(var1: InetAddress, var2: Int, var3: InetAddress, var4: Int): Socket {
|
||||
val result = factory!!.createSocket(var1, var2, var3, var4) as SSLSocket
|
||||
val result = factory.createSocket(var1, var2, var3, var4) as SSLSocket
|
||||
configureSocket(result)
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class CompositeX509TrustManager(private val trustManagers: List<X509TrustManager
|
|||
override fun getAcceptedIssuers(): Array<X509Certificate> {
|
||||
val certificates: MutableList<X509Certificate> = ArrayList()
|
||||
for (trustManager in trustManagers) {
|
||||
certificates.addAll(Arrays.asList(*trustManager.acceptedIssuers))
|
||||
certificates.addAll(listOf(*trustManager.acceptedIssuers))
|
||||
}
|
||||
return certificates.toTypedArray<X509Certificate>()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package ac.mdiq.podcini.net.ssl
|
|||
import ac.mdiq.podcini.net.ssl.BackportTrustManager.create
|
||||
import okhttp3.ConnectionSpec
|
||||
import okhttp3.OkHttpClient.Builder
|
||||
import java.util.*
|
||||
|
||||
object SslClientSetup {
|
||||
fun installCertificates(builder: Builder) {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package ac.mdiq.podcini.net.sync.model
|
||||
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import ac.mdiq.podcini.model.feed.FeedItem
|
||||
import android.util.Log
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.text.ParseException
|
||||
|
@ -87,7 +86,7 @@ class EpisodeAction private constructor(builder: Builder) {
|
|||
obj.put("action", this.actionString)
|
||||
val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US)
|
||||
formatter.timeZone = TimeZone.getTimeZone("UTC")
|
||||
obj.put("timestamp", formatter.format(this.timestamp))
|
||||
if (this.timestamp != null) obj.put("timestamp", formatter.format(this.timestamp))
|
||||
if (this.action == Action.PLAY) {
|
||||
obj.put("started", this.started)
|
||||
obj.put("position", this.position)
|
||||
|
@ -190,10 +189,10 @@ class EpisodeAction private constructor(builder: Builder) {
|
|||
*/
|
||||
@JvmStatic
|
||||
fun readFromJsonObject(`object`: JSONObject): EpisodeAction? {
|
||||
val podcast = `object`.optString("podcast", null)
|
||||
val episode = `object`.optString("episode", null)
|
||||
val actionString = `object`.optString("action", null)
|
||||
if (TextUtils.isEmpty(podcast) || TextUtils.isEmpty(episode) || TextUtils.isEmpty(actionString)) {
|
||||
val podcast = `object`.optString("podcast")
|
||||
val episode = `object`.optString("episode")
|
||||
val actionString = `object`.optString("action")
|
||||
if (podcast.isNullOrEmpty() || episode.isNullOrEmpty() || actionString.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
val action: Action
|
||||
|
@ -203,8 +202,8 @@ class EpisodeAction private constructor(builder: Builder) {
|
|||
return null
|
||||
}
|
||||
val builder = Builder(podcast, episode, action)
|
||||
val utcTimestamp = `object`.optString("timestamp", null)
|
||||
if (!TextUtils.isEmpty(utcTimestamp)) {
|
||||
val utcTimestamp = `object`.optString("timestamp")
|
||||
if (utcTimestamp.isNotEmpty()) {
|
||||
try {
|
||||
val parser = SimpleDateFormat(PATTERN_ISO_DATEFORMAT, Locale.US)
|
||||
parser.timeZone = TimeZone.getTimeZone("UTC")
|
||||
|
@ -213,8 +212,8 @@ class EpisodeAction private constructor(builder: Builder) {
|
|||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
val guid = `object`.optString("guid", null)
|
||||
if (!TextUtils.isEmpty(guid)) {
|
||||
val guid = `object`.optString("guid")
|
||||
if (guid.isNotEmpty()) {
|
||||
builder.guid(guid)
|
||||
}
|
||||
if (action == Action.PLAY) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package ac.mdiq.podcini.parser.feed
|
||||
|
||||
import android.util.Log
|
||||
import ac.mdiq.podcini.model.feed.Feed
|
||||
import ac.mdiq.podcini.parser.feed.UnsupportedFeedtypeException
|
||||
import ac.mdiq.podcini.parser.feed.util.TypeGetter
|
||||
import android.util.Log
|
||||
import org.apache.commons.io.input.XmlStreamReader
|
||||
import org.xml.sax.InputSource
|
||||
import org.xml.sax.SAXException
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.json.JSONException
|
|||
import org.json.JSONObject
|
||||
|
||||
object PodcastIndexChapterParser {
|
||||
fun parse(jsonStr: String?): List<Chapter>? {
|
||||
fun parse(jsonStr: String): List<Chapter> {
|
||||
try {
|
||||
val chapters: MutableList<Chapter> = ArrayList()
|
||||
val obj = JSONObject(jsonStr)
|
||||
|
@ -13,15 +13,15 @@ object PodcastIndexChapterParser {
|
|||
for (i in 0 until objChapters.length()) {
|
||||
val jsonObject = objChapters.getJSONObject(i)
|
||||
val startTime = jsonObject.optInt("startTime", 0)
|
||||
val title = jsonObject.optString("title")
|
||||
val link = jsonObject.optString("url")
|
||||
val img = jsonObject.optString("img")
|
||||
val title = jsonObject.optString("title").takeIf { it.isNotEmpty() }
|
||||
val link = jsonObject.optString("url").takeIf { it.isNotEmpty() }
|
||||
val img = jsonObject.optString("img").takeIf { it.isNotEmpty() }
|
||||
chapters.add(Chapter(startTime * 1000L, title, link, img))
|
||||
}
|
||||
return chapters
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return null
|
||||
return listOf()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,20 +4,25 @@ import androidx.core.text.HtmlCompat
|
|||
import ac.mdiq.podcini.parser.feed.namespace.Namespace
|
||||
|
||||
/** Represents Atom Element which contains text (content, title, summary). */
|
||||
class AtomText(name: String?, namespace: Namespace?, private val type: String?) : SyndElement(
|
||||
name!!, namespace!!) {
|
||||
class AtomText(name: String?, namespace: Namespace?, private val type: String?) : SyndElement(name!!, namespace!!) {
|
||||
|
||||
private var content: String? = null
|
||||
|
||||
val processedContent: String?
|
||||
/** Processes the content according to the type and returns it. */
|
||||
get() = if (type == null) {
|
||||
content
|
||||
} else if (type == TYPE_HTML) {
|
||||
HtmlCompat.fromHtml(content!!, HtmlCompat.FROM_HTML_MODE_LEGACY).toString()
|
||||
} else if (type == TYPE_XHTML) {
|
||||
content
|
||||
} else { // Handle as text by default
|
||||
content
|
||||
get() = when (type) {
|
||||
null -> {
|
||||
content
|
||||
}
|
||||
TYPE_HTML -> {
|
||||
HtmlCompat.fromHtml(content!!, HtmlCompat.FROM_HTML_MODE_LEGACY).toString()
|
||||
}
|
||||
TYPE_XHTML -> {
|
||||
content
|
||||
}
|
||||
else -> { // Handle as text by default
|
||||
content
|
||||
}
|
||||
}
|
||||
|
||||
fun setContent(content: String?) {
|
||||
|
|
|
@ -205,7 +205,7 @@ class Atom : Namespace() {
|
|||
/**
|
||||
* Regexp to test whether an Element is a Text Element.
|
||||
*/
|
||||
private const val isText = (TITLE + "|" + CONTENT + "|" + SUBTITLE + "|" + SUMMARY)
|
||||
private const val isText = ("$TITLE|$CONTENT|$SUBTITLE|$SUMMARY")
|
||||
|
||||
private const val isFeed = FEED + "|" + Rss20.CHANNEL
|
||||
private const val isFeedItem = ENTRY + "|" + Rss20.ITEM
|
||||
|
|
|
@ -8,14 +8,19 @@ object DurationParser {
|
|||
fun inMillis(durationStr: String): Long {
|
||||
val parts = durationStr.trim { it <= ' ' }.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
|
||||
return if (parts.size == 1) {
|
||||
toMillis(parts[0])
|
||||
} else if (parts.size == 2) {
|
||||
toMillis("0", parts[0], parts[1])
|
||||
} else if (parts.size == 3) {
|
||||
toMillis(parts[0], parts[1], parts[2])
|
||||
} else {
|
||||
throw NumberFormatException()
|
||||
return when (parts.size) {
|
||||
1 -> {
|
||||
toMillis(parts[0])
|
||||
}
|
||||
2 -> {
|
||||
toMillis("0", parts[0], parts[1])
|
||||
}
|
||||
3 -> {
|
||||
toMillis(parts[0], parts[1], parts[2])
|
||||
}
|
||||
else -> {
|
||||
throw NumberFormatException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ class TypeGetter {
|
|||
try {
|
||||
reader.close()
|
||||
} catch (e: IOException) {
|
||||
Log.d(TAG, "IOException: " + reader.toString())
|
||||
Log.d(TAG, "IOException: $reader")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
@ -111,9 +111,11 @@ class TypeGetter {
|
|||
}
|
||||
|
||||
private fun createReader(feed: Feed): Reader? {
|
||||
if (feed.file_url == null) return null
|
||||
|
||||
val reader: Reader
|
||||
try {
|
||||
reader = XmlStreamReader(File(feed.file_url))
|
||||
reader = XmlStreamReader(File(feed.file_url!!))
|
||||
} catch (e: FileNotFoundException) {
|
||||
Log.d(TAG, "FileNotFoundException: " + feed.file_url)
|
||||
e.printStackTrace()
|
||||
|
|
|
@ -147,12 +147,16 @@ open class ID3Reader(private val inputStream: CountingInputStream) {
|
|||
|
||||
@Throws(IOException::class)
|
||||
fun readEncodedString(encoding: Int, max: Int): String {
|
||||
return if (encoding == ENCODING_UTF16_WITH_BOM.toInt() || encoding == ENCODING_UTF16_WITHOUT_BOM.toInt()) {
|
||||
readEncodedString2(Charset.forName("UTF-16"), max)
|
||||
} else if (encoding == ENCODING_UTF8.toInt()) {
|
||||
readEncodedString2(Charset.forName("UTF-8"), max)
|
||||
} else {
|
||||
readEncodedString1(Charset.forName("ISO-8859-1"), max)
|
||||
return when (encoding) {
|
||||
ENCODING_UTF16_WITH_BOM.toInt(), ENCODING_UTF16_WITHOUT_BOM.toInt() -> {
|
||||
readEncodedString2(Charset.forName("UTF-16"), max)
|
||||
}
|
||||
ENCODING_UTF8.toInt() -> {
|
||||
readEncodedString2(Charset.forName("UTF-8"), max)
|
||||
}
|
||||
else -> {
|
||||
readEncodedString1(Charset.forName("ISO-8859-1"), max)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
package ac.mdiq.podcini.parser.media.id3.model
|
||||
|
||||
class FrameHeader(id: String?, size: Int, flags: Short) : Header(
|
||||
id!!, size)
|
||||
class FrameHeader(id: String?, size: Int, flags: Short) : Header(id!!, size)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package ac.mdiq.podcini.parser.media.id3.model
|
||||
|
||||
class TagHeader(id: String?, size: Int, @JvmField val version: Short, private val flags: Byte) : Header(
|
||||
id!!, size) {
|
||||
class TagHeader(id: String?, size: Int, @JvmField val version: Short, private val flags: Byte) : Header(id!!, size) {
|
||||
override fun toString(): String {
|
||||
return ("TagHeader [version=" + version + ", flags=" + flags + ", id="
|
||||
+ id + ", size=" + size + "]")
|
||||
return ("TagHeader [version=" + version + ", flags=" + flags + ", id=" + id + ", size=" + size + "]")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package ac.mdiq.podcini.parser.media.vorbis
|
||||
|
||||
import android.util.Log
|
||||
import ac.mdiq.podcini.model.feed.Chapter
|
||||
import ac.mdiq.podcini.parser.media.BuildConfig
|
||||
import ac.mdiq.podcini.parser.media.vorbis.VorbisCommentReaderException
|
||||
import android.util.Log
|
||||
import java.io.InputStream
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
@ -22,24 +21,24 @@ class VorbisCommentChapterReader(input: InputStream?) : VorbisCommentReader(inpu
|
|||
val attribute = getAttributeTypeFromKey(key)
|
||||
val id = getIdFromKey(key)
|
||||
var chapter = getChapterById(id.toLong())
|
||||
if (attribute == null) {
|
||||
if (getChapterById(id.toLong()) == null) {
|
||||
// new chapter
|
||||
val start = getStartTimeFromValue(value)
|
||||
chapter = Chapter()
|
||||
chapter.chapterId = "" + id
|
||||
chapter.start = start
|
||||
chapters.add(chapter)
|
||||
} else {
|
||||
throw VorbisCommentReaderException("Found chapter with duplicate ID ($key, $value)")
|
||||
when (attribute) {
|
||||
null -> {
|
||||
if (getChapterById(id.toLong()) == null) {
|
||||
// new chapter
|
||||
val start = getStartTimeFromValue(value)
|
||||
chapter = Chapter()
|
||||
chapter.chapterId = "" + id
|
||||
chapter.start = start
|
||||
chapters.add(chapter)
|
||||
} else {
|
||||
throw VorbisCommentReaderException("Found chapter with duplicate ID ($key, $value)")
|
||||
}
|
||||
}
|
||||
} else if (attribute == CHAPTER_ATTRIBUTE_TITLE) {
|
||||
if (chapter != null) {
|
||||
chapter.title = value
|
||||
CHAPTER_ATTRIBUTE_TITLE -> {
|
||||
if (chapter != null) chapter.title = value
|
||||
}
|
||||
} else if (attribute == CHAPTER_ATTRIBUTE_LINK) {
|
||||
if (chapter != null) {
|
||||
chapter.link = value
|
||||
CHAPTER_ATTRIBUTE_LINK -> {
|
||||
if (chapter != null) chapter.link = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package ac.mdiq.podcini.parser.media.vorbis
|
|||
|
||||
internal class VorbisCommentHeader(val vendorString: String, val userCommentLength: Long) {
|
||||
override fun toString(): String {
|
||||
return ("VorbisCommentHeader [vendorString=" + vendorString
|
||||
+ ", userCommentLength=" + userCommentLength + "]")
|
||||
return ("VorbisCommentHeader [vendorString=" + vendorString + ", userCommentLength=" + userCommentLength + "]")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class VorbisCommentMetadataReader(input: InputStream?) : VorbisCommentReader(inp
|
|||
|
||||
public override fun onContentVectorValue(key: String?, value: String?) {
|
||||
if (KEY_DESCRIPTION == key || KEY_COMMENT == key) {
|
||||
if (description == null || value!!.length > description!!.length) {
|
||||
if (description == null || (value != null && value.length > description!!.length)) {
|
||||
description = value
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package ac.mdiq.podcini.parser.media.vorbis
|
||||
|
||||
import android.util.Log
|
||||
import ac.mdiq.podcini.parser.media.vorbis.VorbisCommentReaderException
|
||||
import org.apache.commons.io.EndianUtils
|
||||
import org.apache.commons.io.IOUtils
|
||||
import java.io.IOException
|
||||
|
@ -136,7 +135,7 @@ abstract class VorbisCommentReader internal constructor(private val input: Input
|
|||
while (posInHaystack < 0) {
|
||||
posInHaystack += haystack.size
|
||||
}
|
||||
posInHaystack = posInHaystack % haystack.size
|
||||
posInHaystack %= haystack.size
|
||||
if (haystack[posInHaystack] != needle[needle.size - 1 - i]) {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -217,8 +217,8 @@ class PodDBAdapter private constructor() {
|
|||
db.beginTransactionNonExclusive()
|
||||
for (feed in feeds) {
|
||||
setFeed(feed)
|
||||
if (feed.items != null) {
|
||||
for (item in feed.items!!) {
|
||||
if (feed.items.isNotEmpty()) {
|
||||
for (item in feed.items) {
|
||||
updateOrInsertFeedItem(item, false)
|
||||
}
|
||||
}
|
||||
|
@ -546,8 +546,8 @@ class PodDBAdapter private constructor() {
|
|||
fun removeFeed(feed: Feed) {
|
||||
try {
|
||||
db.beginTransactionNonExclusive()
|
||||
if (feed.items != null) {
|
||||
removeFeedItems(feed.items!!)
|
||||
if (feed.items.isNotEmpty()) {
|
||||
removeFeedItems(feed.items)
|
||||
}
|
||||
// delete download log entries for feed
|
||||
db.delete(TABLE_NAME_DOWNLOAD_LOG, "$KEY_FEEDFILE=? AND $KEY_FEEDFILETYPE=?",
|
||||
|
@ -1427,11 +1427,11 @@ class PodDBAdapter private constructor() {
|
|||
|
||||
@JvmStatic
|
||||
@Synchronized
|
||||
fun getInstance(): PodDBAdapter? {
|
||||
fun getInstance(): PodDBAdapter {
|
||||
if (instance == null) {
|
||||
instance = PodDBAdapter()
|
||||
}
|
||||
return instance
|
||||
return instance!!
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1449,14 +1449,14 @@ class PodDBAdapter private constructor() {
|
|||
@JvmStatic
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
fun tearDownTests() {
|
||||
getInstance()!!.dbHelper.close()
|
||||
getInstance().dbHelper.close()
|
||||
instance = null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteDatabase(): Boolean {
|
||||
val adapter = getInstance()
|
||||
adapter!!.open()
|
||||
adapter.open()
|
||||
try {
|
||||
for (tableName in ALL_TABLES) {
|
||||
adapter.db.delete(tableName, "1", null)
|
||||
|
|
|
@ -172,7 +172,7 @@ object UserPreferences {
|
|||
var hiddenDrawerItems: List<String?>?
|
||||
get() {
|
||||
val hiddenItems = prefs!!.getString(PREF_HIDDEN_DRAWER_ITEMS, "")
|
||||
return ArrayList(Arrays.asList(*TextUtils.split(hiddenItems, ",")))
|
||||
return ArrayList(listOf(*TextUtils.split(hiddenItems, ",")))
|
||||
}
|
||||
set(items) {
|
||||
val str = TextUtils.join(",", items!!)
|
||||
|
@ -186,7 +186,7 @@ object UserPreferences {
|
|||
get() {
|
||||
val buttons = TextUtils.split(
|
||||
prefs!!.getString(PREF_FULL_NOTIFICATION_BUTTONS,
|
||||
NOTIFICATION_BUTTON_SKIP.toString() + "," + NOTIFICATION_BUTTON_PLAYBACK_SPEED), ",")
|
||||
"$NOTIFICATION_BUTTON_SKIP,$NOTIFICATION_BUTTON_PLAYBACK_SPEED"), ",")
|
||||
|
||||
val notificationButtons: MutableList<Int> = ArrayList()
|
||||
for (button in buttons) {
|
||||
|
|
Loading…
Reference in New Issue