From defee853c73a9d8e9e459f7910f882441abb5d04 Mon Sep 17 00:00:00 2001 From: Hemanth S Date: Mon, 18 May 2020 01:28:04 +0530 Subject: [PATCH] Add gradient theme --- .../retromusic/activities/MainActivity.java | 10 +- .../base/AbsSlidingMusicPanelActivity.kt | 6 +- .../retromusic/adapter/album/AlbumAdapter.kt | 1 + .../adapter/album/AlbumCoverPagerAdapter.kt | 1 + .../adapter/song/PlayingQueueAdapter.kt | 21 - .../retromusic/fragments/NowPlayingScreen.kt | 1 + .../fragments/albums/AlbumsFragment.kt | 1 + .../player/PlayerAlbumCoverFragment.kt | 5 +- .../player/classic/ClassicPlayerFragment.kt | 5 +- .../full/FullPlaybackControlsFragment.kt | 8 +- .../player/gradient/GradientPlayerFragment.kt | 501 ++++++++++++++++++ .../res/drawable-xxxhdpi/np_gradient.webp | Bin 0 -> 44878 bytes app/src/main/res/layout/fragment_fit.xml | 6 +- app/src/main/res/layout/fragment_full.xml | 10 +- .../res/layout/fragment_gradient_controls.xml | 198 +++++++ .../res/layout/fragment_gradient_player.xml | 155 ++++++ app/src/main/res/menu/menu_main.xml | 7 +- app/src/main/res/values/strings.xml | 1 + 18 files changed, 890 insertions(+), 47 deletions(-) create mode 100644 app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt create mode 100644 app/src/main/res/drawable-xxxhdpi/np_gradient.webp create mode 100644 app/src/main/res/layout/fragment_gradient_controls.xml create mode 100644 app/src/main/res/layout/fragment_gradient_player.xml diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.java b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.java index 582253b0..452bbd61 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.java +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.java @@ -339,7 +339,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity int id = item.getItemId(); switch (id) { case R.id.action_search: - NavigationUtil.goToSearch(this); break; case R.id.action_new_playlist: @@ -520,11 +519,13 @@ public class MainActivity extends AbsSlidingMusicPanelActivity break; } Log.i(TAG, "handleLayoutResType: " + layoutRes); + if (layoutRes != -1) { item.setChecked(true); fragment.setAndSaveLayoutRes(layoutRes); return true; } + return false; } @@ -807,9 +808,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity case R.layout.item_card: subMenu.findItem(R.id.action_layout_card).setChecked(true); break; - case R.layout.item_grid: - subMenu.findItem(R.id.action_layout_normal).setChecked(true); - break; case R.layout.item_card_color: subMenu.findItem(R.id.action_layout_colored_card).setChecked(true); break; @@ -822,6 +820,10 @@ public class MainActivity extends AbsSlidingMusicPanelActivity case R.layout.item_image_gradient: subMenu.findItem(R.id.action_layout_gradient_image).setChecked(true); break; + default: + case R.layout.item_grid: + subMenu.findItem(R.id.action_layout_normal).setChecked(true); + break; } } 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 66d1f4cd..077cac51 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 @@ -29,6 +29,7 @@ import code.name.monkey.retromusic.fragments.player.color.ColorFragment import code.name.monkey.retromusic.fragments.player.fit.FitFragment import code.name.monkey.retromusic.fragments.player.flat.FlatPlayerFragment import code.name.monkey.retromusic.fragments.player.full.FullPlayerFragment +import code.name.monkey.retromusic.fragments.player.gradient.GradientPlayerFragment import code.name.monkey.retromusic.fragments.player.material.MaterialFragment import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment import code.name.monkey.retromusic.fragments.player.peak.PeakPlayerFragment @@ -257,6 +258,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), Peak -> PeakPlayerFragment() Circle -> CirclePlayerFragment() Classic -> ClassicPlayerFragment() + Gradient -> GradientPlayerFragment() else -> PlayerFragment() } // must implement AbsPlayerFragment supportFragmentManager.beginTransaction() @@ -316,7 +318,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), super.setLightStatusbar(false) super.setLightNavigationBar(true) super.setNavigationbarColor(Color.BLACK) - } else if (cps == Color || cps == Tiny) { + } else if (cps == Color || cps == Tiny || cps == Gradient) { super.setNavigationbarColor(paletteColor) super.setLightNavigationBar(isColorLight) super.setLightStatusbar(isColorLight) @@ -324,7 +326,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), super.setNavigationbarColor(paletteColor) super.setLightNavigationBar(isColorLight) super.setLightStatusbar(false) - } else if (cps == Classic ) { + } else if (cps == Classic) { super.setLightStatusbar(false) } else if (cps == Fit) { super.setLightStatusbar(false) diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt index 8c0e42f8..b7e61340 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt @@ -47,6 +47,7 @@ open class AlbumAdapter( } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + println("onCreateViewHolder $itemLayoutRes") itemLayoutRes = if (itemLayoutRes >= -1) { itemLayoutRes } else { diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt index e70a143d..604f3347 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt @@ -95,6 +95,7 @@ class AlbumCoverPagerAdapter( Fit, Tiny, Classic, + Gradient, Full -> R.layout.fragment_album_full_cover else -> { if (PreferenceUtil.getInstance(requireContext()).carouselEffect() diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt index 7f8f8ffb..0a628f2f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt @@ -1,9 +1,7 @@ package code.name.monkey.retromusic.adapter.song -import android.graphics.PorterDuff.Mode import android.view.MenuItem import android.view.View -import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import code.name.monkey.retromusic.R import code.name.monkey.retromusic.helper.MusicPlayerRemote @@ -35,7 +33,6 @@ class PlayingQueueAdapter( SwipeableItemAdapter, PopupTextProvider { - private var color = -1 private var songToRemove: Song? = null override fun createViewHolder(view: View): SongAdapter.ViewHolder { @@ -51,23 +48,6 @@ class PlayingQueueAdapter( } } - private fun setColor(holder: SongAdapter.ViewHolder, white: Int) { - - if (holder.title != null) { - holder.title!!.setTextColor(white) - if (color != -1) { - holder.title!!.setTextColor(color) - } - } - - holder.text?.setTextColor(white) - holder.time?.setTextColor(white) - holder.imageText?.setTextColor(white) - if (holder.menu != null) { - (holder.menu as ImageView).setColorFilter(white, Mode.SRC_IN) - } - } - override fun getItemViewType(position: Int): Int { if (position < current) { return HISTORY @@ -139,7 +119,6 @@ class PlayingQueueAdapter( } inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) { - @DraggableItemStateFlags private var mDragStateFlags: Int = 0 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 0463d1b2..522a9329 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 @@ -21,6 +21,7 @@ enum class NowPlayingScreen constructor( 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), diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt index fadf2db7..0ba59b98 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt @@ -84,6 +84,7 @@ class AlbumsFragment : override fun loadLayoutRes(): Int { + println("loadLayoutRes ${PreferenceUtil.getInstance(requireContext()).albumGridStyle}") return PreferenceUtil.getInstance(requireContext()).albumGridStyle } 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 bf7116c8..9de1f3da 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 @@ -32,7 +32,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan fun removeSlideEffect() { val transformer = ParallaxPagerTransformer(R.id.player_image) transformer.setSpeed(0.3f) - viewPager.setPageTransformer(true, transformer) + //viewPager.setPageTransformer(true, transformer) } override fun onCreateView( @@ -50,8 +50,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan val metrics = resources.displayMetrics val ratio = metrics.heightPixels.toFloat() / metrics.widthPixels.toFloat() - - if (nps == Full || nps == Classic || nps == Fit) { + if (nps == Full || nps == Classic || nps == Fit || nps == Gradient) { viewPager.offscreenPageLimit = 2 } else if (PreferenceUtil.getInstance(requireContext()).carouselEffect()) { viewPager.clipToPadding = false diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt index 926cf19b..f309bf13 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt @@ -135,7 +135,8 @@ class ClassicPlayerFragment : AbsPlayerFragment(), View.OnLayoutChangeListener, 0 ).build() ) - shapeDrawable.fillColor = ColorStateList.valueOf(ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)) + shapeDrawable.fillColor = + ColorStateList.valueOf(ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)) playerQueueSheet.background = shapeDrawable playerQueueSheet.setOnTouchListener { _, _ -> @@ -358,7 +359,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(), View.OnLayoutChangeListener, ToolbarContentTintHelper.colorizeToolbar( playerToolbar, - ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal), + Color.WHITE, requireActivity() ) } 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 2ecf3316..c5fb440a 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 @@ -42,7 +42,7 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(), private var lastPlaybackControlsColor: Int = 0 private var lastDisabledPlaybackControlsColor: Int = 0 - private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null + private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -68,12 +68,12 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(), override fun onResume() { super.onResume() - progressViewUpdateHelper!!.start() + progressViewUpdateHelper.start() } override fun onPause() { super.onPause() - progressViewUpdateHelper!!.stop() + progressViewUpdateHelper.stop() } @@ -97,7 +97,7 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(), lastPlaybackControlsColor = color.primaryTextColor lastDisabledPlaybackControlsColor = ColorUtil.withAlpha(color.primaryTextColor, 0.3f) - val tintList=ColorStateList.valueOf(color.primaryTextColor) + val tintList = ColorStateList.valueOf(color.primaryTextColor) playerMenu.imageTintList = tintList songFavourite.imageTintList = tintList volumeFragment?.setTintableColor(color.primaryTextColor) 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 new file mode 100644 index 00000000..0eee1ce0 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt @@ -0,0 +1,501 @@ +package code.name.monkey.retromusic.fragments.player.gradient + +import android.content.res.ColorStateList +import android.graphics.Color +import android.graphics.PorterDuff +import android.os.AsyncTask +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.PopupMenu +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.ViewCompat +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import code.name.monkey.appthemehelper.util.ATHUtil +import code.name.monkey.appthemehelper.util.ColorUtil +import code.name.monkey.appthemehelper.util.TintHelper +import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.RetroBottomSheetBehavior +import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity +import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter +import code.name.monkey.retromusic.extensions.hide +import code.name.monkey.retromusic.extensions.ripAlpha +import code.name.monkey.retromusic.extensions.show +import code.name.monkey.retromusic.fragments.VolumeFragment +import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment +import code.name.monkey.retromusic.helper.MusicPlayerRemote +import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper +import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.service.MusicService +import code.name.monkey.retromusic.util.MusicUtil +import code.name.monkey.retromusic.util.PreferenceUtil +import code.name.monkey.retromusic.util.ViewUtil +import code.name.monkey.retromusic.util.color.MediaNotificationProcessor +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator +import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager +import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager +import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager +import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils +import kotlinx.android.synthetic.main.fragment_gradient_controls.* +import kotlinx.android.synthetic.main.fragment_gradient_player.* +import kotlinx.android.synthetic.main.status_bar.* + +class GradientPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Callback, + View.OnLayoutChangeListener, PopupMenu.OnMenuItemClickListener { + private var lastColor: Int = 0 + private var lastPlaybackControlsColor: Int = 0 + private var lastDisabledPlaybackControlsColor: Int = 0 + private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper + private var volumeFragment: VolumeFragment? = null + private lateinit var wrappedAdapter: RecyclerView.Adapter<*> + private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null + private var recyclerViewSwipeManager: RecyclerViewSwipeManager? = null + private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null + private var playingQueueAdapter: PlayingQueueAdapter? = null + private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null + private lateinit var linearLayoutManager: LinearLayoutManager + + private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() { + override fun onSlide(bottomSheet: View, slideOffset: Float) { + (requireActivity() as AbsSlidingMusicPanelActivity).getBottomSheetBehavior() + .setAllowDragging(false) + + playerQueueSheet.setPadding( + playerQueueSheet.paddingLeft, + (slideOffset * status_bar.height).toInt(), + playerQueueSheet.paddingRight, + playerQueueSheet.paddingBottom + ) + } + + override fun onStateChanged(bottomSheet: View, newState: Int) { + val activity = requireActivity() as AbsSlidingMusicPanelActivity + val isDark = ATHUtil.isWindowBackgroundDark(requireContext()); + when (newState) { + BottomSheetBehavior.STATE_EXPANDED, + BottomSheetBehavior.STATE_DRAGGING -> { + activity.getBottomSheetBehavior().setAllowDragging(false) + } + BottomSheetBehavior.STATE_COLLAPSED -> { + resetToCurrentPosition() + activity.getBottomSheetBehavior().setAllowDragging(true) + } + else -> { + activity.getBottomSheetBehavior().setAllowDragging(true) + } + } + } + } + + private fun setupFavourite() { + songFavourite.setOnClickListener { + toggleFavorite(MusicPlayerRemote.currentSong) + } + } + + private fun setupMenu() { + playerMenu.setOnClickListener { + val popupMenu = PopupMenu(requireContext(), it) + popupMenu.setOnMenuItemClickListener(this) + popupMenu.inflate(R.menu.menu_player) + popupMenu.show() + } + } + + private fun setupPanel() { + if (!ViewCompat.isLaidOut(colorBackground) || colorBackground.isLayoutRequested) { + colorBackground.addOnLayoutChangeListener(this) + return + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + progressViewUpdateHelper = MusicProgressViewUpdateHelper(this) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_gradient_player, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + hideVolumeIfAvailable() + setUpMusicControllers() + setupPanel() + setupRecyclerView() + setupSheet() + setupMenu() + setupFavourite() + } + + private fun setupSheet() { + getQueuePanel().addBottomSheetCallback(bottomSheetCallbackList) + playerQueueSheet.setOnTouchListener { _, _ -> + (requireActivity() as AbsSlidingMusicPanelActivity).getBottomSheetBehavior() + .setAllowDragging(false) + getQueuePanel().setAllowDragging(true) + return@setOnTouchListener false + } + } + + private fun getQueuePanel(): RetroBottomSheetBehavior { + return RetroBottomSheetBehavior.from(playerQueueSheet) as RetroBottomSheetBehavior + } + + override fun onResume() { + super.onResume() + progressViewUpdateHelper.start() + } + + override fun onPause() { + recyclerViewDragDropManager?.cancelDrag() + super.onPause() + progressViewUpdateHelper.stop() + + } + + override fun playerToolbar(): Toolbar? { + return null + } + + override fun onShow() { + + } + + override fun onHide() { + + } + + override fun onBackPressed(): Boolean { + var wasExpanded = false + if (getQueuePanel().state == BottomSheetBehavior.STATE_EXPANDED) { + wasExpanded = getQueuePanel().state == BottomSheetBehavior.STATE_EXPANDED + getQueuePanel().state = BottomSheetBehavior.STATE_COLLAPSED + return wasExpanded + } + return wasExpanded + } + + override fun toolbarIconColor(): Int { + return Color.WHITE + } + + override val paletteColor: Int + get() = lastColor + + override fun onColorChanged(color: MediaNotificationProcessor) { + lastColor = color.backgroundColor + callbacks?.onPaletteColorChanged() + mask.backgroundTintList = ColorStateList.valueOf(color.backgroundColor) + colorBackground.setBackgroundColor(color.backgroundColor) + container.setBackgroundColor(ColorUtil.darkenColor(color.backgroundColor)) + + lastPlaybackControlsColor = color.primaryTextColor + lastDisabledPlaybackControlsColor = color.secondaryTextColor + + title.setTextColor(lastPlaybackControlsColor) + text.setTextColor(lastDisabledPlaybackControlsColor) + playPauseButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + songFavourite.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + queueIcon.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + playerMenu.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + songCurrentProgress.setTextColor(lastDisabledPlaybackControlsColor) + songTotalTime.setTextColor(lastDisabledPlaybackControlsColor) + nextSong.setTextColor(lastPlaybackControlsColor) + songInfo.setTextColor(lastDisabledPlaybackControlsColor) + + volumeFragment?.setTintableColor(lastPlaybackControlsColor.ripAlpha()) + ViewUtil.setProgressDrawable(progressSlider, color.primaryTextColor.ripAlpha(), true) + + updateRepeatState() + updateShuffleState() + updatePrevNextColor() + } + + override fun toggleFavorite(song: Song) { + super.toggleFavorite(song) + MusicUtil.toggleFavorite(requireContext(), song) + if (song.id == MusicPlayerRemote.currentSong.id) { + updateFavorite() + } + } + + override fun onFavoriteToggled() { + toggleFavorite(MusicPlayerRemote.currentSong) + } + + private fun hideVolumeIfAvailable() { + if (PreferenceUtil.getInstance(requireContext()).volumeToggle) { + childFragmentManager.beginTransaction() + .replace(R.id.volumeFragmentContainer, VolumeFragment.newInstance()) + .commit() + childFragmentManager.executePendingTransactions() + volumeFragment = + childFragmentManager.findFragmentById(R.id.volumeFragmentContainer) as VolumeFragment? + } + } + + override fun onServiceConnected() { + super.onServiceConnected() + updateSong() + updatePlayPauseDrawableState() + updatePlayPauseDrawableState() + updateQueue() + } + + override fun onPlayStateChanged() { + updatePlayPauseDrawableState() + } + + override fun onRepeatModeChanged() { + updateRepeatState() + } + + override fun onShuffleModeChanged() { + updateShuffleState() + } + + override fun onPlayingMetaChanged() { + super.onPlayingMetaChanged() + updateSong() + updateQueuePosition() + } + + private fun updateSong() { + val song = MusicPlayerRemote.currentSong + title.text = song.title + text.text = song.artistName + updateLabel() + if (PreferenceUtil.getInstance(requireContext()).isSongInfo) { + songInfo.text = getSongInfo(song) + songInfo.show() + } else { + songInfo.hide() + } + } + + private fun setUpMusicControllers() { + setUpPlayPauseFab() + setUpPrevNext() + setUpRepeatButton() + setUpShuffleButton() + setUpProgressSlider() + title.isSelected = true + text.isSelected = true + } + + private fun updatePlayPauseDrawableState() { + if (MusicPlayerRemote.isPlaying) { + playPauseButton.setImageResource(R.drawable.ic_pause_sharp_white_64dp) + } else { + playPauseButton.setImageResource(R.drawable.ic_play_arrow_sharp_white_64dp) + } + } + + override fun onUpdateProgressViews(progress: Int, total: Int) { + progressSlider.valueTo = total.toFloat() + progressSlider.value = progress.toFloat() + songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong()) + songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong()) + } + + fun setUpProgressSlider() { + progressSlider.addOnChangeListener { _, value, fromUser -> + if (fromUser) { + MusicPlayerRemote.seekTo(value.toInt()) + onUpdateProgressViews( + MusicPlayerRemote.songProgressMillis, + MusicPlayerRemote.songDurationMillis + ) + } + } + } + + private fun setUpPlayPauseFab() { + playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler()) + } + + private fun setUpPrevNext() { + updatePrevNextColor() + nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() } + previousButton.setOnClickListener { MusicPlayerRemote.back() } + } + + private fun updatePrevNextColor() { + nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + } + + private fun setUpShuffleButton() { + shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() } + } + + fun updateShuffleState() { + when (MusicPlayerRemote.shuffleMode) { + MusicService.SHUFFLE_MODE_SHUFFLE -> + shuffleButton.setColorFilter( + lastPlaybackControlsColor, + PorterDuff.Mode.SRC_IN + ) + else -> shuffleButton.setColorFilter( + lastDisabledPlaybackControlsColor, + PorterDuff.Mode.SRC_IN + ) + } + } + + private fun setUpRepeatButton() { + repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() } + } + + fun updateRepeatState() { + when (MusicPlayerRemote.repeatMode) { + MusicService.REPEAT_MODE_NONE -> { + repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp) + repeatButton.setColorFilter( + lastDisabledPlaybackControlsColor, + PorterDuff.Mode.SRC_IN + ) + } + MusicService.REPEAT_MODE_ALL -> { + repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp) + repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + } + MusicService.REPEAT_MODE_THIS -> { + repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp) + repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) + } + } + } + + private fun updateLabel() { + (MusicPlayerRemote.playingQueue.size - 1).apply { + if (this == (MusicPlayerRemote.position)) { + nextSong.hide() + } else { + val title = MusicPlayerRemote.playingQueue[MusicPlayerRemote.position + 1].title + nextSong.apply { + text = "Next: $title" + show() + } + } + } + } + + override fun onLayoutChange( + v: View?, + left: Int, + top: Int, + right: Int, + bottom: Int, + oldLeft: Int, + oldTop: Int, + oldRight: Int, + oldBottom: Int + ) { + val panel = getQueuePanel() + panel.peekHeight = container.height + } + + private fun setupRecyclerView() { + playingQueueAdapter = PlayingQueueAdapter( + requireActivity() as AppCompatActivity, + MusicPlayerRemote.playingQueue.toMutableList(), + MusicPlayerRemote.position, + R.layout.item_queue + ) + linearLayoutManager = LinearLayoutManager(requireContext()) + recyclerViewTouchActionGuardManager = RecyclerViewTouchActionGuardManager() + recyclerViewDragDropManager = RecyclerViewDragDropManager() + recyclerViewSwipeManager = RecyclerViewSwipeManager() + + val animator = DraggableItemAnimator() + animator.supportsChangeAnimations = false + wrappedAdapter = + recyclerViewDragDropManager?.createWrappedAdapter(playingQueueAdapter!!) as RecyclerView.Adapter<*> + wrappedAdapter = + recyclerViewSwipeManager?.createWrappedAdapter(wrappedAdapter) as RecyclerView.Adapter<*> + recyclerView.layoutManager = linearLayoutManager + recyclerView.adapter = wrappedAdapter + recyclerView.itemAnimator = animator + recyclerViewTouchActionGuardManager?.attachRecyclerView(recyclerView) + recyclerViewDragDropManager?.attachRecyclerView(recyclerView) + recyclerViewSwipeManager?.attachRecyclerView(recyclerView) + + linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0) + } + + override fun onDestroyView() { + super.onDestroyView() + getQueuePanel().removeBottomSheetCallback(bottomSheetCallbackList) + if (recyclerViewDragDropManager != null) { + recyclerViewDragDropManager?.release() + recyclerViewDragDropManager = null + } + + if (recyclerViewSwipeManager != null) { + recyclerViewSwipeManager?.release() + recyclerViewSwipeManager = null + } + + WrapperAdapterUtils.releaseAll(wrappedAdapter) + } + + private fun updateQueuePosition() { + playingQueueAdapter?.setCurrent(MusicPlayerRemote.position) + resetToCurrentPosition() + } + + private fun updateQueue() { + playingQueueAdapter?.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position) + resetToCurrentPosition() + } + + private fun resetToCurrentPosition() { + recyclerView.stopScroll() + linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0) + } + + fun updateFavorite() { + if (updateIsFavoriteTask != null) { + updateIsFavoriteTask?.cancel(false) + } + updateIsFavoriteTask = object : AsyncTask() { + override fun doInBackground(vararg params: Song): Boolean? { + val activity = activity + return if (activity != null) { + MusicUtil.isFavorite(requireActivity(), params[0]) + } else { + cancel(false) + null + } + } + + override fun onPostExecute(isFavorite: Boolean?) { + val activity = activity + if (activity != null) { + val res = if (isFavorite!!) + R.drawable.ic_favorite_white_24dp + else + R.drawable.ic_favorite_border_white_24dp + + val drawable = TintHelper.createTintedDrawable(activity, res, Color.WHITE) + songFavourite?.setImageDrawable(drawable) + } + } + }.execute(MusicPlayerRemote.currentSong) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-xxxhdpi/np_gradient.webp b/app/src/main/res/drawable-xxxhdpi/np_gradient.webp new file mode 100644 index 0000000000000000000000000000000000000000..70f634fdb66d77747e6ce0c2ea8de8c545b954d4 GIT binary patch literal 44878 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�K6b6Si8K^9{xHg-jZISn7TK|8 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 NRg%~FFPMLh{|iwk3`+n2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/fragment_fit.xml b/app/src/main/res/layout/fragment_fit.xml index ffcf7847..9134e5f8 100644 --- a/app/src/main/res/layout/fragment_fit.xml +++ b/app/src/main/res/layout/fragment_fit.xml @@ -22,7 +22,7 @@ android:layout_height="wrap_content" android:layout_weight="1"> - - + tools:layout="@layout/fragment_gradient_controls" /> - - @@ -143,7 +144,6 @@ android:elevation="20dp" android:padding="16dp" android:visibility="gone" - app:layout_constraintBottom_toTopOf="@id/playbackControlsFragment" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/playerToolbar" diff --git a/app/src/main/res/layout/fragment_gradient_controls.xml b/app/src/main/res/layout/fragment_gradient_controls.xml new file mode 100644 index 00000000..386b6511 --- /dev/null +++ b/app/src/main/res/layout/fragment_gradient_controls.xml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_gradient_player.xml b/app/src/main/res/layout/fragment_gradient_player.xml new file mode 100644 index 00000000..293030f8 --- /dev/null +++ b/app/src/main/res/layout/fragment_gradient_player.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index b78a50ea..84252a01 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -21,8 +21,8 @@

diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7bb8532b..21c38703 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -853,6 +853,7 @@ Try Retro Music Premium Share the app with your friends and family Need more help? + Gradient Song