From c29eb0bf1b2377082a61b4d7a22321bd0c20718e Mon Sep 17 00:00:00 2001 From: Xilin Jia <6257601+XilinJia@users.noreply.github.com> Date: Tue, 3 Sep 2024 06:58:12 +0100 Subject: [PATCH] 6.5.2 commit --- app/build.gradle | 14 ++-- app/proguard.cfg | 23 +++---- app/src/main/AndroidManifest.xml | 4 +- .../net/download/VistaDownloaderImpl.kt | 29 +++++--- .../net/download/service/PodciniHttpClient.kt | 8 +-- .../net/feed/discovery/CombinedSearcher.kt | 9 +-- .../net/sync/gpoddernet/GpodnetService.kt | 6 +- .../ac/mdiq/podcini/net/utils/UrlChecker.kt | 4 +- .../playback/service/LocalMediaPlayer.kt | 67 ++++++++----------- .../receiver/PowerConnectionReceiver.kt | 1 - .../ac/mdiq/podcini/storage/database/Feeds.kt | 10 +-- .../ui/fragment/FeedEpisodesFragment.kt | 12 ++-- .../ui/fragment/OnlineFeedViewFragment.kt | 1 + .../podcini/ui/fragment/QueuesFragment.kt | 2 +- .../ac/mdiq/podcini/dialog/RatingDialog.kt | 27 ++------ changelog.md | 5 ++ .../android/en-US/changelogs/3020236.txt | 4 ++ 17 files changed, 102 insertions(+), 124 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/3020236.txt diff --git a/app/build.gradle b/app/build.gradle index 450b7521..5e4d59b3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,8 +31,8 @@ android { testApplicationId "ac.mdiq.podcini.tests" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - versionCode 3020235 - versionName "6.5.1" + versionCode 3020236 + versionName "6.5.2" applicationId "ac.mdiq.podcini.R" def commit = "" @@ -90,8 +90,8 @@ android { compose true } - splits { - abi { + splits { + abi { enable true reset() include "arm64-v8a" // Specify the ABI you want to split. @@ -142,11 +142,11 @@ android { proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard.cfg" resValue "string", "app_name", "Podcini.R" resValue "string", "provider_authority", "ac.mdiq.podcini.R.provider" +// debuggable false vcsInfo.include false minifyEnabled true shrinkResources true signingConfig signingConfigs.releaseConfig - proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard.cfg" } debug { resValue "string", "app_name", "Podcini.R Debug" @@ -161,8 +161,8 @@ android { def buildType = variant.buildType.name def versionName = variant.versionName def flavorName = variant.flavorName ?: "" - def abiName = output.getFilter(com.android.build.OutputFile.ABI) ?: "universal" - outputFileName = "${applicationName}_${flavorName}_${buildType}_${versionName}_${abiName}.apk" + def abiName = output.getFilter(com.android.build.OutputFile.ABI) ?: "" + outputFileName = "${applicationName}_${buildType}_${flavorName}_${versionName}_${abiName}.apk" } } androidResources { diff --git a/app/proguard.cfg b/app/proguard.cfg index 25717d63..3af7827e 100644 --- a/app/proguard.cfg +++ b/app/proguard.cfg @@ -1,17 +1,21 @@ -dontobfuscate --renamesourcefileattribute SourceFile --keepattributes SourceFile,LineNumberTable + +#-renamesourcefileattribute SourceFile +-keepattributes Exceptions, SourceFile,LineNumberTable -optimizations !code/allocation/variable -optimizationpasses 5 ## Rules for VistaGuide +# -keepclassmembers class ac.mdiq.vista** {*;} -keep class ac.mdiq.vista.extractor.timeago.patterns.** { *; } -keep class org.mozilla.javascript.** { *; } -keep class org.mozilla.classfile.ClassFileWriter --keep class java.beans.** -dontwarn org.mozilla.javascript.tools.** +-keep class java.beans.** -dontwarn java.beans.** +-keep class ac.mdiq.vista.settings.notifications.** { *; } + -allowaccessmodification -dontskipnonpubliclibraryclassmembers @@ -19,8 +23,6 @@ # Without this, methods only used in tests are removed and break tests. -keep class ac.mdiq.podcini** -keepclassmembers class ac.mdiq.podcini** {*;} -# -keep class de.test.podcini** -# -keepclassmembers class de.test.podcini** {*;} # Keep methods used in tests. # This is only needed when running tests with proguard enabled. @@ -40,9 +42,6 @@ -dontwarn okhttp3.** -dontwarn okio.** -# android-iconify -#-keep class com.joanzapata.** { *; } - #### Proguard rules for fyyd client # Retrofit 2.0 -dontwarn retrofit2.** @@ -62,10 +61,10 @@ #### # awaitility --dontwarn java.beans.BeanInfo --dontwarn java.beans.Introspector --dontwarn java.beans.IntrospectionException --dontwarn java.beans.PropertyDescriptor +# -dontwarn java.beans.BeanInfo +# -dontwarn java.beans.Introspector +# -dontwarn java.beans.IntrospectionException +# -dontwarn java.beans.PropertyDescriptor -dontwarn java.lang.management.ManagementFactory -dontwarn java.lang.management.ThreadInfo -dontwarn java.lang.management.ThreadMXBean diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dd65545c..8a62c9c2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -45,8 +45,8 @@ android:supportsRtl="true" android:logo="@mipmap/ic_launcher" android:resizeableActivity="true" - android:allowAudioPlaybackCapture="true" - android:networkSecurityConfig="@xml/network_security_config"> + android:allowAudioPlaybackCapture="true"> + = HashMap() private val client: OkHttpClient = builder .readTimeout(30, TimeUnit.SECONDS) - // .cache(new Cache(new File(context.getExternalCacheDir(), "okhttp"), 16 * 1024 * 1024)) +// .cache(Cache(File(context.getExternalCacheDir(), "okhttp"), 16 * 1024 * 1024)) .build() private fun getCookies(url: String): String { @@ -107,17 +109,22 @@ class VistaDownloaderImpl private constructor(builder: OkHttpClient.Builder) : D } } - val response = client.newCall(requestBuilder.build()).execute() - if (response.code == 429) { - response.close() - throw ReCaptchaException("reCaptcha Challenge requested", url) + try { + val response = client.newCall(requestBuilder.build()).execute() + if (response.code == 429) { + response.close() + throw ReCaptchaException("reCaptcha Challenge requested", url) + } + + val body = response.body + val responseBodyToReturn: String? = body?.string() + + val latestUrl = response.request.url.toString() + return Response(response.code, response.message, response.headers.toMultimap(), responseBodyToReturn, latestUrl) + } catch (e: Throwable) { + e.printStackTrace() + throw IOException("Something is wrong ${e.message}") } - - val body = response.body - val responseBodyToReturn: String? = body?.string() - - val latestUrl = response.request.url.toString() - return Response(response.code, response.message, response.headers.toMultimap(), responseBodyToReturn, latestUrl) } companion object { diff --git a/app/src/main/kotlin/ac/mdiq/podcini/net/download/service/PodciniHttpClient.kt b/app/src/main/kotlin/ac/mdiq/podcini/net/download/service/PodciniHttpClient.kt index 74f86905..de3a762c 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/net/download/service/PodciniHttpClient.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/net/download/service/PodciniHttpClient.kt @@ -101,9 +101,7 @@ object PodciniHttpClient { if (!proxyConfig!!.username.isNullOrEmpty() && proxyConfig!!.password != null) { builder.proxyAuthenticator { _: Route?, response: Response -> val credentials = basic(proxyConfig!!.username!!, proxyConfig!!.password!!) - response.request.newBuilder() - .header("Proxy-Authorization", credentials) - .build() + response.request.newBuilder().header("Proxy-Authorization", credentials).build() } } } @@ -126,9 +124,7 @@ object PodciniHttpClient { @Throws(IOException::class) override fun intercept(chain: Chain): Response { TrafficStats.setThreadStatsTag(Thread.currentThread().id.toInt()) - return chain.proceed(chain.request().newBuilder() - .header("User-Agent", ClientConfig.USER_AGENT?:"") - .build()) + return chain.proceed(chain.request().newBuilder().header("User-Agent", ClientConfig.USER_AGENT?:"").build()) } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/net/feed/discovery/CombinedSearcher.kt b/app/src/main/kotlin/ac/mdiq/podcini/net/feed/discovery/CombinedSearcher.kt index 7821f26f..3fd2597f 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/net/feed/discovery/CombinedSearcher.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/net/feed/discovery/CombinedSearcher.kt @@ -1,5 +1,6 @@ package ac.mdiq.podcini.net.feed.discovery +import ac.mdiq.podcini.util.Logd import android.util.Log import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -21,13 +22,9 @@ class CombinedSearcher : PodcastSearcher { try { val results = searcher.search(query) searchResults[index] = results - } catch (e: Throwable) { - Log.d(TAG, Log.getStackTraceString(e)) - } + } catch (e: Throwable) { Logd(TAG, Log.getStackTraceString(e)) } } - } else { - null - } + } else null }.filterNotNull() // Remove null jobs // Wait for all search jobs to complete searchJobs.awaitAll() diff --git a/app/src/main/kotlin/ac/mdiq/podcini/net/sync/gpoddernet/GpodnetService.kt b/app/src/main/kotlin/ac/mdiq/podcini/net/sync/gpoddernet/GpodnetService.kt index a248e51a..0d7f25bb 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/net/sync/gpoddernet/GpodnetService.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/net/sync/gpoddernet/GpodnetService.kt @@ -391,11 +391,7 @@ class GpodnetService(private val httpClient: OkHttpClient, baseHosturl: String?, throw GpodnetServiceAuthenticationException("Wrong username or password") } else { if (BuildConfig.DEBUG) { - try { - Logd(TAG, response.body!!.string()) - } catch (e: IOException) { - e.printStackTrace() - } + try { Logd(TAG, response.body!!.string()) } catch (e: IOException) { e.printStackTrace() } } if (responseCode >= 500) { throw GpodnetServiceBadStatusCodeException("Gpodder.net is currently unavailable (code " + responseCode + ")", responseCode) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/net/utils/UrlChecker.kt b/app/src/main/kotlin/ac/mdiq/podcini/net/utils/UrlChecker.kt index da898ee9..5574ad6e 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/net/utils/UrlChecker.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/net/utils/UrlChecker.kt @@ -39,7 +39,9 @@ object UrlChecker { // prepareUrl(removedWebsite) // } // } - !(lowerCaseUrl.startsWith("http://") || lowerCaseUrl.startsWith("https://")) -> "http://$url" +// TODO: test +// !(lowerCaseUrl.startsWith("http://") || lowerCaseUrl.startsWith("https://")) -> "http://$url" + !(lowerCaseUrl.startsWith("http://") || lowerCaseUrl.startsWith("https://")) -> "https://$url" else -> url } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/playback/service/LocalMediaPlayer.kt b/app/src/main/kotlin/ac/mdiq/podcini/playback/service/LocalMediaPlayer.kt index b7b0fba0..46752f1d 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/playback/service/LocalMediaPlayer.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/playback/service/LocalMediaPlayer.kt @@ -1,6 +1,5 @@ package ac.mdiq.podcini.playback.service -import ac.mdiq.podcini.BuildConfig import ac.mdiq.podcini.R import ac.mdiq.podcini.net.download.service.HttpCredentialEncoder import ac.mdiq.podcini.net.download.service.PodciniHttpClient @@ -20,11 +19,11 @@ import ac.mdiq.podcini.storage.model.Feed import ac.mdiq.podcini.storage.model.MediaType import ac.mdiq.podcini.storage.model.Playable import ac.mdiq.podcini.storage.utils.EpisodeUtil -import ac.mdiq.podcini.util.Logd -import ac.mdiq.podcini.util.config.ClientConfig import ac.mdiq.podcini.util.EventFlow import ac.mdiq.podcini.util.FlowEvent import ac.mdiq.podcini.util.FlowEvent.PlayEvent.Action +import ac.mdiq.podcini.util.Logd +import ac.mdiq.podcini.util.config.ClientConfig import ac.mdiq.vista.extractor.MediaFormat import ac.mdiq.vista.extractor.Vista import ac.mdiq.vista.extractor.stream.* @@ -56,7 +55,6 @@ import androidx.media3.exoplayer.source.ProgressiveMediaSource import androidx.media3.exoplayer.trackselection.DefaultTrackSelector import androidx.media3.exoplayer.trackselection.DefaultTrackSelector.SelectionOverride import androidx.media3.exoplayer.trackselection.ExoTrackSelection -import androidx.media3.exoplayer.util.EventLogger import androidx.media3.extractor.DefaultExtractorsFactory import androidx.media3.extractor.mp3.Mp3Extractor import androidx.media3.ui.DefaultTrackNameProvider @@ -67,8 +65,6 @@ import java.lang.Runnable import java.util.* import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit -import kotlin.collections.ArrayList -import kotlin.collections.HashMap import kotlin.concurrent.Volatile /** @@ -186,28 +182,29 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP @Throws(IllegalArgumentException::class, IllegalStateException::class) private fun setDataSource(metadata: MediaMetadata, media: EpisodeMedia) { val url = media.getStreamUrl() ?: return - Logd(TAG, "setDataSource1: $url") val preferences = media.episodeOrFetch()?.feed?.preferences val user = preferences?.username val password = preferences?.password if (media.episode?.feed?.type == Feed.FeedType.YOUTUBE.name) { - Logd(TAG, "setDataSource setting for YouTube source") + Logd(TAG, "setDataSource1 setting for YouTube source") try { - val streamInfo = StreamInfo.getInfo(Vista.getService(0), url) + val vService = Vista.getService(0) + val streamInfo = StreamInfo.getInfo(vService, url) val audioStreamsList = getFilteredAudioStreams(streamInfo.audioStreams) + Logd(TAG, "setDataSource1 got ${audioStreamsList.size}") val audioIndex = if (isNetworkRestricted) 0 else audioStreamsList.size - 1 val audioStream = audioStreamsList[audioIndex] + Logd(TAG, "setDataSource1 use audio quality: ${audioStream.bitrate}") val aSource = DefaultMediaSourceFactory(context).createMediaSource(MediaItem.Builder().setTag(metadata).setUri(Uri.parse(audioStream.content)).build()) - Logd(TAG, "setDataSource use audio quality: ${audioStream.bitrate}") if (media.episode?.feed?.preferences?.playAudioOnly != true) { - Logd(TAG, "setDataSource result: $streamInfo") - Logd(TAG, "setDataSource videoStreams: ${streamInfo.videoStreams.size} videoOnlyStreams: ${streamInfo.videoOnlyStreams.size} audioStreams: ${streamInfo.audioStreams.size}") + Logd(TAG, "setDataSource1 result: $streamInfo") + Logd(TAG, "setDataSource1 videoStreams: ${streamInfo.videoStreams.size} videoOnlyStreams: ${streamInfo.videoOnlyStreams.size} audioStreams: ${streamInfo.audioStreams.size}") val videoStreamsList = getSortedStreamVideosList(streamInfo.videoStreams, streamInfo.videoOnlyStreams, true, true) val videoIndex = 0 val videoStream = videoStreamsList[videoIndex] - Logd(TAG, "setDataSource use video quality: ${videoStream.resolution}") + Logd(TAG, "setDataSource1 use video quality: ${videoStream.resolution}") val vSource = DefaultMediaSourceFactory(context).createMediaSource(MediaItem.Builder().setTag(metadata).setUri(Uri.parse(videoStream.content)).build()) - val mediaSources: MutableList = java.util.ArrayList() + val mediaSources: MutableList = ArrayList() mediaSources.add(vSource) mediaSources.add(aSource) mediaSource = MergingMediaSource(true, *mediaSources.toTypedArray()) @@ -215,9 +212,9 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP } else mediaSource = aSource mediaItem = mediaSource?.mediaItem setSourceCredentials(user, password) - } catch (throwable: Throwable) { Logd(TAG, "setDataSource error: ${throwable.message}") } + } catch (throwable: Throwable) { Log.e(TAG, "setDataSource1 error: ${throwable.message}") } } else { - Logd(TAG, "setDataSource setting for Podcast source") + Logd(TAG, "setDataSource1 setting for Podcast source") setDataSource(metadata, url,user, password) } } @@ -255,15 +252,15 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP * streams and normal video streams are available * @return the sorted list */ - fun getSortedStreamVideosList(videoStreams: List?, videoOnlyStreams: List?, ascendingOrder: Boolean, + private fun getSortedStreamVideosList(videoStreams: List?, videoOnlyStreams: List?, ascendingOrder: Boolean, preferVideoOnlyStreams: Boolean): List { val videoStreamsOrdered = if (preferVideoOnlyStreams) listOf(videoStreams, videoOnlyStreams) else listOf(videoOnlyStreams, videoStreams) - val allInitialStreams = videoStreamsOrdered.filterNotNull().flatMap { it }.toList() + val allInitialStreams = videoStreamsOrdered.filterNotNull().flatten().toList() val comparator = compareBy { it.resolution.toResolutionValue() } return if (ascendingOrder) allInitialStreams.sortedWith(comparator) else { allInitialStreams.sortedWith(comparator.reversed()) } } - fun String.toResolutionValue(): Int { + private fun String.toResolutionValue(): Int { val match = Regex("(\\d+)p|(\\d+)k").find(this) return when { match?.groupValues?.get(1) != null -> match.groupValues[1].toInt() @@ -272,7 +269,7 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP } } - fun getFilteredAudioStreams(audioStreams: List?): List { + private fun getFilteredAudioStreams(audioStreams: List?): List { if (audioStreams == null) return listOf() val collectedStreams = mutableSetOf() for (stream in audioStreams) { @@ -281,7 +278,7 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP continue collectedStreams.add(stream) } - return collectedStreams.toList().sortedWith(compareBy { it.bitrate }) + return collectedStreams.toList().sortedWith(compareBy { it.bitrate }) } /** @@ -355,7 +352,8 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP if (streamurl != null) { val media = curMedia if (media is EpisodeMedia) { - setDataSource(metadata, media) + val deferred = CoroutineScope(Dispatchers.IO).async { setDataSource(metadata, media) } + runBlocking { deferred.await() } // val preferences = media.episodeOrFetch()?.feed?.preferences // setDataSource(metadata, streamurl, preferences?.username, preferences?.password) } else setDataSource(metadata, streamurl, null, null) @@ -381,13 +379,12 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP e.printStackTrace() setPlayerStatus(PlayerStatus.ERROR, null) EventFlow.postStickyEvent(FlowEvent.PlayerErrorEvent(e.localizedMessage ?: "")) - } finally { - } + } finally { } } override fun resume() { if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) { - Log.d(TAG, "Resuming/Starting playback") + Logd(TAG, "Resuming/Starting playback") acquireWifiLockIfNecessary() setPlaybackParams(getCurrentPlaybackSpeed(curMedia), UserPreferences.isSkipSilence) setVolume(1.0f, 1.0f) @@ -441,9 +438,7 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP releaseWifiLockIfNecessary() when { curMedia != null -> playMediaObject(curMedia!!, isStreaming, startWhenPrepared.get(), prepareImmediately = false, true) - else -> { - Logd(TAG, "Call to reinit: media and mediaPlayer were null, ignored") - } + else -> Logd(TAG, "Call to reinit: media and mediaPlayer were null, ignored") } } @@ -466,11 +461,7 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP PlayerStatus.PLAYING, PlayerStatus.PAUSED, PlayerStatus.PREPARED -> { Logd(TAG, "seekTo() called $t") if (seekLatch != null && seekLatch!!.count > 0) { - try { - seekLatch!!.await(3, TimeUnit.SECONDS) - } catch (e: InterruptedException) { - Log.e(TAG, Log.getStackTraceString(e)) - } + try { seekLatch!!.await(3, TimeUnit.SECONDS) } catch (e: InterruptedException) { Log.e(TAG, Log.getStackTraceString(e)) } } seekLatch = CountDownLatch(1) statusBeforeSeeking = status @@ -479,11 +470,7 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP if (curMedia != null) EventFlow.postEvent(FlowEvent.PlaybackPositionEvent(curMedia, t, curMedia!!.getDuration())) audioSeekCompleteListener?.run() if (statusBeforeSeeking == PlayerStatus.PREPARED) curMedia?.setPosition(t) - try { - seekLatch!!.await(3, TimeUnit.SECONDS) - } catch (e: InterruptedException) { - Log.e(TAG, Log.getStackTraceString(e)) - } + try { seekLatch!!.await(3, TimeUnit.SECONDS) } catch (e: InterruptedException) { Log.e(TAG, Log.getStackTraceString(e)) } } PlayerStatus.INITIALIZED -> { curMedia?.setPosition(t) @@ -729,7 +716,7 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP override fun onIsPlayingChanged(isPlaying: Boolean) { val stat = if (isPlaying) PlayerStatus.PLAYING else PlayerStatus.PAUSED setPlayerStatus(stat, curMedia) - Log.d(TAG, "onIsPlayingChanged $isPlaying") + Logd(TAG, "onIsPlayingChanged $isPlaying") } override fun onPlayerError(error: PlaybackException) { Logd(TAG, "onPlayerError ${error.message}") @@ -808,7 +795,7 @@ class LocalMediaPlayer(context: Context, callback: MediaPlayerCallback) : MediaP .setAudioOffloadPreferences(audioOffloadPreferences) .build() - if (BuildConfig.DEBUG) exoPlayer!!.addAnalyticsListener(EventLogger()) +// if (BuildConfig.DEBUG) exoPlayer!!.addAnalyticsListener(EventLogger()) if (exoplayerListener != null) { exoPlayer?.removeListener(exoplayerListener!!) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/receiver/PowerConnectionReceiver.kt b/app/src/main/kotlin/ac/mdiq/podcini/receiver/PowerConnectionReceiver.kt index 12364f46..4719a3c6 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/receiver/PowerConnectionReceiver.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/receiver/PowerConnectionReceiver.kt @@ -19,7 +19,6 @@ import android.util.Log class PowerConnectionReceiver : BroadcastReceiver() { @UnstableApi override fun onReceive(context: Context, intent: Intent) { val action = intent.action - Log.d(TAG, "onReceive charging intent: $action") ClientConfigurator.initialize(context) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Feeds.kt b/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Feeds.kt index 9b1692b0..592a5c44 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Feeds.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/storage/database/Feeds.kt @@ -152,11 +152,11 @@ object Feeds { } fun getFeed(feedId: Long, copy: Boolean = false): Feed? { - if (BuildConfig.DEBUG) { - val stackTrace = Thread.currentThread().stackTrace - val caller = if (stackTrace.size > 3) stackTrace[3] else null - Logd(TAG, "${caller?.className}.${caller?.methodName} getFeed called") - } +// if (BuildConfig.DEBUG) { +// val stackTrace = Thread.currentThread().stackTrace +// val caller = if (stackTrace.size > 3) stackTrace[3] else null +// Logd(TAG, "${caller?.className}.${caller?.methodName} getFeed called") +// } val f = realm.query(Feed::class, "id == $feedId").first().find() return if (f != null) { if (copy) realm.copyFromRealm(f) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedEpisodesFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedEpisodesFragment.kt index 367f45bc..bd9e59bc 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedEpisodesFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedEpisodesFragment.kt @@ -689,9 +689,7 @@ import java.util.concurrent.Semaphore runOnIOScope { val feed_ = realm.query(Feed::class, "id == ${feed.id}").first().find() if (feed_ != null) { - upsert(feed_) { - it.sortOrder = sortOrder - } + upsert(feed_) { it.sortOrder = sortOrder } } } } @@ -737,6 +735,10 @@ import java.util.concurrent.Semaphore private const val ARGUMENT_FEED_ID = "argument.ac.mdiq.podcini.feed_id" private const val KEY_UP_ARROW = "up_arrow" + var tts: TextToSpeech? = null + var ttsReady = false + var ttsWorking = false + fun newInstance(feedId: Long): FeedEpisodesFragment { val i = FeedEpisodesFragment() val b = Bundle() @@ -744,9 +746,5 @@ import java.util.concurrent.Semaphore i.arguments = b return i } - - var tts: TextToSpeech? = null - var ttsReady = false - var ttsWorking = false } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/OnlineFeedViewFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/OnlineFeedViewFragment.kt index 2b17685a..9f01c5d4 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/OnlineFeedViewFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/OnlineFeedViewFragment.kt @@ -268,6 +268,7 @@ class OnlineFeedViewFragment : Fragment() { val channelTabInfo = ChannelTabInfo.getInfo(service, channelInfo.tabs.first()) Logd(TAG, "startFeedBuilding result1: $channelTabInfo ${channelTabInfo.relatedItems.size}") selectedDownloadUrl = prepareUrl(url) +// selectedDownloadUrl = url val feed_ = Feed(selectedDownloadUrl, null) feed_.id = 1234567889L feed_.type = Feed.FeedType.YOUTUBE.name diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/QueuesFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/QueuesFragment.kt index df8b2142..3aa4c533 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/QueuesFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/QueuesFragment.kt @@ -403,7 +403,7 @@ import java.util.* } private fun onFeedPrefsChanged(event: FlowEvent.FeedPrefsChangeEvent) { - Log.d(TAG,"speedPresetChanged called") + Logd(TAG,"speedPresetChanged called") for (item in queueItems) { if (item.feed?.id == event.feed.id) item.feed = null } diff --git a/app/src/play/kotlin/ac/mdiq/podcini/dialog/RatingDialog.kt b/app/src/play/kotlin/ac/mdiq/podcini/dialog/RatingDialog.kt index 37891387..2128ccdc 100644 --- a/app/src/play/kotlin/ac/mdiq/podcini/dialog/RatingDialog.kt +++ b/app/src/play/kotlin/ac/mdiq/podcini/dialog/RatingDialog.kt @@ -31,18 +31,12 @@ object RatingDialog { mPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) val firstDate: Long = mPreferences.getLong(KEY_FIRST_START_DATE, 0) - if (firstDate == 0L) { - resetStartDate() - } + if (firstDate == 0L) resetStartDate() } fun check() { if (shouldShow()) { - try { - showInAppReview() - } catch (e: Exception) { - Log.e(TAG, Log.getStackTraceString(e)) - } + try { showInAppReview() } catch (e: Exception) { Log.e(TAG, Log.getStackTraceString(e)) } } } @@ -58,9 +52,8 @@ object RatingDialog { val flow: Task = manager.launchReviewFlow(context as Activity, reviewInfo) flow.addOnCompleteListener { task1: Task? -> val previousAttempts: Int = mPreferences.getInt(KEY_NUMBER_OF_REVIEWS, 0) - if (previousAttempts >= 3) { - saveRated() - } else { + if (previousAttempts >= 3) saveRated() + else { resetStartDate() mPreferences .edit() @@ -69,14 +62,10 @@ object RatingDialog { } Logd("ReviewDialog", "Successfully finished in-app review") } - .addOnFailureListener { error: Exception? -> - Logd("ReviewDialog", "failed in reviewing process") - } + .addOnFailureListener { error: Exception? -> Logd("ReviewDialog", "failed in reviewing process") } } } - .addOnFailureListener { error: Exception? -> - Logd("ReviewDialog", "failed to get in-app review request") - } + .addOnFailureListener { error: Exception? -> Logd("ReviewDialog", "failed to get in-app review request") } } private fun rated(): Boolean { @@ -99,9 +88,7 @@ object RatingDialog { } private fun shouldShow(): Boolean { - if (rated() || BuildConfig.DEBUG) { - return false - } + if (rated() || BuildConfig.DEBUG) return false val now = System.currentTimeMillis() val firstDate: Long = mPreferences.getLong(KEY_FIRST_START_DATE, now) diff --git a/changelog.md b/changelog.md index ddbeb454..60c3320a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,8 @@ +# 6.5.2 + +* replace all url of http to https +* resolved the nasty issue of Youtube media not properly played in release app + # 6.5.1 * further improved behavior in video player, seamless switch among audio-only, window and fullscreen modes, and automatical switch to audio when exit diff --git a/fastlane/metadata/android/en-US/changelogs/3020236.txt b/fastlane/metadata/android/en-US/changelogs/3020236.txt new file mode 100644 index 00000000..296401e7 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/3020236.txt @@ -0,0 +1,4 @@ + Version 6.5.2 brings several changes: + +* replace all url of http to https +* resolved the nasty issue of Youtube media not properly played in release app