From 9af80592b3437bc2cb38648f77ba6d6bf9f0aa3c Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 5 Dec 2021 23:39:48 +0530 Subject: [PATCH 01/82] Code Cleanup --- .../retromusic/activities/MainActivity.kt | 22 +++++++++---------- .../fragments/base/AbsRecyclerViewFragment.kt | 5 +++-- .../retromusic/fragments/home/HomeFragment.kt | 5 +++-- .../retromusic/interfaces/IScrollHelper.kt | 5 +++++ 4 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/code/name/monkey/retromusic/interfaces/IScrollHelper.kt diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt index 72b1910ee..60dc7fe89 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt @@ -27,10 +27,9 @@ import code.name.monkey.retromusic.* import code.name.monkey.retromusic.activities.base.AbsCastActivity import code.name.monkey.retromusic.databinding.SlidingMusicPanelLayoutBinding import code.name.monkey.retromusic.extensions.* -import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment -import code.name.monkey.retromusic.fragments.home.HomeFragment import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.SearchQueryHelper.getSongs +import code.name.monkey.retromusic.interfaces.IScrollHelper import code.name.monkey.retromusic.model.CategoryInfo import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.repository.PlaylistSongsLoader @@ -90,21 +89,17 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { bottomNavigationView.setupWithNavController(navController) // Scroll Fragment to top bottomNavigationView.setOnItemReselectedListener { - currentFragment(R.id.fragment_container) - .also { - if (it is AbsRecyclerViewFragment<*, *>) { - it.scrollToTop() - } - if (it is HomeFragment) { - it.scrollToTop() - } + currentFragment(R.id.fragment_container).apply { + if (this is IScrollHelper) { + scrollToTop() } + } } // This is more like a work-around as for start destination of navGraph // enterTransition won't work as expected navGraph.setStartDestination(R.id.libraryFragment) navController.addOnDestinationChangedListener { _, destination, _ -> - when (destination.id) { + when (destination.id) { R.id.action_home, R.id.action_song, R.id.action_album, R.id.action_artist, R.id.action_folder, R.id.action_playlist, R.id.action_genre -> { // Save the last tab if (PreferenceUtil.rememberLastTab) { @@ -117,7 +112,10 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { setBottomNavVisibility(visible = false) hideBottomSheet(true) } - else -> setBottomNavVisibility(visible = false, animate = true) // Hide Bottom Navigation Bar + else -> setBottomNavVisibility( + visible = false, + animate = true + ) // Hide Bottom Navigation Bar } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt index 51dfccdd9..c7eeebe77 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt @@ -34,6 +34,7 @@ import code.name.monkey.retromusic.extensions.accentColor import code.name.monkey.retromusic.extensions.dip import code.name.monkey.retromusic.extensions.drawNextToNavbar import code.name.monkey.retromusic.helper.MusicPlayerRemote +import code.name.monkey.retromusic.interfaces.IScrollHelper import code.name.monkey.retromusic.util.ThemedFastScroller.create import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.transition.MaterialFadeThrough @@ -42,7 +43,7 @@ import me.zhanghai.android.fastscroll.FastScroller import me.zhanghai.android.fastscroll.FastScrollerBuilder abstract class AbsRecyclerViewFragment, LM : RecyclerView.LayoutManager> : - AbsMainActivityFragment(R.layout.fragment_main_recycler) { + AbsMainActivityFragment(R.layout.fragment_main_recycler), IScrollHelper { private var _binding: FragmentMainRecyclerBinding? = null private val binding get() = _binding!! @@ -200,7 +201,7 @@ abstract class AbsRecyclerViewFragment, LM : Recycle val container get() = binding.root - fun scrollToTop() { + override fun scrollToTop() { recyclerView.scrollToPosition(0) binding.appBarLayout.setExpanded(true, true) } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt index 6f521637c..4bc9ca231 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt @@ -40,6 +40,7 @@ import code.name.monkey.retromusic.extensions.drawNextToNavbar import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.RetroGlideExtension +import code.name.monkey.retromusic.interfaces.IScrollHelper import code.name.monkey.retromusic.util.PreferenceUtil import com.google.android.gms.cast.framework.CastButtonFactory import com.google.android.material.shape.MaterialShapeDrawable @@ -47,7 +48,7 @@ import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialSharedAxis class HomeFragment : - AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home) { + AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home), IScrollHelper { private var _binding: HomeBindingAdapter? = null private val binding get() = _binding!! @@ -189,7 +190,7 @@ class HomeFragment : CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast) } - fun scrollToTop() { + override fun scrollToTop() { binding.container.scrollTo(0, 0) binding.appBarLayout.setExpanded(true) } diff --git a/app/src/main/java/code/name/monkey/retromusic/interfaces/IScrollHelper.kt b/app/src/main/java/code/name/monkey/retromusic/interfaces/IScrollHelper.kt new file mode 100644 index 000000000..112bdcdc1 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/interfaces/IScrollHelper.kt @@ -0,0 +1,5 @@ +package code.name.monkey.retromusic.interfaces + +interface IScrollHelper { + fun scrollToTop() +} \ No newline at end of file From b0800504e4e419cad677dab12a60b2fa95c9edff Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 6 Dec 2021 14:10:05 +0530 Subject: [PATCH 02/82] [Bottom Navigation] Fixed bottom navigation visible in Playing Queue --- .../name/monkey/retromusic/activities/MainActivity.kt | 3 +-- .../activities/base/AbsSlidingMusicPanelActivity.kt | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt index 60dc7fe89..b647400e3 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt @@ -109,8 +109,7 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { setBottomNavVisibility(visible = true, animate = true) } R.id.playing_queue_fragment -> { - setBottomNavVisibility(visible = false) - hideBottomSheet(true) + setBottomNavVisibility(visible = false, hideBottomSheet = true) } else -> setBottomNavVisibility( visible = false, diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt index 8034362b5..118fab103 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt @@ -92,7 +92,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { when (newState) { STATE_EXPANDED -> { onPanelExpanded() - } STATE_COLLAPSED -> { onPanelCollapsed() @@ -316,10 +315,11 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { }) } - fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false) { + fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false, hideBottomSheet: Boolean = MusicPlayerRemote.playingQueue.isEmpty()) { val translationY = if (visible) 0F else dip(R.dimen.bottom_nav_height).toFloat() + windowInsets.safeGetBottomInsets() - if (animate) { + val mAnimate = animate && bottomSheetBehavior.state == STATE_COLLAPSED + if (mAnimate) { binding.bottomNavigationView.translateYAnimate(translationY).doOnEnd { if (visible && bottomSheetBehavior.state != STATE_EXPANDED) { binding.bottomNavigationView.bringToFront() @@ -328,12 +328,13 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { } else { binding.bottomNavigationView.translationY = translationY + binding.bottomNavigationView.isVisible = false if (visible && bottomSheetBehavior.state != STATE_EXPANDED) { binding.bottomNavigationView.bringToFront() } } hideBottomSheet( - hide = MusicPlayerRemote.playingQueue.isEmpty(), + hide = hideBottomSheet, animate = animate, isBottomNavVisible = visible ) From 2d7567584aee502799c6f632c707978a18589e24 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 6 Dec 2021 15:07:42 +0530 Subject: [PATCH 03/82] Fixed transition for startDestination --- .../name/monkey/retromusic/activities/MainActivity.kt | 3 --- .../monkey/retromusic/fragments/base/AbsPlayerFragment.kt | 1 + .../retromusic/fragments/base/AbsRecyclerViewFragment.kt | 5 ++--- .../name/monkey/retromusic/fragments/home/HomeFragment.kt | 8 ++++---- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt index b647400e3..b1dc8427d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt @@ -95,9 +95,6 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { } } } - // This is more like a work-around as for start destination of navGraph - // enterTransition won't work as expected - navGraph.setStartDestination(R.id.libraryFragment) navController.addOnDestinationChangedListener { _, destination, _ -> when (destination.id) { R.id.action_home, R.id.action_song, R.id.action_album, R.id.action_artist, R.id.action_folder, R.id.action_playlist, R.id.action_genre -> { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt index c3f9b94e0..7acfc1112 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt @@ -38,6 +38,7 @@ import androidx.core.os.bundleOf import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController import androidx.navigation.navOptions +import androidx.transition.Fade import androidx.viewpager.widget.ViewPager import code.name.monkey.retromusic.EXTRA_ALBUM_ID import code.name.monkey.retromusic.EXTRA_ARTIST_ID diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt index c7eeebe77..2f79563b2 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsRecyclerViewFragment.kt @@ -57,9 +57,8 @@ abstract class AbsRecyclerViewFragment, LM : Recycle _binding = FragmentMainRecyclerBinding.bind(view) postponeEnterTransition() view.doOnPreDraw { startPostponedEnterTransition() } - enterTransition = MaterialFadeThrough().apply { - addTarget(binding.recyclerView) - } + enterTransition = MaterialFadeThrough().addTarget(binding.recyclerView) + reenterTransition = MaterialFadeThrough().addTarget(binding.recyclerView) mainActivity.setSupportActionBar(binding.toolbar) mainActivity.supportActionBar?.title = null initLayoutManager() diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt index 4bc9ca231..bff61411d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt @@ -48,7 +48,8 @@ import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialSharedAxis class HomeFragment : - AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home), IScrollHelper { + AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home), + IScrollHelper { private var _binding: HomeBindingAdapter? = null private val binding get() = _binding!! @@ -61,9 +62,8 @@ class HomeFragment : setupListeners() binding.titleWelcome.text = String.format("%s", PreferenceUtil.userName) - enterTransition = MaterialFadeThrough().apply { - addTarget(binding.contentContainer) - } + enterTransition = MaterialFadeThrough().addTarget(binding.contentContainer) + reenterTransition = MaterialFadeThrough().addTarget(binding.contentContainer) val homeAdapter = HomeAdapter(mainActivity) binding.recyclerView.apply { From 8a181607bea92133b8b7b47a954d42a582ed7cdf Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 6 Dec 2021 15:42:10 +0530 Subject: [PATCH 04/82] Fixed Player not collapsing when Queue is cleared --- .../activities/base/AbsSlidingMusicPanelActivity.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt index 118fab103..b80df4a60 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt @@ -232,9 +232,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { super.onQueueChanged() // Mini player should be hidden in Playing Queue // it may pop up if hideBottomSheet is called - if (currentFragment(R.id.fragment_container) !is PlayingQueueFragment && - bottomSheetBehavior.state != STATE_EXPANDED - ) { + if (currentFragment(R.id.fragment_container) !is PlayingQueueFragment) { hideBottomSheet(MusicPlayerRemote.playingQueue.isEmpty()) } } From c81015905ec484ecd13c41948a2ae709e00701bc Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 6 Dec 2021 15:50:34 +0530 Subject: [PATCH 05/82] [Notification] Fixed notification not updating when Classic Notification is toggled --- .../java/code/name/monkey/retromusic/service/MusicService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java index d9946b82d..435cb9f9e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java +++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java @@ -938,8 +938,9 @@ public class MusicService extends MediaBrowserServiceCompat updateNotification(); break; case CLASSIC_NOTIFICATION: - initNotification(); updateNotification(); + playingNotification.setPlaying(isPlaying()); + playingNotification.updateMetadata(getCurrentSong(), this::startForegroundOrNotify); break; case TOGGLE_HEADSET: registerHeadsetEvents(); From faf4c634be0195b49da407a6c920a54e7882d613 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 6 Dec 2021 17:39:31 +0530 Subject: [PATCH 06/82] Added enter transition to Folders tab --- .../monkey/retromusic/fragments/folder/FoldersFragment.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt index 8eca0382c..63fc310a4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt @@ -107,9 +107,9 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder), mainActivity.addMusicServiceEventListener(libraryViewModel) mainActivity.setSupportActionBar(binding.toolbar) mainActivity.supportActionBar?.title = null - enterTransition = MaterialFadeThrough().apply { - addTarget(binding.recyclerView) - } + enterTransition = MaterialFadeThrough().addTarget(binding.recyclerView) + reenterTransition = MaterialFadeThrough().addTarget(binding.recyclerView) + setUpBreadCrumbs() setUpRecyclerView() setUpAdapter() From a830bc73af55c433d3aa7d80ab7c4920a61d0f29 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 6 Dec 2021 18:02:23 +0530 Subject: [PATCH 07/82] Removed background of card in item_grid.xml --- app/src/main/res/layout/item_grid.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/layout/item_grid.xml b/app/src/main/res/layout/item_grid.xml index e5a5f5e49..1457d7ed4 100644 --- a/app/src/main/res/layout/item_grid.xml +++ b/app/src/main/res/layout/item_grid.xml @@ -16,7 +16,6 @@ android:layout_width="0dp" android:layout_height="0dp" android:scaleType="centerCrop" - app:cardBackgroundColor="@color/transparent" app:cardCornerRadius="@dimen/m3_card_corner_radius" app:layout_constraintDimensionRatio="1:1" app:layout_constraintEnd_toEndOf="parent" From c9ac6498ae9ab738d439e1b9c300adff4307e365 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Tue, 7 Dec 2021 18:13:50 +0530 Subject: [PATCH 08/82] [Menu] Rounded menu popup for songs --- .../code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt | 2 +- app/src/main/res/drawable/popup_background.xml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt index 6dc309230..26dfe7a8c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt @@ -17,7 +17,7 @@ package code.name.monkey.retromusic.helper.menu import android.content.Intent import android.view.MenuItem import android.view.View -import android.widget.PopupMenu +import androidx.appcompat.widget.PopupMenu import androidx.core.os.bundleOf import androidx.fragment.app.FragmentActivity import androidx.navigation.findNavController diff --git a/app/src/main/res/drawable/popup_background.xml b/app/src/main/res/drawable/popup_background.xml index 995f1a73c..168b8ef1b 100644 --- a/app/src/main/res/drawable/popup_background.xml +++ b/app/src/main/res/drawable/popup_background.xml @@ -2,4 +2,7 @@ + \ No newline at end of file From 6dfea430211e8ca880b7e2ac9670da7757f25383 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Tue, 7 Dec 2021 22:08:32 +0530 Subject: [PATCH 09/82] [Now Playing] Fixed a bug in "Plain" Now playing theme where onClick event is consumed by the views behind the bottom sheet --- app/src/main/res/layout/fragment_plain_player.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/fragment_plain_player.xml b/app/src/main/res/layout/fragment_plain_player.xml index 7cc0a06ee..52fb78e33 100644 --- a/app/src/main/res/layout/fragment_plain_player.xml +++ b/app/src/main/res/layout/fragment_plain_player.xml @@ -4,12 +4,12 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="?attr/colorSurface"> - + android:background="?attr/colorSurface" + android:clickable="true" + android:focusable="true"> - Date: Tue, 7 Dec 2021 22:31:50 +0530 Subject: [PATCH 10/82] Fixed incorrect colors in Color Fragment for default/error/placeholder cover art and else where, where colors are extracted from image --- .../retromusic/util/color/MediaNotificationProcessor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java b/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java index 9a380d74b..39044f317 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/color/MediaNotificationProcessor.java @@ -476,9 +476,10 @@ public class MediaNotificationProcessor { public static MediaNotificationProcessor errorColor(Context context) { MediaNotificationProcessor errorColors = new MediaNotificationProcessor(context); - errorColors.backgroundColor = 0x15724528; - errorColors.primaryTextColor = 0x6974059; - errorColors.secondaryTextColor = 0x8684677; + errorColors.backgroundColor = -15724528; + errorColors.primaryTextColor = -6974059; + errorColors.secondaryTextColor = -8684677; + errorColors.actionBarColor = -6974059; return errorColors; } } From 5e7d69f24743ca5430afbe9ed2759d7b8c613092 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Tue, 7 Dec 2021 23:03:57 +0530 Subject: [PATCH 11/82] [Notification] Fixed favorite not updating when song is changed --- .../retromusic/service/notification/PlayingNotificationImpl.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt index 49d43a877..b8ef0cca6 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt @@ -163,6 +163,7 @@ class PlayingNotificationImpl( onUpdate() } }) + updateFavorite(song, onUpdate) } private fun buildPlayAction(isPlaying: Boolean): NotificationCompat.Action { From 8cf36c1afa8e20fe964c561588d934cbd91935ce Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 9 Dec 2021 08:01:26 +0530 Subject: [PATCH 12/82] [UI] Rounded popup menus everywhere --- .../name/monkey/retromusic/adapter/backup/BackupAdapter.kt | 2 +- .../monkey/retromusic/fragments/folder/FoldersFragment.kt | 4 ++-- .../fragments/player/full/FullPlaybackControlsFragment.kt | 2 +- .../fragments/player/gradient/GradientPlayerFragment.kt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt index 186fd3f59..3e32bf0e3 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/backup/BackupAdapter.kt @@ -4,7 +4,7 @@ import android.view.LayoutInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup -import android.widget.PopupMenu +import androidx.appcompat.widget.PopupMenu import android.widget.TextView import androidx.appcompat.widget.AppCompatImageView import androidx.fragment.app.FragmentActivity diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt index 63fc310a4..a30a0993a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.kt @@ -21,7 +21,7 @@ import android.os.Environment import android.text.Html import android.view.* import android.webkit.MimeTypeMap -import android.widget.PopupMenu +import androidx.appcompat.widget.PopupMenu import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.loader.app.LoaderManager @@ -188,7 +188,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder), } override fun onFileMenuClicked(file: File, view: View) { - val popupMenu = PopupMenu(activity, view) + val popupMenu = PopupMenu(requireActivity(), view) if (file.isDirectory) { popupMenu.inflate(R.menu.menu_item_directory) popupMenu.setOnMenuItemClickListener { item: MenuItem -> diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt index 24a3616ad..324b00e8e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt @@ -26,7 +26,7 @@ import android.view.MenuItem import android.view.View import android.view.animation.DecelerateInterpolator import android.view.animation.LinearInterpolator -import android.widget.PopupMenu +import androidx.appcompat.widget.PopupMenu import android.widget.SeekBar import androidx.lifecycle.lifecycleScope import code.name.monkey.appthemehelper.util.ColorUtil diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt index 82f0c8766..20fff4b1a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt @@ -23,7 +23,7 @@ import android.graphics.drawable.AnimatedVectorDrawable import android.os.Bundle import android.view.View import android.view.animation.LinearInterpolator -import android.widget.PopupMenu +import androidx.appcompat.widget.PopupMenu import android.widget.SeekBar import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar From 9fa90786f37f2950e524a990721ab47c8483b8b1 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 9 Dec 2021 08:02:03 +0530 Subject: [PATCH 13/82] [UI] Rounded Banner image in UserInfo fragment --- app/src/debug/res/values/styles.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/debug/res/values/styles.xml b/app/src/debug/res/values/styles.xml index b9ca988eb..f3761b219 100644 --- a/app/src/debug/res/values/styles.xml +++ b/app/src/debug/res/values/styles.xml @@ -94,8 +94,7 @@ ?android:attr/textColorPrimary - From 581b2fb068154f0ac1d8d0e298a9be8577be192b Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 9 Dec 2021 08:06:15 +0530 Subject: [PATCH 14/82] [Now Playing] Fixed Flat player crash --- .../retromusic/fragments/player/flat/FlatPlayerFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt index 2d357fb83..1d5642b12 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt @@ -81,7 +81,7 @@ class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) { GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(animation.animatedValue as Int, android.R.color.transparent), 0 ) - binding.colorGradientBackground.background = drawable + _binding?.colorGradientBackground?.background = drawable } valueAnimator?.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME.toLong())?.start() } From 558f61e905ed5ff884e8e33014f0f14ca531aee4 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 9 Dec 2021 17:56:43 +0530 Subject: [PATCH 15/82] [Settings] Fixed bottom padding issues in Setting screens on older devices [Settings] Fixed bottom padding issues in Setting screens on older devices --- .../fragments/settings/AbsSettingsFragment.kt | 4 ++-- .../fragments/settings/MainSettingsFragment.kt | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt index afdd8a9b6..ab3987a37 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/AbsSettingsFragment.kt @@ -68,10 +68,10 @@ abstract class AbsSettingsFragment : ATEPreferenceFragmentCompat() { super.onViewCreated(view, savedInstanceState) setDivider(ColorDrawable(Color.TRANSPARENT)) // CollapsingToolbarLayout consumes insets and insets are not passed to child views - // So we get insets from root view + // So we get insets from decor view // https://github.com/material-components/material-components-android/issues/1310 ViewCompat.setOnApplyWindowInsetsListener( - view + requireActivity().window.decorView ) { _, insets -> listView.updatePadding(bottom = insets.safeGetBottomInsets()) insets diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/MainSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/MainSettingsFragment.kt index 00935fdfd..2a1d5fd22 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/MainSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/MainSettingsFragment.kt @@ -19,6 +19,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.ViewCompat import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController @@ -26,11 +27,10 @@ import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.retromusic.App import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.FragmentMainSettingsBinding -import code.name.monkey.retromusic.extensions.addBottomInsets import code.name.monkey.retromusic.extensions.hide +import code.name.monkey.retromusic.extensions.safeGetBottomInsets import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.util.NavigationUtil -import code.name.monkey.retromusic.util.RetroUtil class MainSettingsFragment : Fragment(), View.OnClickListener { @@ -87,8 +87,12 @@ class MainSettingsFragment : Fragment(), View.OnClickListener { binding.buyPremium.setTextColor(it) binding.diamondIcon.imageTintList = ColorStateList.valueOf(it) } - if (!RetroUtil.isLandscape()) { - binding.container.updatePadding(bottom = RetroUtil.getNavigationBarHeight()) + + ViewCompat.setOnApplyWindowInsetsListener( + requireActivity().window.decorView + ) { _, insets -> + binding.container.updatePadding(bottom = insets.safeGetBottomInsets()) + insets } } From dc0c4d20466f43ba96b3db8492d93e0828520e8d Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 9 Dec 2021 17:59:21 +0530 Subject: [PATCH 16/82] [UI] Fixed light navigation bar issues --- .../monkey/retromusic/extensions/ActivityThemeExtensions.kt | 2 +- .../src/main/java/code/name/monkey/appthemehelper/ATH.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt index 4806c1bad..217f11b67 100644 --- a/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt +++ b/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityThemeExtensions.kt @@ -101,7 +101,7 @@ fun AppCompatActivity.setLightStatusBarAuto(bgColor: Int) { fun AppCompatActivity.setLightNavigationBar(enabled: Boolean) { if (!ATHUtil.isWindowBackgroundDark(this) and ThemeStore.coloredNavigationBar(this)) { - ATH.setLightNavigationbar(this, enabled) + ATH.setLightNavigationBar(this, enabled) } } diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt index 719d9bf51..4e76e0bdd 100755 --- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/ATH.kt @@ -34,18 +34,18 @@ object ATH { } } - fun setLightNavigationbar(activity: Activity, enabled: Boolean) { + fun setLightNavigationBar(activity: Activity, enabled: Boolean) { activity.window.apply { + navigationBarColor = Color.TRANSPARENT WindowInsetsControllerCompat( this, decorView ).isAppearanceLightNavigationBars = enabled - navigationBarColor = Color.TRANSPARENT } } fun setLightNavigationBarAuto(activity: Activity, bgColor: Int) { - setLightNavigationbar(activity, ColorUtil.isColorLight(bgColor)) + setLightNavigationBar(activity, ColorUtil.isColorLight(bgColor)) } fun setNavigationBarColor(activity: Activity, color: Int) { From 766f62a1b767958d202932615e99fe52041ec8ed Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 9 Dec 2021 21:37:13 +0530 Subject: [PATCH 17/82] [Now Playing] Fixed enterTransition for startDestination --- .../code/name/monkey/retromusic/activities/MainActivity.kt | 3 +++ .../name/monkey/retromusic/extensions/FragmentExtensions.kt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt index b1dc8427d..348084f66 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt @@ -96,6 +96,9 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { } } navController.addOnDestinationChangedListener { _, destination, _ -> + if (destination.id == navGraph.startDestinationId) { + currentFragment(R.id.fragment_container)?.enterTransition = null + } when (destination.id) { R.id.action_home, R.id.action_song, R.id.action_album, R.id.action_artist, R.id.action_folder, R.id.action_playlist, R.id.action_genre -> { // Save the last tab diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentExtensions.kt index 24fc4dd3d..07ce4d3a0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentExtensions.kt +++ b/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentExtensions.kt @@ -67,7 +67,7 @@ fun AppCompatActivity.currentFragment(navHostId: Int): Fragment? { val navHostFragment: NavHostFragment = supportFragmentManager.findFragmentById(navHostId) as NavHostFragment navHostFragment.targetFragment - return navHostFragment.childFragmentManager.fragments.first() + return navHostFragment.childFragmentManager.fragments.firstOrNull() } @Suppress("UNCHECKED_CAST") From 4b857f608861e4a054e8188a3185fb48190172bf Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 9 Dec 2021 21:56:16 +0530 Subject: [PATCH 18/82] [Now Playing] Default Album cover theme for Now playing themes --- .../retromusic/fragments/NowPlayingScreen.kt | 38 ++++++++++--------- .../monkey/retromusic/util/PreferenceUtil.kt | 2 + 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt index 12b514c3d..5cf112c03 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt @@ -22,24 +22,26 @@ enum class NowPlayingScreen constructor( @param:StringRes @field:StringRes val titleRes: Int, @param:DrawableRes @field:DrawableRes val drawableResId: Int, - val id: Int + val id: Int, + val defaultCoverTheme: AlbumCoverStyle? ) { + // Some Now playing themes look better with particular Album cover theme - Adaptive(R.string.adaptive, R.drawable.np_adaptive, 10), - Blur(R.string.blur, R.drawable.np_blur, 4), - BlurCard(R.string.blur_card, R.drawable.np_blur_card, 9), - Card(R.string.card, R.drawable.np_card, 6), - Circle(R.string.circle, R.drawable.np_minimalistic_circle, 15), - Classic(R.string.classic, R.drawable.np_classic, 16), - Color(R.string.color, R.drawable.np_color, 5), - Fit(R.string.fit, R.drawable.np_fit, 12), - Flat(R.string.flat, R.drawable.np_flat, 1), - Full(R.string.full, R.drawable.np_full, 2), - Gradient(R.string.gradient, R.drawable.np_gradient, 17), - Material(R.string.material, R.drawable.np_material, 11), - Normal(R.string.normal, R.drawable.np_normal, 0), - Peak(R.string.peak, R.drawable.np_peak, 14), - Plain(R.string.plain, R.drawable.np_plain, 3), - Simple(R.string.simple, R.drawable.np_simple, 8), - Tiny(R.string.tiny, R.drawable.np_tiny, 7), + Adaptive(R.string.adaptive, R.drawable.np_adaptive, 10, AlbumCoverStyle.FullCard), + Blur(R.string.blur, R.drawable.np_blur, 4, AlbumCoverStyle.Normal), + BlurCard(R.string.blur_card, R.drawable.np_blur_card, 9, AlbumCoverStyle.Card), + Card(R.string.card, R.drawable.np_card, 6, AlbumCoverStyle.Full), + Circle(R.string.circle, R.drawable.np_minimalistic_circle, 15, null), + Classic(R.string.classic, R.drawable.np_classic, 16, AlbumCoverStyle.Full), + Color(R.string.color, R.drawable.np_color, 5, AlbumCoverStyle.Normal), + Fit(R.string.fit, R.drawable.np_fit, 12, AlbumCoverStyle.Full), + Flat(R.string.flat, R.drawable.np_flat, 1, AlbumCoverStyle.Flat), + Full(R.string.full, R.drawable.np_full, 2, AlbumCoverStyle.Full), + Gradient(R.string.gradient, R.drawable.np_gradient, 17, AlbumCoverStyle.Full), + Material(R.string.material, R.drawable.np_material, 11, AlbumCoverStyle.Normal), + Normal(R.string.normal, R.drawable.np_normal, 0, AlbumCoverStyle.Normal), + Peak(R.string.peak, R.drawable.np_peak, 14, AlbumCoverStyle.Normal), + Plain(R.string.plain, R.drawable.np_plain, 3, AlbumCoverStyle.Normal), + Simple(R.string.simple, R.drawable.np_simple, 8, AlbumCoverStyle.Normal), + Tiny(R.string.tiny, R.drawable.np_tiny, 7, null), } diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt index 00268bc6e..cdcc2216d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt +++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt @@ -561,6 +561,8 @@ object PreferenceUtil { } set(value) = sharedPreferences.edit { putInt(NOW_PLAYING_SCREEN_ID, value.id) + // Also set a cover theme for that now playing + value.defaultCoverTheme?.let { coverTheme -> albumCoverStyle = coverTheme } } val albumCoverTransform: ViewPager.PageTransformer From 6dc152b911e1b52ada93c1af8f7844aff90f147b Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 9 Dec 2021 22:25:39 +0530 Subject: [PATCH 19/82] [Now Playing] Moved toolbar of Flat theme to bottom --- .../player/flat/FlatPlayerFragment.kt | 2 +- .../main/res/layout/fragment_flat_player.xml | 30 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt index 1d5642b12..c654882f1 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/flat/FlatPlayerFragment.kt @@ -91,7 +91,7 @@ class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) { _binding = FragmentFlatPlayerBinding.bind(view) setUpPlayerToolbar() setUpSubFragments() - binding.playbackControlsFragment.drawAboveSystemBars() + binding.playerToolbar.drawAboveSystemBars() } override fun onShow() { diff --git a/app/src/main/res/layout/fragment_flat_player.xml b/app/src/main/res/layout/fragment_flat_player.xml index 64294137f..e7c9a4601 100644 --- a/app/src/main/res/layout/fragment_flat_player.xml +++ b/app/src/main/res/layout/fragment_flat_player.xml @@ -18,8 +18,9 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - - + - - - - @@ -60,10 +50,20 @@ android:name="code.name.monkey.retromusic.fragments.player.flat.FlatPlaybackControlsFragment" android:layout_width="0dp" android:layout_height="0dp" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@+id/playerToolbar" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/playerAlbumCoverFragment" tools:layout="@layout/fragment_flat_player_playback_controls" /> + + + \ No newline at end of file From 0cd1b5d3bdfa28a29591b7fc1866ad0f7b3ff638 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Fri, 10 Dec 2021 20:18:18 +0530 Subject: [PATCH 20/82] [Notification] Made notification dismissible on API 31 and lower --- .../monkey/retromusic/service/MusicService.java | 17 +++++++++++++++-- .../service/notification/PlayingNotification.kt | 2 ++ .../notification/PlayingNotificationImpl.kt | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java index 435cb9f9e..36ccbce61 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java +++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java @@ -24,6 +24,8 @@ import static code.name.monkey.retromusic.ConstantsKt.COLORED_NOTIFICATION; import static code.name.monkey.retromusic.ConstantsKt.CROSS_FADE_DURATION; import static code.name.monkey.retromusic.ConstantsKt.TOGGLE_HEADSET; import static code.name.monkey.retromusic.service.AudioFader.startFadeAnimator; +import static code.name.monkey.retromusic.service.notification.PlayingNotification.NOTIFY_MODE_BACKGROUND; +import static code.name.monkey.retromusic.service.notification.PlayingNotification.NOTIFY_MODE_FOREGROUND; import android.app.NotificationManager; import android.app.PendingIntent; @@ -369,6 +371,7 @@ public class MusicService extends MediaBrowserServiceCompat private PowerManager.WakeLock wakeLock; private NotificationManager notificationManager; private boolean isForeground = false; + private int notifyMode = NOTIFY_MODE_BACKGROUND; private static Bitmap copy(Bitmap bitmap) { Bitmap.Config config = bitmap.getConfig(); @@ -1457,9 +1460,18 @@ public class MusicService extends MediaBrowserServiceCompat } private Unit startForegroundOrNotify() { - if (!isForeground) { + int newNotifyMode = isPlaying() ? NOTIFY_MODE_FOREGROUND : NOTIFY_MODE_BACKGROUND; + + if (notifyMode != newNotifyMode && newNotifyMode == NOTIFY_MODE_BACKGROUND) { + // This makes the notification dismissible + // We can't call stopForeground(false) on A12 though, which may result in crashes + // when we call startForeground after that e.g. when Alarm goes off, + if (Build.VERSION.SDK_INT < VERSION_CODES.S) stopForeground(false); + } + + if (newNotifyMode == NOTIFY_MODE_FOREGROUND) { // Specify that this is a media service, if supported. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + if (VersionUtils.hasQ()) { startForeground( PlayingNotification.NOTIFICATION_ID, playingNotification.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK @@ -1475,6 +1487,7 @@ public class MusicService extends MediaBrowserServiceCompat PlayingNotification.NOTIFICATION_ID, playingNotification.build() ); } + notifyMode = newNotifyMode; return Unit.INSTANCE; } diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotification.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotification.kt index 162775f06..3abb52a6e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotification.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotification.kt @@ -37,6 +37,8 @@ abstract class PlayingNotification(context: Context) : const val NOTIFICATION_CONTROLS_SIZE_MULTIPLIER = 1.0f internal const val NOTIFICATION_CHANNEL_ID = "playing_notification" const val NOTIFICATION_ID = 1 + const val NOTIFY_MODE_FOREGROUND = 1 + const val NOTIFY_MODE_BACKGROUND = 0 @RequiresApi(26) diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt index b8ef0cca6..bbeafa735 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt @@ -186,8 +186,23 @@ class PlayingNotificationImpl( ).build() } + private fun buildDismissAction(): NotificationCompat.Action { + return NotificationCompat.Action.Builder( + R.drawable.ic_close, + context.getString(R.string.customactivityoncrash_error_activity_error_details_close), + retrievePlaybackAction(ACTION_QUIT) + ).build() + } + override fun setPlaying(isPlaying: Boolean) { mActions[2] = buildPlayAction(isPlaying) + // Show dismiss action if we are not playing but only for A12+, as we can't call stopForeground(false) + // on A12 which would result in crashes when we call startForeground after that + if (!isPlaying) { + addAction(buildDismissAction()) + } else { + mActions.removeAt(4) + } } override fun updateFavorite(song: Song, onUpdate: () -> Unit) { From 2a3594a05ac8bb7663317baf3f933eacb09c32c9 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Fri, 10 Dec 2021 22:22:43 +0530 Subject: [PATCH 21/82] Restore data for any version(Google Backup & Restore) --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fda8258e7..377342a16 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,6 +27,7 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:requestLegacyExternalStorage="true" + android:restoreAnyVersion="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.RetroMusic.FollowSystem" From e27bf9d2cbf83485e7d50d8efdcf7c2f5ad0a64b Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sat, 11 Dec 2021 01:21:51 +0530 Subject: [PATCH 22/82] Updated dependencies and some changes to Gradle to decrease build time. getDate used to run for every Build which resulted in different versionCode for every which is present in manifest, so heavy tasks used to run everytime so more build time. getDate is used for only release builds now. --- app/build.gradle | 15 ++++++++------- .../retromusic/cast/CastOptionsProvider.kt | 2 +- build.gradle | 16 ++++------------ settings.gradle | 8 ++++++++ 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ddb856324..c2ef5728c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,18 +5,18 @@ apply plugin: "androidx.navigation.safeargs.kotlin" apply plugin: 'kotlin-parcelize' android { - compileSdkVersion 31 + compileSdk 31 defaultConfig { - minSdkVersion 21 - targetSdkVersion 31 + minSdk 21 + targetSdk 31 renderscriptTargetApi 29//must match target sdk and build tools vectorDrawables.useSupportLibrary = true applicationId "code.name.monkey.retromusic" - versionCode 10545 - versionName '5.4.2 ' + "_" + getDate() + versionCode 10547 + versionName '5.4.3' buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"") } @@ -31,7 +31,8 @@ android { } buildTypes { release { - //debuggable true + versionNameSuffix "_" + getDate() + shrinkResources true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release @@ -101,7 +102,7 @@ dependencies { //Cast Dependencies implementation 'androidx.mediarouter:mediarouter:1.2.5' - implementation 'com.google.android.gms:play-services-cast-framework:20.1.0' + implementation 'com.google.android.gms:play-services-cast-framework:21.0.0' //WebServer by NanoHttpd implementation "org.nanohttpd:nanohttpd:2.3.1" diff --git a/app/src/main/java/code/name/monkey/retromusic/cast/CastOptionsProvider.kt b/app/src/main/java/code/name/monkey/retromusic/cast/CastOptionsProvider.kt index a8d14aaef..d6759dc20 100644 --- a/app/src/main/java/code/name/monkey/retromusic/cast/CastOptionsProvider.kt +++ b/app/src/main/java/code/name/monkey/retromusic/cast/CastOptionsProvider.kt @@ -35,7 +35,7 @@ class CastOptionsProvider : OptionsProvider { .build() } - override fun getAdditionalSessionProviders(context: Context?): List? { + override fun getAdditionalSessionProviders(context: Context): MutableList? { return null } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8a6bcb45b..e4eace34c 100644 --- a/build.gradle +++ b/build.gradle @@ -7,22 +7,14 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.3' + classpath 'com.android.tools.build:gradle:7.0.4' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" def nav_version = "2.4.0-beta02" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" - classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.1" + classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.4" } } -allprojects { - repositories { - google() - mavenCentral() - maven { url "https://jitpack.io" } - } -} - -/*task clean(type: Delete) { +task clean(type: Delete) { delete rootProject.buildDir -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 914418483..27bc031ae 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,9 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven { url "https://jitpack.io" } + } +} include ':app', ':appthemehelper' \ No newline at end of file From 2975a33e9537e8bfc7802346407012bc842d1a4d Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 12 Dec 2021 12:35:46 +0530 Subject: [PATCH 23/82] Fixed Gradient theme queue sheet --- .../player/gradient/GradientPlayerFragment.kt | 12 ++++++------ .../service/notification/PlayingNotificationImpl.kt | 2 +- app/src/main/res/layout/fragment_gradient_player.xml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt index 20fff4b1a..7b15c9479 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt @@ -81,7 +81,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null private var playingQueueAdapter: PlayingQueueAdapter? = null private lateinit var linearLayoutManager: LinearLayoutManager - private var bottomInsets = 0 + private var navBarHeight = 0 private var _binding: FragmentGradientPlayerBinding? = null private val binding get() = _binding!! @@ -92,8 +92,8 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play binding.playerQueueSheet.updatePadding( top = (slideOffset * binding.statusBarLayout.statusBar.height).toInt() ) - binding.container.updatePadding( - bottom = ((1 - slideOffset) * bottomInsets).toInt() + binding.recyclerView.updatePadding( + top = ((1 - slideOffset) * navBarHeight).toInt() ) } @@ -161,8 +161,8 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play ViewCompat.setOnApplyWindowInsetsListener( (binding.container) ) { v: View, insets: WindowInsetsCompat -> - bottomInsets = insets.safeGetBottomInsets() - v.updatePadding(bottom = bottomInsets) + navBarHeight = insets.safeGetBottomInsets() + binding.recyclerView.updatePadding(top = navBarHeight) insets } binding.playbackControlsFragment.root.drawAboveSystemBars() @@ -479,7 +479,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play oldBottom: Int ) { val panel = getQueuePanel() - panel.peekHeight = binding.container.height + panel.peekHeight = binding.container.height + navBarHeight } private fun setupRecyclerView() { diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt index bbeafa735..37926da08 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt @@ -201,7 +201,7 @@ class PlayingNotificationImpl( if (!isPlaying) { addAction(buildDismissAction()) } else { - mActions.removeAt(4) + if (mActions.size == 5) mActions.removeAt(4) } } diff --git a/app/src/main/res/layout/fragment_gradient_player.xml b/app/src/main/res/layout/fragment_gradient_player.xml index b8ab7af9b..ea2e8b1e5 100644 --- a/app/src/main/res/layout/fragment_gradient_player.xml +++ b/app/src/main/res/layout/fragment_gradient_player.xml @@ -150,7 +150,7 @@ android:layout_width="0dp" android:layout_height="0dp" android:background="?attr/colorSurface" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/container" From 144fcf29bd217bb8eb5b149198660b32f2e3b419 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 12 Dec 2021 16:53:58 +0530 Subject: [PATCH 24/82] Removed spotless --- app/build.gradle | 5 +---- appthemehelper/build.gradle | 10 ++++------ build.gradle | 1 - spotless.gradle | 30 ------------------------------ 4 files changed, 5 insertions(+), 41 deletions(-) delete mode 100644 spotless.gradle diff --git a/app/build.gradle b/app/build.gradle index c2ef5728c..8c2e9fda6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,6 @@ android { minSdk 21 targetSdk 31 - renderscriptTargetApi 29//must match target sdk and build tools vectorDrawables.useSupportLibrary = true applicationId "code.name.monkey.retromusic" @@ -162,6 +161,4 @@ dependencies { implementation 'me.zhanghai.android.fastscroll:library:1.1.7' implementation 'cat.ereza:customactivityoncrash:2.3.0' debugImplementation 'com.github.amitshekhariitbhu:Android-Debug-Database:1.0.6' -} - -apply from: '../spotless.gradle' +} \ No newline at end of file diff --git a/appthemehelper/build.gradle b/appthemehelper/build.gradle index 468e82ff3..407e90903 100644 --- a/appthemehelper/build.gradle +++ b/appthemehelper/build.gradle @@ -1,13 +1,11 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 31 + compileSdk 31 + defaultConfig { - minSdkVersion 21 - targetSdkVersion 31 - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - + minSdk 21 + targetSdk 31 } buildTypes { release { diff --git a/build.gradle b/build.gradle index e4eace34c..42064114f 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,6 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" def nav_version = "2.4.0-beta02" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" - classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.4" } } diff --git a/spotless.gradle b/spotless.gradle deleted file mode 100644 index 7c8a5be2f..000000000 --- a/spotless.gradle +++ /dev/null @@ -1,30 +0,0 @@ -apply plugin: "com.diffplug.spotless" -spotless { - java { - target "src/*.java" - trimTrailingWhitespace() - removeUnusedImports() - googleJavaFormat() - endWithNewline() - } - kotlin { - target "src/*.kt" - ktlint().userData(['indent_size': '4', 'continuation_indent_size': '2', 'disabled_rules': 'no-wildcard-imports']) - licenseHeaderFile '../spotless.license.kt' - trimTrailingWhitespace() - endWithNewline() - } - format 'misc', { - target '**/*.gradle', '**/*.md', '**/.gitignore' - indentWithSpaces() - trimTrailingWhitespace() - endWithNewline() - } - - format 'xml', { - target 'src/*.xml' - indentWithSpaces() - trimTrailingWhitespace() - endWithNewline() - } -} \ No newline at end of file From 421dc817a22347d2e0e90c5896d6aed87b5040ca Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 12 Dec 2021 17:09:05 +0530 Subject: [PATCH 25/82] Fixed favorite toggle in DriveModeActivity --- .../activities/DriveModeActivity.kt | 56 ++++++++++++++----- .../name/monkey/retromusic/db/PlaylistDao.kt | 2 +- .../retromusic/fragments/LibraryViewModel.kt | 1 + .../fragments/base/AbsPlayerFragment.kt | 51 ++++++++--------- .../full/FullPlaybackControlsFragment.kt | 40 ++++++------- .../player/gradient/GradientPlayerFragment.kt | 30 +++++----- .../fragments/playlists/PlaylistsFragment.kt | 2 +- .../retromusic/repository/Repository.kt | 8 ++- .../retromusic/repository/RoomRepository.kt | 24 ++++++-- .../notification/PlayingNotificationImpl.kt | 6 +- 10 files changed, 125 insertions(+), 95 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt index df912bcd4..1205d1bdb 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt @@ -15,16 +15,22 @@ package code.name.monkey.retromusic.activities import android.animation.ObjectAnimator +import android.content.Intent import android.graphics.Color import android.graphics.PorterDuff import android.os.Bundle import android.view.animation.LinearInterpolator import android.widget.SeekBar +import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity import code.name.monkey.retromusic.databinding.ActivityDriveModeBinding -import code.name.monkey.retromusic.extensions.setDrawUnderStatusBar +import code.name.monkey.retromusic.db.toSongEntity +import code.name.monkey.retromusic.extensions.drawAboveSystemBars +import code.name.monkey.retromusic.fragments.LibraryViewModel +import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment import code.name.monkey.retromusic.glide.BlurTransformation import code.name.monkey.retromusic.glide.GlideApp @@ -35,13 +41,16 @@ import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.repository.RealRepository import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.color.MediaNotificationProcessor -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.koin.android.ext.android.inject +import org.koin.androidx.viewmodel.ext.android.viewModel /** @@ -54,9 +63,9 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { private var lastPlaybackControlsColor: Int = Color.GRAY private var lastDisabledPlaybackControlsColor: Int = Color.GRAY private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper + private val repository: RealRepository by inject() override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() super.onCreate(savedInstanceState) binding = ActivityDriveModeBinding.inflate(layoutInflater) setContentView(binding.root) @@ -67,6 +76,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { binding.close.setOnClickListener { onBackPressed() } + binding.repeatButton.drawAboveSystemBars() } private fun setUpMusicControllers() { @@ -80,19 +90,32 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { private fun setupFavouriteToggle() { binding.songFavourite.setOnClickListener { - MusicUtil.toggleFavorite( - this@DriveModeActivity, - MusicPlayerRemote.currentSong - ) + toggleFavorite(MusicPlayerRemote.currentSong) } } - private fun toggleFavourite() { - CoroutineScope(Dispatchers.IO).launch { - val isFavourite = - MusicUtil.isFavorite(this@DriveModeActivity, MusicPlayerRemote.currentSong) + private fun toggleFavorite(song: Song) { + lifecycleScope.launch(Dispatchers.IO) { + val playlist = repository.favoritePlaylist() + if (playlist != null) { + val songEntity = song.toSongEntity(playlist.playListId) + val isFavorite = repository.isSongFavorite(song.id) + if (isFavorite) { + repository.removeSongFromPlaylist(songEntity) + } else { + repository.insertSongs(listOf(song.toSongEntity(playlist.playListId))) + } + } + sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED)) + } + } + + private fun updateFavorite() { + lifecycleScope.launch(Dispatchers.IO) { + val isFavorite: Boolean = + repository.isSongFavorite(MusicPlayerRemote.currentSong.id) withContext(Dispatchers.Main) { - binding.songFavourite.setImageResource(if (isFavourite) R.drawable.ic_favorite else R.drawable.ic_favorite_border) + binding.songFavourite.setImageResource(if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border) } } } @@ -160,7 +183,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { updateSong() updateRepeatState() updateShuffleState() - toggleFavourite() + updateFavorite() } private fun updatePlayPauseDrawableState() { @@ -213,7 +236,12 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { override fun onPlayingMetaChanged() { super.onPlayingMetaChanged() updateSong() - toggleFavourite() + updateFavorite() + } + + override fun onFavoriteStateChanged() { + super.onFavoriteStateChanged() + updateFavorite() } private fun updateSong() { diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt index fa39a5cb4..a8369226e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt +++ b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt @@ -26,7 +26,7 @@ interface PlaylistDao { suspend fun renamePlaylist(playlistId: Long, name: String) @Query("SELECT * FROM PlaylistEntity WHERE playlist_name = :name") - fun isPlaylistExists(name: String): List + fun playlist(name: String): List @Query("SELECT * FROM PlaylistEntity") suspend fun playlists(): List diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt index 171983cdf..518bca7ac 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt @@ -233,6 +233,7 @@ class LibraryViewModel( suspend fun artistById(id: Long) = repository.artistById(id) suspend fun favoritePlaylist() = repository.favoritePlaylist() suspend fun isFavoriteSong(song: SongEntity) = repository.isFavoriteSong(song) + suspend fun isSongFavorite(songId: Long) = repository.isSongFavorite(songId) suspend fun insertSongs(songs: List) = repository.insertSongs(songs) suspend fun removeSongFromPlaylist(songEntity: SongEntity) = repository.removeSongFromPlaylist(songEntity) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt index 7acfc1112..b63fc6dc9 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt @@ -38,7 +38,6 @@ import androidx.core.os.bundleOf import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController import androidx.navigation.navOptions -import androidx.transition.Fade import androidx.viewpager.widget.ViewPager import code.name.monkey.retromusic.EXTRA_ALBUM_ID import code.name.monkey.retromusic.EXTRA_ARTIST_ID @@ -232,7 +231,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist() if (playlist != null) { val songEntity = song.toSongEntity(playlist.playListId) - val isFavorite = libraryViewModel.isFavoriteSong(songEntity).isNotEmpty() + val isFavorite = libraryViewModel.isSongFavorite(song.id) if (isFavorite) { libraryViewModel.removeSongFromPlaylist(songEntity) } else { @@ -246,32 +245,28 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme fun updateIsFavorite(animate: Boolean = false) { lifecycleScope.launch(IO) { - val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist() - if (playlist != null) { - val song: SongEntity = - MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId) - val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty() - withContext(Main) { - val icon = if (animate) { - if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite - } else { - if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border - } - val drawable: Drawable = RetroUtil.getTintedVectorDrawable( - requireContext(), - icon, - toolbarIconColor() - ) - if (playerToolbar() != null) { - playerToolbar()?.menu?.findItem(R.id.action_toggle_favorite)?.apply { - setIcon(drawable) - title = - if (isFavorite) getString(R.string.action_remove_from_favorites) - else getString(R.string.action_add_to_favorites) - getIcon().also { - if (it is AnimatedVectorDrawable) { - it.start() - } + val isFavorite: Boolean = + libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) + withContext(Main) { + val icon = if (animate) { + if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite + } else { + if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border + } + val drawable: Drawable = RetroUtil.getTintedVectorDrawable( + requireContext(), + icon, + toolbarIconColor() + ) + if (playerToolbar() != null) { + playerToolbar()?.menu?.findItem(R.id.action_toggle_favorite)?.apply { + setIcon(drawable) + title = + if (isFavorite) getString(R.string.action_remove_from_favorites) + else getString(R.string.action_add_to_favorites) + getIcon().also { + if (it is AnimatedVectorDrawable) { + it.start() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt index 324b00e8e..db751d52b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt @@ -317,28 +317,24 @@ class FullPlaybackControlsFragment : fun updateIsFavorite(animate: Boolean = false) { lifecycleScope.launch(Dispatchers.IO) { - val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist() - if (playlist != null) { - val song: SongEntity = - MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId) - val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty() - withContext(Dispatchers.Main) { - val icon = if (animate) { - if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite - } else { - if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border - } - val drawable: Drawable = RetroUtil.getTintedVectorDrawable( - requireContext(), - icon, - Color.WHITE - ) - binding.songFavourite.apply { - setImageDrawable(drawable) - getDrawable().also { - if (it is AnimatedVectorDrawable) { - it.start() - } + val isFavorite: Boolean = + libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) + withContext(Dispatchers.Main) { + val icon = if (animate) { + if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite + } else { + if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border + } + val drawable: Drawable = RetroUtil.getTintedVectorDrawable( + requireContext(), + icon, + Color.WHITE + ) + binding.songFavourite.apply { + setImageDrawable(drawable) + getDrawable().also { + if (it is AnimatedVectorDrawable) { + it.start() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt index 7b15c9479..d24112406 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt @@ -281,23 +281,19 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play private fun updateIsFavoriteIcon(animate: Boolean = false) { lifecycleScope.launch(Dispatchers.IO) { - val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist() - if (playlist != null) { - val song: SongEntity = - MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId) - val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty() - withContext(Dispatchers.Main) { - val icon = if (animate) { - if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite - } else { - if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border - } - binding.playbackControlsFragment.songFavourite.apply { - setImageResource(icon) - drawable.also { - if (it is AnimatedVectorDrawable) { - it.start() - } + val isFavorite: Boolean = + libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) + withContext(Dispatchers.Main) { + val icon = if (animate) { + if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite + } else { + if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border + } + binding.playbackControlsFragment.songFavourite.apply { + setImageResource(icon) + drawable.also { + if (it is AnimatedVectorDrawable) { + it.start() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt index 47db31189..094c146bc 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt @@ -42,7 +42,7 @@ class PlaylistsFragment : super.onViewCreated(view, savedInstanceState) libraryViewModel.getPlaylists().observe(viewLifecycleOwner, { if (it.isNotEmpty()) - adapter?.swapDataSet(it.filter { playlistWithSongs-> playlistWithSongs.songs.isNotEmpty() }) + adapter?.swapDataSet(it) else adapter?.swapDataSet(listOf()) }) diff --git a/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt b/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt index 8fc822f27..0c7a3d9b0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt +++ b/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt @@ -72,6 +72,7 @@ interface Repository { suspend fun genresHome(): Home suspend fun playlists(): Home suspend fun homeSections(): List + @ExperimentalCoroutinesApi suspend fun homeSectionsFlow(): Flow>> suspend fun playlist(playlistId: Long): Playlist @@ -106,6 +107,7 @@ interface Repository { suspend fun searchArtists(query: String): List suspend fun searchSongs(query: String): List suspend fun searchAlbums(query: String): List + suspend fun isSongFavorite(songId: Long): Boolean fun getSongByGenre(genreId: Long): Song } @@ -133,6 +135,9 @@ class RealRepository( override suspend fun searchAlbums(query: String): List = albumRepository.albums(query) + override suspend fun isSongFavorite(songId: Long): Boolean = + roomRepository.isSongFavorite(context, songId) + override fun getSongByGenre(genreId: Long): Song = genreRepository.song(genreId) override suspend fun searchArtists(query: String): List = @@ -150,7 +155,8 @@ class RealRepository( override suspend fun artistById(artistId: Long): Artist = artistRepository.artist(artistId) - override suspend fun albumArtistByName(name: String): Artist = artistRepository.albumArtist(name) + override suspend fun albumArtistByName(name: String): Artist = + artistRepository.albumArtist(name) override suspend fun recentArtists(): List = lastAddedRepository.recentArtists() diff --git a/app/src/main/java/code/name/monkey/retromusic/repository/RoomRepository.kt b/app/src/main/java/code/name/monkey/retromusic/repository/RoomRepository.kt index 346dfa21f..d2b8ec619 100644 --- a/app/src/main/java/code/name/monkey/retromusic/repository/RoomRepository.kt +++ b/app/src/main/java/code/name/monkey/retromusic/repository/RoomRepository.kt @@ -1,7 +1,9 @@ package code.name.monkey.retromusic.repository +import android.content.Context import androidx.annotation.WorkerThread import androidx.lifecycle.LiveData +import code.name.monkey.retromusic.R import code.name.monkey.retromusic.db.* import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder.Companion.PLAYLIST_A_Z import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder.Companion.PLAYLIST_SONG_COUNT @@ -45,6 +47,7 @@ interface RoomRepository { suspend fun insertBlacklistPathAsync(blackListStoreEntity: BlackListStoreEntity) suspend fun blackListPaths(): List suspend fun deleteSongs(songs: List) + suspend fun isSongFavorite(context: Context, songId: Long): Boolean } class RealRoomRepository( @@ -60,7 +63,7 @@ class RealRoomRepository( @WorkerThread override suspend fun checkPlaylistExists(playlistName: String): List = - playlistDao.isPlaylistExists(playlistName) + playlistDao.playlist(playlistName) @WorkerThread override suspend fun playlists(): List = playlistDao.playlists() @@ -111,12 +114,13 @@ class RealRoomRepository( } override suspend fun favoritePlaylist(favorite: String): PlaylistEntity { - val playlist: PlaylistEntity? = playlistDao.isPlaylistExists(favorite).firstOrNull() + val playlist: PlaylistEntity? = playlistDao.playlist(favorite).firstOrNull() return if (playlist != null) { playlist } else { + println("Playlist Created") createPlaylist(PlaylistEntity(playlistName = favorite)) - playlistDao.isPlaylistExists(favorite).first() + playlistDao.playlist(favorite).first() } } @@ -145,12 +149,12 @@ class RealRoomRepository( override fun favoritePlaylistLiveData(favorite: String): LiveData> = playlistDao.favoritesSongsLiveData( - playlistDao.isPlaylistExists(favorite).first().playListId + playlistDao.playlist(favorite).first().playListId ) override suspend fun favoritePlaylistSongs(favorite: String): List = - if (playlistDao.isPlaylistExists(favorite).isNotEmpty()) playlistDao.favoritesSongs( - playlistDao.isPlaylistExists(favorite).first().playListId + if (playlistDao.playlist(favorite).isNotEmpty()) playlistDao.favoritesSongs( + playlistDao.playlist(favorite).first().playListId ) else emptyList() override suspend fun insertSongInPlayCount(playCountEntity: PlayCountEntity) = @@ -192,4 +196,12 @@ class RealRoomRepository( blackListStoreDao.deleteBlacklistPath(blackListStoreEntity) override suspend fun clearBlacklist() = blackListStoreDao.clearBlacklist() + + override suspend fun isSongFavorite(context: Context, songId: Long): Boolean { + return playlistDao.isSongExistsInPlaylist( + playlistDao.playlist(context.getString(R.string.favorites)).firstOrNull()?.playListId + ?: -1, + songId + ).isNotEmpty() + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt index 37926da08..ab4bfb2c7 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt @@ -207,11 +207,7 @@ class PlayingNotificationImpl( override fun updateFavorite(song: Song, onUpdate: () -> Unit) { GlobalScope.launch(Dispatchers.IO) { - val playlist: PlaylistEntity = MusicUtil.repository.favoritePlaylist() - val isFavorite = if (playlist != null) { - val songEntity = song.toSongEntity(playlist.playListId) - MusicUtil.repository.isFavoriteSong(songEntity).isNotEmpty() - } else false + val isFavorite = MusicUtil.repository.isSongFavorite(song.id) withContext(Dispatchers.Main) { mActions[0] = buildFavoriteAction(isFavorite) onUpdate() From 5d8ad186d52e0c1de261b9754bba8d013f57e96e Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 12 Dec 2021 17:11:11 +0530 Subject: [PATCH 26/82] Edge-to-edge Code cleanup --- .../activities/LockScreenActivity.kt | 1 - .../retromusic/activities/MainActivity.kt | 1 - .../retromusic/activities/PurchaseActivity.kt | 2 -- .../retromusic/activities/SettingsActivity.kt | 1 - .../activities/ShareInstagramStory.kt | 3 --- .../activities/base/AbsThemeActivity.kt | 1 + .../tageditor/AlbumTagEditorActivity.kt | 2 -- .../extensions/ActivityThemeExtensions.kt | 12 +++++----- .../res/layout/fragment_album_content.xml | 2 +- ...fragment_lock_screen_playback_controls.xml | 1 + .../code/name/monkey/appthemehelper/ATH.kt | 1 - .../monkey/appthemehelper/util/ATHUtil.kt | 8 +++---- gradle.properties | 23 ++++++++++++++----- 13 files changed, 29 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt index 46c1e4385..7c5013b88 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/LockScreenActivity.kt @@ -41,7 +41,6 @@ class LockScreenActivity : AbsMusicServiceActivity() { private var fragment: LockScreenControlsFragment? = null override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() super.onCreate(savedInstanceState) lockScreenInit() binding = ActivityLockScreenBinding.inflate(layoutInflater) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt index 348084f66..d7d99f4bc 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt @@ -51,7 +51,6 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener { } override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() super.onCreate(savedInstanceState) setTaskDescriptionColorAuto() hideStatusBar() diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt index 1054c1ef9..656423df5 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt @@ -28,7 +28,6 @@ import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsBaseActivity import code.name.monkey.retromusic.databinding.ActivityProVersionBinding -import code.name.monkey.retromusic.extensions.setDrawUnderStatusBar import code.name.monkey.retromusic.extensions.setLightStatusBar import code.name.monkey.retromusic.extensions.setStatusBarColor import com.anjlab.android.iab.v3.BillingProcessor @@ -40,7 +39,6 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler { private lateinit var billingProcessor: BillingProcessor override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() super.onCreate(savedInstanceState) binding = ActivityProVersionBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/SettingsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/SettingsActivity.kt index 39702cf9f..23ae725a3 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/SettingsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/SettingsActivity.kt @@ -32,7 +32,6 @@ import com.afollestad.materialdialogs.color.ColorCallback class SettingsActivity : AbsThemeActivity(), ColorCallback, OnThemeChangedListener { private lateinit var binding: ActivitySettingsBinding override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() val mSavedInstanceState = extra(TAG).value ?: savedInstanceState super.onCreate(mSavedInstanceState) setLightStatusBarAuto(surfaceColor()) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt b/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt index 6fd9a2b86..7632d68e1 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/ShareInstagramStory.kt @@ -28,8 +28,6 @@ import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.retromusic.activities.base.AbsBaseActivity import code.name.monkey.retromusic.databinding.ActivityShareInstagramBinding -import code.name.monkey.retromusic.extensions.applyToolbar -import code.name.monkey.retromusic.extensions.setDrawUnderStatusBar import code.name.monkey.retromusic.extensions.setLightStatusBar import code.name.monkey.retromusic.extensions.setStatusBarColor import code.name.monkey.retromusic.glide.GlideApp @@ -60,7 +58,6 @@ class ShareInstagramStory : AbsBaseActivity() { } override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() super.onCreate(savedInstanceState) binding = ActivityShareInstagramBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt index 87ff2f32a..e9cac3e2a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsThemeActivity.kt @@ -35,6 +35,7 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable { private val handler = Handler() override fun onCreate(savedInstanceState: Bundle?) { + setDrawBehindSystemBars() updateTheme() hideStatusBar() super.onCreate(savedInstanceState) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt index 4b9958c6b..18b73ed29 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt @@ -32,7 +32,6 @@ import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.ActivityAlbumTagEditorBinding import code.name.monkey.retromusic.extensions.appHandleColor -import code.name.monkey.retromusic.extensions.setDrawUnderStatusBar import code.name.monkey.retromusic.extensions.setTint import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper @@ -109,7 +108,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity + tools:listitem="@layout/item_song"/> Date: Sun, 12 Dec 2021 20:58:58 +0530 Subject: [PATCH 27/82] MD3 look for Smart playlist buttons --- .../retromusic/extensions/ColorExtensions.kt | 8 + .../retromusic/fragments/home/HomeFragment.kt | 9 + app/src/main/res/layout/abs_playlists.xml | 179 ++++-------------- app/src/main/res/values/styles.xml | 12 ++ app/src/main/res/values/styles_parents.xml | 2 +- 5 files changed, 72 insertions(+), 138 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/ColorExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ColorExtensions.kt index 8c0bb5b36..dfd78bcbd 100644 --- a/app/src/main/java/code/name/monkey/retromusic/extensions/ColorExtensions.kt +++ b/app/src/main/java/code/name/monkey/retromusic/extensions/ColorExtensions.kt @@ -120,6 +120,14 @@ fun MaterialButton.accentOutlineColor() { rippleColor = colorStateList } +fun MaterialButton.elevatedAccentColor() { + if (materialYou) return + val color = ThemeStore.accentColor(context) + val colorStateList = ColorStateList.valueOf(color) + iconTint = colorStateList + rippleColor = colorStateList +} + fun SeekBar.applyColor(@ColorInt color: Int) { thumbTintList = ColorStateList.valueOf(color) progressTintList = ColorStateList.valueOf(color) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt index bff61411d..647361a84 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt @@ -37,6 +37,7 @@ import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog import code.name.monkey.retromusic.extensions.accentColor import code.name.monkey.retromusic.extensions.drawNextToNavbar +import code.name.monkey.retromusic.extensions.elevatedAccentColor import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.RetroGlideExtension @@ -76,6 +77,7 @@ class HomeFragment : loadProfile() setupTitle() + colorButtons() postponeEnterTransition() view.doOnPreDraw { startPostponedEnterTransition() } binding.appBarLayout.statusBarForeground = @@ -173,6 +175,13 @@ class HomeFragment : .into(binding.userImage) } + fun colorButtons() { + binding.history.elevatedAccentColor() + binding.lastAdded.elevatedAccentColor() + binding.topPlayed.elevatedAccentColor() + binding.actionShuffle.elevatedAccentColor() + } + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { super.onCreateOptionsMenu(menu, inflater) inflater.inflate(R.menu.menu_main, menu) diff --git a/app/src/main/res/layout/abs_playlists.xml b/app/src/main/res/layout/abs_playlists.xml index 608b697a0..bf4b5e80c 100644 --- a/app/src/main/res/layout/abs_playlists.xml +++ b/app/src/main/res/layout/abs_playlists.xml @@ -6,155 +6,60 @@ android:orientation="vertical" android:paddingBottom="12dp"> - + app:layout_constraintTop_toTopOf="parent" /> - - - - - - - - - - - - - - - - - - - - - - - + app:layout_constraintStart_toEndOf="@+id/history" + app:layout_constraintTop_toTopOf="@+id/history" /> - - - - - - - + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:text="@string/my_top_tracks" + app:icon="@drawable/ic_trending_up" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/actionShuffle" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="@+id/history" + app:layout_constraintTop_toBottomOf="@+id/history" /> + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 39810478b..d1fbc9261 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -222,6 +222,18 @@ adjustResize|stateVisible + +

Phonograph by Karim Abou Zeid

-

Material Dialogs and Cab - by Aidan Michael Follestad

AOSP Support Librariesby AOSP contributors

+ title="AOSP Support Libraries">AOSP Support Libraries by AOSP contributors

Glide by Sam Judd

Retrofit by Square team

+

OkHttp by Square team

+

Koin by Arnaud Giuliani

+

Material Dialogs and Cab + by Aidan Michael Follestad

Material Contextual Action Bar by Aidan Michael Follestad

-

OkHttp by Square team

-

- CircleImageView by Henning Dodenhof

-

- MaterialProgressBar by Zhang Hai

Android In-App Billing v3 Library by Henning Dodenhof

Advanced RecyclerView by Haruki Hasegawa

-

Android-ObservableScrollView by Soichiro - Kashima

+

Custom Activity on Crash by Eduard Ereza Martínez +

+

NanoHttpd by NanoHttpd Team

+

Circular Seekbar by Tankery

+

jAudioTagger by Kanedias

+

Android Fast Scroll by Zhang Hai

+

Image Picker by Dhaval Patel

+

Material Intro by Jan Heinrich Reimer

+

Slidr by Drew Heavner

Icons by Austin Andrews

Material Design City Wallpaper

- diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/LicenseActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/LicenseActivity.kt index 11cd201ca..52498d447 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/LicenseActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/LicenseActivity.kt @@ -16,8 +16,6 @@ package code.name.monkey.retromusic.activities import android.graphics.Color import android.os.Bundle import android.view.MenuItem -import android.webkit.WebView -import androidx.appcompat.widget.Toolbar import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor import code.name.monkey.appthemehelper.util.ATHUtil.isWindowBackgroundDark import code.name.monkey.appthemehelper.util.ATHUtil.resolveColor @@ -25,29 +23,31 @@ import code.name.monkey.appthemehelper.util.ColorUtil.lightenColor import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsThemeActivity +import code.name.monkey.retromusic.databinding.ActivityLicenseBinding +import code.name.monkey.retromusic.extensions.drawAboveSystemBars +import code.name.monkey.retromusic.extensions.drawAboveSystemBarsWithPadding import java.io.BufferedReader import java.io.InputStreamReader import java.nio.charset.StandardCharsets /** Created by hemanths on 2019-09-27. */ class LicenseActivity : AbsThemeActivity() { + private lateinit var binding: ActivityLicenseBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_license) - val toolbar = findViewById(R.id.toolbar) - setSupportActionBar(toolbar) - ToolbarContentTintHelper.colorBackButton(toolbar) - toolbar.setBackgroundColor(resolveColor(this, R.attr.colorSurface)) - val webView = findViewById(R.id.license) + binding = ActivityLicenseBinding.inflate(layoutInflater) + setContentView(binding.root) + setSupportActionBar(binding.toolbar) + ToolbarContentTintHelper.colorBackButton(binding.toolbar) try { val buf = StringBuilder() val json = assets.open("oldindex.html") - val br = BufferedReader(InputStreamReader(json, StandardCharsets.UTF_8)) - var str: String? - while (br.readLine().also { str = it } != null) { - buf.append(str) + BufferedReader(InputStreamReader(json, StandardCharsets.UTF_8)).use { br -> + var str: String? + while (br.readLine().also { str = it } != null) { + buf.append(str) + } } - br.close() // Inject color values for WebView body background and links val isDark = isWindowBackgroundDark(this) @@ -72,12 +72,13 @@ class LicenseActivity : AbsThemeActivity() { lightenColor(accentColor(this)) ) ) - webView.loadData(changeLog, "text/html", "UTF-8") + binding.license.loadData(changeLog, "text/html", "UTF-8") } catch (e: Throwable) { - webView.loadData( + binding.license.loadData( "

Unable to load

" + e.localizedMessage + "

", "text/html", "UTF-8" ) } + binding.license.drawAboveSystemBars() } override fun onOptionsItemSelected(item: MenuItem): Boolean { diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewActivity.kt index 40200eba0..b1c979076 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/WhatsNewActivity.kt @@ -17,6 +17,7 @@ import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsThemeActivity import code.name.monkey.retromusic.databinding.ActivityWhatsNewBinding import code.name.monkey.retromusic.extensions.accentColor +import code.name.monkey.retromusic.extensions.drawAboveSystemBars import code.name.monkey.retromusic.extensions.setLightStatusBarAuto import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto import code.name.monkey.retromusic.util.PreferenceUtil.lastVersion @@ -38,12 +39,12 @@ class WhatsNewActivity : AbsThemeActivity() { try { val buf = StringBuilder() val json = assets.open("retro-changelog.html") - val br = BufferedReader(InputStreamReader(json, StandardCharsets.UTF_8)) - var str: String? - while (br.readLine().also { str = it } != null) { - buf.append(str) + BufferedReader(InputStreamReader(json, StandardCharsets.UTF_8)).use { br -> + var str: String? + while (br.readLine().also { str = it } != null) { + buf.append(str) + } } - br.close() // Inject color values for WebView body background and links val isDark = isWindowBackgroundDark(this) @@ -100,6 +101,7 @@ class WhatsNewActivity : AbsThemeActivity() { binding.tgFab.extend() } } + binding.webView.drawAboveSystemBars() } companion object { diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/M3UWriter.kt b/app/src/main/java/code/name/monkey/retromusic/helper/M3UWriter.kt index f6044b2de..c1b6cfee3 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/M3UWriter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/M3UWriter.kt @@ -31,15 +31,15 @@ object M3UWriter : M3UConstants { val file = File(dir, playlist.name + "." + M3UConstants.EXTENSION) val songs = playlist.getSongs() if (songs.isNotEmpty()) { - val bw = BufferedWriter(FileWriter(file)) - bw.write(M3UConstants.HEADER) - for (song in songs) { - bw.newLine() - bw.write(M3UConstants.ENTRY + song.duration + M3UConstants.DURATION_SEPARATOR + song.artistName + " - " + song.title) - bw.newLine() - bw.write(song.data) + BufferedWriter(FileWriter(file)).use { bw -> + bw.write(M3UConstants.HEADER) + for (song in songs) { + bw.newLine() + bw.write(M3UConstants.ENTRY + song.duration + M3UConstants.DURATION_SEPARATOR + song.artistName + " - " + song.title) + bw.newLine() + bw.write(song.data) + } } - bw.close() } return file } @@ -54,15 +54,15 @@ object M3UWriter : M3UConstants { it.songPrimaryKey }.toSongs() if (songs.isNotEmpty()) { - val bufferedWriter = BufferedWriter(FileWriter(file)) - bufferedWriter.write(M3UConstants.HEADER) - songs.forEach { - bufferedWriter.newLine() - bufferedWriter.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title) - bufferedWriter.newLine() - bufferedWriter.write(it.data) + BufferedWriter(FileWriter(file)).use { bw-> + bw.write(M3UConstants.HEADER) + songs.forEach { + bw.newLine() + bw.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title) + bw.newLine() + bw.write(it.data) + } } - bufferedWriter.close() } return file } @@ -72,15 +72,15 @@ object M3UWriter : M3UConstants { it.songPrimaryKey }.toSongs() if (songs.isNotEmpty()) { - val bufferedWriter = outputStream.bufferedWriter() - bufferedWriter.write(M3UConstants.HEADER) - songs.forEach { - bufferedWriter.newLine() - bufferedWriter.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title) - bufferedWriter.newLine() - bufferedWriter.write(it.data) + outputStream.bufferedWriter().use{ bw-> + bw.write(M3UConstants.HEADER) + songs.forEach { + bw.newLine() + bw.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title) + bw.newLine() + bw.write(it.data) + } } - bufferedWriter.close() } outputStream.flush() outputStream.close() diff --git a/app/src/main/res/layout/activity_license.xml b/app/src/main/res/layout/activity_license.xml index 25569ea28..57555118e 100644 --- a/app/src/main/res/layout/activity_license.xml +++ b/app/src/main/res/layout/activity_license.xml @@ -6,23 +6,17 @@ android:layout_height="match_parent" android:orientation="vertical"> - - + android:background="?attr/colorSurface" + android:fitsSystemWindows="true"> + android:layout_height="wrap_content" + android:scrollbars="none" + android:fitsSystemWindows="true" + app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" /> From c919033a2c3a1bf2915516bdd0f2f3d0229cce6d Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 15 Dec 2021 00:45:30 +0530 Subject: [PATCH 39/82] Added CrossFade effect to Blur, Blur Card & Circle player --- .../player/blur/BlurPlayerFragment.kt | 39 +++++++++---------- .../player/cardblur/CardBlurFragment.kt | 35 ++++++++--------- .../player/circle/CirclePlayerFragment.kt | 17 +++++--- .../retromusic/glide/RetroGlideExtension.kt | 37 ++++++++++++++++++ 4 files changed, 84 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/blur/BlurPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/blur/BlurPlayerFragment.kt index aec5f2e57..6f9b3798d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/blur/BlurPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/blur/BlurPlayerFragment.kt @@ -16,6 +16,7 @@ package code.name.monkey.retromusic.fragments.player.blur import android.content.SharedPreferences import android.graphics.Color +import android.graphics.drawable.Drawable import android.os.Bundle import android.view.View import androidx.appcompat.widget.Toolbar @@ -27,18 +28,18 @@ import code.name.monkey.retromusic.databinding.FragmentBlurBinding import code.name.monkey.retromusic.extensions.drawAboveSystemBars import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment -import code.name.monkey.retromusic.glide.BlurTransformation -import code.name.monkey.retromusic.glide.GlideApp -import code.name.monkey.retromusic.glide.RetroGlideExtension -import code.name.monkey.retromusic.glide.RetroMusicColoredTarget +import code.name.monkey.retromusic.glide.* import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.PreferenceUtil.blurAmount import code.name.monkey.retromusic.util.color.MediaNotificationProcessor + class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur), SharedPreferences.OnSharedPreferenceChangeListener { + private var lastRequest: GlideRequest? = null + override fun playerToolbar(): Toolbar { return binding.playerToolbar } @@ -111,23 +112,21 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur), get() = lastColor private fun updateBlur() { - binding.colorBackground.clearColorFilter() - GlideApp.with(requireActivity()).asBitmapPalette() - .songCoverOptions(MusicPlayerRemote.currentSong) + // https://github.com/bumptech/glide/issues/527#issuecomment-148840717 + GlideApp.with(this) .load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong)) - .dontAnimate() - .transform( - BlurTransformation.Builder(requireContext()) - .blurRadius(blurAmount.toFloat()) - .build() - ) - .into(object : RetroMusicColoredTarget(binding.colorBackground) { - override fun onColorReady(colors: MediaNotificationProcessor) { - if (colors.backgroundColor == defaultFooterColor) { - binding.colorBackground.setColorFilter(colors.backgroundColor) - } - } - }) + .songCoverOptions(MusicPlayerRemote.currentSong).apply { + thumbnail(lastRequest) + .crossfadeListener() + .transform( + BlurTransformation.Builder(requireContext()) + .blurRadius(blurAmount.toFloat()) + .build() + ) + .into(binding.colorBackground) + lastRequest = this + } + } override fun onServiceConnected() { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/cardblur/CardBlurFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/cardblur/CardBlurFragment.kt index bec78c7e5..dc78a10cd 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/cardblur/CardBlurFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/cardblur/CardBlurFragment.kt @@ -16,6 +16,7 @@ package code.name.monkey.retromusic.fragments.player.cardblur import android.content.SharedPreferences import android.graphics.Color +import android.graphics.drawable.Drawable import android.os.Bundle import android.view.View import androidx.appcompat.widget.Toolbar @@ -28,10 +29,7 @@ import code.name.monkey.retromusic.extensions.drawAboveSystemBars import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment -import code.name.monkey.retromusic.glide.BlurTransformation -import code.name.monkey.retromusic.glide.GlideApp -import code.name.monkey.retromusic.glide.RetroGlideExtension -import code.name.monkey.retromusic.glide.RetroMusicColoredTarget +import code.name.monkey.retromusic.glide.* import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.PreferenceUtil.blurAmount @@ -50,6 +48,7 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player), private var _binding: FragmentCardBlurPlayerBinding? = null private val binding get() = _binding!! + private var lastRequest: GlideRequest? = null override fun onShow() { playbackControlsFragment.show() @@ -136,22 +135,20 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player), } private fun updateBlur() { - binding.colorBackground.clearColorFilter() - GlideApp.with(requireActivity()).asBitmapPalette() - .songCoverOptions(MusicPlayerRemote.currentSong) + // https://github.com/bumptech/glide/issues/527#issuecomment-148840717 + GlideApp.with(this) .load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong)) - .dontAnimate() - .transform( - BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat()) - .build() - ) - .into(object : RetroMusicColoredTarget(binding.colorBackground) { - override fun onColorReady(colors: MediaNotificationProcessor) { - if (colors.backgroundColor == defaultFooterColor) { - binding.colorBackground.setColorFilter(colors.backgroundColor) - } - } - }) + .songCoverOptions(MusicPlayerRemote.currentSong).apply { + thumbnail(lastRequest) + .crossfadeListener() + .transform( + BlurTransformation.Builder(requireContext()) + .blurRadius(blurAmount.toFloat()) + .build() + ) + .into(binding.colorBackground) + lastRequest = this + } } override fun onResume() { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/circle/CirclePlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/circle/CirclePlayerFragment.kt index 10de5dc26..1e68528bd 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/circle/CirclePlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/circle/CirclePlayerFragment.kt @@ -19,6 +19,7 @@ import android.content.Context import android.graphics.Color import android.graphics.PorterDuff import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable import android.media.AudioManager import android.os.Bundle import android.view.LayoutInflater @@ -37,8 +38,7 @@ import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.goToAlbum import code.name.monkey.retromusic.fragments.base.goToArtist -import code.name.monkey.retromusic.glide.GlideApp -import code.name.monkey.retromusic.glide.RetroGlideExtension +import code.name.monkey.retromusic.glide.* import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback @@ -70,6 +70,7 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player), private val binding get() = _binding!! private var rotateAnimator: ObjectAnimator? = null + private var lastRequest: GlideRequest? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -241,9 +242,15 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player), binding.songInfo.hide() } GlideApp.with(this) - .load(RetroGlideExtension.getSongModel(song)) - .songCoverOptions(song) - .into(binding.albumCover) + .load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong)) + .songCoverOptions(MusicPlayerRemote.currentSong).apply { + thumbnail(lastRequest) + .crossfadeListener() + .fitCenter() + .into(binding.albumCover) + lastRequest = this + } + } private fun updatePlayPauseDrawableState() { diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/RetroGlideExtension.kt b/app/src/main/java/code/name/monkey/retromusic/glide/RetroGlideExtension.kt index 9db983669..e16971768 100644 --- a/app/src/main/java/code/name/monkey/retromusic/glide/RetroGlideExtension.kt +++ b/app/src/main/java/code/name/monkey/retromusic/glide/RetroGlideExtension.kt @@ -1,8 +1,10 @@ package code.name.monkey.retromusic.glide import android.graphics.drawable.Drawable +import androidx.core.graphics.drawable.toDrawable import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor import code.name.monkey.appthemehelper.util.TintHelper +import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App.Companion.getContext import code.name.monkey.retromusic.Constants.USER_BANNER import code.name.monkey.retromusic.Constants.USER_PROFILE @@ -23,9 +25,15 @@ import com.bumptech.glide.RequestBuilder import com.bumptech.glide.annotation.GlideExtension import com.bumptech.glide.annotation.GlideOption import com.bumptech.glide.annotation.GlideType +import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.Key import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.request.BaseRequestOptions +import com.bumptech.glide.request.RequestListener +import com.bumptech.glide.request.target.Target +import com.bumptech.glide.request.transition.DrawableCrossFadeFactory +import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.signature.MediaStoreSignature import java.io.File @@ -194,4 +202,33 @@ object RetroGlideExtension { fun getDefaultTransition(): GenericTransitionOptions { return GenericTransitionOptions().transition(DEFAULT_ANIMATION) } +} + +// https://github.com/bumptech/glide/issues/527#issuecomment-148840717 +fun GlideRequest.crossfadeListener(): GlideRequest { + return listener(object : RequestListener { + override fun onLoadFailed( + e: GlideException?, + model: Any?, + target: Target?, + isFirstResource: Boolean + ): Boolean { + return false + } + + override fun onResourceReady( + resource: Drawable?, + model: Any?, + target: Target?, + dataSource: DataSource?, + isFirstResource: Boolean + ): Boolean { + return if (isFirstResource) { + false // thumbnail was not shown, do as usual + } else DrawableCrossFadeFactory.Builder() + .setCrossFadeEnabled(true).build() + .build(dataSource, isFirstResource) + .transition(resource, target as Transition.ViewAdapter) + } + }) } \ No newline at end of file From 5a204b3653735a89a01ef0a038a38e7d0dbe58d3 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 15 Dec 2021 12:03:01 +0530 Subject: [PATCH 40/82] [Lockscreen Controls] Fixed glitchy Lockscreen Slide --- .../res/layout/fragment_lock_screen_playback_controls.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_lock_screen_playback_controls.xml b/app/src/main/res/layout/fragment_lock_screen_playback_controls.xml index a8f9a71a5..95fe798f5 100644 --- a/app/src/main/res/layout/fragment_lock_screen_playback_controls.xml +++ b/app/src/main/res/layout/fragment_lock_screen_playback_controls.xml @@ -10,7 +10,7 @@ Date: Wed, 15 Dec 2021 12:06:43 +0530 Subject: [PATCH 41/82] [Tag Editor] Readable text color for Tag Editor save button --- .../tageditor/AlbumTagEditorActivity.kt | 8 ++++++++ .../tageditor/SongTagEditorActivity.kt | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt index 79a954055..404f505a7 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt @@ -29,9 +29,11 @@ import android.view.LayoutInflater import android.widget.ImageView import android.widget.Toast import code.name.monkey.appthemehelper.util.ATHUtil +import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.databinding.ActivityAlbumTagEditorBinding import code.name.monkey.retromusic.extensions.appHandleColor +import code.name.monkey.retromusic.extensions.isColorLight import code.name.monkey.retromusic.extensions.setTint import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper @@ -213,6 +215,12 @@ class AlbumTagEditorActivity : AbsTagEditorActivity binding.trackNumberText.appHandleColor().addTextChangedListener(this) binding.lyricsText.appHandleColor().addTextChangedListener(this) binding.songComposerText.appHandleColor().addTextChangedListener(this) - - binding.lyricsText.setOnTouchListener { view, _ -> - view.parent.requestDisallowInterceptTouchEvent(true) - return@setOnTouchListener false - } } private fun fillViewsWithFileTags() { @@ -133,6 +131,17 @@ class SongTagEditorActivity : AbsTagEditorActivity dataChanged() } + override fun setColors(color: Int) { + super.setColors(color) + saveFab.backgroundTintList = ColorStateList.valueOf(color) + saveFab.iconTint = ColorStateList.valueOf( + MaterialValueHelper.getPrimaryTextColor( + this, + color.isColorLight + ) + ) + } + override fun save() { val fieldKeyValueMap = EnumMap(FieldKey::class.java) fieldKeyValueMap[FieldKey.TITLE] = binding.songText.text.toString() From 9806e2119af191a8ff36b797c1ca802ca41b8271 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 15 Dec 2021 13:37:25 +0530 Subject: [PATCH 42/82] Updated dependencies --- app/build.gradle | 2 +- appthemehelper/build.gradle | 1 - build.gradle | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1c5c52c52..a97588114 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -138,7 +138,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - def kotlin_coroutines_version = '1.6.0-RC' + def kotlin_coroutines_version = '1.6.0-RC2' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" diff --git a/appthemehelper/build.gradle b/appthemehelper/build.gradle index 407e90903..10c0f52e5 100644 --- a/appthemehelper/build.gradle +++ b/appthemehelper/build.gradle @@ -20,7 +20,6 @@ android { } dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.appcompat:appcompat:1.4.0' implementation 'com.google.android.material:material:1.5.0-beta01' implementation 'androidx.preference:preference-ktx:1.2.0-beta01' diff --git a/build.gradle b/build.gradle index 42064114f..1c7975412 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.6.0' + ext.kotlin_version = '1.6.10' repositories { mavenCentral() google() From e4a309af664cd992fc6cec2928524a039e9c2c4d Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Wed, 15 Dec 2021 15:05:45 +0530 Subject: [PATCH 43/82] [Now Playing] Replaced old lyrics with LrcView, this replaces Album Cover with LrcView when enabled [Now Playing] Replaced old lyrics with LrcView, this replaces Album Cover with LrcView when enabled --- .../fragments/other/UserInfoFragment.kt | 3 +- .../player/PlayerAlbumCoverFragment.kt | 203 ++--- .../player/adaptive/AdaptiveFragment.kt | 2 +- .../monkey/retromusic/lyrics/CoverLrcView.kt | 718 ++++++++++++++++++ ...fragment_flat_player_playback_controls.xml | 1 - .../layout/fragment_player_album_cover.xml | 59 +- app/src/main/res/values/lrc_dimens.xml | 4 +- 7 files changed, 818 insertions(+), 172 deletions(-) create mode 100644 app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/other/UserInfoFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/other/UserInfoFragment.kt index ea3653eba..38b040b6c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/other/UserInfoFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/other/UserInfoFragment.kt @@ -134,12 +134,11 @@ class UserInfoFragment : Fragment() { private fun loadProfile() { binding.bannerImage.let { GlideApp.with(this) - .asBitmap() .load(RetroGlideExtension.getBannerModel()) .profileBannerOptions(RetroGlideExtension.getBannerModel()) .into(it) } - GlideApp.with(this).asBitmap() + GlideApp.with(this) .load(RetroGlideExtension.getUserModel()) .userProfileOptions(RetroGlideExtension.getUserModel()) .into(binding.userImage) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt index e75ab76cb..027a773e0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt @@ -14,42 +14,36 @@ */ package code.name.monkey.retromusic.fragments.player +import android.annotation.SuppressLint import android.content.SharedPreferences +import android.graphics.Color import android.os.Bundle -import android.text.TextUtils import android.view.View -import android.widget.FrameLayout -import android.widget.TextView +import androidx.core.view.isInvisible import androidx.core.view.isVisible -import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager import androidx.viewpager.widget.ViewPager +import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.SHOW_LYRICS import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter.AlbumCoverFragment import code.name.monkey.retromusic.databinding.FragmentPlayerAlbumCoverBinding +import code.name.monkey.retromusic.extensions.isColorLight +import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.fragments.NowPlayingScreen.* import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.goToLyrics import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper -import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics +import code.name.monkey.retromusic.lyrics.CoverLrcView import code.name.monkey.retromusic.model.lyrics.Lyrics import code.name.monkey.retromusic.transform.CarousalPagerTransformer import code.name.monkey.retromusic.transform.ParallaxPagerTransformer import code.name.monkey.retromusic.util.LyricUtil import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.color.MediaNotificationProcessor -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.jaudiotagger.audio.AudioFileIO -import org.jaudiotagger.audio.exceptions.CannotReadException -import org.jaudiotagger.tag.FieldKey -import java.io.File -import java.io.FileNotFoundException class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_player_album_cover), ViewPager.OnPageChangeListener, MusicProgressViewUpdateHelper.Callback, @@ -70,9 +64,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe } private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null - private val lyricsLayout: FrameLayout get() = binding.playerLyrics - private val lyricsLine1: TextView get() = binding.playerLyricsLine1 - private val lyricsLine2: TextView get() = binding.playerLyricsLine2 + private val lrcView: CoverLrcView get() = binding.lyricsView var lyrics: Lyrics? = null @@ -82,102 +74,28 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe } private fun updateLyrics() { - lyrics = null - lifecycleScope.launch(Dispatchers.IO) { - val song = MusicPlayerRemote.currentSong - val lyrics = try { - var lrcFile: File? = null - if (LyricUtil.isLrcOriginalFileExist(song.data)) { - lrcFile = LyricUtil.getLocalLyricOriginalFile(song.data) - } else if (LyricUtil.isLrcFileExist(song.title, song.artistName)) { - lrcFile = LyricUtil.getLocalLyricFile(song.title, song.artistName) - } - val data: String = LyricUtil.getStringFromLrc(lrcFile) - if (!TextUtils.isEmpty(data)) { - Lyrics.parse(song, data) - } else { - // Get Embedded Lyrics and check if they are Synchronized - val embeddedLyrics = try{ - AudioFileIO.read(File(song.data)).tagOrCreateDefault.getFirst(FieldKey.LYRICS) - } catch(e: Exception){ - null - } - if (AbsSynchronizedLyrics.isSynchronized(embeddedLyrics)) { - Lyrics.parse(song, embeddedLyrics) - } else { - null - } - } - } catch (err: FileNotFoundException) { - null - } catch (e: CannotReadException){ - null + binding.lyricsView.setLabel("Empty") + val song = MusicPlayerRemote.currentSong + when { + LyricUtil.isLrcOriginalFileExist(song.data) -> { + LyricUtil.getLocalLyricOriginalFile(song.data) + ?.let { binding.lyricsView.loadLrc(it) } } - withContext(Dispatchers.Main) { - this@PlayerAlbumCoverFragment.lyrics = lyrics + LyricUtil.isLrcFileExist(song.title, song.artistName) -> { + LyricUtil.getLocalLyricFile(song.title, song.artistName) + ?.let { binding.lyricsView.loadLrc(it) } + } + else -> { + binding.lyricsView.reset() } } } override fun onUpdateProgressViews(progress: Int, total: Int) { - if (_binding == null) return - - if (!isLyricsLayoutVisible()) { - hideLyricsLayout() - return - } - - if (lyrics !is AbsSynchronizedLyrics) return - val synchronizedLyrics = lyrics as AbsSynchronizedLyrics - - lyricsLayout.visibility = View.VISIBLE - lyricsLayout.alpha = 1f - - val oldLine = lyricsLine2.text.toString() - val line = synchronizedLyrics.getLine(progress) - - if (oldLine != line || oldLine.isEmpty()) { - lyricsLine1.text = oldLine - lyricsLine2.text = line - - lyricsLine1.visibility = View.VISIBLE - lyricsLine2.visibility = View.VISIBLE - - lyricsLine2.measure( - View.MeasureSpec.makeMeasureSpec( - lyricsLine2.measuredWidth, - View.MeasureSpec.EXACTLY - ), - View.MeasureSpec.UNSPECIFIED - ) - val h: Float = lyricsLine2.measuredHeight.toFloat() - - lyricsLine1.alpha = 1f - lyricsLine1.translationY = 0f - lyricsLine1.animate().alpha(0f).translationY(-h).duration = - AbsPlayerFragment.VISIBILITY_ANIM_DURATION - - lyricsLine2.alpha = 0f - lyricsLine2.translationY = h - lyricsLine2.animate().alpha(1f).translationY(0f).duration = - AbsPlayerFragment.VISIBILITY_ANIM_DURATION - } - } - - private fun isLyricsLayoutVisible(): Boolean { - return lyrics != null && lyrics!!.isSynchronized && lyrics!!.isValid - } - - private fun hideLyricsLayout() { - lyricsLayout.animate().alpha(0f).setDuration(AbsPlayerFragment.VISIBILITY_ANIM_DURATION) - .withEndAction { - if (_binding == null) return@withEndAction - lyricsLayout.visibility = View.GONE - lyricsLine1.text = null - lyricsLine2.text = null - } + binding.lyricsView.updateTime(progress.toLong()) } + @SuppressLint("ClickableViewAccessibility") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) _binding = FragmentPlayerAlbumCoverBinding.bind(view) @@ -210,14 +128,25 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe progressViewUpdateHelper = MusicProgressViewUpdateHelper(this, 500, 1000) // Don't show lyrics container for below conditions if (!(nps == Circle || nps == Peak || nps == Tiny || !PreferenceUtil.showLyrics)) { - lyricsLayout.isVisible = false + lrcView.isVisible = false + viewPager.isInvisible = false progressViewUpdateHelper?.stop() } else { - lyricsLayout.isVisible = true + lrcView.isVisible = true + viewPager.isInvisible = true progressViewUpdateHelper?.start() } + lrcView.apply { + setDraggable(true, object : CoverLrcView.OnPlayClickListener { + override fun onPlayClick(time: Long): Boolean { + MusicPlayerRemote.seekTo(time.toInt()) + MusicPlayerRemote.resumePlaying() + return true + } + }) + } // Go to lyrics activity when clicked lyrics - binding.playerLyricsLine2.setOnClickListener { + lrcView.setOnClickListener { goToLyrics(requireActivity()) } } @@ -227,10 +156,12 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe val nps = PreferenceUtil.nowPlayingScreen // Don't show lyrics container for below conditions if (nps == Circle || nps == Peak || nps == Tiny || !PreferenceUtil.showLyrics) { - lyricsLayout.isVisible = false + lrcView.isVisible = false + viewPager.isInvisible = false progressViewUpdateHelper?.stop() } else { - lyricsLayout.isVisible = true + lrcView.isVisible = true + viewPager.isInvisible = true progressViewUpdateHelper?.start() } PreferenceManager.getDefaultSharedPreferences(requireContext()) @@ -266,30 +197,42 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe val nps = PreferenceUtil.nowPlayingScreen // Don't show lyrics container for below conditions if (!(nps == Circle || nps == Peak || nps == Tiny || !PreferenceUtil.showLyrics)) { - lyricsLayout.isVisible = false - progressViewUpdateHelper?.stop() - } else { - lyricsLayout.isVisible = true + lrcView.isVisible = true + viewPager.isInvisible = true progressViewUpdateHelper?.start() - lyricsLayout.animate().alpha(1f).duration = + lrcView.animate().alpha(1f).duration = AbsPlayerFragment.VISIBILITY_ANIM_DURATION - binding.playerLyrics.isVisible = true + } else { + lrcView.isVisible = false + viewPager.isInvisible = false + progressViewUpdateHelper?.stop() } } else { + lrcView.isVisible = false + viewPager.isInvisible = false progressViewUpdateHelper?.stop() - lyricsLayout.animate().alpha(0f) - .setDuration(AbsPlayerFragment.VISIBILITY_ANIM_DURATION) - .withEndAction { - if (_binding != null) { - binding.playerLyrics.isVisible = false - lyricsLine1.text = null - lyricsLine2.text = null - } - } } } } + private fun setLRCViewColors(backgroundColor: Int) { + val primaryColor = MaterialValueHelper.getPrimaryTextColor( + requireContext(), + backgroundColor.isColorLight + ) + val secondaryColor = MaterialValueHelper.getSecondaryDisabledTextColor( + requireContext(), + backgroundColor.isColorLight + ) + lrcView.apply { + setCurrentColor(primaryColor) + setTimeTextColor(primaryColor) + setTimelineColor(primaryColor) + setNormalColor(secondaryColor) + setTimelineTextColor(primaryColor) + } + } + private fun updatePlayingQueue() { binding.viewPager.apply { adapter = AlbumCoverPagerAdapter(childFragmentManager, MusicPlayerRemote.playingQueue) @@ -321,6 +264,18 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe private fun notifyColorChange(color: MediaNotificationProcessor) { callbacks?.onColorChanged(color) + setLRCViewColors( + when (PreferenceUtil.nowPlayingScreen) { + Adaptive, Fit, Plain, Simple -> surfaceColor() + Flat, Normal -> if (PreferenceUtil.isAdaptiveColor) { + color.backgroundColor + } else { + surfaceColor() + } + Color ->color.backgroundColor + Blur -> Color.BLACK + else -> color.backgroundColor + }) } fun setCallbacks(listener: Callbacks) { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/adaptive/AdaptiveFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/adaptive/AdaptiveFragment.kt index 225d7b208..32bb5c259 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/adaptive/AdaptiveFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/adaptive/AdaptiveFragment.kt @@ -47,7 +47,7 @@ class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) { _binding = FragmentAdaptivePlayerBinding.bind(view) setUpSubFragments() setUpPlayerToolbar() - binding.root.drawAboveSystemBars() + binding.playbackControlsFragment.drawAboveSystemBars() } private fun setUpSubFragments() { diff --git a/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt b/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt new file mode 100644 index 000000000..1173632c8 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt @@ -0,0 +1,718 @@ +/* + * Copyright (C) 2017 wangchenyan + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package code.name.monkey.retromusic.lyrics + +import android.annotation.SuppressLint +import kotlin.jvm.JvmOverloads +import android.text.TextPaint +import android.graphics.drawable.Drawable +import android.animation.ValueAnimator +import android.view.GestureDetector +import android.widget.Scroller +import android.view.GestureDetector.SimpleOnGestureListener +import android.view.MotionEvent +import code.name.monkey.retromusic.R +import android.text.TextUtils +import android.os.AsyncTask +import android.text.StaticLayout +import android.view.animation.LinearInterpolator +import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.os.Looper +import android.text.Layout +import android.text.format.DateUtils +import android.util.AttributeSet +import android.view.View +import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat +import code.name.monkey.retromusic.BuildConfig +import java.io.File +import java.lang.StringBuilder +import java.util.* +import kotlin.math.abs + +/** + * 歌词 Created by wcy on 2015/11/9. + */ +@SuppressLint("StaticFieldLeak") +class CoverLrcView @JvmOverloads constructor( + context: Context?, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : View(context, attrs, defStyleAttr) { + private val mLrcEntryList: MutableList = ArrayList() + private val mLrcPaint = TextPaint() + private val mTimePaint = TextPaint() + private var mTimeFontMetrics: Paint.FontMetrics? = null + private var mPlayDrawable: Drawable? = null + private var mDividerHeight = 0f + private var mAnimationDuration: Long = 0 + private var mNormalTextColor = 0 + private var mNormalTextSize = 0f + private var mCurrentTextColor = 0 + private var mCurrentTextSize = 0f + private var mTimelineTextColor = 0 + private var mTimelineColor = 0 + private var mTimeTextColor = 0 + private var mDrawableWidth = 0 + private var mTimeTextWidth = 0 + private var mDefaultLabel: String? = null + private var mLrcPadding = 0f + private var mOnPlayClickListener: OnPlayClickListener? = null + private var mAnimator: ValueAnimator? = null + private var mGestureDetector: GestureDetector? = null + private var mScroller: Scroller? = null + private var mOffset = 0f + private var mCurrentLine = 0 + private var flag: Any? = null + private var isShowTimeline = false + private var isTouching = false + private var isFling = false + private var mTextGravity // 歌词显示位置,靠左/居中/靠右 + = 0 + private val hideTimelineRunnable = Runnable { + if (hasLrc() && isShowTimeline) { + isShowTimeline = false + smoothScrollTo(mCurrentLine) + } + } + + /** + * 手势监听器 + */ + private val mSimpleOnGestureListener: SimpleOnGestureListener = + object : SimpleOnGestureListener() { + override fun onDown(e: MotionEvent): Boolean { + if (mOffset != getOffset(0)) { + parent.requestDisallowInterceptTouchEvent(true) + } + if (hasLrc() && mOnPlayClickListener != null) { + mScroller!!.forceFinished(true) + removeCallbacks(hideTimelineRunnable) + isTouching = true + isShowTimeline = true + invalidate() + return true + } + return super.onDown(e) + } + + override fun onScroll( + e1: MotionEvent, + e2: MotionEvent, + distanceX: Float, + distanceY: Float + ): Boolean { + if (mOffset == getOffset(0) && distanceY < 0F) { + return super.onScroll(e1, e2, distanceX, distanceY) + } + if (hasLrc()) { + mOffset += -distanceY + mOffset = mOffset.coerceAtMost(getOffset(0)) + mOffset = mOffset.coerceAtLeast(getOffset(mLrcEntryList.size - 1)) + invalidate() + parent.requestDisallowInterceptTouchEvent(true) + return true + } + return super.onScroll(e1, e2, distanceX, distanceY) + } + + override fun onFling( + e1: MotionEvent, + e2: MotionEvent, + velocityX: Float, + velocityY: Float + ): Boolean { + if (hasLrc()) { + mScroller!!.fling( + 0, + mOffset.toInt(), + 0, + velocityY.toInt(), + 0, + 0, + getOffset(mLrcEntryList.size - 1).toInt(), + getOffset(0).toInt() + ) + isFling = true + return true + } + return super.onFling(e1, e2, velocityX, velocityY) + } + + override fun onSingleTapConfirmed(e: MotionEvent): Boolean { + if (hasLrc() + && isShowTimeline + && mPlayDrawable!!.bounds.contains(e.x.toInt(), e.y.toInt()) + ) { + val centerLine = centerLine + val centerLineTime = mLrcEntryList[centerLine].time + // onPlayClick 消费了才更新 UI + if (mOnPlayClickListener != null && mOnPlayClickListener!!.onPlayClick( + centerLineTime + ) + ) { + isShowTimeline = false + removeCallbacks(hideTimelineRunnable) + mCurrentLine = centerLine + invalidate() + return true + } + } + return super.onSingleTapConfirmed(e) + } + } + + private fun init(attrs: AttributeSet?) { + val ta = context.obtainStyledAttributes(attrs, R.styleable.LrcView) + mCurrentTextSize = ta.getDimension( + R.styleable.LrcView_lrcTextSize, resources.getDimension(R.dimen.lrc_text_size) + ) + mNormalTextSize = ta.getDimension( + R.styleable.LrcView_lrcNormalTextSize, + resources.getDimension(R.dimen.lrc_text_size) + ) + if (mNormalTextSize == 0f) { + mNormalTextSize = mCurrentTextSize + } + mDividerHeight = ta.getDimension( + R.styleable.LrcView_lrcDividerHeight, + resources.getDimension(R.dimen.lrc_divider_height) + ) + val defDuration = resources.getInteger(R.integer.lrc_animation_duration) + mAnimationDuration = + ta.getInt(R.styleable.LrcView_lrcAnimationDuration, defDuration).toLong() + mAnimationDuration = + if (mAnimationDuration < 0) defDuration.toLong() else mAnimationDuration + mNormalTextColor = ta.getColor( + R.styleable.LrcView_lrcNormalTextColor, + ContextCompat.getColor(context, R.color.lrc_normal_text_color) + ) + mCurrentTextColor = ta.getColor( + R.styleable.LrcView_lrcCurrentTextColor, + ContextCompat.getColor(context, R.color.lrc_current_text_color) + ) + mTimelineTextColor = ta.getColor( + R.styleable.LrcView_lrcTimelineTextColor, + ContextCompat.getColor(context, R.color.lrc_timeline_text_color) + ) + mDefaultLabel = ta.getString(R.styleable.LrcView_lrcLabel) + mDefaultLabel = + if (TextUtils.isEmpty(mDefaultLabel)) context.getString(R.string.empty) else mDefaultLabel + mLrcPadding = ta.getDimension(R.styleable.LrcView_lrcPadding, 0f) + mTimelineColor = ta.getColor( + R.styleable.LrcView_lrcTimelineColor, + ContextCompat.getColor(context, R.color.lrc_timeline_color) + ) + val timelineHeight = ta.getDimension( + R.styleable.LrcView_lrcTimelineHeight, + resources.getDimension(R.dimen.lrc_timeline_height) + ) + mPlayDrawable = ta.getDrawable(R.styleable.LrcView_lrcPlayDrawable) + mPlayDrawable = + if (mPlayDrawable == null) ContextCompat.getDrawable( + context, + R.drawable.ic_play_arrow + ) else mPlayDrawable + mTimeTextColor = ta.getColor( + R.styleable.LrcView_lrcTimeTextColor, + ContextCompat.getColor(context, R.color.lrc_time_text_color) + ) + val timeTextSize = ta.getDimension( + R.styleable.LrcView_lrcTimeTextSize, + resources.getDimension(R.dimen.lrc_time_text_size) + ) + mTextGravity = ta.getInteger(R.styleable.LrcView_lrcTextGravity, LrcEntry.GRAVITY_CENTER) + ta.recycle() + mDrawableWidth = resources.getDimension(R.dimen.lrc_drawable_width).toInt() + mTimeTextWidth = resources.getDimension(R.dimen.lrc_time_width).toInt() + mLrcPaint.isAntiAlias = true + mLrcPaint.textSize = mCurrentTextSize + mLrcPaint.textAlign = Paint.Align.LEFT + mTimePaint.isAntiAlias = true + mTimePaint.textSize = timeTextSize + mTimePaint.textAlign = Paint.Align.CENTER + mTimePaint.strokeWidth = timelineHeight + mTimePaint.strokeCap = Paint.Cap.ROUND + mTimeFontMetrics = mTimePaint.fontMetrics + mGestureDetector = GestureDetector(context, mSimpleOnGestureListener) + mGestureDetector!!.setIsLongpressEnabled(false) + mScroller = Scroller(context) + } + + /** 设置非当前行歌词字体颜色 */ + fun setNormalColor(normalColor: Int) { + mNormalTextColor = normalColor + postInvalidate() + } + + /** 普通歌词文本字体大小 */ + fun setNormalTextSize(size: Float) { + mNormalTextSize = size + } + + /** 当前歌词文本字体大小 */ + fun setCurrentTextSize(size: Float) { + mCurrentTextSize = size + } + + /** 设置当前行歌词的字体颜色 */ + fun setCurrentColor(currentColor: Int) { + mCurrentTextColor = currentColor + postInvalidate() + } + + /** 设置拖动歌词时选中歌词的字体颜色 */ + fun setTimelineTextColor(timelineTextColor: Int) { + mTimelineTextColor = timelineTextColor + postInvalidate() + } + + /** 设置拖动歌词时时间线的颜色 */ + fun setTimelineColor(timelineColor: Int) { + mTimelineColor = timelineColor + postInvalidate() + } + + /** 设置拖动歌词时右侧时间字体颜色 */ + fun setTimeTextColor(timeTextColor: Int) { + mTimeTextColor = timeTextColor + postInvalidate() + } + + /** + * 设置歌词是否允许拖动 + * + * @param draggable 是否允许拖动 + * @param onPlayClickListener 设置歌词拖动后播放按钮点击监听器,如果允许拖动,则不能为 null + */ + fun setDraggable(draggable: Boolean, onPlayClickListener: OnPlayClickListener?) { + mOnPlayClickListener = if (draggable) { + requireNotNull(onPlayClickListener) { "if draggable == true, onPlayClickListener must not be null" } + onPlayClickListener + } else { + null + } + } + + /** + * 设置播放按钮点击监听器 + * + * @param onPlayClickListener 如果为非 null ,则激活歌词拖动功能,否则将将禁用歌词拖动功能 + */ + @Deprecated("use {@link #setDraggable(boolean, OnPlayClickListener)} instead") + fun setOnPlayClickListener(onPlayClickListener: OnPlayClickListener?) { + mOnPlayClickListener = onPlayClickListener + } + + /** 设置歌词为空时屏幕中央显示的文字,如“暂无歌词” */ + fun setLabel(label: String?) { + runOnUi { + mDefaultLabel = label + invalidate() + } + } + + /** + * 加载歌词文件 + * + * @param lrcFile 歌词文件 + */ + fun loadLrc(lrcFile: File) { + loadLrc(lrcFile, null) + } + + /** + * 加载双语歌词文件,两种语言的歌词时间戳需要一致 + * + * @param mainLrcFile 第一种语言歌词文件 + * @param secondLrcFile 第二种语言歌词文件 + */ + fun loadLrc(mainLrcFile: File, secondLrcFile: File?) { + runOnUi { + reset() + val sb = StringBuilder("file://") + sb.append(mainLrcFile.path) + if (secondLrcFile != null) { + sb.append("#").append(secondLrcFile.path) + } + val flag = sb.toString() + this.flag = flag + object : AsyncTask>() { + override fun doInBackground(vararg params: File?): List? { + return LrcUtils.parseLrc(params) + } + + override fun onPostExecute(lrcEntries: List) { + if (flag === flag) { + onLrcLoaded(lrcEntries) + this@CoverLrcView.flag = null + } + } + }.execute(mainLrcFile, secondLrcFile) + } + } + + /** + * 加载歌词文本 + * + * @param lrcText 歌词文本 + */ + fun loadLrc(lrcText: String?) { + loadLrc(lrcText, null) + } + + /** + * 加载双语歌词文本,两种语言的歌词时间戳需要一致 + * + * @param mainLrcText 第一种语言歌词文本 + * @param secondLrcText 第二种语言歌词文本 + */ + fun loadLrc(mainLrcText: String?, secondLrcText: String?) { + runOnUi { + reset() + val sb = StringBuilder("file://") + sb.append(mainLrcText) + if (secondLrcText != null) { + sb.append("#").append(secondLrcText) + } + val flag = sb.toString() + this.flag = flag + object : AsyncTask>() { + override fun doInBackground(vararg params: String?): List? { + return LrcUtils.parseLrc(params) + } + + override fun onPostExecute(lrcEntries: List) { + if (flag === flag) { + onLrcLoaded(lrcEntries) + this@CoverLrcView.flag = null + } + } + }.execute(mainLrcText, secondLrcText) + } + } + /** + * 加载在线歌词 + * + * @param lrcUrl 歌词文件的网络地址 + * @param charset 编码格式 + */ + /** + * 加载在线歌词,默认使用 utf-8 编码 + * + * @param lrcUrl 歌词文件的网络地址 + */ + @JvmOverloads + fun loadLrcByUrl(lrcUrl: String, charset: String? = "utf-8") { + val flag = "url://$lrcUrl" + this.flag = flag + object : AsyncTask() { + override fun doInBackground(vararg params: String?): String? { + return LrcUtils.getContentFromNetwork(params[0], params[1]) + } + + override fun onPostExecute(lrcText: String) { + if (flag === flag) { + loadLrc(lrcText) + } + } + }.execute(lrcUrl, charset) + } + + /** + * 歌词是否有效 + * + * @return true,如果歌词有效,否则false + */ + fun hasLrc(): Boolean { + return mLrcEntryList.isNotEmpty() + } + + /** + * 刷新歌词 + * + * @param time 当前播放时间 + */ + fun updateTime(time: Long) { + runOnUi { + if (!hasLrc()) { + return@runOnUi + } + val line = findShowLine(time) + if (line != mCurrentLine) { + mCurrentLine = line + if (!isShowTimeline) { + smoothScrollTo(line) + } else { + invalidate() + } + } + } + } + + override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { + super.onLayout(changed, left, top, right, bottom) + if (changed) { + initPlayDrawable() + initEntryList() + if (hasLrc()) { + smoothScrollTo(mCurrentLine, 0L) + } + } + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + val centerY = height / 2 + + // 无歌词文件 + if (!hasLrc()) { + mLrcPaint.color = mCurrentTextColor + @SuppressLint("DrawAllocation") val staticLayout = StaticLayout( + mDefaultLabel, + mLrcPaint, + lrcWidth.toInt(), + Layout.Alignment.ALIGN_CENTER, + 1f, + 0f, + false + ) + drawText(canvas, staticLayout, centerY.toFloat()) + return + } + val centerLine = centerLine + if (isShowTimeline) { + mPlayDrawable?.draw(canvas) + mTimePaint.color = mTimeTextColor + val timeText = LrcUtils.formatTime(mLrcEntryList[centerLine].time) + val timeX = (width - mTimeTextWidth / 2).toFloat() + val timeY = centerY - (mTimeFontMetrics!!.descent + mTimeFontMetrics!!.ascent) / 2 + canvas.drawText(timeText, timeX, timeY, mTimePaint) + } + canvas.translate(0f, mOffset) + var y = 0f + for (i in mLrcEntryList.indices) { + if (i > 0) { + y += ((mLrcEntryList[i - 1].height + mLrcEntryList[i].height shr 1) + + mDividerHeight) + } + if (BuildConfig.DEBUG) { + mLrcPaint.typeface = ResourcesCompat.getFont(context, R.font.sans) + } + if (i == mCurrentLine) { + mLrcPaint.textSize = mCurrentTextSize + mLrcPaint.color = mCurrentTextColor + } else if (isShowTimeline && i == centerLine) { + mLrcPaint.color = mTimelineTextColor + } else { + mLrcPaint.textSize = mNormalTextSize + mLrcPaint.color = mNormalTextColor + } + drawText(canvas, mLrcEntryList[i].staticLayout, y) + } + } + + /** + * 画一行歌词 + * + * @param y 歌词中心 Y 坐标 + */ + private fun drawText(canvas: Canvas, staticLayout: StaticLayout, y: Float) { + canvas.save() + canvas.translate(mLrcPadding, y - (staticLayout.height shr 1)) + staticLayout.draw(canvas) + canvas.restore() + } + + @SuppressLint("ClickableViewAccessibility") + override fun onTouchEvent(event: MotionEvent): Boolean { + if (event.action == MotionEvent.ACTION_UP + || event.action == MotionEvent.ACTION_CANCEL + ) { + isTouching = false + if (hasLrc() && !isFling) { + adjustCenter() + postDelayed(hideTimelineRunnable, TIMELINE_KEEP_TIME) + } + } + return mGestureDetector!!.onTouchEvent(event) + } + + override fun computeScroll() { + if (mScroller!!.computeScrollOffset()) { + mOffset = mScroller!!.currY.toFloat() + invalidate() + } + if (isFling && mScroller!!.isFinished) { + isFling = false + if (hasLrc() && !isTouching) { + adjustCenter() + postDelayed(hideTimelineRunnable, TIMELINE_KEEP_TIME) + } + } + } + + override fun onDetachedFromWindow() { + removeCallbacks(hideTimelineRunnable) + super.onDetachedFromWindow() + } + + private fun onLrcLoaded(entryList: List?) { + if (entryList != null && entryList.isNotEmpty()) { + mLrcEntryList.addAll(entryList) + } + mLrcEntryList.sort() + initEntryList() + invalidate() + } + + private fun initPlayDrawable() { + val l = (mTimeTextWidth - mDrawableWidth) / 2 + val t = height / 2 - mDrawableWidth / 2 + val r = l + mDrawableWidth + val b = t + mDrawableWidth + mPlayDrawable!!.setBounds(l, t, r, b) + } + + private fun initEntryList() { + if (!hasLrc() || width == 0) { + return + } + for (lrcEntry in mLrcEntryList) { + lrcEntry.init(mLrcPaint, lrcWidth.toInt(), mTextGravity) + } + mOffset = (height / 2).toFloat() + } + + fun reset() { + endAnimation() + mScroller!!.forceFinished(true) + isShowTimeline = false + isTouching = false + isFling = false + removeCallbacks(hideTimelineRunnable) + mLrcEntryList.clear() + mOffset = 0f + mCurrentLine = 0 + invalidate() + } + + /** 将中心行微调至正中心 */ + private fun adjustCenter() { + smoothScrollTo(centerLine, ADJUST_DURATION) + } + /** 滚动到某一行 */ + /** 滚动到某一行 */ + private fun smoothScrollTo(line: Int, duration: Long = mAnimationDuration) { + val offset = getOffset(line) + endAnimation() + mAnimator = ValueAnimator.ofFloat(mOffset, offset).apply { + this.duration = duration + interpolator = LinearInterpolator() + addUpdateListener { animation: ValueAnimator -> + mOffset = animation.animatedValue as Float + invalidate() + } + LrcUtils.resetDurationScale() + start() + } + } + + /** 结束滚动动画 */ + private fun endAnimation() { + if (mAnimator != null && mAnimator!!.isRunning) { + mAnimator!!.end() + } + } + + /** 二分法查找当前时间应该显示的行数(最后一个 <= time 的行数) */ + private fun findShowLine(time: Long): Int { + var left = 0 + var right = mLrcEntryList.size + while (left <= right) { + val middle = (left + right) / 2 + val middleTime = mLrcEntryList[middle].time + if (time < middleTime) { + right = middle - 1 + } else { + if (middle + 1 >= mLrcEntryList.size || time < mLrcEntryList[middle + 1].time) { + return middle + } + left = middle + 1 + } + } + return 0 + } + + /** 获取当前在视图中央的行数 */ + private val centerLine: Int + get() { + var centerLine = 0 + var minDistance = Float.MAX_VALUE + for (i in mLrcEntryList.indices) { + if (abs(mOffset - getOffset(i)) < minDistance) { + minDistance = abs(mOffset - getOffset(i)) + centerLine = i + } + } + return centerLine + } + + /** 获取歌词距离视图顶部的距离 采用懒加载方式 */ + private fun getOffset(line: Int): Float { + if (mLrcEntryList[line].offset == Float.MIN_VALUE) { + var offset = (height / 2).toFloat() + for (i in 1..line) { + offset -= ((mLrcEntryList[i - 1].height + mLrcEntryList[i].height shr 1) + + mDividerHeight) + } + mLrcEntryList[line].offset = offset + } + return mLrcEntryList[line].offset + } + + /** 获取歌词宽度 */ + private val lrcWidth: Float + get() = width - mLrcPadding * 2 + + /** 在主线程中运行 */ + private fun runOnUi(r: Runnable) { + if (Looper.myLooper() == Looper.getMainLooper()) { + r.run() + } else { + post(r) + } + } + + /** 播放按钮点击监听器,点击后应该跳转到指定播放位置 */ + interface OnPlayClickListener { + /** + * 播放按钮被点击,应该跳转到指定播放位置 + * + * @return 是否成功消费该事件,如果成功消费,则会更新UI + */ + fun onPlayClick(time: Long): Boolean + } + + companion object { + private const val ADJUST_DURATION: Long = 100 + private const val TIMELINE_KEEP_TIME = 4 * DateUtils.SECOND_IN_MILLIS + } + + init { + init(attrs) + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_flat_player_playback_controls.xml b/app/src/main/res/layout/fragment_flat_player_playback_controls.xml index 283b1868e..bee59f8f8 100644 --- a/app/src/main/res/layout/fragment_flat_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_flat_player_playback_controls.xml @@ -153,7 +153,6 @@ android:layout_height="52dp" android:layout_centerVertical="true" android:background="?colorAccent" - android:foreground="?attr/rectSelector" android:padding="12dp" android:scaleType="fitCenter" tools:ignore="MissingPrefix" diff --git a/app/src/main/res/layout/fragment_player_album_cover.xml b/app/src/main/res/layout/fragment_player_album_cover.xml index 3789feebc..90aa7633c 100644 --- a/app/src/main/res/layout/fragment_player_album_cover.xml +++ b/app/src/main/res/layout/fragment_player_album_cover.xml @@ -1,5 +1,6 @@ @@ -7,50 +8,24 @@ + android:layout_height="match_parent" + android:overScrollMode="@integer/overScrollMode"> - + + + app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" + app:lrcLabel="@string/no_lyrics_found" + app:lrcNormalTextSize="28sp" + app:lrcPadding="24dp" + app:lrcTextGravity="center" + app:lrcTextSize="32sp" + app:lrcTimelineColor="@color/transparent" + tools:visibility="visible" /> - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/lrc_dimens.xml b/app/src/main/res/values/lrc_dimens.xml index 4a5c994f4..b022d846b 100644 --- a/app/src/main/res/values/lrc_dimens.xml +++ b/app/src/main/res/values/lrc_dimens.xml @@ -1,8 +1,8 @@ 1000 - 16sp - 12sp + 20sp + 16sp 16dp 1dp 30dp From adab132bf3214414426ca1ae13ddca304ab45f5a Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Thu, 16 Dec 2021 00:36:28 +0530 Subject: [PATCH 44/82] [Home] Consistent no. of lines for Home playlist buttons --- .../retromusic/fragments/home/HomeFragment.kt | 16 ++++++++++++++++ app/src/main/res/layout/abs_playlists.xml | 1 - app/src/main/res/values/styles.xml | 3 ++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt index 647361a84..3390621d4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt @@ -23,6 +23,7 @@ import android.view.View import androidx.activity.addCallback import androidx.core.os.bundleOf import androidx.core.text.HtmlCompat +import androidx.core.view.doOnLayout import androidx.core.view.doOnPreDraw import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.findNavController @@ -87,6 +88,21 @@ class HomeFragment : remove() mainActivity.finish() } + view.doOnLayout { + adjustPlaylistButtons() + } + } + + private fun adjustPlaylistButtons() { + val buttons = + listOf(binding.history, binding.lastAdded, binding.topPlayed, binding.actionShuffle) + buttons.maxOf { it.lineCount }.let { maxLineCount-> + buttons.forEach { button -> + // Set the highest line count to every button for consistency + button.setLines(maxLineCount) + } + } + } private fun setupListeners() { diff --git a/app/src/main/res/layout/abs_playlists.xml b/app/src/main/res/layout/abs_playlists.xml index bf4b5e80c..ee11757cd 100644 --- a/app/src/main/res/layout/abs_playlists.xml +++ b/app/src/main/res/layout/abs_playlists.xml @@ -43,7 +43,6 @@ android:layout_marginEnd="16dp" android:text="@string/my_top_tracks" app:icon="@drawable/ic_trending_up" - app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@+id/actionShuffle" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/history" diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d1fbc9261..159bd3f86 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -223,7 +223,8 @@ + + + + + + + From 0544db11743d096b123e936beb6c19d40a051503 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 19 Dec 2021 16:11:50 +0530 Subject: [PATCH 56/82] Disabled EditText of Restore Activity --- app/src/main/res/layout/activity_restore.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/activity_restore.xml b/app/src/main/res/layout/activity_restore.xml index fb38360b5..5f5224af6 100644 --- a/app/src/main/res/layout/activity_restore.xml +++ b/app/src/main/res/layout/activity_restore.xml @@ -16,7 +16,7 @@ android:id="@+id/backupName" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="none"/> + android:enabled="false" /> + Date: Mon, 20 Dec 2021 16:03:02 +0530 Subject: [PATCH 57/82] Use proguard-android-optimize.txt --- app/build.gradle | 2 +- appthemehelper/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 021f48dae..d67b927b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,7 +33,7 @@ android { versionNameSuffix "_" + getDate() shrinkResources true minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } debug { diff --git a/appthemehelper/build.gradle b/appthemehelper/build.gradle index 898a58e25..383b4637d 100644 --- a/appthemehelper/build.gradle +++ b/appthemehelper/build.gradle @@ -10,7 +10,7 @@ android { buildTypes { release { minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { From a26f08127cc26ec498856563111322e2af1ab0a8 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 20 Dec 2021 16:03:46 +0530 Subject: [PATCH 58/82] Fixed navigation bar color pre Oreo --- .../base/AbsSlidingMusicPanelActivity.kt | 14 ++++++++------ .../name/monkey/retromusic/lyrics/CoverLrcView.kt | 5 ----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt index 2f1c2acd4..62b23ec8d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt @@ -31,7 +31,6 @@ import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.commit -import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.retromusic.R import code.name.monkey.retromusic.RetroBottomSheetBehavior @@ -83,6 +82,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { private var nowPlayingScreen: NowPlayingScreen? = null private var taskColor: Int = 0 private var paletteColor: Int = Color.WHITE + private var navigationBarColor = 0 protected abstract fun createContentView(): SlidingMusicPanelLayoutBinding private val panelState: Int get() = bottomSheetBehavior.state @@ -100,7 +100,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { argbEvaluator.evaluate( slideOffset, surfaceColor(), - playerFragment!!.paletteColor + navigationBarColor ) as Int ) } @@ -148,6 +148,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { updateColor() binding.slidingPanel.backgroundTintList = ColorStateList.valueOf(darkAccentColor()) bottomNavigationView.backgroundTintList = ColorStateList.valueOf(darkAccentColor()) + navigationBarColor = surfaceColor() } private fun setupBottomSheet() { @@ -285,6 +286,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { private fun onPaletteColorChanged() { if (panelState == STATE_EXPANDED) { + navigationBarColor = surfaceColor() setTaskDescColor(paletteColor) val isColorLight = ColorUtil.isColorLight(paletteColor) if (PreferenceUtil.isAdaptiveColor && (nowPlayingScreen == Normal || nowPlayingScreen == Flat)) { @@ -292,14 +294,17 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { setLightStatusBar(isColorLight) } else if (nowPlayingScreen == Card || nowPlayingScreen == Blur || nowPlayingScreen == BlurCard) { animateNavigationBarColor(Color.BLACK) + navigationBarColor = Color.BLACK setLightStatusBar(false) setLightNavigationBar(true) } else if (nowPlayingScreen == Color || nowPlayingScreen == Tiny || nowPlayingScreen == Gradient) { animateNavigationBarColor(paletteColor) + navigationBarColor = paletteColor setLightNavigationBar(isColorLight) setLightStatusBar(isColorLight) } else if (nowPlayingScreen == Full) { animateNavigationBarColor(paletteColor) + navigationBarColor = paletteColor setLightNavigationBar(isColorLight) setLightStatusBar(false) } else if (nowPlayingScreen == Classic) { @@ -309,10 +314,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() { } else { setLightStatusBar( ColorUtil.isColorLight( - ATHUtil.resolveColor( - this, - android.R.attr.windowBackground - ) + surfaceColor() ) ) setLightNavigationBar(true) diff --git a/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt b/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt index 28a0b8de6..d722668dc 100644 --- a/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt +++ b/app/src/main/java/code/name/monkey/retromusic/lyrics/CoverLrcView.kt @@ -34,8 +34,6 @@ import android.view.View import android.view.animation.LinearInterpolator import android.widget.Scroller import androidx.core.content.ContextCompat -import androidx.core.content.res.ResourcesCompat -import code.name.monkey.retromusic.BuildConfig import code.name.monkey.retromusic.R import java.io.File import java.util.* @@ -507,9 +505,6 @@ class CoverLrcView @JvmOverloads constructor( y += ((mLrcEntryList[i - 1].height + mLrcEntryList[i].height shr 1) + mDividerHeight) } - if (BuildConfig.DEBUG) { - mLrcPaint.typeface = ResourcesCompat.getFont(context, R.font.sans) - } if (i == mCurrentLine) { mLrcPaint.textSize = mCurrentTextSize mLrcPaint.color = mCurrentTextColor From 0dd5663e9e61dfeca6527fb71aa0761a2e7ad734 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 20 Dec 2021 16:42:49 +0530 Subject: [PATCH 59/82] Added fade in layout animation for DetailListFragment --- .../fragments/other/DetailListFragment.kt | 13 +++++-------- app/src/main/res/anim/layout_anim_fade.xml | 5 +++++ .../main/res/layout/fragment_playlist_detail.xml | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 app/src/main/res/anim/layout_anim_fade.xml diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/other/DetailListFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/other/DetailListFragment.kt index b28d903c0..14df3272c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/other/DetailListFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/other/DetailListFragment.kt @@ -64,14 +64,6 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de returnTransition = MaterialSharedAxis(MaterialSharedAxis.Y, false) } } - binding.appBarLayout.statusBarForeground = - MaterialShapeDrawable.createWithElevationOverlay(requireContext()) - postponeEnterTransition() - view.doOnPreDraw { startPostponedEnterTransition() } - } - - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) mainActivity.setSupportActionBar(binding.toolbar) binding.progressIndicator.hide() when (args.type) { @@ -92,6 +84,10 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de binding.recyclerView.updatePadding(bottom = height.toInt()) } }) + binding.appBarLayout.statusBarForeground = + MaterialShapeDrawable.createWithElevationOverlay(requireContext()) + postponeEnterTransition() + view.doOnPreDraw { startPostponedEnterTransition() } } private fun lastAddedSongs() { @@ -104,6 +100,7 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de binding.recyclerView.apply { adapter = songAdapter layoutManager = linearLayoutManager() + scheduleLayoutAnimation() } libraryViewModel.recentSongs().observe(viewLifecycleOwner, { songs -> songAdapter.swapDataSet(songs) diff --git a/app/src/main/res/anim/layout_anim_fade.xml b/app/src/main/res/anim/layout_anim_fade.xml new file mode 100644 index 000000000..ba154e91e --- /dev/null +++ b/app/src/main/res/anim/layout_anim_fade.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_playlist_detail.xml b/app/src/main/res/layout/fragment_playlist_detail.xml index 2b6d68a26..ffaf5985d 100644 --- a/app/src/main/res/layout/fragment_playlist_detail.xml +++ b/app/src/main/res/layout/fragment_playlist_detail.xml @@ -37,6 +37,7 @@ android:clipToPadding="false" android:overScrollMode="@integer/overScrollMode" android:scrollbars="none" + android:layoutAnimation="@anim/layout_anim_fade" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" /> Date: Mon, 20 Dec 2021 18:08:55 +0530 Subject: [PATCH 60/82] [Now playing] Fixed lyrics color --- .../retromusic/fragments/player/PlayerAlbumCoverFragment.kt | 5 ++--- app/src/main/res/values/styles.xml | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt index 027a773e0..fe7217f9f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/PlayerAlbumCoverFragment.kt @@ -266,15 +266,14 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe callbacks?.onColorChanged(color) setLRCViewColors( when (PreferenceUtil.nowPlayingScreen) { - Adaptive, Fit, Plain, Simple -> surfaceColor() Flat, Normal -> if (PreferenceUtil.isAdaptiveColor) { color.backgroundColor } else { surfaceColor() } - Color ->color.backgroundColor + Color, Gradient, Full ->color.backgroundColor Blur -> Color.BLACK - else -> color.backgroundColor + else -> surfaceColor() }) } diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e8e081dff..ddfb5a421 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -197,9 +197,8 @@ @android:anim/fade_out -