4.3.4 commit
This commit is contained in:
parent
c5bf432283
commit
cc4cdb281a
|
@ -149,8 +149,8 @@ android {
|
|||
// Version code schema (not used):
|
||||
// "1.2.3-beta4" -> 1020304
|
||||
// "1.2.3" -> 1020395
|
||||
versionCode 3020114
|
||||
versionName "4.3.3"
|
||||
versionCode 3020115
|
||||
versionName "4.3.4"
|
||||
|
||||
def commit = ""
|
||||
try {
|
||||
|
|
|
@ -62,12 +62,12 @@ class HttpDownloaderTest {
|
|||
|
||||
private fun download(url: String?, title: String, expectedResult: Boolean, deleteExisting: Boolean = true,
|
||||
username: String? = null, password: String? = null
|
||||
): ac.mdiq.podcini.service.download.Downloader {
|
||||
): Downloader {
|
||||
val feedFile: FeedFile = setupFeedFile(url, title, deleteExisting)
|
||||
val request = DownloadRequest(
|
||||
feedFile.getFile_url()!!, url!!, title, 0, feedFile.getTypeAsInt(),
|
||||
username, password, null, false)
|
||||
val downloader: ac.mdiq.podcini.service.download.Downloader = HttpDownloader(request)
|
||||
val downloader: Downloader = HttpDownloader(request)
|
||||
downloader.call()
|
||||
val status = downloader.result
|
||||
Assert.assertNotNull(status)
|
||||
|
@ -101,7 +101,7 @@ class HttpDownloaderTest {
|
|||
fun testCancel() {
|
||||
val url = httpServer!!.baseUrl + "/delay/3"
|
||||
val feedFile = setupFeedFile(url, "delay", true)
|
||||
val downloader: ac.mdiq.podcini.service.download.Downloader = HttpDownloader(DownloadRequest(
|
||||
val downloader: Downloader = HttpDownloader(DownloadRequest(
|
||||
feedFile.getFile_url()!!, url, "delay", 0,
|
||||
feedFile.getTypeAsInt(), null, null, null, false))
|
||||
val t: Thread = object : Thread() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ac.mdiq.podcini.feed.parser.namespace
|
||||
|
||||
import ac.mdiq.podcini.feed.parser.HandlerState
|
||||
import android.util.Log
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedFunding
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedItem
|
||||
|
@ -13,7 +14,7 @@ import ac.mdiq.podcini.feed.parser.util.SyndStringUtils.trimAllWhitespace
|
|||
import org.xml.sax.Attributes
|
||||
|
||||
class Atom : Namespace() {
|
||||
override fun handleElementStart(localName: String, state: ac.mdiq.podcini.feed.parser.HandlerState, attributes: Attributes): SyndElement {
|
||||
override fun handleElementStart(localName: String, state: HandlerState, attributes: Attributes): SyndElement {
|
||||
if (ENTRY == localName) {
|
||||
state.currentItem = FeedItem()
|
||||
state.items.add(state.currentItem!!)
|
||||
|
@ -88,7 +89,7 @@ class Atom : Namespace() {
|
|||
return SyndElement(localName, this)
|
||||
}
|
||||
|
||||
override fun handleElementEnd(localName: String, state: ac.mdiq.podcini.feed.parser.HandlerState) {
|
||||
override fun handleElementEnd(localName: String, state: HandlerState) {
|
||||
if (ENTRY == localName) {
|
||||
if (state.currentItem != null &&
|
||||
state.tempObjects.containsKey(Itunes.DURATION)) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ac.mdiq.podcini.feed.parser.namespace
|
||||
|
||||
import ac.mdiq.podcini.feed.parser.HandlerState
|
||||
import android.util.Log
|
||||
import androidx.core.text.HtmlCompat
|
||||
import ac.mdiq.podcini.feed.parser.element.SyndElement
|
||||
|
@ -7,7 +8,7 @@ import ac.mdiq.podcini.feed.parser.util.DurationParser.inMillis
|
|||
import org.xml.sax.Attributes
|
||||
|
||||
class Itunes : Namespace() {
|
||||
override fun handleElementStart(localName: String, state: ac.mdiq.podcini.feed.parser.HandlerState,
|
||||
override fun handleElementStart(localName: String, state: HandlerState,
|
||||
attributes: Attributes): SyndElement {
|
||||
if (IMAGE == localName) {
|
||||
val url: String? = attributes.getValue(IMAGE_HREF)
|
||||
|
@ -25,7 +26,7 @@ class Itunes : Namespace() {
|
|||
return SyndElement(localName, this)
|
||||
}
|
||||
|
||||
override fun handleElementEnd(localName: String, state: ac.mdiq.podcini.feed.parser.HandlerState) {
|
||||
override fun handleElementEnd(localName: String, state: HandlerState) {
|
||||
if (state.contentBuf == null) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ac.mdiq.podcini.feed.parser.namespace
|
||||
|
||||
import ac.mdiq.podcini.feed.parser.HandlerState
|
||||
import android.util.Log
|
||||
import ac.mdiq.podcini.storage.model.feed.Chapter
|
||||
import ac.mdiq.podcini.feed.parser.element.SyndElement
|
||||
|
@ -7,7 +8,7 @@ import ac.mdiq.podcini.feed.parser.util.DateUtils.parseTimeString
|
|||
import org.xml.sax.Attributes
|
||||
|
||||
class SimpleChapters : Namespace() {
|
||||
override fun handleElementStart(localName: String, state: ac.mdiq.podcini.feed.parser.HandlerState, attributes: Attributes): SyndElement {
|
||||
override fun handleElementStart(localName: String, state: HandlerState, attributes: Attributes): SyndElement {
|
||||
val currentItem = state.currentItem
|
||||
if (currentItem != null) {
|
||||
if (localName == CHAPTERS) {
|
||||
|
@ -29,7 +30,7 @@ class SimpleChapters : Namespace() {
|
|||
return SyndElement(localName, this)
|
||||
}
|
||||
|
||||
override fun handleElementEnd(localName: String, state: ac.mdiq.podcini.feed.parser.HandlerState) {
|
||||
override fun handleElementEnd(localName: String, state: HandlerState) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -267,17 +267,20 @@ abstract class PlaybackController(private val activity: FragmentActivity) {
|
|||
fun playPause() {
|
||||
if (media == null) return
|
||||
if (playbackService == null) {
|
||||
PlaybackServiceStarter(activity, media!!).start()
|
||||
// PlaybackServiceStarter(activity, media!!).start()
|
||||
PlaybackServiceStarter(activity, media!!)
|
||||
.callEvenIfRunning(true)
|
||||
.start()
|
||||
Log.w(TAG, "Play/Pause button was pressed, but playbackservice was null!")
|
||||
return
|
||||
// return
|
||||
}
|
||||
when (status) {
|
||||
PlayerStatus.PLAYING -> playbackService!!.pause(true, false)
|
||||
PlayerStatus.PAUSED, PlayerStatus.PREPARED -> playbackService!!.resume()
|
||||
PlayerStatus.PLAYING -> playbackService?.pause(true, false)
|
||||
PlayerStatus.PAUSED, PlayerStatus.PREPARED -> playbackService?.resume()
|
||||
PlayerStatus.PREPARING -> playbackService!!.isStartWhenPrepared = !playbackService!!.isStartWhenPrepared
|
||||
PlayerStatus.INITIALIZED -> {
|
||||
playbackService!!.isStartWhenPrepared = true
|
||||
playbackService!!.prepare()
|
||||
if (playbackService != null) playbackService!!.isStartWhenPrepared = true
|
||||
playbackService?.prepare()
|
||||
}
|
||||
else -> {
|
||||
PlaybackServiceStarter(activity, media!!)
|
||||
|
|
|
@ -1,29 +1,28 @@
|
|||
package ac.mdiq.podcini.preferences
|
||||
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.databinding.ThemePreferenceBinding
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceViewHolder
|
||||
import com.google.android.material.elevation.SurfaceColors
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.databinding.ThemePreferenceBinding
|
||||
|
||||
class ThemePreference : Preference {
|
||||
var viewBinding: ThemePreferenceBinding? = null
|
||||
var binding: ThemePreferenceBinding? = null
|
||||
|
||||
constructor(context: Context) : super(context!!) {
|
||||
constructor(context: Context) : super(context) {
|
||||
layoutResource = R.layout.theme_preference
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context!!, attrs) {
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
layoutResource = R.layout.theme_preference
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: PreferenceViewHolder) {
|
||||
super.onBindViewHolder(holder)
|
||||
viewBinding = ThemePreferenceBinding.bind(holder.itemView)
|
||||
binding = ThemePreferenceBinding.bind(holder.itemView)
|
||||
updateUi()
|
||||
}
|
||||
|
||||
|
@ -33,7 +32,7 @@ class ThemePreference : Preference {
|
|||
val surfaceColorActive = SurfaceColors.getColorForElevation(context, 32 * density)
|
||||
val activeTheme = UserPreferences.theme
|
||||
card.setCardBackgroundColor(if (theme == activeTheme) surfaceColorActive else surfaceColor)
|
||||
card.setOnClickListener { v: View? ->
|
||||
card.setOnClickListener {
|
||||
UserPreferences.theme = theme
|
||||
if (onPreferenceChangeListener != null) {
|
||||
onPreferenceChangeListener!!.onPreferenceChange(this, UserPreferences.theme)
|
||||
|
@ -43,8 +42,8 @@ class ThemePreference : Preference {
|
|||
}
|
||||
|
||||
fun updateUi() {
|
||||
updateThemeCard(viewBinding!!.themeSystemCard, UserPreferences.ThemePreference.SYSTEM)
|
||||
updateThemeCard(viewBinding!!.themeLightCard, UserPreferences.ThemePreference.LIGHT)
|
||||
updateThemeCard(viewBinding!!.themeDarkCard, UserPreferences.ThemePreference.DARK)
|
||||
updateThemeCard(binding!!.themeSystemCard, UserPreferences.ThemePreference.SYSTEM)
|
||||
updateThemeCard(binding!!.themeLightCard, UserPreferences.ThemePreference.LIGHT)
|
||||
updateThemeCard(binding!!.themeDarkCard, UserPreferences.ThemePreference.DARK)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ac.mdiq.podcini.service.download.handler
|
||||
|
||||
import ac.mdiq.podcini.feed.parser.FeedHandlerResult
|
||||
import android.util.Log
|
||||
import ac.mdiq.podcini.util.InvalidFeedException
|
||||
import ac.mdiq.podcini.storage.model.download.DownloadError
|
||||
|
@ -16,7 +17,7 @@ import java.util.*
|
|||
import java.util.concurrent.Callable
|
||||
import javax.xml.parsers.ParserConfigurationException
|
||||
|
||||
class FeedParserTask(private val request: DownloadRequest) : Callable<ac.mdiq.podcini.feed.parser.FeedHandlerResult?> {
|
||||
class FeedParserTask(private val request: DownloadRequest) : Callable<FeedHandlerResult?> {
|
||||
var downloadStatus: DownloadResult
|
||||
private set
|
||||
var isSuccessful: Boolean = true
|
||||
|
@ -29,7 +30,7 @@ class FeedParserTask(private val request: DownloadRequest) : Callable<ac.mdiq.po
|
|||
"Unknown error: Status not set")
|
||||
}
|
||||
|
||||
override fun call(): ac.mdiq.podcini.feed.parser.FeedHandlerResult? {
|
||||
override fun call(): FeedHandlerResult? {
|
||||
val feed = Feed(request.source, request.lastModified)
|
||||
feed.file_url = request.destination
|
||||
feed.id = request.feedfileId
|
||||
|
@ -42,7 +43,7 @@ class FeedParserTask(private val request: DownloadRequest) : Callable<ac.mdiq.po
|
|||
var reasonDetailed: String? = null
|
||||
val feedHandler = ac.mdiq.podcini.feed.parser.FeedHandler()
|
||||
|
||||
var result: ac.mdiq.podcini.feed.parser.FeedHandlerResult? = null
|
||||
var result: FeedHandlerResult? = null
|
||||
try {
|
||||
result = feedHandler.parseFeed(feed)
|
||||
Log.d(TAG, feed.title + " parsed")
|
||||
|
|
|
@ -25,6 +25,7 @@ import ac.mdiq.podcini.playback.base.PlaybackServiceMediaPlayer
|
|||
import ac.mdiq.podcini.playback.base.PlayerStatus
|
||||
import ac.mdiq.podcini.playback.base.RewindAfterPauseUtils
|
||||
import ac.mdiq.podcini.preferences.UserPreferences
|
||||
import ac.mdiq.podcini.util.event.PlayerErrorEvent
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
@ -197,11 +198,11 @@ class LocalPSMP(context: Context, callback: PSMPCallback) : PlaybackServiceMedia
|
|||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
setPlayerStatus(PlayerStatus.ERROR, null)
|
||||
EventBus.getDefault().postSticky(ac.mdiq.podcini.util.event.PlayerErrorEvent(e.localizedMessage ?: ""))
|
||||
EventBus.getDefault().postSticky(PlayerErrorEvent(e.localizedMessage ?: ""))
|
||||
} catch (e: IllegalStateException) {
|
||||
e.printStackTrace()
|
||||
setPlayerStatus(PlayerStatus.ERROR, null)
|
||||
EventBus.getDefault().postSticky(ac.mdiq.podcini.util.event.PlayerErrorEvent(e.localizedMessage ?: ""))
|
||||
EventBus.getDefault().postSticky(PlayerErrorEvent(e.localizedMessage ?: ""))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -727,7 +728,7 @@ class LocalPSMP(context: Context, callback: PSMPCallback) : PlaybackServiceMedia
|
|||
}
|
||||
})
|
||||
mp.setOnErrorListener(Consumer { message: String ->
|
||||
EventBus.getDefault().postSticky(ac.mdiq.podcini.util.event.PlayerErrorEvent(message))
|
||||
EventBus.getDefault().postSticky(PlayerErrorEvent(message))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ import ac.mdiq.podcini.util.FeedUtil.shouldAutoDeleteItemsOnThatFeed
|
|||
import ac.mdiq.podcini.util.IntentUtils.sendLocalBroadcast
|
||||
import ac.mdiq.podcini.util.NetworkUtils.isStreamingAllowed
|
||||
import ac.mdiq.podcini.util.event.MessageEvent
|
||||
import ac.mdiq.podcini.util.event.PlayerErrorEvent
|
||||
import ac.mdiq.podcini.util.event.settings.SkipIntroEndingChangedEvent
|
||||
import ac.mdiq.podcini.util.event.settings.SpeedPresetChangedEvent
|
||||
import ac.mdiq.podcini.util.event.settings.VolumeAdaptionChangedEvent
|
||||
import android.Manifest
|
||||
|
@ -924,7 +926,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
|
|||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
@Suppress("unused")
|
||||
fun playerError(event: ac.mdiq.podcini.util.event.PlayerErrorEvent?) {
|
||||
fun playerError(event: PlayerErrorEvent?) {
|
||||
if (mediaPlayer?.playerStatus == PlayerStatus.PLAYING) {
|
||||
mediaPlayer!!.pause(true, false)
|
||||
}
|
||||
|
@ -1548,7 +1550,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
|
|||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
@Suppress("unused")
|
||||
fun skipIntroEndingPresetChanged(event: ac.mdiq.podcini.util.event.settings.SkipIntroEndingChangedEvent) {
|
||||
fun skipIntroEndingPresetChanged(event: SkipIntroEndingChangedEvent) {
|
||||
if (playable is FeedMedia) {
|
||||
if ((playable as FeedMedia).item?.feed?.id == event.feedId) {
|
||||
if (event.skipEnding != 0) {
|
||||
|
|
|
@ -310,7 +310,7 @@ object DBReader {
|
|||
*/
|
||||
@JvmStatic
|
||||
fun getEpisodes(offset: Int, limit: Int, filter: FeedItemFilter?, sortOrder: SortOrder?): List<FeedItem> {
|
||||
Log.d(TAG, "getRecentlyPublishedEpisodes() called with: offset=$offset, limit=$limit")
|
||||
Log.d(TAG, "getEpisodes called with: offset=$offset, limit=$limit")
|
||||
val adapter = getInstance()
|
||||
adapter.open()
|
||||
try {
|
||||
|
|
|
@ -8,6 +8,8 @@ object FeedItemSortQuery {
|
|||
fun generateFrom(sortOrder: SortOrder?): String {
|
||||
var sortQuery = ""
|
||||
sortQuery = when (sortOrder) {
|
||||
SortOrder.FEED_TITLE_A_Z -> PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + " " + "ASC"
|
||||
SortOrder.FEED_TITLE_Z_A -> PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + " " + "DESC"
|
||||
SortOrder.EPISODE_TITLE_A_Z -> PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_TITLE + " " + "ASC"
|
||||
SortOrder.EPISODE_TITLE_Z_A -> PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_TITLE + " " + "DESC"
|
||||
SortOrder.DATE_OLD_NEW -> PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_PUBDATE + " " + "ASC"
|
||||
|
|
|
@ -2,6 +2,7 @@ package ac.mdiq.podcini.storage.model.feed
|
|||
|
||||
import android.text.TextUtils
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedFunding.Companion.extractPaymentLinks
|
||||
import android.util.Log
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
@ -107,10 +108,15 @@ class Feed : FeedFile {
|
|||
*/
|
||||
var sortOrder: SortOrder? = null
|
||||
set(sortOrder) {
|
||||
require(!(sortOrder != null && sortOrder.scope != SortOrder.Scope.INTRA_FEED)) {
|
||||
("The specified sortOrder " + sortOrder
|
||||
if (!(sortOrder != null && sortOrder.scope != SortOrder.Scope.INTRA_FEED)) {
|
||||
Log.w("Feed sortOrder", "The specified sortOrder " + sortOrder
|
||||
+ " is invalid. Only those with INTRA_FEED scope are allowed.")
|
||||
}
|
||||
// This looks suicidal:
|
||||
// require(!(sortOrder != null && sortOrder.scope != SortOrder.Scope.INTRA_FEED)) {
|
||||
// ("The specified sortOrder " + sortOrder
|
||||
// + " is invalid. Only those with INTRA_FEED scope are allowed.")
|
||||
// }
|
||||
field = sortOrder
|
||||
}
|
||||
|
||||
|
|
|
@ -286,10 +286,6 @@ class MainActivity : CastEnabledActivity() {
|
|||
}
|
||||
override fun onSlide(view: View, slideOffset: Float) {
|
||||
val audioPlayer = supportFragmentManager.findFragmentByTag(AudioPlayerFragment.TAG) as? AudioPlayerFragment ?: return
|
||||
|
||||
// if (slideOffset == 0.0f) { //STATE_COLLAPSED
|
||||
// audioPlayer.scrollToPage(AudioPlayerFragment.FIRST_PAGE)
|
||||
// }
|
||||
audioPlayer.fadePlayerToToolbar(slideOffset)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import ac.mdiq.podcini.preferences.UserPreferences.setShowRemainTimeSetting
|
|||
import ac.mdiq.podcini.preferences.UserPreferences.shouldShowRemainingTime
|
||||
import ac.mdiq.podcini.ui.appstartintent.MainActivityStarter
|
||||
import ac.mdiq.podcini.util.event.MessageEvent
|
||||
import ac.mdiq.podcini.util.event.PlayerErrorEvent
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.PixelFormat
|
||||
|
@ -489,7 +490,7 @@ class VideoplayerActivity : CastEnabledActivity(), OnSeekBarChangeListener {
|
|||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onMediaPlayerError(event: ac.mdiq.podcini.util.event.PlayerErrorEvent) {
|
||||
fun onMediaPlayerError(event: PlayerErrorEvent) {
|
||||
MediaPlayerErrorDialog.show(this, event)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import ac.mdiq.podcini.util.Converter.getDurationStringLocalized
|
|||
import ac.mdiq.podcini.util.Converter.getDurationStringLong
|
||||
import ac.mdiq.podcini.util.IntentUtils.openInBrowser
|
||||
import ac.mdiq.podcini.storage.model.feed.Chapter
|
||||
import ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage
|
||||
import ac.mdiq.podcini.storage.model.playback.Playable
|
||||
import ac.mdiq.podcini.ui.common.CircularProgressBar
|
||||
import kotlin.math.max
|
||||
|
@ -89,7 +90,7 @@ class ChaptersListAdapter(private val context: Context, private val callback: Ca
|
|||
Glide.with(context).clear(holder.image)
|
||||
} else {
|
||||
if (media != null) Glide.with(context)
|
||||
.load(ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage.getModelFor(media!!, position))
|
||||
.load(EmbeddedChapterImage.getModelFor(media!!, position))
|
||||
.apply(RequestOptions()
|
||||
.dontAnimate()
|
||||
.transform(FitCenter(), RoundedCorners((4 * context.resources.displayMetrics.density).toInt())))
|
||||
|
|
|
@ -15,8 +15,9 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||
/**
|
||||
* Displays a dialog with a text box for filtering episodes and two radio buttons for exclusion/inclusion
|
||||
*/
|
||||
abstract class EpisodeFilterDialog(context: Context, filter: FeedFilter) : MaterialAlertDialogBuilder(
|
||||
context) {
|
||||
abstract class EpisodeFilterDialog(context: Context, filter: FeedFilter) :
|
||||
MaterialAlertDialogBuilder(context) {
|
||||
|
||||
private val viewBinding = EpisodeFilterDialogBinding.inflate(LayoutInflater.from(context))
|
||||
private val termList: MutableList<String>
|
||||
|
||||
|
|
|
@ -15,7 +15,11 @@ import ac.mdiq.podcini.R
|
|||
import ac.mdiq.podcini.databinding.SortDialogBinding
|
||||
import ac.mdiq.podcini.databinding.SortDialogItemActiveBinding
|
||||
import ac.mdiq.podcini.databinding.SortDialogItemBinding
|
||||
import ac.mdiq.podcini.preferences.UserPreferences
|
||||
import ac.mdiq.podcini.storage.model.feed.SortOrder
|
||||
import android.graphics.Color
|
||||
import android.util.Log
|
||||
import android.view.WindowManager
|
||||
|
||||
open class ItemSortDialog : BottomSheetDialogFragment() {
|
||||
protected var _binding: SortDialogBinding? = null
|
||||
|
@ -30,6 +34,11 @@ open class ItemSortDialog : BottomSheetDialogFragment() {
|
|||
return binding.root
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||
}
|
||||
|
||||
private fun populateList() {
|
||||
binding.gridLayout.removeAllViews()
|
||||
onAddItem(R.string.episode_title, SortOrder.EPISODE_TITLE_A_Z, SortOrder.EPISODE_TITLE_Z_A, true)
|
||||
|
|
|
@ -36,6 +36,9 @@ import org.greenrobot.eventbus.ThreadMode
|
|||
|
||||
@UnstableApi
|
||||
class ChaptersFragment : AppCompatDialogFragment() {
|
||||
private var _binding: SimpleListFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private lateinit var layoutManager: LinearLayoutManager
|
||||
private lateinit var progressBar: ProgressBar
|
||||
private lateinit var adapter: ChaptersListAdapter
|
||||
|
@ -63,12 +66,12 @@ class ChaptersFragment : AppCompatDialogFragment() {
|
|||
}
|
||||
|
||||
fun onCreateView(inflater: LayoutInflater): View {
|
||||
val viewBinding = SimpleListFragmentBinding.inflate(inflater)
|
||||
viewBinding.toolbar.visibility = View.GONE
|
||||
_binding = SimpleListFragmentBinding.inflate(inflater)
|
||||
binding.toolbar.visibility = View.GONE
|
||||
|
||||
Log.d(TAG, "fragment onCreateView")
|
||||
val recyclerView = viewBinding.recyclerView
|
||||
progressBar = viewBinding.progLoading
|
||||
val recyclerView = binding.recyclerView
|
||||
progressBar = binding.progLoading
|
||||
layoutManager = LinearLayoutManager(activity)
|
||||
recyclerView.layoutManager = layoutManager
|
||||
recyclerView.addItemDecoration(DividerItemDecoration(recyclerView.context, layoutManager.orientation))
|
||||
|
@ -100,11 +103,12 @@ class ChaptersFragment : AppCompatDialogFragment() {
|
|||
EventBus.getDefault().register(this)
|
||||
loadMediaInfo(false)
|
||||
|
||||
return viewBinding.root
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
controller?.release()
|
||||
controller = null
|
||||
EventBus.getDefault().unregister(this)
|
||||
|
|
|
@ -25,9 +25,7 @@ import ac.mdiq.podcini.ui.view.EpisodeItemListRecyclerView
|
|||
import ac.mdiq.podcini.ui.view.LiftOnScrollListener
|
||||
import ac.mdiq.podcini.ui.view.viewholder.EpisodeItemViewHolder
|
||||
import ac.mdiq.podcini.util.FeedItemUtil
|
||||
import ac.mdiq.podcini.util.event.EpisodeDownloadEvent
|
||||
import ac.mdiq.podcini.util.event.FeedItemEvent
|
||||
import ac.mdiq.podcini.util.event.SwipeActionsChangedEvent
|
||||
import ac.mdiq.podcini.util.event.*
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
|
@ -55,12 +53,12 @@ import java.util.*
|
|||
* Displays all completed downloads and provides a button to delete them.
|
||||
*/
|
||||
class CompletedDownloadsFragment : Fragment(), SelectableAdapter.OnSelectModeListener, Toolbar.OnMenuItemClickListener {
|
||||
private var runningDownloads: Set<String>? = HashSet()
|
||||
private var items: MutableList<FeedItem> = mutableListOf()
|
||||
|
||||
private var _binding: SimpleListFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private var runningDownloads: Set<String> = HashSet()
|
||||
private var items: MutableList<FeedItem> = mutableListOf()
|
||||
|
||||
private lateinit var infoBar: TextView
|
||||
private lateinit var adapter: CompletedDownloadsListAdapter
|
||||
private lateinit var toolbar: MaterialToolbar
|
||||
|
@ -105,12 +103,12 @@ class CompletedDownloadsFragment : Fragment(), SelectableAdapter.OnSelectModeLis
|
|||
swipeActions = SwipeActions(this, TAG).attachTo(recyclerView)
|
||||
swipeActions.setFilter(FeedItemFilter(FeedItemFilter.DOWNLOADED))
|
||||
refreshSwipeTelltale()
|
||||
binding.leftActionIcon.setOnClickListener({
|
||||
binding.leftActionIcon.setOnClickListener {
|
||||
swipeActions.showDialog()
|
||||
})
|
||||
binding.rightActionIcon.setOnClickListener({
|
||||
}
|
||||
binding.rightActionIcon.setOnClickListener {
|
||||
swipeActions.showDialog()
|
||||
})
|
||||
}
|
||||
|
||||
val animator: RecyclerView.ItemAnimator? = recyclerView.itemAnimator
|
||||
if (animator is SimpleItemAnimator) {
|
||||
|
@ -127,8 +125,8 @@ class CompletedDownloadsFragment : Fragment(), SelectableAdapter.OnSelectModeLis
|
|||
speedDialView.overlayLayout = multiSelectDial.fabSDOverlay
|
||||
speedDialView.inflate(R.menu.episodes_apply_action_speeddial)
|
||||
speedDialView.removeActionItemById(R.id.download_batch)
|
||||
speedDialView.removeActionItemById(R.id.mark_read_batch)
|
||||
speedDialView.removeActionItemById(R.id.mark_unread_batch)
|
||||
// speedDialView.removeActionItemById(R.id.mark_read_batch)
|
||||
// speedDialView.removeActionItemById(R.id.mark_unread_batch)
|
||||
speedDialView.removeActionItemById(R.id.remove_from_queue_batch)
|
||||
speedDialView.setOnChangeListener(object : SpeedDialView.OnChangeListener {
|
||||
override fun onMainActionSelected(): Boolean {
|
||||
|
@ -286,17 +284,17 @@ class CompletedDownloadsFragment : Fragment(), SelectableAdapter.OnSelectModeLis
|
|||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onPlayerStatusChanged(event: ac.mdiq.podcini.util.event.PlayerStatusEvent?) {
|
||||
fun onPlayerStatusChanged(event: PlayerStatusEvent?) {
|
||||
loadItems()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onDownloadLogChanged(event: ac.mdiq.podcini.util.event.DownloadLogEvent?) {
|
||||
fun onDownloadLogChanged(event: DownloadLogEvent?) {
|
||||
loadItems()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onUnreadItemsChanged(event: ac.mdiq.podcini.util.event.UnreadItemsUpdateEvent?) {
|
||||
fun onUnreadItemsChanged(event: UnreadItemsUpdateEvent?) {
|
||||
loadItems()
|
||||
}
|
||||
|
||||
|
@ -324,10 +322,10 @@ class CompletedDownloadsFragment : Fragment(), SelectableAdapter.OnSelectModeLis
|
|||
FeedItemFilter(FeedItemFilter.DOWNLOADED), sortOrder)
|
||||
|
||||
val mediaUrls: MutableList<String> = ArrayList()
|
||||
if (runningDownloads == null) {
|
||||
if (runningDownloads.isEmpty()) {
|
||||
return@fromCallable downloadedItems
|
||||
}
|
||||
for (url in runningDownloads!!) {
|
||||
for (url in runningDownloads) {
|
||||
if (FeedItemUtil.indexOfItemWithDownloadUrl(downloadedItems, url) != -1) {
|
||||
continue // Already in list
|
||||
}
|
||||
|
@ -409,7 +407,11 @@ class CompletedDownloadsFragment : Fragment(), SelectableAdapter.OnSelectModeLis
|
|||
descending: SortOrder,
|
||||
ascendingIsDefault: Boolean
|
||||
) {
|
||||
if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.DURATION_SHORT_LONG || ascending == SortOrder.EPISODE_TITLE_A_Z || ascending == SortOrder.SIZE_SMALL_LARGE) {
|
||||
if (ascending == SortOrder.DATE_OLD_NEW ||
|
||||
ascending == SortOrder.DURATION_SHORT_LONG ||
|
||||
ascending == SortOrder.EPISODE_TITLE_A_Z ||
|
||||
ascending == SortOrder.SIZE_SMALL_LARGE ||
|
||||
ascending == SortOrder.FEED_TITLE_A_Z) {
|
||||
super.onAddItem(title, ascending, descending, ascendingIsDefault)
|
||||
}
|
||||
}
|
||||
|
@ -417,7 +419,7 @@ class CompletedDownloadsFragment : Fragment(), SelectableAdapter.OnSelectModeLis
|
|||
override fun onSelectionChanged() {
|
||||
super.onSelectionChanged()
|
||||
UserPreferences.downloadsSortedOrder = sortOrder
|
||||
EventBus.getDefault().post(ac.mdiq.podcini.util.event.DownloadLogEvent.listUpdated())
|
||||
EventBus.getDefault().post(DownloadLogEvent.listUpdated())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@ import java.util.*
|
|||
* Searches iTunes store for top podcasts and displays results in a list.
|
||||
*/
|
||||
class DiscoveryFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
||||
private var _binding: FragmentItunesSearchBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private lateinit var prefs: SharedPreferences
|
||||
private lateinit var gridView: GridView
|
||||
private lateinit var progressBar: ProgressBar
|
||||
|
@ -94,15 +97,15 @@ class DiscoveryFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
// Inflate the layout for this fragment
|
||||
val viewBinding = FragmentItunesSearchBinding.inflate(inflater)
|
||||
_binding = FragmentItunesSearchBinding.inflate(inflater)
|
||||
// val root = inflater.inflate(R.layout.fragment_itunes_search, container, false)
|
||||
|
||||
Log.d(TAG, "fragment onCreateView")
|
||||
gridView = viewBinding.gridView
|
||||
gridView = binding.gridView
|
||||
adapter = OnlineFeedsAdapter(requireActivity(), ArrayList())
|
||||
gridView.setAdapter(adapter)
|
||||
|
||||
toolbar = viewBinding.toolbar
|
||||
toolbar = binding.toolbar
|
||||
toolbar.setNavigationOnClickListener { parentFragmentManager.popBackStack() }
|
||||
toolbar.inflateMenu(R.menu.countries_menu)
|
||||
val discoverHideItem = toolbar.menu.findItem(R.id.discover_hide_item)
|
||||
|
@ -121,17 +124,18 @@ class DiscoveryFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
|||
startActivity(intent)
|
||||
}
|
||||
|
||||
progressBar = viewBinding.progressBar
|
||||
txtvError = viewBinding.txtvError
|
||||
butRetry = viewBinding.butRetry
|
||||
txtvEmpty = viewBinding.empty
|
||||
progressBar = binding.progressBar
|
||||
txtvError = binding.txtvError
|
||||
butRetry = binding.butRetry
|
||||
txtvEmpty = binding.empty
|
||||
|
||||
loadToplist(countryCode)
|
||||
return viewBinding.root
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
disposable?.dispose()
|
||||
|
||||
adapter = null
|
||||
|
|
|
@ -23,6 +23,7 @@ import ac.mdiq.podcini.util.DateFormatter
|
|||
import ac.mdiq.podcini.util.PlaybackStatus
|
||||
import ac.mdiq.podcini.util.event.EpisodeDownloadEvent
|
||||
import ac.mdiq.podcini.util.event.FeedItemEvent
|
||||
import ac.mdiq.podcini.util.event.PlayerStatusEvent
|
||||
import ac.mdiq.podcini.util.event.UnreadItemsUpdateEvent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
|
@ -409,7 +410,7 @@ class EpisodeInfoFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
|||
}
|
||||
|
||||
@UnstableApi @Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onPlayerStatusChanged(event: ac.mdiq.podcini.util.event.PlayerStatusEvent?) {
|
||||
fun onPlayerStatusChanged(event: PlayerStatusEvent?) {
|
||||
updateButtons()
|
||||
}
|
||||
|
||||
|
|
|
@ -105,12 +105,12 @@ abstract class EpisodesListFragment : Fragment(), SelectableAdapter.OnSelectMode
|
|||
swipeActions = SwipeActions(this, getFragmentTag()).attachTo(recyclerView)
|
||||
swipeActions.setFilter(getFilter())
|
||||
refreshSwipeTelltale()
|
||||
binding.leftActionIcon.setOnClickListener({
|
||||
binding.leftActionIcon.setOnClickListener {
|
||||
swipeActions.showDialog()
|
||||
})
|
||||
binding.rightActionIcon.setOnClickListener({
|
||||
}
|
||||
binding.rightActionIcon.setOnClickListener {
|
||||
swipeActions.showDialog()
|
||||
})
|
||||
}
|
||||
|
||||
val animator: RecyclerView.ItemAnimator? = recyclerView.itemAnimator
|
||||
if (animator is SimpleItemAnimator) {
|
||||
|
|
|
@ -54,6 +54,9 @@ import kotlin.math.max
|
|||
* Fragment which is supposed to be displayed outside of the MediaplayerActivity.
|
||||
*/
|
||||
class ExternalPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
||||
private var _binding: ExternalPlayerFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private lateinit var imgvCover: ImageView
|
||||
private lateinit var butPlay: PlayButton
|
||||
|
||||
|
@ -79,22 +82,22 @@ class ExternalPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
|||
@UnstableApi
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
val viewBinding = ExternalPlayerFragmentBinding.inflate(inflater)
|
||||
_binding = ExternalPlayerFragmentBinding.inflate(inflater)
|
||||
Log.d(TAG, "fragment onCreateView")
|
||||
|
||||
episodeTitle = viewBinding.titleView
|
||||
butPlaybackSpeed = viewBinding.butPlaybackSpeed
|
||||
txtvPlaybackSpeed = viewBinding.txtvPlaybackSpeed
|
||||
imgvCover = viewBinding.imgvCover
|
||||
butPlay = viewBinding.butPlay
|
||||
butRev = viewBinding.butRev
|
||||
txtvRev = viewBinding.txtvRev
|
||||
butFF = viewBinding.butFF
|
||||
txtvFF = viewBinding.txtvFF
|
||||
butSkip = viewBinding.butSkip
|
||||
sbPosition = viewBinding.sbPosition
|
||||
txtvPosition = viewBinding.txtvPosition
|
||||
txtvLength = viewBinding.txtvLength
|
||||
episodeTitle = binding.titleView
|
||||
butPlaybackSpeed = binding.butPlaybackSpeed
|
||||
txtvPlaybackSpeed = binding.txtvPlaybackSpeed
|
||||
imgvCover = binding.imgvCover
|
||||
butPlay = binding.butPlay
|
||||
butRev = binding.butRev
|
||||
txtvRev = binding.txtvRev
|
||||
butFF = binding.butFF
|
||||
txtvFF = binding.txtvFF
|
||||
butSkip = binding.butSkip
|
||||
sbPosition = binding.sbPosition
|
||||
txtvPosition = binding.txtvPosition
|
||||
txtvLength = binding.txtvLength
|
||||
|
||||
setupLengthTextView()
|
||||
setupControlButtons()
|
||||
|
@ -103,7 +106,7 @@ class ExternalPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
|||
}
|
||||
sbPosition.setOnSeekBarChangeListener(this)
|
||||
|
||||
viewBinding.externalPlayerFragment.setOnClickListener {
|
||||
binding.externalPlayerFragment.setOnClickListener {
|
||||
Log.d(TAG, "externalPlayerFragment was clicked")
|
||||
val media = controller?.getMedia()
|
||||
if (media != null) {
|
||||
|
@ -118,13 +121,14 @@ class ExternalPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
|||
|
||||
controller = setupPlaybackController()
|
||||
controller!!.init()
|
||||
loadMediaInfo()
|
||||
// loadMediaInfo()
|
||||
EventBus.getDefault().register(this)
|
||||
return viewBinding.root
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class) override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
controller?.release()
|
||||
controller = null
|
||||
EventBus.getDefault().unregister(this)
|
||||
|
@ -134,11 +138,9 @@ class ExternalPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
butPlay.setOnClickListener {
|
||||
if (controller == null) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
val media = controller!!.getMedia()
|
||||
if (controller == null) return@setOnClickListener
|
||||
|
||||
val media = controller!!.getMedia()
|
||||
if (media?.getMediaType() == MediaType.VIDEO && controller!!.status != PlayerStatus.PLAYING) {
|
||||
controller!!.playPause()
|
||||
requireContext().startActivity(getPlayerActivityIntent(requireContext(), media))
|
||||
|
@ -161,10 +163,10 @@ class ExternalPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
|||
SkipPreferenceDialog.SkipDirection.SKIP_REWIND, txtvRev)
|
||||
true
|
||||
}
|
||||
butPlay.setOnClickListener {
|
||||
controller?.init()
|
||||
controller?.playPause()
|
||||
}
|
||||
// butPlay.setOnClickListener {
|
||||
// controller?.init()
|
||||
// controller?.playPause()
|
||||
// }
|
||||
butFF.setOnClickListener {
|
||||
if (controller != null) {
|
||||
val curr: Int = controller!!.position
|
||||
|
|
|
@ -71,10 +71,11 @@ class FeedItemlistFragment : Fragment(), AdapterView.OnItemClickListener, Toolba
|
|||
|
||||
private var _binding: FeedItemListFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private var _speedDialBinding: MultiSelectSpeedDialBinding? = null
|
||||
private val speedDialBinding get() = _speedDialBinding!!
|
||||
|
||||
private lateinit var adapter: FeedItemListAdapter
|
||||
private lateinit var swipeActions: SwipeActions
|
||||
private lateinit var speedDialBinding: MultiSelectSpeedDialBinding
|
||||
private lateinit var nextPageLoader: MoreContentListFooterUtil
|
||||
|
||||
private var displayUpArrow = false
|
||||
|
@ -96,7 +97,7 @@ class FeedItemlistFragment : Fragment(), AdapterView.OnItemClickListener, Toolba
|
|||
Log.d(TAG, "fragment onCreateView")
|
||||
|
||||
_binding = FeedItemListFragmentBinding.inflate(inflater)
|
||||
speedDialBinding = MultiSelectSpeedDialBinding.bind(binding.root)
|
||||
_speedDialBinding = MultiSelectSpeedDialBinding.bind(binding.root)
|
||||
|
||||
binding.toolbar.inflateMenu(R.menu.feedlist)
|
||||
binding.toolbar.setOnMenuItemClickListener(this)
|
||||
|
@ -198,6 +199,7 @@ class FeedItemlistFragment : Fragment(), AdapterView.OnItemClickListener, Toolba
|
|||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
_speedDialBinding
|
||||
EventBus.getDefault().unregister(this)
|
||||
disposable?.dispose()
|
||||
adapter.endSelectMode()
|
||||
|
@ -209,9 +211,8 @@ class FeedItemlistFragment : Fragment(), AdapterView.OnItemClickListener, Toolba
|
|||
}
|
||||
|
||||
private fun updateToolbar() {
|
||||
if (feed == null) {
|
||||
return
|
||||
}
|
||||
if (feed == null) return
|
||||
|
||||
binding.toolbar.menu.findItem(R.id.visit_website_item).setVisible(feed!!.link != null)
|
||||
binding.toolbar.menu.findItem(R.id.refresh_complete_item).setVisible(feed!!.isPaged)
|
||||
if (StringUtils.isBlank(feed!!.link)) {
|
||||
|
@ -620,8 +621,11 @@ class FeedItemlistFragment : Fragment(), AdapterView.OnItemClickListener, Toolba
|
|||
descending: SortOrder,
|
||||
ascendingIsDefault: Boolean
|
||||
) {
|
||||
if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.DURATION_SHORT_LONG || ascending == SortOrder.EPISODE_TITLE_A_Z || (requireArguments().getBoolean(
|
||||
ARG_FEED_IS_LOCAL) && ascending == SortOrder.EPISODE_FILENAME_A_Z)) {
|
||||
if (ascending == SortOrder.DATE_OLD_NEW ||
|
||||
ascending == SortOrder.DURATION_SHORT_LONG ||
|
||||
ascending == SortOrder.RANDOM ||
|
||||
ascending == SortOrder.EPISODE_TITLE_A_Z ||
|
||||
(requireArguments().getBoolean(ARG_FEED_IS_LOCAL) && ascending == SortOrder.EPISODE_FILENAME_A_Z)) {
|
||||
super.onAddItem(title, ascending, descending, ascendingIsDefault)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ import ac.mdiq.podcini.ui.dialog.*
|
|||
import ac.mdiq.podcini.ui.menuhandler.MenuItemUtils
|
||||
import ac.mdiq.podcini.ui.statistics.StatisticsFragment
|
||||
import ac.mdiq.podcini.util.event.FeedListUpdateEvent
|
||||
import ac.mdiq.podcini.util.event.QueueEvent
|
||||
import ac.mdiq.podcini.util.event.UnreadItemsUpdateEvent
|
||||
import android.R.attr
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
|
@ -195,7 +197,7 @@ class NavDrawerFragment : Fragment(), SharedPreferences.OnSharedPreferenceChange
|
|||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onUnreadItemsChanged(event: ac.mdiq.podcini.util.event.UnreadItemsUpdateEvent?) {
|
||||
fun onUnreadItemsChanged(event: UnreadItemsUpdateEvent?) {
|
||||
loadData()
|
||||
}
|
||||
|
||||
|
@ -206,7 +208,7 @@ class NavDrawerFragment : Fragment(), SharedPreferences.OnSharedPreferenceChange
|
|||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onQueueChanged(event: ac.mdiq.podcini.util.event.QueueEvent) {
|
||||
fun onQueueChanged(event: QueueEvent) {
|
||||
Log.d(TAG, "onQueueChanged($event)")
|
||||
// we are only interested in the number of queue items, not download status or position
|
||||
if (event.action == ac.mdiq.podcini.util.event.QueueEvent.Action.DELETED_MEDIA || event.action == ac.mdiq.podcini.util.event.QueueEvent.Action.SORTED || event.action == ac.mdiq.podcini.util.event.QueueEvent.Action.MOVED) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import ac.mdiq.podcini.playback.PlaybackController
|
|||
import ac.mdiq.podcini.playback.event.PlaybackPositionEvent
|
||||
import ac.mdiq.podcini.storage.DBReader
|
||||
import ac.mdiq.podcini.storage.model.feed.Chapter
|
||||
import ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedMedia
|
||||
import ac.mdiq.podcini.storage.model.playback.Playable
|
||||
import ac.mdiq.podcini.ui.activity.MainActivity
|
||||
|
@ -279,7 +280,7 @@ class PlayerDetailsFragment : Fragment() {
|
|||
cover.into(binding.imgvCover)
|
||||
} else {
|
||||
Glide.with(this)
|
||||
.load(ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage.getModelFor(media!!, displayedChapterIndex))
|
||||
.load(EmbeddedChapterImage.getModelFor(media!!, displayedChapterIndex))
|
||||
.apply(options)
|
||||
.thumbnail(cover)
|
||||
.error(cover)
|
||||
|
|
|
@ -1,6 +1,34 @@
|
|||
package ac.mdiq.podcini.ui.fragment
|
||||
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.databinding.CheckboxDoNotShowAgainBinding
|
||||
import ac.mdiq.podcini.databinding.MultiSelectSpeedDialBinding
|
||||
import ac.mdiq.podcini.databinding.QueueFragmentBinding
|
||||
import ac.mdiq.podcini.feed.util.PlaybackSpeedUtils
|
||||
import ac.mdiq.podcini.net.download.FeedUpdateManager
|
||||
import ac.mdiq.podcini.playback.event.PlaybackPositionEvent
|
||||
import ac.mdiq.podcini.preferences.UserPreferences
|
||||
import ac.mdiq.podcini.storage.DBReader
|
||||
import ac.mdiq.podcini.storage.DBWriter
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedItem
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedItemFilter
|
||||
import ac.mdiq.podcini.storage.model.feed.SortOrder
|
||||
import ac.mdiq.podcini.ui.activity.MainActivity
|
||||
import ac.mdiq.podcini.ui.adapter.QueueRecyclerAdapter
|
||||
import ac.mdiq.podcini.ui.adapter.SelectableAdapter
|
||||
import ac.mdiq.podcini.ui.dialog.ConfirmationDialog
|
||||
import ac.mdiq.podcini.ui.dialog.ItemSortDialog
|
||||
import ac.mdiq.podcini.ui.fragment.actions.EpisodeMultiSelectActionHandler
|
||||
import ac.mdiq.podcini.ui.fragment.swipeactions.SwipeActions
|
||||
import ac.mdiq.podcini.ui.menuhandler.FeedItemMenuHandler
|
||||
import ac.mdiq.podcini.ui.menuhandler.MenuItemUtils
|
||||
import ac.mdiq.podcini.ui.view.EmptyViewHandler
|
||||
import ac.mdiq.podcini.ui.view.EpisodeItemListRecyclerView
|
||||
import ac.mdiq.podcini.ui.view.LiftOnScrollListener
|
||||
import ac.mdiq.podcini.ui.view.viewholder.EpisodeItemViewHolder
|
||||
import ac.mdiq.podcini.util.Converter
|
||||
import ac.mdiq.podcini.util.FeedItemUtil
|
||||
import ac.mdiq.podcini.util.event.*
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.SharedPreferences
|
||||
|
@ -22,35 +50,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.leinardi.android.speeddial.SpeedDialActionItem
|
||||
import com.leinardi.android.speeddial.SpeedDialView
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.databinding.CheckboxDoNotShowAgainBinding
|
||||
import ac.mdiq.podcini.databinding.MultiSelectSpeedDialBinding
|
||||
import ac.mdiq.podcini.databinding.QueueFragmentBinding
|
||||
import ac.mdiq.podcini.ui.adapter.QueueRecyclerAdapter
|
||||
import ac.mdiq.podcini.ui.adapter.SelectableAdapter
|
||||
import ac.mdiq.podcini.ui.dialog.ConfirmationDialog
|
||||
import ac.mdiq.podcini.feed.util.PlaybackSpeedUtils
|
||||
import ac.mdiq.podcini.ui.menuhandler.MenuItemUtils
|
||||
import ac.mdiq.podcini.storage.DBReader
|
||||
import ac.mdiq.podcini.storage.DBWriter
|
||||
import ac.mdiq.podcini.util.FeedItemUtil
|
||||
import ac.mdiq.podcini.net.download.FeedUpdateManager
|
||||
import ac.mdiq.podcini.ui.dialog.ItemSortDialog
|
||||
import ac.mdiq.podcini.util.event.*
|
||||
import ac.mdiq.podcini.playback.event.PlaybackPositionEvent
|
||||
import ac.mdiq.podcini.ui.fragment.actions.EpisodeMultiSelectActionHandler
|
||||
import ac.mdiq.podcini.ui.fragment.swipeactions.SwipeActions
|
||||
import ac.mdiq.podcini.ui.menuhandler.FeedItemMenuHandler
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedItem
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedItemFilter
|
||||
import ac.mdiq.podcini.storage.model.feed.SortOrder
|
||||
import ac.mdiq.podcini.preferences.UserPreferences
|
||||
import ac.mdiq.podcini.ui.dialog.SwipeActionsDialog
|
||||
import ac.mdiq.podcini.ui.view.EmptyViewHandler
|
||||
import ac.mdiq.podcini.ui.view.EpisodeItemListRecyclerView
|
||||
import ac.mdiq.podcini.ui.view.LiftOnScrollListener
|
||||
import ac.mdiq.podcini.ui.view.viewholder.EpisodeItemViewHolder
|
||||
import ac.mdiq.podcini.util.Converter
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
|
@ -126,12 +125,12 @@ class QueueFragment : Fragment(), Toolbar.OnMenuItemClickListener, SelectableAda
|
|||
swipeActions.setFilter(FeedItemFilter(FeedItemFilter.QUEUED))
|
||||
swipeActions.attachTo(recyclerView)
|
||||
refreshSwipeTelltale()
|
||||
binding.leftActionIcon.setOnClickListener({
|
||||
binding.leftActionIcon.setOnClickListener {
|
||||
swipeActions.showDialog()
|
||||
})
|
||||
binding.rightActionIcon.setOnClickListener({
|
||||
}
|
||||
binding.rightActionIcon.setOnClickListener {
|
||||
swipeActions.showDialog()
|
||||
})
|
||||
}
|
||||
|
||||
recyclerAdapter = object : QueueRecyclerAdapter(activity as MainActivity, swipeActions) {
|
||||
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) {
|
||||
|
|
|
@ -33,6 +33,9 @@ import org.greenrobot.eventbus.ThreadMode
|
|||
import java.util.*
|
||||
|
||||
class QuickFeedDiscoveryFragment : Fragment(), AdapterView.OnItemClickListener {
|
||||
private var _binding: QuickFeedDiscoveryBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private var disposable: Disposable? = null
|
||||
|
||||
private lateinit var adapter: FeedDiscoverAdapter
|
||||
|
@ -44,18 +47,17 @@ class QuickFeedDiscoveryFragment : Fragment(), AdapterView.OnItemClickListener {
|
|||
|
||||
@OptIn(UnstableApi::class) override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
val viewBinding = QuickFeedDiscoveryBinding.inflate(inflater)
|
||||
// val root: View = inflater.inflate(R.layout.quick_feed_discovery, container, false)
|
||||
_binding = QuickFeedDiscoveryBinding.inflate(inflater)
|
||||
|
||||
Log.d(TAG, "fragment onCreateView")
|
||||
val discoverMore = viewBinding.discoverMore
|
||||
val discoverMore = binding.discoverMore
|
||||
discoverMore.setOnClickListener { (activity as MainActivity).loadChildFragment(DiscoveryFragment()) }
|
||||
|
||||
discoverGridLayout = viewBinding.discoverGrid
|
||||
errorView = viewBinding.discoverError
|
||||
errorTextView = viewBinding.discoverErrorTxtV
|
||||
errorRetry = viewBinding.discoverErrorRetryBtn
|
||||
poweredByTextView = viewBinding.discoverPoweredByItunes
|
||||
discoverGridLayout = binding.discoverGrid
|
||||
errorView = binding.discoverError
|
||||
errorTextView = binding.discoverErrorTxtV
|
||||
errorRetry = binding.discoverErrorRetryBtn
|
||||
poweredByTextView = binding.discoverPoweredByItunes
|
||||
|
||||
adapter = FeedDiscoverAdapter(activity as MainActivity)
|
||||
discoverGridLayout.setAdapter(adapter)
|
||||
|
@ -80,11 +82,12 @@ class QuickFeedDiscoveryFragment : Fragment(), AdapterView.OnItemClickListener {
|
|||
loadToplist()
|
||||
|
||||
EventBus.getDefault().register(this)
|
||||
return viewBinding.root
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
EventBus.getDefault().unregister(this)
|
||||
disposable?.dispose()
|
||||
}
|
||||
|
|
|
@ -56,6 +56,9 @@ import org.greenrobot.eventbus.ThreadMode
|
|||
* Performs a search operation on all feeds or one specific feed and displays the search result.
|
||||
*/
|
||||
class SearchFragment : Fragment(), SelectableAdapter.OnSelectModeListener {
|
||||
private var _binding: SearchFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private lateinit var adapter: EpisodeItemListAdapter
|
||||
private lateinit var adapterFeeds: HorizontalFeedListAdapter
|
||||
private lateinit var progressBar: ProgressBar
|
||||
|
@ -87,14 +90,13 @@ class SearchFragment : Fragment(), SelectableAdapter.OnSelectModeListener {
|
|||
@UnstableApi override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
val viewBinding = SearchFragmentBinding.inflate(inflater)
|
||||
// val layout: View = inflater.inflate(R.layout.search_fragment, container, false)
|
||||
_binding = SearchFragmentBinding.inflate(inflater)
|
||||
|
||||
Log.d(TAG, "fragment onCreateView")
|
||||
setupToolbar(viewBinding.toolbar)
|
||||
speedDialBinding = MultiSelectSpeedDialBinding.bind(viewBinding.root)
|
||||
progressBar = viewBinding.progressBar
|
||||
recyclerView = viewBinding.recyclerView
|
||||
setupToolbar(binding.toolbar)
|
||||
speedDialBinding = MultiSelectSpeedDialBinding.bind(binding.root)
|
||||
progressBar = binding.progressBar
|
||||
recyclerView = binding.recyclerView
|
||||
recyclerView.setRecycledViewPool((activity as MainActivity).recycledViewPool)
|
||||
registerForContextMenu(recyclerView)
|
||||
adapter = object : EpisodeItemListAdapter(activity as MainActivity) {
|
||||
|
@ -109,9 +111,9 @@ class SearchFragment : Fragment(), SelectableAdapter.OnSelectModeListener {
|
|||
}
|
||||
adapter.setOnSelectModeListener(this)
|
||||
recyclerView.adapter = adapter
|
||||
recyclerView.addOnScrollListener(LiftOnScrollListener(viewBinding.appbar))
|
||||
recyclerView.addOnScrollListener(LiftOnScrollListener(binding.appbar))
|
||||
|
||||
val recyclerViewFeeds = viewBinding.recyclerViewFeeds
|
||||
val recyclerViewFeeds = binding.recyclerViewFeeds
|
||||
val layoutManagerFeeds = LinearLayoutManager(activity)
|
||||
layoutManagerFeeds.orientation = RecyclerView.HORIZONTAL
|
||||
recyclerViewFeeds.layoutManager = layoutManagerFeeds
|
||||
|
@ -133,7 +135,7 @@ class SearchFragment : Fragment(), SelectableAdapter.OnSelectModeListener {
|
|||
emptyViewHandler.setMessage(R.string.type_to_search)
|
||||
EventBus.getDefault().register(this)
|
||||
|
||||
chip = viewBinding.feedTitleChip
|
||||
chip = binding.feedTitleChip
|
||||
chip.setOnCloseIconClickListener {
|
||||
requireArguments().putLong(ARG_FEED, 0)
|
||||
searchWithProgressBar()
|
||||
|
@ -178,11 +180,12 @@ class SearchFragment : Fragment(), SelectableAdapter.OnSelectModeListener {
|
|||
true
|
||||
}
|
||||
|
||||
return viewBinding.root
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
EventBus.getDefault().unregister(this)
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class ApGlideModule : AppGlideModule() {
|
|||
registry.append(String::class.java, InputStream::class.java, ApOkHttpUrlLoader.Factory())
|
||||
registry.append(String::class.java, InputStream::class.java, NoHttpStringLoader.StreamFactory())
|
||||
|
||||
registry.append(ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage::class.java, ByteBuffer::class.java, ChapterImageModelLoader.Factory())
|
||||
registry.append(EmbeddedChapterImage::class.java, ByteBuffer::class.java, ChapterImageModelLoader.Factory())
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ac.mdiq.podcini.ui.glide
|
||||
|
||||
import ac.mdiq.podcini.service.download.PodciniHttpClient.getHttpClient
|
||||
import ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.Options
|
||||
|
@ -17,9 +18,9 @@ import java.io.FileInputStream
|
|||
import java.io.IOException
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
class ChapterImageModelLoader : ModelLoader<ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage?, ByteBuffer?> {
|
||||
class Factory : ModelLoaderFactory<ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage?, ByteBuffer?> {
|
||||
override fun build(unused: MultiModelLoaderFactory): ModelLoader<ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage?, ByteBuffer?> {
|
||||
class ChapterImageModelLoader : ModelLoader<EmbeddedChapterImage?, ByteBuffer?> {
|
||||
class Factory : ModelLoaderFactory<EmbeddedChapterImage?, ByteBuffer?> {
|
||||
override fun build(unused: MultiModelLoaderFactory): ModelLoader<EmbeddedChapterImage?, ByteBuffer?> {
|
||||
return ChapterImageModelLoader()
|
||||
}
|
||||
|
||||
|
@ -28,7 +29,7 @@ class ChapterImageModelLoader : ModelLoader<ac.mdiq.podcini.storage.model.feed.E
|
|||
}
|
||||
}
|
||||
|
||||
override fun buildLoadData(model: ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage,
|
||||
override fun buildLoadData(model: EmbeddedChapterImage,
|
||||
width: Int,
|
||||
height: Int,
|
||||
options: Options
|
||||
|
@ -36,11 +37,11 @@ class ChapterImageModelLoader : ModelLoader<ac.mdiq.podcini.storage.model.feed.E
|
|||
return ModelLoader.LoadData(ObjectKey(model), EmbeddedImageFetcher(model))
|
||||
}
|
||||
|
||||
override fun handles(model: ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage): Boolean {
|
||||
override fun handles(model: EmbeddedChapterImage): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
internal class EmbeddedImageFetcher(private val image: ac.mdiq.podcini.storage.model.feed.EmbeddedChapterImage) : DataFetcher<ByteBuffer?> {
|
||||
internal class EmbeddedImageFetcher(private val image: EmbeddedChapterImage) : DataFetcher<ByteBuffer?> {
|
||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in ByteBuffer?>) {
|
||||
var stream: BufferedInputStream? = null
|
||||
try {
|
||||
|
|
|
@ -10,6 +10,7 @@ import ac.mdiq.podcini.ui.dialog.ConfirmationDialog
|
|||
import ac.mdiq.podcini.ui.statistics.downloads.DownloadStatisticsFragment
|
||||
import ac.mdiq.podcini.ui.statistics.subscriptions.SubscriptionStatisticsFragment
|
||||
import ac.mdiq.podcini.ui.statistics.years.YearsStatisticsFragment
|
||||
import ac.mdiq.podcini.util.event.StatisticsEvent
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
|
@ -106,7 +107,7 @@ class StatisticsFragment : PagedToolbarFragment() {
|
|||
val disposable = Completable.fromFuture(DBWriter.resetStatistics())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ EventBus.getDefault().post(ac.mdiq.podcini.util.event.StatisticsEvent()) },
|
||||
.subscribe({ EventBus.getDefault().post(StatisticsEvent()) },
|
||||
{ error: Throwable? -> Log.e(TAG, Log.getStackTraceString(error)) })
|
||||
}
|
||||
|
||||
|
|
|
@ -17,19 +17,21 @@ import io.reactivex.schedulers.Schedulers
|
|||
import java.util.*
|
||||
|
||||
class FeedStatisticsFragment : Fragment() {
|
||||
private var _binding: FeedStatisticsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private var feedId: Long = 0
|
||||
private var disposable: Disposable? = null
|
||||
private var viewBinding: FeedStatisticsBinding? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
feedId = requireArguments().getLong(EXTRA_FEED_ID)
|
||||
viewBinding = FeedStatisticsBinding.inflate(inflater)
|
||||
_binding = FeedStatisticsBinding.inflate(inflater)
|
||||
|
||||
if (!requireArguments().getBoolean(EXTRA_DETAILED)) {
|
||||
for (i in 0 until viewBinding!!.root.childCount) {
|
||||
val child = viewBinding!!.root.getChildAt(i)
|
||||
for (i in 0 until binding.root.childCount) {
|
||||
val child = binding.root.getChildAt(i)
|
||||
if ("detailed" == child.tag) {
|
||||
child.visibility = View.GONE
|
||||
}
|
||||
|
@ -37,7 +39,7 @@ class FeedStatisticsFragment : Fragment() {
|
|||
}
|
||||
|
||||
loadStatistics()
|
||||
return viewBinding!!.root
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private fun loadStatistics() {
|
||||
|
@ -62,21 +64,20 @@ class FeedStatisticsFragment : Fragment() {
|
|||
}
|
||||
|
||||
private fun showStats(s: StatisticsItem?) {
|
||||
viewBinding!!.startedTotalLabel.text = String.format(Locale.getDefault(), "%d / %d",
|
||||
binding.startedTotalLabel.text = String.format(Locale.getDefault(), "%d / %d",
|
||||
s!!.episodesStarted, s.episodes)
|
||||
viewBinding!!.timePlayedLabel.text =
|
||||
binding.timePlayedLabel.text =
|
||||
shortLocalizedDuration(requireContext(), s.timePlayed)
|
||||
viewBinding!!.totalDurationLabel.text =
|
||||
binding.totalDurationLabel.text =
|
||||
shortLocalizedDuration(requireContext(), s.time)
|
||||
viewBinding!!.onDeviceLabel.text = String.format(Locale.getDefault(), "%d", s.episodesDownloadCount)
|
||||
viewBinding!!.spaceUsedLabel.text = Formatter.formatShortFileSize(context, s.totalDownloadSize)
|
||||
binding.onDeviceLabel.text = String.format(Locale.getDefault(), "%d", s.episodesDownloadCount)
|
||||
binding.spaceUsedLabel.text = Formatter.formatShortFileSize(context, s.totalDownloadSize)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (disposable != null) {
|
||||
disposable!!.dispose()
|
||||
}
|
||||
_binding = null
|
||||
disposable?.dispose()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -7,6 +7,7 @@ import ac.mdiq.podcini.storage.DBReader
|
|||
import ac.mdiq.podcini.storage.DBReader.StatisticsResult
|
||||
import ac.mdiq.podcini.storage.StatisticsItem
|
||||
import ac.mdiq.podcini.ui.statistics.StatisticsFragment
|
||||
import ac.mdiq.podcini.util.event.StatisticsEvent
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
|
@ -67,7 +68,7 @@ class SubscriptionStatisticsFragment : Fragment() {
|
|||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun statisticsEvent(event: ac.mdiq.podcini.util.event.StatisticsEvent?) {
|
||||
fun statisticsEvent(event: StatisticsEvent?) {
|
||||
refreshStatistics()
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import ac.mdiq.podcini.R
|
|||
import ac.mdiq.podcini.databinding.StatisticsFragmentBinding
|
||||
import ac.mdiq.podcini.storage.DBReader
|
||||
import ac.mdiq.podcini.storage.DBReader.MonthlyStatisticsItem
|
||||
import ac.mdiq.podcini.util.event.StatisticsEvent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
|
@ -59,7 +60,7 @@ class YearsStatisticsFragment : Fragment() {
|
|||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun statisticsEvent(event: ac.mdiq.podcini.util.event.StatisticsEvent?) {
|
||||
fun statisticsEvent(event: StatisticsEvent?) {
|
||||
refreshStatistics()
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package ac.mdiq.podcini.util
|
|||
|
||||
import ac.mdiq.podcini.storage.model.feed.FeedItem
|
||||
import ac.mdiq.podcini.storage.model.feed.SortOrder
|
||||
import android.util.Log
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
|
@ -96,7 +97,8 @@ object FeedItemPermutors {
|
|||
}
|
||||
|
||||
private fun feedTitle(item: FeedItem?): String {
|
||||
return if (item?.feed != null && item.feed!!.title != null) item.feed!!.title!!.lowercase(Locale.getDefault()) else ""
|
||||
Log.d("permutors", "feedTitle ${item?.feed?.title}")
|
||||
return if (item?.feed?.title != null) item.feed!!.title!!.lowercase(Locale.getDefault()) else ""
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,7 @@ import ac.mdiq.podcini.net.ssl.SslProviderInstaller
|
|||
import ac.mdiq.podcini.storage.database.PodDBAdapter
|
||||
import ac.mdiq.podcini.preferences.UserPreferences
|
||||
import ac.mdiq.podcini.preferences.UserPreferences.proxyConfig
|
||||
import ac.mdiq.podcini.service.download.DownloadServiceInterfaceImpl
|
||||
import java.io.File
|
||||
|
||||
@UnstableApi
|
||||
|
@ -35,7 +36,7 @@ object ClientConfigurator {
|
|||
SslProviderInstaller.install(context)
|
||||
NetworkUtils.init(context)
|
||||
NetworkConnectionChangeHandler.init(context)
|
||||
DownloadServiceInterface.setImpl(ac.mdiq.podcini.service.download.DownloadServiceInterfaceImpl())
|
||||
DownloadServiceInterface.setImpl(DownloadServiceInterfaceImpl())
|
||||
SynchronizationQueueSink.setServiceStarterImpl { SyncService.sync(context) }
|
||||
setCacheDirectory(File(context.cacheDir, "okhttp"))
|
||||
setProxyConfig(proxyConfig)
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
<item
|
||||
android:id="@+id/sort_items"
|
||||
android:icon="@drawable/arrows_sort"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/sort"
|
||||
custom:showAsAction="never">
|
||||
custom:showAsAction="always">
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/refresh_item"
|
||||
|
@ -31,7 +32,7 @@
|
|||
android:id="@+id/visit_website_item"
|
||||
android:icon="@drawable/ic_web"
|
||||
android:menuCategory="container"
|
||||
custom:showAsAction="collapseActionView"
|
||||
custom:showAsAction="ifRoom|collapseActionView"
|
||||
android:title="@string/visit_website_label"
|
||||
android:visible="true">
|
||||
</item>
|
||||
|
|
|
@ -58,8 +58,8 @@ class LocalFeedUpdaterTest {
|
|||
init(context)
|
||||
|
||||
val app = context as Application?
|
||||
ac.mdiq.podcini.util.config.ClientConfig.applicationCallbacks = Mockito.mock(ac.mdiq.podcini.util.config.ApplicationCallbacks::class.java)
|
||||
Mockito.`when`(ac.mdiq.podcini.util.config.ClientConfig.applicationCallbacks?.getApplicationInstance()).thenReturn(app)
|
||||
ClientConfig.applicationCallbacks = Mockito.mock(ApplicationCallbacks::class.java)
|
||||
Mockito.`when`(ClientConfig.applicationCallbacks?.getApplicationInstance()).thenReturn(app)
|
||||
DownloadServiceInterface.setImpl(DownloadServiceInterfaceStub())
|
||||
|
||||
// Initialize database
|
||||
|
|
|
@ -72,8 +72,8 @@ open class DbCleanupTests {
|
|||
init(context)
|
||||
|
||||
val app = context as Application?
|
||||
ac.mdiq.podcini.util.config.ClientConfig.applicationCallbacks = Mockito.mock(ac.mdiq.podcini.util.config.ApplicationCallbacks::class.java)
|
||||
Mockito.`when`(ac.mdiq.podcini.util.config.ClientConfig.applicationCallbacks?.getApplicationInstance()).thenReturn(app)
|
||||
ClientConfig.applicationCallbacks = Mockito.mock(ApplicationCallbacks::class.java)
|
||||
Mockito.`when`(ClientConfig.applicationCallbacks?.getApplicationInstance()).thenReturn(app)
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
@ -40,8 +40,8 @@ class DbTasksTest {
|
|||
init(context)
|
||||
|
||||
val app = context as Application?
|
||||
ac.mdiq.podcini.util.config.ClientConfig.applicationCallbacks = Mockito.mock(ac.mdiq.podcini.util.config.ApplicationCallbacks::class.java)
|
||||
Mockito.`when`(ac.mdiq.podcini.util.config.ClientConfig.applicationCallbacks?.getApplicationInstance()).thenReturn(app)
|
||||
ClientConfig.applicationCallbacks = Mockito.mock(ApplicationCallbacks::class.java)
|
||||
Mockito.`when`(ClientConfig.applicationCallbacks?.getApplicationInstance()).thenReturn(app)
|
||||
|
||||
// create new database
|
||||
PodDBAdapter.init(context!!)
|
||||
|
|
|
@ -64,8 +64,8 @@ class DbWriterTest {
|
|||
init(context)
|
||||
|
||||
val app = context as Application?
|
||||
ac.mdiq.podcini.util.config.ClientConfig.applicationCallbacks = Mockito.mock(ac.mdiq.podcini.util.config.ApplicationCallbacks::class.java)
|
||||
Mockito.`when`(ac.mdiq.podcini.util.config.ClientConfig.applicationCallbacks?.getApplicationInstance()).thenReturn(app)
|
||||
ClientConfig.applicationCallbacks = Mockito.mock(ApplicationCallbacks::class.java)
|
||||
Mockito.`when`(ClientConfig.applicationCallbacks?.getApplicationInstance()).thenReturn(app)
|
||||
DownloadServiceInterface.setImpl(DownloadServiceInterfaceStub())
|
||||
|
||||
// create new database
|
||||
|
|
10
changelog.md
10
changelog.md
|
@ -137,3 +137,13 @@
|
|||
* only the down arrow on top left page collapses the expanded view
|
||||
* share notes directly from expanded view of the player
|
||||
* in episode info, changed rendering of description, removed nested scroll
|
||||
|
||||
# 4.3.4
|
||||
|
||||
* fixed bug player disappear on first play
|
||||
* more viewbinding GC enhancements
|
||||
* added sort by feed title in downloads view
|
||||
* more items on action bar in feed item list view
|
||||
* some cleaning of redundant qualifiers
|
||||
* sort dialog no longer dims the main view
|
||||
* added random sort to feed items view
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
Version 4.3.4 brings several changes:
|
||||
|
||||
* fixed bug player disappear on first play
|
||||
* more viewbinding GC enhancements
|
||||
* added sort by feed title in downloads view
|
||||
* more items on action bar in feed item list view
|
||||
* some cleaning of redundant qualifiers
|
||||
* sort dialog no longer dims the main view
|
||||
* added random sort to feed items view
|
Loading…
Reference in New Issue