From ac412c390639f23fc7a46a1e3e6ab0defd88ea5d Mon Sep 17 00:00:00 2001 From: Xilin Jia <6257601+XilinJia@users.noreply.github.com> Date: Thu, 17 Oct 2024 14:42:23 +0100 Subject: [PATCH] 6.11.4 commit --- Licenses_and_permissions.md | 2 +- app/build.gradle | 6 +- .../podcini/ui/actions/EpisodeActionButton.kt | 8 +- .../mdiq/podcini/ui/actions/SwipeActions.kt | 4 +- .../mdiq/podcini/ui/activity/MainActivity.kt | 18 ++-- .../ac/mdiq/podcini/ui/compose/EpisodesVM.kt | 18 ++-- .../ac/mdiq/podcini/ui/compose/Feeds.kt | 25 ++++-- .../podcini/ui/dialog/EpisodeFilterDialog.kt | 24 ------ .../podcini/ui/dialog/EpisodeSortDialog.kt | 24 ------ .../mdiq/podcini/ui/dialog/FeedSortDialog.kt | 26 +----- .../ui/fragment/AudioPlayerFragment.kt | 29 +++---- .../ui/fragment/EpisodeInfoFragment.kt | 6 +- .../ui/fragment/FeedEpisodesFragment.kt | 7 +- .../podcini/ui/fragment/FeedInfoFragment.kt | 85 ++++++++++--------- .../podcini/ui/fragment/OnlineFeedFragment.kt | 4 +- .../podcini/ui/fragment/QueuesFragment.kt | 3 +- .../ui/fragment/SubscriptionsFragment.kt | 19 ----- .../ui/utils/LockableBottomSheetBehavior.kt | 63 -------------- .../ViewPagerBottomSheetBehavior.kt | 55 ------------ app/src/main/res/layout/main_activity.xml | 2 +- .../res/layout/multi_select_speed_dial.xml | 41 --------- app/src/main/res/values/dimens.xml | 2 +- changelog.md | 12 +++ .../android/en-US/changelogs/3020274.txt | 11 +++ gradle/libs.versions.toml | 14 +-- 25 files changed, 139 insertions(+), 369 deletions(-) delete mode 100644 app/src/main/kotlin/ac/mdiq/podcini/ui/utils/LockableBottomSheetBehavior.kt delete mode 100644 app/src/main/kotlin/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.kt delete mode 100644 app/src/main/res/layout/multi_select_speed_dial.xml create mode 100644 fastlane/metadata/android/en-US/changelogs/3020274.txt diff --git a/Licenses_and_permissions.md b/Licenses_and_permissions.md index 9492bb91..2f833a1c 100644 --- a/Licenses_and_permissions.md +++ b/Licenses_and_permissions.md @@ -26,7 +26,7 @@ Apache License 2.0 [com.mikepenz:iconics-core](https://github.com/mikepenz/Android-Iconics/blob/develop/LICENSE) Apache License 2.0 -[com.leinardi.android](https://github.com/leinardi/FloatingActionButtonSpeedDial/blob/release/LICENSE) Apache License 2.0 +[//]: # ([com.leinardi.android](https://github.com/leinardi/FloatingActionButtonSpeedDial/blob/release/LICENSE) Apache License 2.0) [com.github.ByteHamster](https://github.com/ByteHamster/SearchPreference/blob/master/LICENSE) MIT License diff --git a/app/build.gradle b/app/build.gradle index 73b28957..1c8b4ec6 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 3020273 - versionName "6.11.3" + versionCode 3020274 + versionName "6.11.4" applicationId "ac.mdiq.podcini.R" def commit = "" @@ -240,7 +240,7 @@ dependencies { implementation libs.google.material.typeface.outlined implementation libs.fontawesome.typeface - implementation libs.speed.dial +// implementation libs.speed.dial implementation libs.searchpreference implementation libs.balloon implementation libs.recyclerviewswipedecorator diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/actions/EpisodeActionButton.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/actions/EpisodeActionButton.kt index ad765d86..9211ae13 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/actions/EpisodeActionButton.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/actions/EpisodeActionButton.kt @@ -440,13 +440,11 @@ class TTSActionButton(item: Episode) : EpisodeActionButton(item) { j++ Logd(TAG, "onDone ${mediaFile.length()} $utteranceId") } - @Deprecated("Deprecated in Java") override fun onError(utteranceId: String) { Log.e(TAG, "onError utterance error: $utteranceId") Log.e(TAG, "onError $readerText") } - override fun onError(utteranceId: String, errorCode: Int) { Log.e(TAG, "onError1 utterance error: $utteranceId $errorCode") Log.e(TAG, "onError1 $readerText") @@ -504,11 +502,7 @@ class TTSActionButton(item: Episode) : EpisodeActionButton(item) { f.delete() } FeedEpisodesFragment.ttsWorking = false - } else withContext(Dispatchers.Main) { - Toast.makeText(context, - R.string.episode_has_no_content, - Toast.LENGTH_LONG).show() - } + } else withContext(Dispatchers.Main) { Toast.makeText(context, R.string.episode_has_no_content, Toast.LENGTH_LONG).show() } item.setPlayed(false) processing = 1f diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/actions/SwipeActions.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/actions/SwipeActions.kt index f6aea8fb..ac4b1363 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/actions/SwipeActions.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/actions/SwipeActions.kt @@ -600,8 +600,8 @@ open class SwipeActions(private val fragment: Fragment, private val tag: String) } showPickerDialog = false }) { - Icon(painter = painterResource(keys[index].getActionIcon()), tint = Color.Black, contentDescription = null, modifier = Modifier.width(35.dp).height(35.dp)) - Text(keys[index].getTitle(context), textAlign = TextAlign.Center) + Icon(painter = painterResource(keys[index].getActionIcon()), tint = textColor, contentDescription = null, modifier = Modifier.width(35.dp).height(35.dp)) + Text(keys[index].getTitle(context), color = textColor, textAlign = TextAlign.Center) } } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/activity/MainActivity.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/activity/MainActivity.kt index b8493bdf..d941b205 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/activity/MainActivity.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/activity/MainActivity.kt @@ -29,7 +29,6 @@ import ac.mdiq.podcini.ui.dialog.RatingDialog import ac.mdiq.podcini.ui.fragment.* import ac.mdiq.podcini.ui.fragment.AudioPlayerFragment.Companion.media3Controller import ac.mdiq.podcini.ui.statistics.StatisticsFragment -import ac.mdiq.podcini.ui.utils.LockableBottomSheetBehavior import ac.mdiq.podcini.ui.utils.ThemeUtils.getDrawableFromAttr import ac.mdiq.podcini.ui.utils.TransitionEffect import ac.mdiq.podcini.util.EventFlow @@ -57,7 +56,6 @@ import android.view.ViewGroup.MarginLayoutParams import android.widget.EditText import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.ActionBarDrawerToggle -import androidx.compose.ui.platform.ComposeView import androidx.core.graphics.Insets import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat @@ -99,7 +97,7 @@ class MainActivity : CastEnabledActivity() { private lateinit var navDrawer: View private lateinit var dummyView : View private lateinit var controllerFuture: ListenableFuture - lateinit var bottomSheet: LockableBottomSheetBehavior<*> + lateinit var bottomSheet: BottomSheetBehavior<*> private set private var drawerToggle: ActionBarDrawerToggle? = null @@ -239,10 +237,10 @@ class MainActivity : CastEnabledActivity() { runOnIOScope { checkFirstLaunch() } - this.bottomSheet = BottomSheetBehavior.from(audioPlayerView) as LockableBottomSheetBehavior<*> + this.bottomSheet = BottomSheetBehavior.from(audioPlayerView) this.bottomSheet.isHideable = false this.bottomSheet.isDraggable = false - this.bottomSheet.setBottomSheetCallback(bottomSheetCallback) + this.bottomSheet.addBottomSheetCallback(bottomSheetCallback) restartUpdateAlarm(this, false) runOnIOScope { SynchronizationQueueSink.syncNowIfNotSyncedRecently() } @@ -362,6 +360,7 @@ class MainActivity : CastEnabledActivity() { // WorkManager.getInstance(this).pruneWork() _binding = null // realm.close() + bottomSheet.removeBottomSheetCallback(bottomSheetCallback) drawerLayout?.removeDrawerListener(drawerToggle!!) MediaController.releaseFuture(controllerFuture) super.onDestroy() @@ -380,6 +379,7 @@ class MainActivity : CastEnabledActivity() { private fun updateInsets() { setPlayerVisible(audioPlayerView.visibility == View.VISIBLE) val playerHeight = resources.getDimension(R.dimen.external_player_height).toInt() + Logd(TAG, "playerHeight: $playerHeight ${navigationBarInsets.bottom}") bottomSheet.peekHeight = playerHeight + navigationBarInsets.bottom } @@ -387,20 +387,16 @@ class MainActivity : CastEnabledActivity() { Logd(TAG, "setPlayerVisible $visible_") val visible = visible_ ?: (bottomSheet.state != BottomSheetBehavior.STATE_COLLAPSED) - bottomSheet.setLocked(!visible) +// bottomSheet.setLocked(!visible) if (visible) bottomSheetCallback.onStateChanged(dummyView, bottomSheet.state) // Update toolbar visibility else bottomSheet.setState(BottomSheetBehavior.STATE_COLLAPSED) val params = mainView.layoutParams as MarginLayoutParams val externalPlayerHeight = resources.getDimension(R.dimen.external_player_height).toInt() + Logd(TAG, "externalPlayerHeight: $externalPlayerHeight ${navigationBarInsets.bottom}") params.setMargins(navigationBarInsets.left, 0, navigationBarInsets.right, navigationBarInsets.bottom + (if (visible) externalPlayerHeight else 0)) mainView.layoutParams = params -// val playerView = findViewById(R.id.playerFragment1) -// val playerView = findViewById(R.id.player1) -// val playerParams = playerView?.layoutParams as? MarginLayoutParams -// playerParams?.setMargins(navigationBarInsets.left, 0, navigationBarInsets.right, 0) -// playerView?.layoutParams = playerParams audioPlayerView.visibility = if (visible) View.VISIBLE else View.GONE } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/compose/EpisodesVM.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/compose/EpisodesVM.kt index 077d82cb..c3b9e979 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/compose/EpisodesVM.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/compose/EpisodesVM.kt @@ -81,6 +81,7 @@ import androidx.compose.ui.window.Dialog import androidx.constraintlayout.compose.ConstraintLayout import androidx.documentfile.provider.DocumentFile import coil.compose.AsyncImage +import coil.compose.rememberAsyncImagePainter import io.realm.kotlin.notifications.SingleQueryChange import io.realm.kotlin.notifications.UpdatedObject import kotlinx.coroutines.* @@ -602,10 +603,10 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: SnapshotStateList, ConstraintLayout(modifier = Modifier.width(56.dp).height(56.dp)) { val (imgvCover, checkMark) = createRefs() val imgLoc = ImageResourceUtils.getEpisodeListImageLocation(vm.episode) - Logd(TAG, "imgLoc: $imgLoc") - AsyncImage(model = imgLoc, contentDescription = "imgvCover", - placeholder = painterResource(R.mipmap.ic_launcher), - error = painterResource(R.mipmap.ic_launcher), + val painter = rememberAsyncImagePainter(model = imgLoc) + Image( + painter = painter, + contentDescription = "imgvCover", modifier = Modifier.width(56.dp).height(56.dp) .constrainAs(imgvCover) { top.linkTo(parent.top) @@ -615,7 +616,8 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: SnapshotStateList, Logd(TAG, "icon clicked!") if (selectMode) toggleSelected() else if (vm.episode.feed != null) activity.loadChildFragment(FeedInfoFragment.newInstance(vm.episode.feed!!)) - })) + }) + ) val alpha = if (vm.playedState) 1.0f else 0f if (vm.playedState) Icon(painter = painterResource(R.drawable.ic_check), tint = textColor, contentDescription = "played_mark", modifier = Modifier.background(Color.Green).alpha(alpha).constrainAs(checkMark) { @@ -645,7 +647,7 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: SnapshotStateList, if (index>=vms.size) return@LaunchedEffect vms[index].inQueueState = curQueue.contains(vms[index].episode) } - val dur = vm.episode.media!!.getDuration() + val dur = vm.episode.media?.getDuration() ?: 0 val durText = DurationConverter.getDurationStringLong(dur) Row { if (vm.episode.media?.getMediaType() == MediaType.VIDEO) @@ -656,7 +658,7 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: SnapshotStateList, if (vm.inQueueState) Icon(painter = painterResource(R.drawable.ic_playlist_play), tint = textColor, contentDescription = "ivInPlaylist", modifier = Modifier.width(14.dp).height(14.dp)) val curContext = LocalContext.current - val dateSizeText = " · " + formatAbbrev(curContext, vm.episode.getPubDate()) + " · " + durText + " · " + if((vm.episode.media?.size?:0) > 0) Formatter.formatShortFileSize(curContext, vm.episode.media!!.size) else "" + val dateSizeText = " · " + formatAbbrev(curContext, vm.episode.getPubDate()) + " · " + durText + " · " + if((vm.episode.media?.size?:0) > 0) Formatter.formatShortFileSize(curContext, vm.episode.media?.size ?: 0) else "" Text(dateSizeText, color = textColor, style = MaterialTheme.typography.bodyMedium) } Text(vm.episode.title?:"", color = textColor, maxLines = 2, overflow = TextOverflow.Ellipsis) @@ -677,7 +679,7 @@ fun EpisodeLazyColumn(activity: MainActivity, vms: SnapshotStateList, if (actionButton_ == null) { LaunchedEffect(vms[index].downloadState) { if (index>=vms.size) return@LaunchedEffect - if (isDownloading()) vm.dlPercent = dls?.getProgress(vms[index].episode.media!!.downloadUrl!!) ?: 0 + if (isDownloading()) vm.dlPercent = dls?.getProgress(vms[index].episode.media?.downloadUrl?:"") ?: 0 Logd(TAG, "LaunchedEffect $index downloadState: ${vms[index].downloadState} ${vm.episode.media?.downloaded} ${vm.dlPercent}") vm.actionButton = EpisodeActionButton.forItem(vm.episode) vm.actionRes = vm.actionButton!!.getDrawable() diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/compose/Feeds.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/compose/Feeds.kt index 93542f85..0ba2526e 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/compose/Feeds.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/compose/Feeds.kt @@ -7,6 +7,7 @@ import ac.mdiq.podcini.storage.database.Feeds import ac.mdiq.podcini.storage.database.Feeds.deleteFeedSync import ac.mdiq.podcini.storage.database.RealmDB.upsert import ac.mdiq.podcini.storage.model.Feed +import ac.mdiq.podcini.storage.model.Feed.Companion.MAX_SYNTHETIC_ID import ac.mdiq.podcini.storage.model.Rating import ac.mdiq.podcini.storage.model.SubscriptionLog import ac.mdiq.podcini.ui.activity.MainActivity @@ -88,12 +89,24 @@ fun RemoveFeedDialog(feeds: List, onDismissRequest: () -> Unit, callback: CoroutineScope(Dispatchers.IO).launch { try { for (f in feeds) { - val sLog = SubscriptionLog(f.id, f.title?:"", f.downloadUrl?:"", f.link?:"", SubscriptionLog.Type.Feed.name) - upsert(sLog) { - it.rating = f.rating - it.comment = f.comment - it.comment += "\nReason to remove:\n" + textState.text - it.cancelDate = Date().time + if (f.id > MAX_SYNTHETIC_ID) { + val sLog = SubscriptionLog(f.id, f.title ?: "", f.downloadUrl ?: "", f.link ?: "", SubscriptionLog.Type.Feed.name) + upsert(sLog) { + it.rating = f.rating + it.comment = f.comment + it.comment += "\nReason to remove:\n" + textState.text + it.cancelDate = Date().time + } + } else { + for (e in f.episodes) { + val sLog = SubscriptionLog(e.id, e.title ?: "", e.media?.downloadUrl ?: "", e.link ?: "", SubscriptionLog.Type.Media.name) + upsert(sLog) { + it.rating = e.rating + it.comment = e.comment + it.comment += "\nReason to remove:\n" + textState.text + it.cancelDate = Date().time + } + } } deleteFeedSync(context, f.id, false) } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeFilterDialog.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeFilterDialog.kt index 6665e536..f7bbb19e 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeFilterDialog.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeFilterDialog.kt @@ -6,17 +6,12 @@ import ac.mdiq.podcini.databinding.FilterDialogRowBinding import ac.mdiq.podcini.storage.model.EpisodeFilter import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.TAG import ac.mdiq.podcini.util.Logd -import android.app.Dialog -import android.content.DialogInterface import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button -import android.widget.FrameLayout import android.widget.LinearLayout -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.button.MaterialButtonToggleGroup @@ -89,31 +84,12 @@ abstract class EpisodeFilterDialog : BottomSheetDialogFragment() { return layout } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = super.onCreateDialog(savedInstanceState) - dialog.setOnShowListener { dialogInterface: DialogInterface -> - val bottomSheetDialog = dialogInterface as BottomSheetDialog - setupFullHeight(bottomSheetDialog) - } - return dialog - } - override fun onDestroyView() { Logd(TAG, "onDestroyView") _binding = null super.onDestroyView() } - private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) { - val bottomSheet = bottomSheetDialog.findViewById(com.leinardi.android.speeddial.R.id.design_bottom_sheet) as? FrameLayout - if (bottomSheet != null) { - val behavior = BottomSheetBehavior.from(bottomSheet) - val layoutParams = bottomSheet.layoutParams - bottomSheet.layoutParams = layoutParams - behavior.state = BottomSheetBehavior.STATE_EXPANDED - } - } - abstract fun onFilterChanged(newFilterValues: Set) enum class FeedItemFilterGroup(vararg values: ItemProperties) { diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeSortDialog.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeSortDialog.kt index ec05d9fe..fa427f4f 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeSortDialog.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/EpisodeSortDialog.kt @@ -7,17 +7,12 @@ import ac.mdiq.podcini.databinding.SortDialogItemBinding import ac.mdiq.podcini.storage.model.EpisodeSortOrder import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.TAG import ac.mdiq.podcini.util.Logd -import android.app.Dialog -import android.content.DialogInterface import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.widget.CompoundButton -import android.widget.FrameLayout -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment open class EpisodeSortDialog : BottomSheetDialogFragment() { @@ -91,28 +86,9 @@ open class EpisodeSortDialog : BottomSheetDialogFragment() { protected open fun onSelectionChanged() {} - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = super.onCreateDialog(savedInstanceState) - dialog.setOnShowListener { dialogInterface: DialogInterface -> - val bottomSheetDialog = dialogInterface as BottomSheetDialog - setupFullHeight(bottomSheetDialog) - } - return dialog - } - override fun onDestroyView() { Logd(TAG, "onDestroyView") _binding = null super.onDestroyView() } - - private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) { - val bottomSheet = bottomSheetDialog.findViewById(com.leinardi.android.speeddial.R.id.design_bottom_sheet) - if (bottomSheet != null) { - val behavior = BottomSheetBehavior.from(bottomSheet) - val layoutParams = bottomSheet.layoutParams - bottomSheet.layoutParams = layoutParams - behavior.state = BottomSheetBehavior.STATE_EXPANDED - } - } } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialog.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialog.kt index 08c64540..a5353f9f 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialog.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/dialog/FeedSortDialog.kt @@ -10,20 +10,15 @@ import ac.mdiq.podcini.storage.model.FeedSortOrder import ac.mdiq.podcini.storage.model.FeedSortOrder.Companion.getSortOrder import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.feedOrderBy import ac.mdiq.podcini.ui.fragment.SubscriptionsFragment.Companion.feedOrderDir -import ac.mdiq.podcini.util.Logd import ac.mdiq.podcini.util.EventFlow import ac.mdiq.podcini.util.FlowEvent -import android.app.Dialog -import android.content.DialogInterface +import ac.mdiq.podcini.util.Logd import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.widget.CompoundButton -import android.widget.FrameLayout -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment open class FeedSortDialog : BottomSheetDialogFragment() { @@ -110,31 +105,12 @@ open class FeedSortDialog : BottomSheetDialogFragment() { protected open fun onSelectionChanged() {} - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = super.onCreateDialog(savedInstanceState) - dialog.setOnShowListener { dialogInterface: DialogInterface -> - val bottomSheetDialog = dialogInterface as BottomSheetDialog - setupFullHeight(bottomSheetDialog) - } - return dialog - } - override fun onDestroyView() { Logd(TAG, "onDestroyView") _binding = null super.onDestroyView() } - private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) { - val bottomSheet = bottomSheetDialog.findViewById(com.leinardi.android.speeddial.R.id.design_bottom_sheet) - if (bottomSheet != null) { - val behavior = BottomSheetBehavior.from(bottomSheet) - val layoutParams = bottomSheet.layoutParams - bottomSheet.layoutParams = layoutParams - behavior.state = BottomSheetBehavior.STATE_EXPANDED - } - } - private fun setFeedOrder(selected: String, dir: Int) { appPrefs.edit().putString(UserPreferences.Prefs.prefDrawerFeedOrder.name, selected).apply() appPrefs.edit().putInt(UserPreferences.Prefs.prefDrawerFeedOrderDir.name, dir).apply() diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AudioPlayerFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AudioPlayerFragment.kt index 50d325db..5deb339b 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AudioPlayerFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/AudioPlayerFragment.kt @@ -6,7 +6,6 @@ import ac.mdiq.podcini.playback.PlaybackServiceStarter import ac.mdiq.podcini.playback.ServiceStatusHandler import ac.mdiq.podcini.playback.base.InTheatre.curEpisode import ac.mdiq.podcini.playback.base.InTheatre.curMedia -import ac.mdiq.podcini.playback.base.MediaPlayerBase import ac.mdiq.podcini.playback.base.MediaPlayerBase.Companion.status import ac.mdiq.podcini.playback.base.PlayerStatus import ac.mdiq.podcini.playback.base.VideoMode @@ -149,19 +148,10 @@ class AudioPlayerFragment : Fragment() { val composeView = ComposeView(requireContext()).apply { setContent { CustomTheme(requireContext()) { -// Column(modifier = Modifier.fillMaxSize().statusBarsPadding().navigationBarsPadding() ) { -// if (isCollapsed) PlayerUI() -//// else Spacer(modifier = Modifier.size(0.dp)) -// Toolbar() -// DetailUI(modifier = Modifier.weight(1f)) -// if (!isCollapsed) PlayerUI() -//// else Spacer(modifier = Modifier.size(0.dp)) -// } - Box(modifier = Modifier.fillMaxWidth().statusBarsPadding().navigationBarsPadding()) { - val aligm = if (isCollapsed) Alignment.TopCenter else Alignment.BottomCenter - PlayerUI(Modifier.align(aligm).zIndex(1f)) + Box(modifier = Modifier.fillMaxWidth().then(if (isCollapsed) Modifier else Modifier.statusBarsPadding().navigationBarsPadding())) { + PlayerUI(Modifier.align(if (isCollapsed) Alignment.TopCenter else Alignment.BottomCenter).zIndex(1f)) if (!isCollapsed) { - Column(Modifier.padding(bottom = 90.dp)) { + Column(Modifier.padding(bottom = 120.dp)) { Toolbar() DetailUI(modifier = Modifier) } @@ -269,14 +259,14 @@ class AudioPlayerFragment : Fragment() { if (curMedia != null) { val media = curMedia!! setIsShowPlay(!isShowPlay) - if (media.getMediaType() == MediaType.VIDEO && MediaPlayerBase.status != PlayerStatus.PLAYING && + if (media.getMediaType() == MediaType.VIDEO && status != PlayerStatus.PLAYING && (media is EpisodeMedia && media.episode?.feed?.preferences?.videoModePolicy != VideoMode.AUDIO_ONLY)) { playPause() requireContext().startActivity(getPlayerActivityIntent(requireContext(), curMedia!!.getMediaType())) } else playPause() } }, onLongClick = { - if (controller != null && MediaPlayerBase.status == PlayerStatus.PLAYING) { + if (controller != null && status == PlayerStatus.PLAYING) { val fallbackSpeed = UserPreferences.fallbackSpeed if (fallbackSpeed > 0.1f) toggleFallbackSpeed(fallbackSpeed) } @@ -307,7 +297,7 @@ class AudioPlayerFragment : Fragment() { Icon(painter = painterResource(R.drawable.ic_skip_48dp), tint = textColor, contentDescription = "rewind", modifier = Modifier.width(43.dp).height(43.dp).combinedClickable(onClick = { - if (controller != null && MediaPlayerBase.status == PlayerStatus.PLAYING) { + if (controller != null && status == PlayerStatus.PLAYING) { val speedForward = UserPreferences.speedforwardSpeed if (speedForward > 0.1f) speedForward(speedForward) } @@ -530,9 +520,10 @@ class AudioPlayerFragment : Fragment() { onPositionUpdate(FlowEvent.PlaybackPositionEvent(media, media.getPosition(), media.getDuration())) if (prevMedia?.getIdentifier() != media.getIdentifier()) imgLoc = ImageResourceUtils.getEpisodeListImageLocation(media) if (isPlayingVideoLocally && (curMedia as? EpisodeMedia)?.episode?.feed?.preferences?.videoModePolicy != VideoMode.AUDIO_ONLY) { - (activity as MainActivity).bottomSheet.setLocked(true) - (activity as MainActivity).bottomSheet.setState(BottomSheetBehavior.STATE_COLLAPSED) - } else (activity as MainActivity).bottomSheet.setLocked(false) +// (activity as MainActivity).bottomSheet.setLocked(true) + (activity as MainActivity).bottomSheet.state = BottomSheetBehavior.STATE_COLLAPSED + } +// else (activity as MainActivity).bottomSheet.setLocked(false) prevMedia = media } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/EpisodeInfoFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/EpisodeInfoFragment.kt index b0361ed4..6b9bef1a 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/EpisodeInfoFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/EpisodeInfoFragment.kt @@ -32,8 +32,6 @@ import ac.mdiq.podcini.storage.utils.DurationConverter import ac.mdiq.podcini.storage.utils.ImageResourceUtils import ac.mdiq.podcini.ui.actions.* import ac.mdiq.podcini.ui.activity.MainActivity -import ac.mdiq.podcini.ui.activity.VideoplayerActivity -import ac.mdiq.podcini.ui.activity.VideoplayerActivity.Companion import ac.mdiq.podcini.ui.compose.ChaptersDialog import ac.mdiq.podcini.ui.compose.ChooseRatingDialog import ac.mdiq.podcini.ui.compose.CustomTheme @@ -193,8 +191,8 @@ class EpisodeInfoFragment : Fragment(), Toolbar.OnMenuItemClickListener { val imgLoc = if (episode != null) ImageResourceUtils.getEpisodeListImageLocation(episode!!) else null AsyncImage(model = imgLoc, contentDescription = "imgvCover", error = painterResource(R.mipmap.ic_launcher), modifier = Modifier.width(56.dp).height(56.dp).clickable(onClick = { openPodcast() })) Column(modifier = Modifier.padding(start = 10.dp)) { - Text(txtvPodcast, color = textColor, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.clickable { openPodcast() }) - Text(txtvTitle, color = textColor, style = MaterialTheme.typography.bodyLarge.copy(fontWeight = FontWeight.Bold), maxLines = 5, overflow = TextOverflow.Ellipsis) + Text(txtvPodcast, color = textColor, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.fillMaxWidth().clickable { openPodcast() }) + Text(txtvTitle, color = textColor, style = MaterialTheme.typography.bodyLarge.copy(fontWeight = FontWeight.Bold), modifier = Modifier.fillMaxWidth(), maxLines = 5, overflow = TextOverflow.Ellipsis) Text("$txtvPublished · $txtvDuration · $txtvSize", color = textColor, style = MaterialTheme.typography.bodyMedium) } } 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 26d26cfd..461e7798 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 @@ -1,6 +1,5 @@ package ac.mdiq.podcini.ui.fragment -//import ac.mdiq.podcini.databinding.MultiSelectSpeedDialBinding import ac.mdiq.podcini.R import ac.mdiq.podcini.databinding.FeedItemListFragmentBinding import ac.mdiq.podcini.net.download.DownloadStatus @@ -286,8 +285,8 @@ import java.util.concurrent.Semaphore Column(Modifier.fillMaxWidth().constrainAs(taColumn) { top.linkTo(imgvCover.top) start.linkTo(imgvCover.end) }) { - Text(feed?.title?:"", color = textColor, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodyLarge, maxLines = 2, overflow = TextOverflow.Ellipsis) - Text(feed?.author?:"", color = textColor, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodyMedium, maxLines = 1, overflow = TextOverflow.Ellipsis) + Text(feed?.title?:"", color = textColor, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.fillMaxWidth(), maxLines = 2, overflow = TextOverflow.Ellipsis) + Text(feed?.author?:"", color = textColor, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.fillMaxWidth(), maxLines = 1, overflow = TextOverflow.Ellipsis) } } } @@ -504,7 +503,7 @@ import java.util.concurrent.Semaphore // if (!event.isRunning) nextPageLoader.root.visibility = View.GONE infoTextUpdate = if (event.isRunning) getString(R.string.refreshing_label) else "" infoBarText.value = "$infoTextFiltered $infoTextUpdate" - if (event.isRunning == false) loadFeed() + if (!event.isRunning) loadFeed() // binding.swipeRefresh.isRefreshing = event.isRunning } diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedInfoFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedInfoFragment.kt index f5b0f9a3..342fe9ae 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedInfoFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/FeedInfoFragment.kt @@ -13,6 +13,7 @@ import ac.mdiq.podcini.storage.database.RealmDB.realm import ac.mdiq.podcini.storage.database.RealmDB.runOnIOScope import ac.mdiq.podcini.storage.database.RealmDB.upsert import ac.mdiq.podcini.storage.model.Feed +import ac.mdiq.podcini.storage.model.Feed.Companion.MAX_SYNTHETIC_ID import ac.mdiq.podcini.storage.model.FeedFunding import ac.mdiq.podcini.storage.model.Rating import ac.mdiq.podcini.ui.activity.MainActivity @@ -210,8 +211,8 @@ class FeedInfoFragment : Fragment(), Toolbar.OnMenuItemClickListener { Column(Modifier.constrainAs(taColumn) { top.linkTo(imgvCover.top) start.linkTo(imgvCover.end) }) { - Text(feed.title ?:"", color = textColor, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodyLarge, maxLines = 2, overflow = TextOverflow.Ellipsis) - Text(txtvAuthor, color = textColor, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodyMedium, maxLines = 1, overflow = TextOverflow.Ellipsis) + Text(feed.title ?:"", color = textColor, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.fillMaxWidth(), maxLines = 2, overflow = TextOverflow.Ellipsis) + Text(text = txtvAuthor, color = textColor, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.fillMaxWidth(), maxLines = 1, overflow = TextOverflow.Ellipsis) } } } @@ -240,50 +241,52 @@ class FeedInfoFragment : Fragment(), Toolbar.OnMenuItemClickListener { modifier = Modifier.padding(start = 15.dp, top = 10.dp, bottom = 5.dp).clickable { showEditComment = true }) Text(commentTextState.text, color = textColor, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.padding(start = 15.dp, bottom = 10.dp)) - Text(stringResource(R.string.url_label), color = textColor, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(top = 16.dp, bottom = 4.dp)) - Text(text = txtvUrl?:"", color = textColor, modifier = Modifier.clickable { - if (feed.downloadUrl != null) { - val url: String = feed.downloadUrl!! - val clipData: ClipData = ClipData.newPlainText(url, url) - val cm = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - cm.setPrimaryClip(clipData) - if (Build.VERSION.SDK_INT <= 32) (activity as MainActivity).showSnackbarAbovePlayer(R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT) - } - }) - if (feed.paymentLinks.isNotEmpty()) { - Text(stringResource(R.string.support_funding_label), color = textColor, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(top = 16.dp, bottom = 4.dp)) - fun fundingText(): String { - val fundingList: ArrayList = feed.paymentLinks - // Filter for duplicates, but keep items in the order that they have in the feed. - val i: MutableIterator = fundingList.iterator() - while (i.hasNext()) { - val funding: FeedFunding = i.next() - for (other in fundingList) { - if (other.url == funding.url) { - if (other.content != null && funding.content != null && other.content!!.length > funding.content!!.length) { - i.remove() - break + if (feed.id > MAX_SYNTHETIC_ID) { + Text(stringResource(R.string.url_label), color = textColor, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(top = 16.dp, bottom = 4.dp)) + Text(text = txtvUrl ?: "", color = textColor, modifier = Modifier.clickable { + if (feed.downloadUrl != null) { + val url: String = feed.downloadUrl!! + val clipData: ClipData = ClipData.newPlainText(url, url) + val cm = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + cm.setPrimaryClip(clipData) + if (Build.VERSION.SDK_INT <= 32) (activity as MainActivity).showSnackbarAbovePlayer(R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT) + } + }) + if (feed.paymentLinks.isNotEmpty()) { + Text(stringResource(R.string.support_funding_label), color = textColor, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(top = 16.dp, bottom = 4.dp)) + fun fundingText(): String { + val fundingList: ArrayList = feed.paymentLinks + // Filter for duplicates, but keep items in the order that they have in the feed. + val i: MutableIterator = fundingList.iterator() + while (i.hasNext()) { + val funding: FeedFunding = i.next() + for (other in fundingList) { + if (other.url == funding.url) { + if (other.content != null && funding.content != null && other.content!!.length > funding.content!!.length) { + i.remove() + break + } } } } + val str = StringBuilder() + for (funding in fundingList) { + str.append(if (funding.content == null || funding.content!!.isEmpty()) requireContext().resources.getString( + R.string.support_podcast) + else funding.content).append(" ").append(funding.url) + str.append("\n") + } + return StringBuilder(StringUtils.trim(str.toString())).toString() } - val str = StringBuilder() - for (funding in fundingList) { - str.append(if (funding.content == null || funding.content!!.isEmpty()) requireContext().resources.getString( - R.string.support_podcast) - else funding.content).append(" ").append(funding.url) - str.append("\n") - } - return StringBuilder(StringUtils.trim(str.toString())).toString() + val fundText = remember { fundingText() } + Text(fundText, color = textColor) + } + Button(modifier = Modifier.padding(top = 10.dp), onClick = { + val fragment = SearchResultsFragment.newInstance(CombinedSearcher::class.java, "$txtvAuthor podcasts") + (activity as MainActivity).loadChildFragment(fragment, TransitionEffect.SLIDE) + }) { + Text(stringResource(R.string.feeds_related_to_author)) } - val fundText = remember { fundingText() } - Text(fundText, color = textColor) - } - Button(modifier = Modifier.padding(top = 10.dp), onClick = { - val fragment = SearchResultsFragment.newInstance(CombinedSearcher::class.java, "$txtvAuthor podcasts") - (activity as MainActivity).loadChildFragment(fragment, TransitionEffect.SLIDE) - }) { - Text(stringResource(R.string.feeds_related_to_author)) } Text(stringResource(R.string.statistics_label), color = textColor, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(top = 16.dp, bottom = 4.dp)) val arguments = Bundle() diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/OnlineFeedFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/OnlineFeedFragment.kt index e07d9798..8fe29459 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/OnlineFeedFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/OnlineFeedFragment.kt @@ -418,11 +418,11 @@ class OnlineFeedFragment : Fragment() { Text(HtmlToPlainText.getPlainText(feed?.description ?: ""), color = textColor, style = MaterialTheme.typography.bodyMedium) val sLog = remember {feedLogsMap_[feed?.downloadUrl?:""] } if (sLog != null) { - val commentTextState by remember { mutableStateOf(TextFieldValue(sLog?.comment ?: "")) } + val commentTextState by remember { mutableStateOf(TextFieldValue(sLog.comment ?: "")) } val context = LocalContext.current val cancelDate = remember { formatAbbrev(context, Date(sLog.cancelDate)) } val ratingRes = remember { fromCode(sLog.rating).res } - if (!commentTextState.text.isEmpty()) { + if (commentTextState.text.isNotEmpty()) { Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(start = 15.dp, top = 10.dp, bottom = 5.dp)) { Text(stringResource(R.string.my_opinion_label), color = MaterialTheme.colorScheme.primary, style = MaterialTheme.typography.titleMedium) Icon(painter = painterResource(ratingRes), tint = MaterialTheme.colorScheme.tertiary, contentDescription = null, modifier = Modifier.padding(start = 5.dp)) 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 b117609c..99f77d45 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 @@ -181,7 +181,7 @@ import kotlin.math.max swipeActions = SwipeActions(this, TAG) swipeActions.setFilter(EpisodeFilter(EpisodeFilter.States.queued.name)) - swipeActionsBin = SwipeActions(this, TAG+".Bin") + swipeActionsBin = SwipeActions(this, "$TAG.Bin") swipeActionsBin.setFilter(EpisodeFilter(EpisodeFilter.States.queued.name)) binding.lazyColumn.setContent { @@ -462,6 +462,7 @@ import kotlin.math.max toolbar.addView(spinnerLayout) } refreshMenuItems() + refreshSwipeTelltale() if (showBin) { item.setIcon(R.drawable.playlist_play) // speedDialView.addActionItem(addToQueueActionItem) diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/SubscriptionsFragment.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/SubscriptionsFragment.kt index 9585427f..2bce6284 100644 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/SubscriptionsFragment.kt +++ b/app/src/main/kotlin/ac/mdiq/podcini/ui/fragment/SubscriptionsFragment.kt @@ -1160,31 +1160,12 @@ class SubscriptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener { return layout } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = super.onCreateDialog(savedInstanceState) - dialog.setOnShowListener { dialogInterface: DialogInterface -> - val bottomSheetDialog = dialogInterface as BottomSheetDialog - setupFullHeight(bottomSheetDialog) - } - return dialog - } - override fun onDestroyView() { Logd(TAG, "onDestroyView") _binding = null super.onDestroyView() } - private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) { - val bottomSheet = bottomSheetDialog.findViewById(com.leinardi.android.speeddial.R.id.design_bottom_sheet) as? FrameLayout - if (bottomSheet != null) { - val behavior = BottomSheetBehavior.from(bottomSheet) - val layoutParams = bottomSheet.layoutParams - bottomSheet.layoutParams = layoutParams - behavior.state = BottomSheetBehavior.STATE_EXPANDED - } - } - private fun onFilterChanged(newFilterValues: Set) { feedsFilter = StringUtils.join(newFilterValues, ",") Logd(TAG, "onFilterChanged: $feedsFilter") diff --git a/app/src/main/kotlin/ac/mdiq/podcini/ui/utils/LockableBottomSheetBehavior.kt b/app/src/main/kotlin/ac/mdiq/podcini/ui/utils/LockableBottomSheetBehavior.kt deleted file mode 100644 index 67e8e5a9..00000000 --- a/app/src/main/kotlin/ac/mdiq/podcini/ui/utils/LockableBottomSheetBehavior.kt +++ /dev/null @@ -1,63 +0,0 @@ -package ac.mdiq.podcini.ui.utils - -import android.content.Context -import android.util.AttributeSet -import android.view.MotionEvent -import android.view.View -import androidx.coordinatorlayout.widget.CoordinatorLayout -import com.google.android.material.bottomsheet.ViewPagerBottomSheetBehavior - -/** - * Based on https://stackoverflow.com/a/40798214 - */ -class LockableBottomSheetBehavior : ViewPagerBottomSheetBehavior { - private var isLocked = false - - constructor() - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - - fun setLocked(locked: Boolean) { - isLocked = locked - } - - override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: V & Any, event: MotionEvent): Boolean { - var handled = false - - if (!isLocked) handled = super.onInterceptTouchEvent(parent, child, event) - - return handled - } - - override fun onTouchEvent(parent: CoordinatorLayout, child: V & Any, event: MotionEvent): Boolean { - var handled = false - - if (!isLocked) handled = super.onTouchEvent(parent, child, event) - - return handled - } - - override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: V & Any, directTargetChild: View, target: View, axes: Int, type: Int): Boolean { - var handled = false - - if (!isLocked) handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type) - - return handled - } - - override fun onNestedPreScroll(coordinatorLayout: CoordinatorLayout, child: V & Any, target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) { - if (!isLocked) super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type) - } - - override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: V & Any, target: View, type: Int) { - if (!isLocked) super.onStopNestedScroll(coordinatorLayout, child, target, type) - } - - override fun onNestedPreFling(coordinatorLayout: CoordinatorLayout, child: V & Any, target: View, velocityX: Float, velocityY: Float): Boolean { - var handled = false - - if (!isLocked) handled = super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY) - - return handled - } -} diff --git a/app/src/main/kotlin/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.kt b/app/src/main/kotlin/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.kt deleted file mode 100644 index fc3a355e..00000000 --- a/app/src/main/kotlin/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.google.android.material.bottomsheet - -import android.content.Context -import android.util.AttributeSet -import android.view.View -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import androidx.viewpager2.widget.ViewPager2 -import java.lang.ref.WeakReference - -/** - * Override [.findScrollingChild] to support [ViewPager]'s nested scrolling. - * In order to override package level method and field. - * This class put in the same package path where [BottomSheetBehavior] located. - * Source: https://medium.com/@hanru.yeh/funny-solution-that-makes-bottomsheetdialog-support-viewpager-with-nestedscrollingchilds-bfdca72235c3 - */ -open class ViewPagerBottomSheetBehavior : BottomSheetBehavior { - constructor() : super() - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - - public override fun findScrollingChild(view: View): View? { - if (view.isNestedScrollingEnabled) { - return view - } - - when (view) { - is ViewPager2 -> { - val recycler = view.getChildAt(0) as RecyclerView - val currentViewPagerChild = recycler.getChildAt(view.currentItem) - if (currentViewPagerChild != null) { - return findScrollingChild(currentViewPagerChild) - } - } - is ViewGroup -> { - var i = 0 - val count = view.childCount - while (i < count) { - val scrollingChild = findScrollingChild(view.getChildAt(i)) - if (scrollingChild != null) { - return scrollingChild - } - i++ - } - } - } - return null - } - - fun updateScrollingChild() { - val childView = viewRef?.get() ?: return - val scrollingChild = findScrollingChild(childView) - nestedScrollingChildRef = WeakReference(scrollingChild) - } -} \ No newline at end of file diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml index 7d521c5b..3f272125 100644 --- a/app/src/main/res/layout/main_activity.xml +++ b/app/src/main/res/layout/main_activity.xml @@ -30,7 +30,7 @@ android:background="?android:attr/colorBackground" android:elevation="8dp" android:visibility="gone" - app:layout_behavior="ac.mdiq.podcini.ui.utils.LockableBottomSheetBehavior" /> + app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" /> diff --git a/app/src/main/res/layout/multi_select_speed_dial.xml b/app/src/main/res/layout/multi_select_speed_dial.xml deleted file mode 100644 index 0451471b..00000000 --- a/app/src/main/res/layout/multi_select_speed_dial.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index bd93c7f8..9cbc8380 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -6,7 +6,7 @@ 16dp 0dp 4dp - 135dp + 110dp 12sp 14sp 16sp diff --git a/changelog.md b/changelog.md index 424eb891..b1b2a6b0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,15 @@ +# 6.11.4 + +* corrected color contrast in SwipeActions dialog +* removed the empty space on top of playerUI +* largely improved scroll performance of episodes list caused by image loading +* fixed title text out of screen issue in some headers +* fixed swipe actions not initialized in Queue Bin +* in FeedInfo details, removed inapplicable items for synthetic feeds +* when removing synthetic feed, record all episodes in the feed in SubscriptionLog +* updated some Compose dependencies +* speed-dial dependency removed and old bottomSheet multi-select codes cleaned up + # 6.11.3 * supports Youtube live episodes received from share diff --git a/fastlane/metadata/android/en-US/changelogs/3020274.txt b/fastlane/metadata/android/en-US/changelogs/3020274.txt new file mode 100644 index 00000000..616ccbef --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/3020274.txt @@ -0,0 +1,11 @@ + Version 6.11.4 + +* corrected color contrast in SwipeActions dialog +* removed the empty space on top of playerUI +* largely improved scroll performance of episodes list caused by image loading +* fixed title text out of screen issue in some headers +* fixed swipe actions not initialized in Queue Bin +* in FeedInfo details, removed inapplicable items for synthetic feeds +* when removing synthetic feed, record all episodes in the feed in SubscriptionLog +* updated some Compose dependencies +* speed-dial dependency removed and old bottomSheet multi-select codes cleaned up diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 76d5aa84..6e049b6c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,14 +1,14 @@ [versions] -activityCompose = "1.9.2" -annotation = "1.8.2" +activityCompose = "1.9.3" +annotation = "1.9.0" appcompat = "1.7.0" awaitility = "4.2.1" balloon = "1.6.6" coil = "2.7.0" commonsLang3 = "3.15.0" commonsIo = "2.16.1" -composeBom = "2024.09.03" +composeBom = "2024.10.00" conscryptAndroid = "2.5.2" constraintlayoutCompose = "1.0.1" coordinatorlayout = "1.2.0" @@ -63,11 +63,11 @@ runner = "1.6.2" rxandroid = "3.0.2" rxjava = "2.2.21" rxjavaVersion = "3.1.8" -speedDial = "3.3.0" +#speedDial = "3.3.0" searchpreference = "v2.5.0" stream = "1.2.2" -uiToolingPreview = "1.7.3" -uiTooling = "1.7.3" +uiToolingPreview = "1.7.4" +uiTooling = "1.7.4" viewpager2 = "1.1.0" vistaguide = "lv0.24.2.6" wearable = "2.9.0" @@ -151,7 +151,7 @@ rxandroid = { module = "io.reactivex.rxjava3:rxandroid", version.ref = "rxandroi rxjava3-rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjavaVersion" } rxjava = { module = "io.reactivex.rxjava2:rxjava", version.ref = "rxjava" } searchpreference = { module = "com.github.ByteHamster:SearchPreference", version.ref = "searchpreference" } -speed-dial = { module = "com.leinardi.android:speed-dial", version.ref = "speedDial" } +#speed-dial = { module = "com.leinardi.android:speed-dial", version.ref = "speedDial" } stream = { module = "com.annimon:stream", version.ref = "stream" } vistaguide = { module = "com.github.XilinJia.vistaguide:VistaGuide", version.ref = "vistaguide" } desugar_jdk_libs_nio = { module = "com.android.tools:desugar_jdk_libs_nio", version.ref = "desugar_jdk_libs_nio" }