6.0.8 commit
This commit is contained in:
parent
8eee3644a8
commit
0f99aa2dd7
|
@ -125,8 +125,8 @@ android {
|
|||
buildConfig true
|
||||
}
|
||||
defaultConfig {
|
||||
versionCode 3020207
|
||||
versionName "6.0.7"
|
||||
versionCode 3020208
|
||||
versionName "6.0.8"
|
||||
|
||||
applicationId "ac.mdiq.podcini.R"
|
||||
def commit = ""
|
||||
|
|
|
@ -52,7 +52,7 @@ class DownloadServiceInterfaceImpl : DownloadServiceInterface() {
|
|||
|
||||
override fun downloadNow(context: Context, item: Episode, ignoreConstraints: Boolean) {
|
||||
Logd(TAG, "starting downloadNow")
|
||||
val workRequest: OneTimeWorkRequest.Builder = getRequest(context, item)
|
||||
val workRequest: OneTimeWorkRequest.Builder = getRequest(item)
|
||||
workRequest.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||
if (ignoreConstraints) workRequest.setConstraints(Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
|
||||
else workRequest.setConstraints(constraints)
|
||||
|
@ -63,7 +63,7 @@ class DownloadServiceInterfaceImpl : DownloadServiceInterface() {
|
|||
|
||||
override fun download(context: Context, item: Episode) {
|
||||
Logd(TAG, "starting download")
|
||||
val workRequest: OneTimeWorkRequest.Builder = getRequest(context, item)
|
||||
val workRequest: OneTimeWorkRequest.Builder = getRequest(item)
|
||||
workRequest.setConstraints(constraints)
|
||||
if (item.media?.downloadUrl != null)
|
||||
WorkManager.getInstance(context).enqueueUniqueWork(item.media!!.downloadUrl!!, ExistingWorkPolicy.KEEP, workRequest.build())
|
||||
|
@ -108,7 +108,7 @@ class DownloadServiceInterfaceImpl : DownloadServiceInterface() {
|
|||
return constraints.build()
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class) private fun getRequest(context: Context, item: Episode): OneTimeWorkRequest.Builder {
|
||||
@OptIn(UnstableApi::class) private fun getRequest(item: Episode): OneTimeWorkRequest.Builder {
|
||||
Logd(TAG, "starting getRequest")
|
||||
val workRequest: OneTimeWorkRequest.Builder = OneTimeWorkRequest.Builder(EpisodeDownloadWorker::class.java)
|
||||
.setInitialDelay(0L, TimeUnit.MILLISECONDS)
|
||||
|
@ -208,7 +208,7 @@ class DownloadServiceInterfaceImpl : DownloadServiceInterface() {
|
|||
|
||||
if (dest.exists()) {
|
||||
try {
|
||||
media.fileUrl = request.destination
|
||||
media.setfileUrlOrNull(request.destination)
|
||||
Episodes.persistEpisodeMedia(media)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "performDownload Exception in writeFileUrl: " + e.message)
|
||||
|
@ -353,8 +353,10 @@ class DownloadServiceInterfaceImpl : DownloadServiceInterface() {
|
|||
}
|
||||
// media.setDownloaded modifies played state
|
||||
val broadcastUnreadStateUpdate = media.episode != null && media.episode!!.isNew
|
||||
media.downloaded = true
|
||||
media.fileUrl = request.destination
|
||||
// media.downloaded = true
|
||||
media.setIsDownloaded()
|
||||
Logd(TAG, "media.episode.isNew: ${media.episode?.isNew} ${media.episode?.playState}")
|
||||
media.setfileUrlOrNull(request.destination)
|
||||
if (request.destination != null) media.size = File(request.destination).length()
|
||||
|
||||
media.checkEmbeddedPicture() // enforce check
|
||||
|
@ -388,7 +390,7 @@ class DownloadServiceInterfaceImpl : DownloadServiceInterface() {
|
|||
// we've received the media, we don't want to autodownload it again
|
||||
if (item != null) {
|
||||
item.disableAutoDownload()
|
||||
Logd(TAG, "persisting episode downloaded ${item.title} ${item.media?.fileUrl} ${item.media?.downloaded}")
|
||||
Logd(TAG, "persisting episode downloaded ${item.title} ${item.media?.fileUrl} ${item.media?.downloaded} ${item.isNew}")
|
||||
// setFeedItem() signals that the item has been updated,
|
||||
// so we do it after the enclosing media has been updated above,
|
||||
// to ensure subscribers will get the updated EpisodeMedia as well
|
||||
|
|
|
@ -550,13 +550,14 @@ class PlaybackService : MediaSessionService() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
Logd(TAG, "Service is about to be destroyed")
|
||||
|
||||
isRunning = false
|
||||
currentMediaType = MediaType.UNKNOWN
|
||||
castStateListener.destroy()
|
||||
|
||||
currentitem = null
|
||||
|
||||
LocalMediaPlayer.cleanup()
|
||||
mediaSession?.run {
|
||||
player.release()
|
||||
|
@ -573,6 +574,8 @@ class PlaybackService : MediaSessionService() {
|
|||
unregisterReceiver(bluetoothStateUpdated)
|
||||
unregisterReceiver(audioBecomingNoisy)
|
||||
taskManager.shutdown()
|
||||
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
fun isServiceReady(): Boolean {
|
||||
|
|
|
@ -605,8 +605,8 @@ class SynchronizationPreferencesFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
cancelFlowEvents()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class) override fun onResume() {
|
||||
|
|
|
@ -108,6 +108,7 @@ object Episodes {
|
|||
Logd(TAG, String.format(Locale.US, "Requested to delete EpisodeMedia [id=%d, title=%s, downloaded=%s", media.id, media.getEpisodeTitle(), media.downloaded))
|
||||
var localDelete = false
|
||||
val url = media.fileUrl
|
||||
var episode = episode
|
||||
when {
|
||||
url != null && url.startsWith("content://") -> {
|
||||
// Local feed
|
||||
|
@ -116,8 +117,8 @@ object Episodes {
|
|||
EventFlow.postEvent(FlowEvent.MessageEvent(context.getString(R.string.delete_local_failed)))
|
||||
return episode
|
||||
}
|
||||
upsertBlk(episode) {
|
||||
it.media?.fileUrl = null
|
||||
episode = upsertBlk(episode) {
|
||||
it.media?.setfileUrlOrNull(null)
|
||||
if (media.downloadUrl.isNullOrEmpty()) it.media = null
|
||||
}
|
||||
localDelete = true
|
||||
|
@ -131,9 +132,9 @@ object Episodes {
|
|||
EventFlow.postEvent(evt)
|
||||
return episode
|
||||
}
|
||||
upsertBlk(episode) {
|
||||
episode = upsertBlk(episode) {
|
||||
it.media?.downloaded = false
|
||||
it.media?.fileUrl = null
|
||||
it.media?.setfileUrlOrNull(null)
|
||||
it.media?.hasEmbeddedPicture = false
|
||||
if (media.downloadUrl.isNullOrEmpty()) it.media = null
|
||||
}
|
||||
|
@ -209,10 +210,10 @@ object Episodes {
|
|||
fun persistEpisodeMedia(media: EpisodeMedia) : Job {
|
||||
Logd(TAG, "persistEpisodeMedia called")
|
||||
return runOnIOScope {
|
||||
val episode = media.episode
|
||||
var episode = media.episode
|
||||
if (episode != null) {
|
||||
episode.media = media
|
||||
upsert(episode) {}
|
||||
episode = upsert(episode) {}
|
||||
EventFlow.postEvent(FlowEvent.EpisodeEvent.updated(episode))
|
||||
} else Log.e(TAG, "persistEpisodeMedia media.episode is null")
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ object RealmDB {
|
|||
if (BuildConfig.DEBUG) {
|
||||
val stackTrace = Thread.currentThread().stackTrace
|
||||
val caller = if (stackTrace.size > 3) stackTrace[3] else null
|
||||
Logd(TAG, "${caller?.className}.${caller?.methodName} upsert: ${entity.javaClass.simpleName}")
|
||||
Logd(TAG, "${caller?.className}.${caller?.methodName} unmanaged: ${entity.javaClass.simpleName}")
|
||||
}
|
||||
return if (entity.isManaged()) realm.copyFromRealm(entity) else entity
|
||||
}
|
||||
|
|
|
@ -19,18 +19,19 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
|
|||
var id: Long = 0L // same as the episode id
|
||||
|
||||
var fileUrl: String? = null
|
||||
set(value) {
|
||||
field = value
|
||||
if (value == null) downloaded = false
|
||||
}
|
||||
// set(value) {
|
||||
// field = value
|
||||
// if (value == null) downloaded = false
|
||||
// }
|
||||
|
||||
var downloadUrl: String? = null
|
||||
|
||||
var downloaded: Boolean = false
|
||||
set(value) {
|
||||
field = value
|
||||
if (value && episode?.isNew == true) episode!!.setPlayed(false)
|
||||
}
|
||||
// set(value) {
|
||||
// Logd(TAG, "setting downloaded: $value ${episode?.isNew}")
|
||||
// field = value
|
||||
// if (value && episode?.isNew == true) episode!!.setPlayed(false)
|
||||
// }
|
||||
|
||||
@get:JvmName("getDurationProperty")
|
||||
@set:JvmName("setDurationProperty")
|
||||
|
@ -88,9 +89,8 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
|
|||
this.episode = i
|
||||
this.size = size
|
||||
this.mimeType = mime_type
|
||||
fileUrl = null
|
||||
setfileUrlOrNull(null)
|
||||
this.downloadUrl = download_url
|
||||
downloaded = false
|
||||
}
|
||||
|
||||
constructor(id: Long, item: Episode?, duration: Int, position: Int,
|
||||
|
@ -108,20 +108,12 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
|
|||
this.playbackCompletionDate = playbackCompletionDate?.clone() as? Date
|
||||
this.playbackCompletionTime = playbackCompletionDate?.time ?: 0
|
||||
this.lastPlayedTime = lastPlayedTime
|
||||
this.fileUrl = file_url
|
||||
setfileUrlOrNull(file_url)
|
||||
this.downloadUrl = download_url
|
||||
this.downloaded = downloaded
|
||||
if (downloaded) setIsDownloaded()
|
||||
else this.downloaded = downloaded
|
||||
}
|
||||
|
||||
// constructor(id: Long, item: Episode?, duration: Int, position: Int,
|
||||
// size: Long, mime_type: String?, file_url: String?, download_url: String?,
|
||||
// downloaded: Boolean, playbackCompletionDate: Date?, played_duration: Int,
|
||||
// hasEmbeddedPicture: Boolean?, lastPlayedTime: Long)
|
||||
// : this(id, item, duration, position, size, mime_type, file_url, download_url, downloaded, playbackCompletionDate, played_duration, lastPlayedTime) {
|
||||
//
|
||||
// this.hasEmbeddedPicture = hasEmbeddedPicture
|
||||
// }
|
||||
|
||||
fun getHumanReadableIdentifier(): String? {
|
||||
return if (episode?.title != null) episode!!.title else downloadUrl
|
||||
}
|
||||
|
@ -158,6 +150,16 @@ class EpisodeMedia: EmbeddedRealmObject, Playable {
|
|||
return FEEDFILETYPE_FEEDMEDIA
|
||||
}
|
||||
|
||||
fun setIsDownloaded() {
|
||||
downloaded = true
|
||||
if (episode?.isNew == true) episode!!.setPlayed(false)
|
||||
}
|
||||
|
||||
fun setfileUrlOrNull(url: String?) {
|
||||
fileUrl = url
|
||||
if (url == null) downloaded = false
|
||||
}
|
||||
|
||||
override fun getDuration(): Int {
|
||||
return duration
|
||||
}
|
||||
|
|
|
@ -40,10 +40,10 @@ class Feed : RealmObject {
|
|||
*/
|
||||
@FullText
|
||||
var customTitle: String? = null
|
||||
set(value) {
|
||||
field = if (value == null || value == eigenTitle) null
|
||||
else value
|
||||
}
|
||||
// set(value) {
|
||||
// field = if (value == null || value == eigenTitle) null
|
||||
// else value
|
||||
// }
|
||||
|
||||
var link: String? = null
|
||||
|
||||
|
@ -163,7 +163,7 @@ class Feed : RealmObject {
|
|||
this.fileUrl = fileUrl
|
||||
this.downloadUrl = downloadUrl
|
||||
this.eigenTitle = title
|
||||
this.customTitle = customTitle
|
||||
setCustomTitle1(customTitle)
|
||||
this.lastUpdate = lastUpdate
|
||||
this.link = link
|
||||
this.description = description
|
||||
|
@ -210,6 +210,10 @@ class Feed : RealmObject {
|
|||
preferences = FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF, username, password)
|
||||
}
|
||||
|
||||
fun setCustomTitle1(value: String?) {
|
||||
customTitle = if (value == null || value == eigenTitle) null else value
|
||||
}
|
||||
|
||||
fun getTextIdentifier(): String? {
|
||||
return when {
|
||||
!customTitle.isNullOrEmpty() -> customTitle
|
||||
|
|
|
@ -246,5 +246,4 @@ object ChapterUtils {
|
|||
}
|
||||
return listOf()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class EpisodeMultiSelectHandler(private val activity: MainActivity, private val
|
|||
showMessage(R.plurals.marked_unread_batch_label, items.size)
|
||||
}
|
||||
R.id.download_batch -> downloadChecked(items)
|
||||
R.id.delete_batch -> LocalDeleteModal.showLocalFeedDeleteWarningIfNecessary(activity, items) { deleteChecked(items) }
|
||||
R.id.delete_batch -> deleteChecked(items)
|
||||
else -> Log.e(TAG, "Unrecognized speed dial action item. Do nothing. id=$actionId")
|
||||
}
|
||||
}
|
||||
|
@ -57,18 +57,6 @@ class EpisodeMultiSelectHandler(private val activity: MainActivity, private val
|
|||
showMessage(R.plurals.removed_from_queue_batch_label, checkedIds.size)
|
||||
}
|
||||
|
||||
// private fun markedCheckedPlayed(items: List<FeedItem>) {
|
||||
//// val checkedIds = getSelectedIds(items)
|
||||
// DBWriter.markItemsPlayed(FeedItem.PLAYED, *items.toTypedArray())
|
||||
// showMessage(R.plurals.marked_read_batch_label, items.size)
|
||||
// }
|
||||
//
|
||||
// private fun markedCheckedUnplayed(items: List<FeedItem>) {
|
||||
//// val checkedIds = getSelectedIds(items)
|
||||
// DBWriter.markItemsPlayed(FeedItem.UNPLAYED, *items.toTypedArray())
|
||||
// showMessage(R.plurals.marked_unread_batch_label, items.size)
|
||||
// }
|
||||
|
||||
private fun markFavorite(items: List<Episode>, stat: Boolean) {
|
||||
for (item in items) {
|
||||
Episodes.setFavorite(item, true)
|
||||
|
@ -85,14 +73,8 @@ class EpisodeMultiSelectHandler(private val activity: MainActivity, private val
|
|||
}
|
||||
|
||||
private fun deleteChecked(items: List<Episode>) {
|
||||
var countHasMedia = 0
|
||||
for (feedItem in items) {
|
||||
if (feedItem.media != null && feedItem.media!!.downloaded) {
|
||||
countHasMedia++
|
||||
deleteMediaOfEpisode(activity, feedItem)
|
||||
}
|
||||
}
|
||||
showMessage(R.plurals.deleted_multi_episode_batch_label, countHasMedia)
|
||||
LocalDeleteModal.deleteEpisodesWarnLocal(activity, items)
|
||||
showMessage(R.plurals.deleted_multi_episode_batch_label, items.size)
|
||||
}
|
||||
|
||||
private fun showMessage(@PluralsRes msgId: Int, numItems: Int) {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package ac.mdiq.podcini.ui.actions.actionbutton
|
||||
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.storage.model.Episode
|
||||
import ac.mdiq.podcini.ui.utils.LocalDeleteModal.deleteEpisodesWarnLocal
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.storage.database.Episodes.deleteMediaOfEpisode
|
||||
import ac.mdiq.podcini.storage.model.Episode
|
||||
import ac.mdiq.podcini.ui.utils.LocalDeleteModal.showLocalFeedDeleteWarningIfNecessary
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
|
||||
class DeleteActionButton(item: Episode) : EpisodeActionButton(item) {
|
||||
|
@ -16,7 +15,7 @@ class DeleteActionButton(item: Episode) : EpisodeActionButton(item) {
|
|||
return R.drawable.ic_delete
|
||||
}
|
||||
@UnstableApi override fun onClick(context: Context) {
|
||||
showLocalFeedDeleteWarningIfNecessary(context, listOf(item)) { deleteMediaOfEpisode(context, item) }
|
||||
deleteEpisodesWarnLocal(context, listOf(item))
|
||||
}
|
||||
|
||||
override val visibility: Int
|
||||
|
|
|
@ -132,7 +132,8 @@ class TTSActionButton(item: Episode) : EpisodeActionButton(item) {
|
|||
Logd(TAG, "saving TTS to file $mFilename")
|
||||
val media = EpisodeMedia(item, null, 0, "audio/*")
|
||||
media.fileUrl = mFilename
|
||||
media.downloaded = true
|
||||
// media.downloaded = true
|
||||
media.setIsDownloaded()
|
||||
item.media = media
|
||||
// DBWriter.persistFeedMedia(media)
|
||||
item.setTranscriptIfLonger(readerText)
|
||||
|
|
|
@ -137,9 +137,7 @@ object EpisodeMenuHandler {
|
|||
when (menuItemId) {
|
||||
R.id.skip_episode_item -> context.sendBroadcast(MediaButtonReceiver.createIntent(context, KeyEvent.KEYCODE_MEDIA_NEXT))
|
||||
R.id.remove_item -> {
|
||||
LocalDeleteModal.showLocalFeedDeleteWarningIfNecessary(context, listOf(selectedItem)) {
|
||||
if (selectedItem.media != null) deleteMediaOfEpisode(context, selectedItem)
|
||||
}
|
||||
LocalDeleteModal.deleteEpisodesWarnLocal(context, listOf(selectedItem))
|
||||
}
|
||||
R.id.mark_read_item -> {
|
||||
selectedItem.setPlayed(true)
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package ac.mdiq.podcini.ui.actions.swipeactions
|
||||
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.storage.model.Episode
|
||||
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
||||
import ac.mdiq.podcini.ui.utils.LocalDeleteModal.deleteEpisodesWarnLocal
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.storage.database.Episodes.deleteMediaOfEpisode
|
||||
import ac.mdiq.podcini.storage.model.Episode
|
||||
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
||||
import ac.mdiq.podcini.ui.utils.LocalDeleteModal.showLocalFeedDeleteWarningIfNecessary
|
||||
|
||||
class DeleteSwipeAction : SwipeAction {
|
||||
override fun getId(): String {
|
||||
|
@ -29,9 +28,7 @@ class DeleteSwipeAction : SwipeAction {
|
|||
@UnstableApi override fun performAction(item: Episode, fragment: Fragment, filter: EpisodeFilter) {
|
||||
if (!item.isDownloaded && item.feed?.isLocalFeed != true) return
|
||||
|
||||
showLocalFeedDeleteWarningIfNecessary(fragment.requireContext(), listOf(item)) {
|
||||
deleteMediaOfEpisode(fragment.requireContext(), item)
|
||||
}
|
||||
deleteEpisodesWarnLocal(fragment.requireContext(), listOf(item))
|
||||
}
|
||||
|
||||
override fun willRemove(filter: EpisodeFilter, item: Episode): Boolean {
|
||||
|
|
|
@ -70,8 +70,8 @@ class BugReportActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
|
|
|
@ -364,11 +364,11 @@ class MainActivity : CastEnabledActivity() {
|
|||
|
||||
override fun onDestroy() {
|
||||
Logd(TAG, "onDestroy")
|
||||
super.onDestroy()
|
||||
// WorkManager.getInstance(this).pruneWork()
|
||||
_binding = null
|
||||
// realm.close()
|
||||
drawerLayout?.removeDrawerListener(drawerToggle!!)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun checkFirstLaunch() {
|
||||
|
@ -391,6 +391,7 @@ class MainActivity : CastEnabledActivity() {
|
|||
}
|
||||
|
||||
fun setPlayerVisible(visible_: Boolean?) {
|
||||
Logd(TAG, "setPlayerVisible $visible_")
|
||||
val visible = visible_ ?: (bottomSheet.state != BottomSheetBehavior.STATE_COLLAPSED)
|
||||
|
||||
bottomSheet.setLocked(!visible)
|
||||
|
|
|
@ -251,8 +251,8 @@ class OpmlImportActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -139,8 +139,8 @@ class PreferenceActivity : AppCompatActivity(), SearchPreferenceResultListener {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private var eventSink: Job? = null
|
||||
|
|
|
@ -138,8 +138,8 @@ class SelectSubscriptionActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -21,6 +21,8 @@ import ac.mdiq.podcini.ui.dialog.ShareDialog
|
|||
import ac.mdiq.podcini.ui.dialog.SleepTimerDialog
|
||||
import ac.mdiq.podcini.ui.dialog.VariableSpeedDialog
|
||||
import ac.mdiq.podcini.ui.fragment.ChaptersFragment
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.fragment.VideoEpisodeFragment
|
||||
import ac.mdiq.podcini.ui.utils.PictureInPictureUtil
|
||||
import ac.mdiq.podcini.util.IntentUtils.openInBrowser
|
||||
|
@ -136,12 +138,12 @@ class VideoplayerActivity : CastEnabledActivity() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN)
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN)
|
||||
_binding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
||||
|
@ -419,8 +421,9 @@ class VideoplayerActivity : CastEnabledActivity() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@UnstableApi private fun setupAudioTracks() {
|
||||
|
|
|
@ -89,9 +89,9 @@ class WidgetConfigActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
_wpBinding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun setInitialState() {
|
||||
|
|
|
@ -14,7 +14,6 @@ import android.app.Activity
|
|||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
|
@ -51,6 +50,12 @@ open class EpisodesAdapter(mainActivity: MainActivity)
|
|||
setHasStableIds(true)
|
||||
}
|
||||
|
||||
fun clearData() {
|
||||
episodes = listOf()
|
||||
feed = null
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun setDummyViews(dummyViews: Int) {
|
||||
this.dummyViews = dummyViews
|
||||
notifyDataSetChanged()
|
||||
|
@ -90,8 +95,7 @@ open class EpisodesAdapter(mainActivity: MainActivity)
|
|||
|
||||
val item: Episode = unmanaged(episodes[pos])
|
||||
// val item: Episode = episodes[pos]
|
||||
if (feed != null) item.feed = feed
|
||||
else item.feed = episodes[pos].feed
|
||||
item.feed = feed ?: episodes[pos].feed
|
||||
holder.bind(item)
|
||||
|
||||
// holder.infoCard.setOnCreateContextMenuListener(this)
|
||||
|
|
|
@ -17,7 +17,7 @@ class OnlineFeedsAdapter(private val context: Context, objects: List<PodcastSear
|
|||
: ArrayAdapter<PodcastSearchResult?>(context, 0, objects) {
|
||||
|
||||
// List holding the podcasts found in the search
|
||||
private val data: List<PodcastSearchResult> = objects
|
||||
private val data: MutableList<PodcastSearchResult> = objects.toMutableList()
|
||||
|
||||
@UnstableApi override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
val podcast: PodcastSearchResult = data[position]
|
||||
|
@ -65,6 +65,10 @@ class OnlineFeedsAdapter(private val context: Context, objects: List<PodcastSear
|
|||
return view
|
||||
}
|
||||
|
||||
fun clearData() {
|
||||
data.clear()
|
||||
}
|
||||
|
||||
internal class PodcastViewHolder(view: View) {
|
||||
val binding = OnlinePodcastListitemBinding.bind(view)
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class CustomFeedNameDialog(activity: Activity, private var feed: Feed) {
|
|||
.setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int ->
|
||||
feed = unmanaged(feed)
|
||||
val newTitle = binding.editText.text.toString()
|
||||
feed.customTitle = newTitle
|
||||
feed.setCustomTitle1(newTitle)
|
||||
upsertBlk(feed) {}
|
||||
}
|
||||
.setNeutralButton(R.string.reset, null)
|
||||
|
|
|
@ -4,6 +4,7 @@ import ac.mdiq.podcini.R
|
|||
import ac.mdiq.podcini.databinding.FilterDialogBinding
|
||||
import ac.mdiq.podcini.databinding.FilterDialogRowBinding
|
||||
import ac.mdiq.podcini.storage.model.EpisodeFilter
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.TAG
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
|
@ -98,8 +99,9 @@ abstract class EpisodeFilterDialog : BottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) {
|
||||
|
|
|
@ -5,6 +5,8 @@ import ac.mdiq.podcini.databinding.SortDialogBinding
|
|||
import ac.mdiq.podcini.databinding.SortDialogItemActiveBinding
|
||||
import ac.mdiq.podcini.databinding.SortDialogItemBinding
|
||||
import ac.mdiq.podcini.storage.model.EpisodeSortOrder
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.TAG
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
|
@ -98,8 +100,9 @@ open class EpisodeSortDialog : BottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) {
|
||||
|
|
|
@ -9,6 +9,8 @@ import ac.mdiq.podcini.preferences.UserPreferences.feedOrderDir
|
|||
import ac.mdiq.podcini.preferences.UserPreferences.setFeedOrder
|
||||
import ac.mdiq.podcini.storage.model.FeedSortOrder
|
||||
import ac.mdiq.podcini.storage.model.FeedSortOrder.Companion.getSortOrder
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import ac.mdiq.podcini.util.event.EventFlow
|
||||
import ac.mdiq.podcini.util.event.FlowEvent
|
||||
|
@ -40,6 +42,7 @@ open class FeedSortDialogNew : BottomSheetDialogFragment() {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
_binding = SortDialogBinding.inflate(inflater)
|
||||
binding.gridLayout.columnCount = 1
|
||||
populateList()
|
||||
binding.keepSortedCheckbox.setOnCheckedChangeListener { _: CompoundButton?, _: Boolean -> this@FeedSortDialogNew.onSelectionChanged() }
|
||||
return binding.root
|
||||
|
@ -117,8 +120,9 @@ open class FeedSortDialogNew : BottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) {
|
||||
|
|
|
@ -13,6 +13,8 @@ import ac.mdiq.podcini.util.ShareUtils.shareFeedItemLinkWithDownloadLink
|
|||
import ac.mdiq.podcini.util.ShareUtils.shareMediaDownloadLink
|
||||
import ac.mdiq.podcini.databinding.ShareEpisodeDialogBinding
|
||||
import ac.mdiq.podcini.storage.model.Episode
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.TAG
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
|
||||
class ShareDialog : BottomSheetDialogFragment() {
|
||||
private lateinit var ctx: Context
|
||||
|
@ -83,8 +85,9 @@ class ShareDialog : BottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
fun setItem(item_: Episode) {
|
||||
|
|
|
@ -18,8 +18,10 @@ import ac.mdiq.podcini.preferences.SleepTimerPreferences.shakeToReset
|
|||
import ac.mdiq.podcini.preferences.SleepTimerPreferences.timerMillis
|
||||
import ac.mdiq.podcini.preferences.SleepTimerPreferences.vibrate
|
||||
import ac.mdiq.podcini.storage.model.Playable
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.TAG
|
||||
import ac.mdiq.podcini.ui.utils.ThemeUtils.getColorFromAttr
|
||||
import ac.mdiq.podcini.util.Converter.getDurationStringLong
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import ac.mdiq.podcini.util.event.EventFlow
|
||||
import ac.mdiq.podcini.util.event.FlowEvent
|
||||
import android.app.Activity
|
||||
|
@ -160,8 +162,9 @@ class SleepTimerDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
fun extendSleepTimer(extendTime: Long) {
|
||||
|
|
|
@ -11,6 +11,8 @@ import ac.mdiq.podcini.storage.database.RealmDB.upsertBlk
|
|||
import ac.mdiq.podcini.storage.model.Feed
|
||||
import ac.mdiq.podcini.storage.model.FeedPreferences
|
||||
import ac.mdiq.podcini.ui.adapter.SimpleChipAdapter
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.ItemOffsetDecoration
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import android.app.Dialog
|
||||
|
@ -97,8 +99,9 @@ class TagSettingsDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class) private fun updatePreferencesTags(commonTags: Set<String>) {
|
||||
|
|
|
@ -16,6 +16,8 @@ import ac.mdiq.podcini.storage.database.Feeds.persistFeedPreferences
|
|||
import ac.mdiq.podcini.storage.database.RealmDB.unmanaged
|
||||
import ac.mdiq.podcini.storage.model.EpisodeMedia
|
||||
import ac.mdiq.podcini.storage.model.MediaType
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.ItemOffsetDecoration
|
||||
import ac.mdiq.podcini.ui.view.PlaybackSpeedSeekBar
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
|
@ -158,8 +160,9 @@ import java.util.*
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun addCurrentSpeed() {
|
||||
|
|
|
@ -10,6 +10,7 @@ import ac.mdiq.podcini.storage.model.Feed
|
|||
import ac.mdiq.podcini.storage.model.EpisodeSortOrder
|
||||
import ac.mdiq.podcini.ui.activity.MainActivity
|
||||
import ac.mdiq.podcini.ui.activity.OpmlImportActivity
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import android.content.*
|
||||
import android.net.Uri
|
||||
|
@ -150,8 +151,9 @@ class AddFeedFragment : Fragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun chooseOpmlImportPathResult(uri: Uri?) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import ac.mdiq.podcini.ui.activity.MainActivity
|
|||
import ac.mdiq.podcini.ui.dialog.EpisodeFilterDialog
|
||||
import ac.mdiq.podcini.ui.dialog.EpisodeSortDialog
|
||||
import ac.mdiq.podcini.ui.dialog.SwitchQueueDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import ac.mdiq.podcini.util.event.EventFlow
|
||||
import ac.mdiq.podcini.util.event.FlowEvent
|
||||
|
@ -49,6 +50,11 @@ import kotlin.math.min
|
|||
return root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
allEpisodes = listOf()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
procFlowEvents()
|
||||
|
@ -115,6 +121,10 @@ import kotlin.math.min
|
|||
Logd(TAG, "Received event: ${event.TAG}")
|
||||
when (event) {
|
||||
is FlowEvent.AllEpisodesFilterEvent -> onFilterChanged(event)
|
||||
is FlowEvent.AllEpisodesSortEvent -> {
|
||||
page = 1
|
||||
loadItems()
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -148,13 +158,14 @@ import kotlin.math.min
|
|||
}
|
||||
override fun onAddItem(title: Int, ascending: EpisodeSortOrder, descending: EpisodeSortOrder, ascendingIsDefault: Boolean) {
|
||||
if (ascending == EpisodeSortOrder.DATE_OLD_NEW || ascending == EpisodeSortOrder.DURATION_SHORT_LONG
|
||||
|| ascending == EpisodeSortOrder.PLAYED_DATE_OLD_NEW || ascending == EpisodeSortOrder.COMPLETED_DATE_OLD_NEW)
|
||||
|| ascending == EpisodeSortOrder.PLAYED_DATE_OLD_NEW || ascending == EpisodeSortOrder.COMPLETED_DATE_OLD_NEW
|
||||
|| ascending == EpisodeSortOrder.EPISODE_TITLE_A_Z)
|
||||
super.onAddItem(title, ascending, descending, ascendingIsDefault)
|
||||
}
|
||||
override fun onSelectionChanged() {
|
||||
super.onSelectionChanged()
|
||||
allEpisodesSortOrder = sortOrder
|
||||
EventFlow.postEvent(FlowEvent.FeedsSortedEvent())
|
||||
EventFlow.postEvent(FlowEvent.AllEpisodesSortEvent())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +181,6 @@ import kotlin.math.min
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG = AllEpisodesFragment::class.simpleName ?: "Anonymous"
|
||||
const val PREF_NAME: String = "PrefAllEpisodesFragment"
|
||||
|
|
|
@ -38,6 +38,7 @@ import ac.mdiq.podcini.ui.dialog.MediaPlayerErrorDialog
|
|||
import ac.mdiq.podcini.ui.dialog.SkipPreferenceDialog
|
||||
import ac.mdiq.podcini.ui.dialog.SleepTimerDialog
|
||||
import ac.mdiq.podcini.ui.dialog.VariableSpeedDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.view.ChapterSeekBar
|
||||
import ac.mdiq.podcini.ui.view.PlayButton
|
||||
import ac.mdiq.podcini.util.Converter
|
||||
|
@ -145,39 +146,40 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
|||
playerUIView2?.setBackgroundColor(SurfaceColors.getColorForElevation(requireContext(), 8 * resources.displayMetrics.density))
|
||||
onCollaped()
|
||||
cardViewSeek = binding.cardViewSeek
|
||||
|
||||
initDetailedView()
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
// fun initDetailedView() {
|
||||
// if (playerDetailsFragment == null) {
|
||||
// val fm = requireActivity().supportFragmentManager
|
||||
// val transaction = fm.beginTransaction()
|
||||
// playerDetailsFragment = PlayerDetailsFragment()
|
||||
// transaction.replace(R.id.itemDescription, playerDetailsFragment!!).commit()
|
||||
// }
|
||||
// }
|
||||
|
||||
override fun onDestroyView() {
|
||||
Logd(TAG, "Fragment destroyed")
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
controller?.release()
|
||||
controller = null
|
||||
}
|
||||
|
||||
fun onExpanded() {
|
||||
Logd(TAG, "onExpanded()")
|
||||
fun initDetailedView() {
|
||||
if (playerDetailsFragment == null) {
|
||||
val fm = requireActivity().supportFragmentManager
|
||||
val transaction = fm.beginTransaction()
|
||||
playerDetailsFragment = PlayerDetailsFragment()
|
||||
transaction.replace(R.id.itemDescription, playerDetailsFragment!!).commit()
|
||||
}
|
||||
isCollapsed = false
|
||||
playerUI = playerUI2
|
||||
playerUI?.updateUi(currentMedia)
|
||||
playerUI?.butPlay?.setIsShowPlay(isShowPlay)
|
||||
playerDetailsFragment?.updateInfo()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
Logd(TAG, "Fragment destroyed")
|
||||
_binding = null
|
||||
controller?.release()
|
||||
controller = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
fun onExpanded() {
|
||||
Logd(TAG, "onExpanded()")
|
||||
initDetailedView()
|
||||
// the function can also be called from MainActivity when a select menu pops up and closes
|
||||
if (isCollapsed) {
|
||||
isCollapsed = false
|
||||
playerUI = playerUI2
|
||||
playerUI?.updateUi(currentMedia)
|
||||
playerUI?.butPlay?.setIsShowPlay(isShowPlay)
|
||||
playerDetailsFragment?.updateInfo()
|
||||
}
|
||||
}
|
||||
|
||||
fun onCollaped() {
|
||||
|
@ -340,7 +342,10 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
|||
is FlowEvent.FavoritesEvent -> onFavoriteEvent(event)
|
||||
is FlowEvent.PlayerErrorEvent -> MediaPlayerErrorDialog.show(activity as Activity, event)
|
||||
is FlowEvent.SleepTimerUpdatedEvent -> if (event.isCancelled || event.wasJustEnabled()) loadMediaInfo(false)
|
||||
is FlowEvent.PlaybackPositionEvent -> playerUI?.onPositionUpdate(event)
|
||||
is FlowEvent.PlaybackPositionEvent -> {
|
||||
playerUI?.onPositionUpdate(event)
|
||||
if (!isCollapsed) playerDetailsFragment?.onPlaybackPositionEvent(event)
|
||||
}
|
||||
is FlowEvent.SpeedChangedEvent -> playerUI?.updatePlaybackSpeedButton(event)
|
||||
else -> {}
|
||||
}
|
||||
|
@ -528,8 +533,9 @@ class AudioPlayerFragment : Fragment(), SeekBar.OnSeekBarChangeListener, Toolbar
|
|||
return binding.root
|
||||
}
|
||||
@OptIn(UnstableApi::class) override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
@UnstableApi
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import ac.mdiq.podcini.ui.utils.EmptyViewHandler
|
|||
import ac.mdiq.podcini.ui.view.EpisodesRecyclerView
|
||||
import ac.mdiq.podcini.ui.utils.LiftOnScrollListener
|
||||
import ac.mdiq.podcini.storage.utils.EpisodeUtil
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import ac.mdiq.podcini.util.event.EventFlow
|
||||
import ac.mdiq.podcini.util.event.FlowEvent
|
||||
|
@ -305,9 +306,12 @@ import kotlinx.coroutines.flow.collectLatest
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
adapter.clearData()
|
||||
adapter.endSelectMode()
|
||||
episodes.clear()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onStartSelectMode() {
|
||||
|
|
|
@ -15,6 +15,7 @@ import ac.mdiq.podcini.playback.PlaybackController.Companion.curPosition
|
|||
import ac.mdiq.podcini.playback.PlaybackController.Companion.seekTo
|
||||
import ac.mdiq.podcini.storage.model.Chapter
|
||||
import ac.mdiq.podcini.storage.model.EmbeddedChapterImage
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.view.CircularProgressBar
|
||||
import ac.mdiq.podcini.util.Converter.getDurationStringLocalized
|
||||
import ac.mdiq.podcini.util.Converter.getDurationStringLong
|
||||
|
@ -133,11 +134,11 @@ class ChaptersFragment : AppCompatDialogFragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
controller?.release()
|
||||
controller = null
|
||||
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private var eventSink: Job? = null
|
||||
|
|
|
@ -64,7 +64,6 @@ class DiscoveryFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
|||
private var hidden = false
|
||||
private var needsConfirm = false
|
||||
|
||||
|
||||
/**
|
||||
* Replace adapter data with provided search results from SearchTask.
|
||||
*
|
||||
|
@ -131,9 +130,12 @@ class DiscoveryFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
adapter?.clearData()
|
||||
adapter = null
|
||||
searchResults = null
|
||||
topList = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun loadToplist(country: String?) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import ac.mdiq.podcini.storage.model.Feed
|
|||
import ac.mdiq.podcini.ui.actions.actionbutton.DownloadActionButton
|
||||
import ac.mdiq.podcini.ui.activity.MainActivity
|
||||
import ac.mdiq.podcini.ui.dialog.DownloadLogDetailsDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.EmptyViewHandler
|
||||
import ac.mdiq.podcini.ui.utils.ThemeUtils
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
|
@ -86,8 +87,10 @@ class DownloadLogFragment : BottomSheetDialogFragment(), OnItemClickListener, To
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
downloadLog = listOf()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onItemClick(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import ac.mdiq.podcini.ui.adapter.EpisodesAdapter
|
|||
import ac.mdiq.podcini.ui.adapter.SelectableAdapter
|
||||
import ac.mdiq.podcini.ui.dialog.EpisodeSortDialog
|
||||
import ac.mdiq.podcini.ui.dialog.SwitchQueueDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.EmptyViewHandler
|
||||
import ac.mdiq.podcini.ui.utils.LiftOnScrollListener
|
||||
import ac.mdiq.podcini.ui.view.EpisodesRecyclerView
|
||||
|
@ -163,10 +164,13 @@ import java.util.*
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
adapter.endSelectMode()
|
||||
adapter.clearData()
|
||||
toolbar.setOnMenuItemClickListener(null)
|
||||
toolbar.setOnLongClickListener(null)
|
||||
episodes = mutableListOf()
|
||||
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
@ -279,7 +283,7 @@ import java.util.*
|
|||
val size: Int = event.episodes.size
|
||||
while (i < size) {
|
||||
val item: Episode = event.episodes[i]
|
||||
val pos = EpisodeUtil.indexOfItemWithId(episodes.toList(), item.id)
|
||||
val pos = EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
||||
if (pos >= 0) {
|
||||
episodes.removeAt(pos)
|
||||
val media = item.media
|
||||
|
|
|
@ -8,6 +8,7 @@ import ac.mdiq.podcini.util.Logd
|
|||
import ac.mdiq.podcini.net.utils.NetworkUtils.fetchHtmlSource
|
||||
import ac.mdiq.podcini.storage.database.Episodes.persistEpisode
|
||||
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.speech.tts.TextToSpeech
|
||||
|
@ -257,7 +258,6 @@ class EpisodeHomeFragment : Fragment() {
|
|||
}
|
||||
|
||||
@OptIn(UnstableApi::class) override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
cleatWebview(binding.webView)
|
||||
cleatWebview(binding.readerView)
|
||||
|
@ -265,6 +265,7 @@ class EpisodeHomeFragment : Fragment() {
|
|||
tts?.stop()
|
||||
tts?.shutdown()
|
||||
tts = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@UnstableApi private fun updateAppearance() {
|
||||
|
|
|
@ -19,6 +19,7 @@ import ac.mdiq.podcini.storage.model.MediaType
|
|||
import ac.mdiq.podcini.ui.actions.actionbutton.*
|
||||
import ac.mdiq.podcini.ui.actions.menuhandler.EpisodeMenuHandler
|
||||
import ac.mdiq.podcini.ui.activity.MainActivity
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.ShownotesCleaner
|
||||
import ac.mdiq.podcini.ui.utils.ThemeUtils
|
||||
import ac.mdiq.podcini.ui.view.ShownotesWebView
|
||||
|
@ -230,14 +231,15 @@ import kotlin.math.max
|
|||
}
|
||||
|
||||
@OptIn(UnstableApi::class) override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
binding.root.removeView(webvDescription)
|
||||
episode = null
|
||||
webvDescription.clearHistory()
|
||||
webvDescription.clearCache(true)
|
||||
webvDescription.clearView()
|
||||
webvDescription.destroy()
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@UnstableApi private fun onFragmentLoaded() {
|
||||
|
|
|
@ -30,6 +30,7 @@ import ac.mdiq.podcini.ui.activity.MainActivity
|
|||
import ac.mdiq.podcini.ui.adapter.EpisodesAdapter
|
||||
import ac.mdiq.podcini.ui.adapter.SelectableAdapter
|
||||
import ac.mdiq.podcini.ui.dialog.*
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.ToolbarIconTintManager
|
||||
import ac.mdiq.podcini.ui.utils.TransitionEffect
|
||||
import ac.mdiq.podcini.ui.view.viewholder.EpisodeViewHolder
|
||||
|
@ -226,18 +227,23 @@ import java.util.concurrent.Semaphore
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
_dialBinding = null
|
||||
|
||||
ioScope.cancel()
|
||||
adapter.endSelectMode()
|
||||
adapter.clearData()
|
||||
|
||||
feed = null
|
||||
episodes = mutableListOf()
|
||||
|
||||
tts?.stop()
|
||||
tts?.shutdown()
|
||||
ttsWorking = false
|
||||
ttsReady = false
|
||||
tts = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
|
@ -335,8 +341,8 @@ import java.util.concurrent.Semaphore
|
|||
if (item.feedId != feed!!.id) continue
|
||||
val pos: Int = EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
||||
if (pos >= 0) {
|
||||
episodes.removeAt(pos)
|
||||
episodes.add(pos, item)
|
||||
Logd(TAG, "episode event: ${item.title} ${item.playState}")
|
||||
episodes[pos] = item
|
||||
adapter.notifyItemChangedCompat(pos)
|
||||
}
|
||||
i++
|
||||
|
@ -352,8 +358,7 @@ import java.util.concurrent.Semaphore
|
|||
if (item.feedId != feed!!.id) continue
|
||||
val pos: Int = EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
||||
if (pos >= 0) {
|
||||
episodes.removeAt(pos)
|
||||
episodes.add(pos, item)
|
||||
episodes[pos] = item
|
||||
adapter.notifyItemChangedCompat(pos)
|
||||
// episodes[pos].playState = item.playState
|
||||
// adapter.notifyItemChangedCompat(pos)
|
||||
|
@ -375,6 +380,7 @@ import java.util.concurrent.Semaphore
|
|||
val item = event.episode
|
||||
val pos: Int = EpisodeUtil.indexOfItemWithId(episodes, item.id)
|
||||
if (pos >= 0) {
|
||||
Logd(TAG, "played item: ${item.title} ${item.playState}")
|
||||
episodes[pos] = item
|
||||
adapter.notifyItemChangedCompat(pos)
|
||||
// episodes[pos].playState = item.playState
|
||||
|
|
|
@ -11,6 +11,7 @@ import ac.mdiq.podcini.storage.database.Feeds.updateFeedDownloadURL
|
|||
import ac.mdiq.podcini.storage.model.Feed
|
||||
import ac.mdiq.podcini.storage.model.FeedFunding
|
||||
import ac.mdiq.podcini.ui.activity.MainActivity
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.statistics.FeedStatisticsFragment
|
||||
import ac.mdiq.podcini.ui.statistics.StatisticsFragment
|
||||
import ac.mdiq.podcini.ui.utils.ToolbarIconTintManager
|
||||
|
@ -204,9 +205,10 @@ class FeedInfoFragment : Fragment(), Toolbar.OnMenuItemClickListener {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
// feed = null
|
||||
feed = Feed()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun refreshToolbarState() {
|
||||
|
|
|
@ -17,6 +17,7 @@ import ac.mdiq.podcini.storage.model.VolumeAdaptionSetting
|
|||
import ac.mdiq.podcini.ui.adapter.SimpleChipAdapter
|
||||
import ac.mdiq.podcini.ui.dialog.AuthenticationDialog
|
||||
import ac.mdiq.podcini.ui.dialog.TagSettingsDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.ItemOffsetDecoration
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import android.content.Context
|
||||
|
@ -65,8 +66,10 @@ class FeedSettingsFragment : Fragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
feed = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
class FeedSettingsPreferenceFragment : PreferenceFragmentCompat() {
|
||||
|
|
|
@ -12,6 +12,7 @@ import ac.mdiq.podcini.ui.adapter.EpisodesAdapter
|
|||
import ac.mdiq.podcini.ui.dialog.ConfirmationDialog
|
||||
import ac.mdiq.podcini.ui.dialog.DatesFilterDialog
|
||||
import ac.mdiq.podcini.ui.dialog.EpisodeSortDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.view.viewholder.EpisodeViewHolder
|
||||
import ac.mdiq.podcini.util.DateFormatter
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
|
@ -86,6 +87,12 @@ import kotlin.math.min
|
|||
cancelFlowEvents()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
allHistory = listOf()
|
||||
adapter.clearData()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class) override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||
if (super.onOptionsItemSelected(item)) return true
|
||||
when (item.itemId) {
|
||||
|
|
|
@ -19,6 +19,7 @@ import ac.mdiq.podcini.ui.activity.MainActivity
|
|||
import ac.mdiq.podcini.ui.activity.PreferenceActivity
|
||||
import ac.mdiq.podcini.ui.activity.starter.MainActivityStarter
|
||||
import ac.mdiq.podcini.ui.dialog.DrawerPreferencesDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.statistics.StatisticsFragment
|
||||
import ac.mdiq.podcini.ui.utils.ThemeUtils
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
|
@ -127,9 +128,10 @@ class NavDrawerFragment : Fragment(), OnSharedPreferenceChangeListener {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
prefs!!.unregisterOnSharedPreferenceChangeListener(this)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -276,7 +278,6 @@ class NavDrawerFragment : Fragment(), OnSharedPreferenceChangeListener {
|
|||
} else return false
|
||||
}
|
||||
@UnstableApi private fun bindNavView(title: String, position: Int, holder: NavHolder) {
|
||||
Logd(TAG, "bindNavView called")
|
||||
val context = activity ?: return
|
||||
holder.title.text = title
|
||||
// reset for re-use
|
||||
|
|
|
@ -164,8 +164,9 @@ import kotlin.concurrent.Volatile
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
feeds = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class) override fun onSaveInstanceState(outState: Bundle) {
|
||||
|
|
|
@ -97,10 +97,11 @@ class OnlineSearchFragment : Fragment() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
// disposable?.dispose()
|
||||
searchResults = null
|
||||
adapter?.clearData()
|
||||
adapter = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun setupToolbar(toolbar: MaterialToolbar) {
|
||||
|
|
|
@ -2,26 +2,22 @@ package ac.mdiq.podcini.ui.fragment
|
|||
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.databinding.PlayerDetailsFragmentBinding
|
||||
import ac.mdiq.podcini.storage.utils.ChapterUtils
|
||||
import ac.mdiq.podcini.storage.utils.ImageResourceUtils
|
||||
import ac.mdiq.podcini.net.utils.NetworkUtils.fetchHtmlSource
|
||||
import ac.mdiq.podcini.playback.PlaybackController.Companion.curSpeedMultiplier
|
||||
import ac.mdiq.podcini.playback.base.InTheatre.curMedia
|
||||
import ac.mdiq.podcini.playback.PlaybackController.Companion.curPosition
|
||||
import ac.mdiq.podcini.playback.PlaybackController.Companion.curSpeedMultiplier
|
||||
import ac.mdiq.podcini.playback.PlaybackController.Companion.seekTo
|
||||
import ac.mdiq.podcini.playback.base.InTheatre.curMedia
|
||||
import ac.mdiq.podcini.storage.database.Episodes.persistEpisode
|
||||
import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope
|
||||
import ac.mdiq.podcini.storage.model.Chapter
|
||||
import ac.mdiq.podcini.storage.model.Episode
|
||||
import ac.mdiq.podcini.storage.model.EpisodeMedia
|
||||
import ac.mdiq.podcini.storage.model.Playable
|
||||
import ac.mdiq.podcini.storage.model.EmbeddedChapterImage
|
||||
import ac.mdiq.podcini.storage.model.*
|
||||
import ac.mdiq.podcini.storage.utils.ChapterUtils
|
||||
import ac.mdiq.podcini.storage.utils.ImageResourceUtils
|
||||
import ac.mdiq.podcini.ui.activity.MainActivity
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.ShownotesCleaner
|
||||
import ac.mdiq.podcini.ui.view.ShownotesWebView
|
||||
import ac.mdiq.podcini.util.DateFormatter
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import ac.mdiq.podcini.util.event.EventFlow
|
||||
import ac.mdiq.podcini.util.event.FlowEvent
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
|
@ -50,8 +46,9 @@ import coil.request.ErrorResult
|
|||
import coil.request.ImageRequest
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.dankito.readability4j.Readability4J
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
|
||||
|
@ -117,21 +114,24 @@ class PlayerDetailsFragment : Fragment() {
|
|||
override fun onStart() {
|
||||
Logd(TAG, "onStart()")
|
||||
super.onStart()
|
||||
procFlowEvents()
|
||||
// procFlowEvents()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
Logd(TAG, "onStop()")
|
||||
super.onStop()
|
||||
cancelFlowEvents()
|
||||
// cancelFlowEvents()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
prevItem = null
|
||||
currentItem = null
|
||||
Logd(TAG, "Fragment destroyed")
|
||||
shownoteView.removeAllViews()
|
||||
shownoteView.destroy()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onContextItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -280,6 +280,7 @@ class PlayerDetailsFragment : Fragment() {
|
|||
}
|
||||
|
||||
private fun refreshChapterData(chapterIndex: Int) {
|
||||
Logd(TAG, "in refreshChapterData $chapterIndex")
|
||||
if (playable != null && chapterIndex > -1) {
|
||||
if (playable!!.getPosition() > playable!!.getDuration() || chapterIndex >= playable!!.getChapters().size - 1) {
|
||||
displayedChapterIndex = playable!!.getChapters().size - 1
|
||||
|
@ -409,25 +410,25 @@ class PlayerDetailsFragment : Fragment() {
|
|||
savePreference()
|
||||
}
|
||||
|
||||
private var eventSink: Job? = null
|
||||
private fun cancelFlowEvents() {
|
||||
eventSink?.cancel()
|
||||
eventSink = null
|
||||
}
|
||||
private fun procFlowEvents() {
|
||||
if (eventSink != null) return
|
||||
eventSink = lifecycleScope.launch {
|
||||
EventFlow.events.collectLatest { event ->
|
||||
Logd(TAG, "Received event: ${event.TAG}")
|
||||
when (event) {
|
||||
is FlowEvent.PlaybackPositionEvent -> onEventMainThread(event)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// private var eventSink: Job? = null
|
||||
// private fun cancelFlowEvents() {
|
||||
// eventSink?.cancel()
|
||||
// eventSink = null
|
||||
// }
|
||||
// private fun procFlowEvents() {
|
||||
// if (eventSink != null) return
|
||||
// eventSink = lifecycleScope.launch {
|
||||
// EventFlow.events.collectLatest { event ->
|
||||
// Logd(TAG, "Received event: ${event.TAG}")
|
||||
// when (event) {
|
||||
// is FlowEvent.PlaybackPositionEvent -> onPlaybackPositionEvent(event)
|
||||
// else -> {}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun onEventMainThread(event: FlowEvent.PlaybackPositionEvent) {
|
||||
fun onPlaybackPositionEvent(event: FlowEvent.PlaybackPositionEvent) {
|
||||
if (playable?.getIdentifier() != event.media?.getIdentifier()) return
|
||||
val newChapterIndex: Int = ChapterUtils.getCurrentChapterIndex(playable, event.position)
|
||||
if (newChapterIndex >= 0 && newChapterIndex != displayedChapterIndex) {
|
||||
|
|
|
@ -30,6 +30,7 @@ import ac.mdiq.podcini.ui.adapter.SelectableAdapter
|
|||
import ac.mdiq.podcini.ui.dialog.ConfirmationDialog
|
||||
import ac.mdiq.podcini.ui.dialog.EpisodeSortDialog
|
||||
import ac.mdiq.podcini.ui.dialog.SwitchQueueDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.EmptyViewHandler
|
||||
import ac.mdiq.podcini.ui.utils.LiftOnScrollListener
|
||||
import ac.mdiq.podcini.ui.view.EpisodesRecyclerView
|
||||
|
@ -301,8 +302,7 @@ import java.util.*
|
|||
val item: Episode = event.episodes[i]
|
||||
val pos: Int = EpisodeUtil.indexOfItemWithId(queueItems, item.id)
|
||||
if (pos >= 0) {
|
||||
queueItems.removeAt(pos)
|
||||
queueItems.add(pos, item)
|
||||
queueItems[pos] = item
|
||||
adapter?.notifyItemChangedCompat(pos)
|
||||
refreshInfoBar()
|
||||
}
|
||||
|
@ -322,7 +322,8 @@ import java.util.*
|
|||
val pos: Int = EpisodeUtil.indexOfItemWithDownloadUrl(queueItems.toList(), downloadUrl)
|
||||
if (pos >= 0) {
|
||||
val item = queueItems[pos]
|
||||
item.media?.downloaded = true
|
||||
// item.media?.downloaded = true
|
||||
item.media?.setIsDownloaded()
|
||||
adapter?.notifyItemChangedCompat(pos)
|
||||
}
|
||||
}
|
||||
|
@ -380,12 +381,15 @@ import java.util.*
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
queueItems = mutableListOf()
|
||||
adapter?.endSelectMode()
|
||||
adapter?.clearData()
|
||||
adapter = null
|
||||
toolbar.setOnMenuItemClickListener(null)
|
||||
toolbar.setOnLongClickListener(null)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun refreshToolbarState() {
|
||||
|
|
|
@ -90,8 +90,8 @@ class QuickDiscoveryFragment : Fragment(), AdapterView.OnItemClickListener {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private var eventSink: Job? = null
|
||||
|
|
|
@ -2,6 +2,7 @@ package ac.mdiq.podcini.ui.fragment
|
|||
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.storage.model.Episode
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
import ac.mdiq.podcini.util.event.EventFlow
|
||||
import ac.mdiq.podcini.util.event.FlowEvent
|
||||
|
@ -46,6 +47,11 @@ import kotlin.math.min
|
|||
cancelFlowEvents()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
episodeList.clear()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
fun setEpisodes(episodeList_: MutableList<Episode>) {
|
||||
episodeList.clear()
|
||||
episodeList.addAll(episodeList_)
|
||||
|
|
|
@ -19,6 +19,7 @@ import ac.mdiq.podcini.ui.actions.menuhandler.MenuItemUtils
|
|||
import ac.mdiq.podcini.ui.activity.MainActivity
|
||||
import ac.mdiq.podcini.ui.adapter.EpisodesAdapter
|
||||
import ac.mdiq.podcini.ui.adapter.SelectableAdapter
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.EmptyViewHandler
|
||||
import ac.mdiq.podcini.ui.utils.LiftOnScrollListener
|
||||
import ac.mdiq.podcini.ui.view.EpisodesRecyclerView
|
||||
|
@ -185,8 +186,11 @@ import java.lang.ref.WeakReference
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
adapter.clearData()
|
||||
results = mutableListOf()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupToolbar(toolbar: MaterialToolbar) {
|
||||
|
@ -282,8 +286,7 @@ import java.lang.ref.WeakReference
|
|||
val item: Episode = event.episodes[i]
|
||||
val pos: Int = EpisodeUtil.indexOfItemWithId(results, item.id)
|
||||
if (pos >= 0) {
|
||||
results.removeAt(pos)
|
||||
results.add(pos, item)
|
||||
results[pos] = item
|
||||
adapter.notifyItemChangedCompat(pos)
|
||||
}
|
||||
i++
|
||||
|
|
|
@ -210,8 +210,12 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
feedList = mutableListOf()
|
||||
feedListFiltered = mutableListOf()
|
||||
adapter.clearData()
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
|
@ -309,7 +313,6 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
|
|||
lifecycleScope.launch {
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
feedList = getFeedList().toMutableList()
|
||||
sortFeeds()
|
||||
resetTags()
|
||||
}
|
||||
|
@ -396,7 +399,8 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
|
|||
comparator(counterMap, dir)
|
||||
}
|
||||
}
|
||||
synchronized(feedList) { feedList.sortWith(comparator) }
|
||||
val feedList_ = getFeedList().toMutableList()
|
||||
synchronized(feedList_) { feedList = feedList_.sortedWith(comparator).toMutableList() }
|
||||
}
|
||||
|
||||
private fun counterMap(episodes: RealmResults<Episode>): Map<Long, Long> {
|
||||
|
@ -552,6 +556,9 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener, Selec
|
|||
this.feedList = ArrayList()
|
||||
setHasStableIds(true)
|
||||
}
|
||||
fun clearData() {
|
||||
feedList = listOf()
|
||||
}
|
||||
fun getItem(position: Int): Any {
|
||||
return feedList[position]
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import ac.mdiq.podcini.ui.activity.VideoplayerActivity
|
|||
import ac.mdiq.podcini.ui.activity.VideoplayerActivity.Companion.videoMode
|
||||
import ac.mdiq.podcini.ui.activity.starter.MainActivityStarter
|
||||
import ac.mdiq.podcini.ui.dialog.SkipPreferenceDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.utils.PictureInPictureUtil
|
||||
import ac.mdiq.podcini.ui.utils.ShownotesCleaner
|
||||
import ac.mdiq.podcini.ui.view.ShownotesWebView
|
||||
|
@ -166,12 +167,13 @@ class VideoEpisodeFragment : Fragment(), OnSeekBarChangeListener {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
root.removeView(webvDescription)
|
||||
webvDescription.destroy()
|
||||
_binding = null
|
||||
controller?.release()
|
||||
controller = null // prevent leak
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private var eventSink: Job? = null
|
||||
|
|
|
@ -66,8 +66,8 @@ class FeedStatisticsFragment : Fragment() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -12,6 +12,8 @@ import ac.mdiq.podcini.ui.activity.MainActivity
|
|||
import ac.mdiq.podcini.ui.activity.starter.MainActivityStarter
|
||||
import ac.mdiq.podcini.ui.dialog.ConfirmationDialog
|
||||
import ac.mdiq.podcini.ui.dialog.DatesFilterDialog
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment
|
||||
import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion
|
||||
import ac.mdiq.podcini.ui.statistics.PieChartView.PieChartData
|
||||
import ac.mdiq.podcini.util.Converter.shortLocalizedDuration
|
||||
import ac.mdiq.podcini.util.Logd
|
||||
|
@ -92,8 +94,9 @@ class StatisticsFragment : Fragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
|
@ -218,8 +221,9 @@ class StatisticsFragment : Fragment() {
|
|||
cancelFlowEvents()
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
private var eventSink: Job? = null
|
||||
private fun cancelFlowEvents() {
|
||||
|
@ -370,8 +374,9 @@ class StatisticsFragment : Fragment() {
|
|||
cancelFlowEvents()
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
private var eventSink: Job? = null
|
||||
private fun cancelFlowEvents() {
|
||||
|
@ -561,8 +566,9 @@ class StatisticsFragment : Fragment() {
|
|||
return binding.root
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
Logd(TAG, "onDestroyView")
|
||||
_binding = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ac.mdiq.podcini.ui.utils
|
||||
|
||||
import ac.mdiq.podcini.R
|
||||
import ac.mdiq.podcini.storage.database.Episodes.deleteMediaOfEpisode
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
@ -8,25 +9,25 @@ import ac.mdiq.podcini.storage.model.Episode
|
|||
|
||||
object LocalDeleteModal {
|
||||
|
||||
fun showLocalFeedDeleteWarningIfNecessary(context: Context, items: Iterable<Episode>, deleteCommand: Runnable) {
|
||||
var anyLocalFeed = false
|
||||
fun deleteEpisodesWarnLocal(context: Context, items: Iterable<Episode>) {
|
||||
val localItems: MutableList<Episode> = mutableListOf()
|
||||
for (item in items) {
|
||||
if (item.feed?.isLocalFeed == true) {
|
||||
anyLocalFeed = true
|
||||
break
|
||||
}
|
||||
localItems.add(item)
|
||||
} else deleteMediaOfEpisode(context, item)
|
||||
}
|
||||
|
||||
if (!anyLocalFeed) {
|
||||
deleteCommand.run()
|
||||
return
|
||||
if (localItems.isNotEmpty()) {
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.delete_episode_label)
|
||||
.setMessage(R.string.delete_local_feed_warning_body)
|
||||
.setPositiveButton(R.string.delete_label) { dialog: DialogInterface?, which: Int ->
|
||||
for (item in localItems) {
|
||||
deleteMediaOfEpisode(context, item)
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.cancel_label, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.delete_episode_label)
|
||||
.setMessage(R.string.delete_local_feed_warning_body)
|
||||
.setPositiveButton(R.string.delete_label) { dialog: DialogInterface?, which: Int -> deleteCommand.run() }
|
||||
.setNegativeButton(R.string.cancel_label, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@ open class EpisodeViewHolder(private val activity: MainActivity, parent: ViewGro
|
|||
container.alpha = if (item.isPlayed()) 0.7f else 1.0f
|
||||
leftPadding.contentDescription = item.title
|
||||
binding.playedMark.visibility = View.GONE
|
||||
binding.txtvPubDate.setTextColor(getColorFromAttr(activity, com.google.android.material.R.attr.colorOnSurfaceVariant))
|
||||
when {
|
||||
item.isPlayed() -> {
|
||||
leftPadding.contentDescription = item.title + ". " + activity.getString(R.string.is_played)
|
||||
|
|
|
@ -155,6 +155,8 @@ sealed class FlowEvent {
|
|||
|
||||
data class AllEpisodesFilterEvent(val filterValues: Set<String?>?) : FlowEvent()
|
||||
|
||||
data class AllEpisodesSortEvent(val dummy: Unit = Unit) : FlowEvent()
|
||||
|
||||
data class EpisodeEvent(val episodes: List<Episode>) : FlowEvent() {
|
||||
companion object {
|
||||
fun updated(episodes: List<Episode>): EpisodeEvent {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path android:fillColor="?attr/action_icon_color" android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
|
||||
</vector>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<vector android:height="24dp"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path android:fillColor="#FFFFFFFF" android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
|
||||
</vector>
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?attr/action_icon_color" android:pathData="M12,5.69l5,4.5V18h-2v-6H9v6H7v-7.81l5,-4.5M12,3L2,12h3v8h6v-6h2v6h6v-8h3L12,3z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path
|
||||
android:fillColor="?attr/action_icon_color"
|
||||
android:pathData="M12,5.69l5,4.5V18h-2v-6H9v6H7v-7.81l5,-4.5M12,3L2,12h3v8h6v-6h2v6h6v-8h3L12,3z"/>
|
||||
</vector>
|
||||
|
|
|
@ -271,7 +271,7 @@
|
|||
<string name="skip_episode_label">Skip episode</string>
|
||||
<string name="reset_position">Reset playback position</string>
|
||||
<string name="no_items_selected">No items selected</string>
|
||||
<string name="delete_local_feed_warning_body">Deleting removes the episode from Podcini and deletes the media file from your device storage. It cannot be downloaded again through Podcini.</string>
|
||||
<string name="delete_local_feed_warning_body">Warning: you are deleting local episodes. It will delete the media files from your device storage. It cannot be downloaded again through Podcini. Continue?</string>
|
||||
|
||||
<!-- Download messages and labels -->
|
||||
<string name="download_successful">successful</string>
|
||||
|
|
10
changelog.md
10
changelog.md
|
@ -1,3 +1,13 @@
|
|||
## 6.0.8
|
||||
|
||||
* feeds sorting dialog layout is set to single column due to potential long text issue
|
||||
* fixed issue of not being able to copy text from player detailed view
|
||||
* fixed issue of some menu icon not correctly shown in dark theme
|
||||
* fixed issue of results not updated in views when deleting episodes
|
||||
* fixed issue of downloaded episode still showing as New
|
||||
* fixed sorting on All Episodes view
|
||||
* added more garbage collections
|
||||
|
||||
## 6.0.7
|
||||
|
||||
* feeds sorting is bi-directional and in the same style as episodes sorting
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
Version 6.0.8 brings several changes:
|
||||
|
||||
* feeds sorting dialog layout is set to single column due to potential long text issue
|
||||
* fixed issue of not being able to copy text from player detailed view
|
||||
* fixed issue of some menu icon not correctly shown in dark theme
|
||||
* fixed issue of results not updated in views when deleting episodes
|
||||
* fixed issue of downloaded episode still showing as New
|
||||
* fixed sorting on All Episodes view
|
||||
* added more garbage collections
|
Loading…
Reference in New Issue