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