Add gradient theme
This commit is contained in:
parent
563ae8a699
commit
defee853c7
18 changed files with 890 additions and 47 deletions
|
@ -339,7 +339,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case R.id.action_search:
|
case R.id.action_search:
|
||||||
|
|
||||||
NavigationUtil.goToSearch(this);
|
NavigationUtil.goToSearch(this);
|
||||||
break;
|
break;
|
||||||
case R.id.action_new_playlist:
|
case R.id.action_new_playlist:
|
||||||
|
@ -520,11 +519,13 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Log.i(TAG, "handleLayoutResType: " + layoutRes);
|
Log.i(TAG, "handleLayoutResType: " + layoutRes);
|
||||||
|
|
||||||
if (layoutRes != -1) {
|
if (layoutRes != -1) {
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
fragment.setAndSaveLayoutRes(layoutRes);
|
fragment.setAndSaveLayoutRes(layoutRes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -807,9 +808,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
||||||
case R.layout.item_card:
|
case R.layout.item_card:
|
||||||
subMenu.findItem(R.id.action_layout_card).setChecked(true);
|
subMenu.findItem(R.id.action_layout_card).setChecked(true);
|
||||||
break;
|
break;
|
||||||
case R.layout.item_grid:
|
|
||||||
subMenu.findItem(R.id.action_layout_normal).setChecked(true);
|
|
||||||
break;
|
|
||||||
case R.layout.item_card_color:
|
case R.layout.item_card_color:
|
||||||
subMenu.findItem(R.id.action_layout_colored_card).setChecked(true);
|
subMenu.findItem(R.id.action_layout_colored_card).setChecked(true);
|
||||||
break;
|
break;
|
||||||
|
@ -822,6 +820,10 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
||||||
case R.layout.item_image_gradient:
|
case R.layout.item_image_gradient:
|
||||||
subMenu.findItem(R.id.action_layout_gradient_image).setChecked(true);
|
subMenu.findItem(R.id.action_layout_gradient_image).setChecked(true);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
case R.layout.item_grid:
|
||||||
|
subMenu.findItem(R.id.action_layout_normal).setChecked(true);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.fit.FitFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.flat.FlatPlayerFragment
|
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.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.material.MaterialFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
|
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.peak.PeakPlayerFragment
|
import code.name.monkey.retromusic.fragments.player.peak.PeakPlayerFragment
|
||||||
|
@ -257,6 +258,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
|
||||||
Peak -> PeakPlayerFragment()
|
Peak -> PeakPlayerFragment()
|
||||||
Circle -> CirclePlayerFragment()
|
Circle -> CirclePlayerFragment()
|
||||||
Classic -> ClassicPlayerFragment()
|
Classic -> ClassicPlayerFragment()
|
||||||
|
Gradient -> GradientPlayerFragment()
|
||||||
else -> PlayerFragment()
|
else -> PlayerFragment()
|
||||||
} // must implement AbsPlayerFragment
|
} // must implement AbsPlayerFragment
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
|
@ -316,7 +318,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
|
||||||
super.setLightStatusbar(false)
|
super.setLightStatusbar(false)
|
||||||
super.setLightNavigationBar(true)
|
super.setLightNavigationBar(true)
|
||||||
super.setNavigationbarColor(Color.BLACK)
|
super.setNavigationbarColor(Color.BLACK)
|
||||||
} else if (cps == Color || cps == Tiny) {
|
} else if (cps == Color || cps == Tiny || cps == Gradient) {
|
||||||
super.setNavigationbarColor(paletteColor)
|
super.setNavigationbarColor(paletteColor)
|
||||||
super.setLightNavigationBar(isColorLight)
|
super.setLightNavigationBar(isColorLight)
|
||||||
super.setLightStatusbar(isColorLight)
|
super.setLightStatusbar(isColorLight)
|
||||||
|
|
|
@ -47,6 +47,7 @@ open class AlbumAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
println("onCreateViewHolder $itemLayoutRes")
|
||||||
itemLayoutRes = if (itemLayoutRes >= -1) {
|
itemLayoutRes = if (itemLayoutRes >= -1) {
|
||||||
itemLayoutRes
|
itemLayoutRes
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -95,6 +95,7 @@ class AlbumCoverPagerAdapter(
|
||||||
Fit,
|
Fit,
|
||||||
Tiny,
|
Tiny,
|
||||||
Classic,
|
Classic,
|
||||||
|
Gradient,
|
||||||
Full -> R.layout.fragment_album_full_cover
|
Full -> R.layout.fragment_album_full_cover
|
||||||
else -> {
|
else -> {
|
||||||
if (PreferenceUtil.getInstance(requireContext()).carouselEffect()
|
if (PreferenceUtil.getInstance(requireContext()).carouselEffect()
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package code.name.monkey.retromusic.adapter.song
|
package code.name.monkey.retromusic.adapter.song
|
||||||
|
|
||||||
import android.graphics.PorterDuff.Mode
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
|
@ -35,7 +33,6 @@ class PlayingQueueAdapter(
|
||||||
SwipeableItemAdapter<PlayingQueueAdapter.ViewHolder>,
|
SwipeableItemAdapter<PlayingQueueAdapter.ViewHolder>,
|
||||||
PopupTextProvider {
|
PopupTextProvider {
|
||||||
|
|
||||||
private var color = -1
|
|
||||||
private var songToRemove: Song? = null
|
private var songToRemove: Song? = null
|
||||||
|
|
||||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
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 {
|
override fun getItemViewType(position: Int): Int {
|
||||||
if (position < current) {
|
if (position < current) {
|
||||||
return HISTORY
|
return HISTORY
|
||||||
|
@ -139,7 +119,6 @@ class PlayingQueueAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
|
||||||
|
|
||||||
@DraggableItemStateFlags
|
@DraggableItemStateFlags
|
||||||
private var mDragStateFlags: Int = 0
|
private var mDragStateFlags: Int = 0
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ enum class NowPlayingScreen constructor(
|
||||||
Fit(R.string.fit, R.drawable.np_fit, 12),
|
Fit(R.string.fit, R.drawable.np_fit, 12),
|
||||||
Flat(R.string.flat, R.drawable.np_flat, 1),
|
Flat(R.string.flat, R.drawable.np_flat, 1),
|
||||||
Full(R.string.full, R.drawable.np_full, 2),
|
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),
|
Material(R.string.material, R.drawable.np_material, 11),
|
||||||
Normal(R.string.normal, R.drawable.np_normal, 0),
|
Normal(R.string.normal, R.drawable.np_normal, 0),
|
||||||
Peak(R.string.peak, R.drawable.np_peak, 14),
|
Peak(R.string.peak, R.drawable.np_peak, 14),
|
||||||
|
|
|
@ -84,6 +84,7 @@ class AlbumsFragment :
|
||||||
|
|
||||||
|
|
||||||
override fun loadLayoutRes(): Int {
|
override fun loadLayoutRes(): Int {
|
||||||
|
println("loadLayoutRes ${PreferenceUtil.getInstance(requireContext()).albumGridStyle}")
|
||||||
return PreferenceUtil.getInstance(requireContext()).albumGridStyle
|
return PreferenceUtil.getInstance(requireContext()).albumGridStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
|
||||||
fun removeSlideEffect() {
|
fun removeSlideEffect() {
|
||||||
val transformer = ParallaxPagerTransformer(R.id.player_image)
|
val transformer = ParallaxPagerTransformer(R.id.player_image)
|
||||||
transformer.setSpeed(0.3f)
|
transformer.setSpeed(0.3f)
|
||||||
viewPager.setPageTransformer(true, transformer)
|
//viewPager.setPageTransformer(true, transformer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
|
@ -50,8 +50,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
|
||||||
val metrics = resources.displayMetrics
|
val metrics = resources.displayMetrics
|
||||||
val ratio = metrics.heightPixels.toFloat() / metrics.widthPixels.toFloat()
|
val ratio = metrics.heightPixels.toFloat() / metrics.widthPixels.toFloat()
|
||||||
|
|
||||||
|
if (nps == Full || nps == Classic || nps == Fit || nps == Gradient) {
|
||||||
if (nps == Full || nps == Classic || nps == Fit) {
|
|
||||||
viewPager.offscreenPageLimit = 2
|
viewPager.offscreenPageLimit = 2
|
||||||
} else if (PreferenceUtil.getInstance(requireContext()).carouselEffect()) {
|
} else if (PreferenceUtil.getInstance(requireContext()).carouselEffect()) {
|
||||||
viewPager.clipToPadding = false
|
viewPager.clipToPadding = false
|
||||||
|
|
|
@ -135,7 +135,8 @@ class ClassicPlayerFragment : AbsPlayerFragment(), View.OnLayoutChangeListener,
|
||||||
0
|
0
|
||||||
).build()
|
).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.background = shapeDrawable
|
||||||
|
|
||||||
playerQueueSheet.setOnTouchListener { _, _ ->
|
playerQueueSheet.setOnTouchListener { _, _ ->
|
||||||
|
@ -358,7 +359,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(), View.OnLayoutChangeListener,
|
||||||
|
|
||||||
ToolbarContentTintHelper.colorizeToolbar(
|
ToolbarContentTintHelper.colorizeToolbar(
|
||||||
playerToolbar,
|
playerToolbar,
|
||||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
Color.WHITE,
|
||||||
requireActivity()
|
requireActivity()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(),
|
||||||
|
|
||||||
private var lastPlaybackControlsColor: Int = 0
|
private var lastPlaybackControlsColor: Int = 0
|
||||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||||
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
|
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -68,12 +68,12 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(),
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
progressViewUpdateHelper!!.start()
|
progressViewUpdateHelper.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
progressViewUpdateHelper!!.stop()
|
progressViewUpdateHelper.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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<ConstraintLayout> {
|
||||||
|
return RetroBottomSheetBehavior.from(playerQueueSheet) as RetroBottomSheetBehavior<ConstraintLayout>
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Song, Void, Boolean>() {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
BIN
app/src/main/res/drawable-xxxhdpi/np_gradient.webp
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/np_gradient.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
|
@ -22,7 +22,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1">
|
||||||
|
|
||||||
<fragment
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/playerAlbumCoverFragment"
|
android:id="@+id/playerAlbumCoverFragment"
|
||||||
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
|
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -37,12 +37,12 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0">
|
android:layout_weight="0">
|
||||||
|
|
||||||
<fragment
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/playbackControlsFragment"
|
android:id="@+id/playbackControlsFragment"
|
||||||
android:name="code.name.monkey.retromusic.fragments.player.fit.FitPlaybackControlsFragment"
|
android:name="code.name.monkey.retromusic.fragments.player.fit.FitPlaybackControlsFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:layout="@layout/fragment_fit_playback_controls" />
|
tools:layout="@layout/fragment_gradient_controls" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
|
|
||||||
|
|
||||||
<fragment
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/playerAlbumCoverFragment"
|
android:id="@+id/playerAlbumCoverFragment"
|
||||||
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
|
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -31,14 +31,15 @@
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
<fragment
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/playbackControlsFragment"
|
android:id="@+id/playbackControlsFragment"
|
||||||
android:name="code.name.monkey.retromusic.fragments.player.full.FullPlaybackControlsFragment"
|
android:name="code.name.monkey.retromusic.fragments.player.full.FullPlaybackControlsFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHeight_default="wrap"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
tools:layout="@layout/fragment_full_player_controls" />
|
tools:layout="@layout/fragment_full_player_controls" />
|
||||||
|
|
||||||
|
@ -143,7 +144,6 @@
|
||||||
android:elevation="20dp"
|
android:elevation="20dp"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toTopOf="@id/playbackControlsFragment"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/playerToolbar"
|
app:layout_constraintTop_toBottomOf="@id/playerToolbar"
|
||||||
|
|
198
app/src/main/res/layout/fragment_gradient_controls.xml
Normal file
198
app/src/main/res/layout/fragment_gradient_controls.xml
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/player_footer_frame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/playerMenu"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/roundSelector"
|
||||||
|
android:padding="16dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/titleContainer"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/titleContainer"
|
||||||
|
app:srcCompat="@drawable/ic_more_vert_white_24dp"
|
||||||
|
tools:tint="@color/md_black_1000" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/titleContainer"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/progressSlider"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/songFavourite"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:gravity="center"
|
||||||
|
android:marqueeRepeatLimit="marquee_forever"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/TextViewHeadline6"
|
||||||
|
android:textColor="@color/md_white_1000"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="@tools:sample/lorem/random"
|
||||||
|
tools:textColor="@color/md_black_1000" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:alpha="0.75"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingTop="6dp"
|
||||||
|
android:textColor="@color/md_white_1000"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/progressSlider"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/songFavourite"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||||
|
tools:layout_editor_absoluteX="48dp"
|
||||||
|
tools:text="@tools:sample/lorem/random"
|
||||||
|
tools:textColor="@color/md_black_1000" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/songFavourite"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/roundSelector"
|
||||||
|
android:padding="16dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/titleContainer"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/titleContainer"
|
||||||
|
app:srcCompat="@drawable/ic_favorite_border_white_24dp"
|
||||||
|
tools:tint="@color/md_black_1000" />
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/songCurrentProgress"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:minWidth="40dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/progressSlider"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/progressSlider"
|
||||||
|
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||||
|
tools:text="00:22" />
|
||||||
|
|
||||||
|
<com.google.android.material.slider.Slider
|
||||||
|
android:id="@+id/progressSlider"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
app:haloRadius="0dp"
|
||||||
|
app:labelBehavior="gone"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleContainer"
|
||||||
|
app:thumbColor="@color/md_white_1000"
|
||||||
|
app:thumbRadius="@dimen/slider_thumb_radius"
|
||||||
|
app:trackColorActive="@color/md_white_1000"
|
||||||
|
app:trackColorInactive="@color/md_white_semi_transparent"
|
||||||
|
app:trackHeight="@dimen/slider_track_height"
|
||||||
|
tools:ignore="RtlHardcoded,UnusedAttribute"
|
||||||
|
tools:progress="20" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/songTotalTime"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:minWidth="40dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/progressSlider"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/progressSlider"
|
||||||
|
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||||
|
tools:text="00:22" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/previousButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/roundSelector"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
|
||||||
|
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
|
||||||
|
tools:ignore="MissingPrefix"
|
||||||
|
tools:tint="@color/md_black_1000" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/playPauseButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/roundSelector"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/progressSlider"
|
||||||
|
app:srcCompat="@drawable/ic_pause_sharp_white_64dp"
|
||||||
|
tools:tint="@color/md_black_1000" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/nextButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/roundSelector"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
|
||||||
|
app:srcCompat="@drawable/ic_skip_next_white_24dp"
|
||||||
|
tools:ignore="MissingPrefix"
|
||||||
|
tools:tint="@color/md_black_1000" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/volumeFragmentContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/songInfo"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/playPauseButton"
|
||||||
|
tools:background="@color/md_red_400"
|
||||||
|
tools:layout_height="52dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/songInfo"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
|
android:textColor="@color/md_white_1000"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="@tools:sample/lorem/random"
|
||||||
|
tools:textColor="@color/md_black_1000" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
155
app/src/main/res/layout/fragment_gradient_player.xml
Normal file
155
app/src/main/res/layout/fragment_gradient_player.xml
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/colorBackground"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingBottom="48dp">
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@+id/playerAlbumCoverFragment"
|
||||||
|
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constrainedHeight="true"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/playbackControlsFragment"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:layout="@layout/fragment_album_full_cover" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/mask"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@drawable/shadow_up_full_theme"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/playerAlbumCoverFragment"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/playerAlbumCoverFragment"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/playerAlbumCoverFragment"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/playerAlbumCoverFragment" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/playbackControlsFragment"
|
||||||
|
layout="@layout/fragment_gradient_controls"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constrainedHeight="true"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/playerAlbumCoverFragment" />
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/statusBarContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<include layout="@layout/status_bar" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/playerQueueSheet"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface"
|
||||||
|
app:behavior_hideable="false"
|
||||||
|
app:layout_behavior="code.name.monkey.retromusic.RetroBottomSheetBehavior">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/twenty_percent_black_overlay"
|
||||||
|
app:layout_constrainedHeight="true"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintWidth_default="spread">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/queueIcon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:padding="14dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/nextSongLabel"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_queue_music_white_24dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/nextSong"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textAppearance="@style/TextViewSubtitle1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/queueIcon"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHeight_default="wrap"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/queueIcon"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/queueIcon"
|
||||||
|
tools:text="@tools:sample/lorem/random" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/repeatButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/roundSelector"
|
||||||
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/previousButton"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/previousButton"
|
||||||
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/previousButton"
|
||||||
|
app:srcCompat="@drawable/ic_repeat_white_24dp"
|
||||||
|
tools:ignore="MissingPrefix"
|
||||||
|
tools:tint="@color/md_black_1000" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/shuffleButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/roundSelector"
|
||||||
|
android:padding="14dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/nextButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/nextButton"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/nextButton"
|
||||||
|
app:srcCompat="@drawable/ic_shuffle_white_24dp"
|
||||||
|
tools:ignore="MissingPrefix"
|
||||||
|
tools:tint="@color/md_black_1000" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:overScrollMode="never"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/container"
|
||||||
|
tools:listitem="@layout/item_list" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -21,8 +21,8 @@
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_grid_size"
|
android:id="@+id/action_grid_size"
|
||||||
android:icon="@drawable/ic_grid_size_white_24dp"
|
android:icon="@drawable/ic_grid_size_white_24dp"
|
||||||
android:title="@string/action_grid_size"
|
|
||||||
android:orderInCategory="5"
|
android:orderInCategory="5"
|
||||||
|
android:title="@string/action_grid_size"
|
||||||
app:showAsAction="ifRoom">
|
app:showAsAction="ifRoom">
|
||||||
<menu>
|
<menu>
|
||||||
<group
|
<group
|
||||||
|
@ -58,8 +58,8 @@
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_layout_type"
|
android:id="@+id/action_layout_type"
|
||||||
android:icon="@drawable/ic_dashboard_white_24dp"
|
android:icon="@drawable/ic_dashboard_white_24dp"
|
||||||
android:title="@string/grid_style_label"
|
|
||||||
android:orderInCategory="6"
|
android:orderInCategory="6"
|
||||||
|
android:title="@string/grid_style_label"
|
||||||
app:showAsAction="ifRoom">
|
app:showAsAction="ifRoom">
|
||||||
<menu>
|
<menu>
|
||||||
<group
|
<group
|
||||||
|
@ -67,6 +67,7 @@
|
||||||
android:checkableBehavior="single">
|
android:checkableBehavior="single">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_layout_normal"
|
android:id="@+id/action_layout_normal"
|
||||||
|
android:checked="true"
|
||||||
android:title="@string/normal" />
|
android:title="@string/normal" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_layout_card"
|
android:id="@+id/action_layout_card"
|
||||||
|
@ -87,9 +88,9 @@
|
||||||
</menu>
|
</menu>
|
||||||
</item>
|
</item>
|
||||||
<item
|
<item
|
||||||
android:orderInCategory="2"
|
|
||||||
android:id="@+id/action_sort_order"
|
android:id="@+id/action_sort_order"
|
||||||
android:icon="@drawable/ic_sort_white_24dp"
|
android:icon="@drawable/ic_sort_white_24dp"
|
||||||
|
android:orderInCategory="2"
|
||||||
android:title="@string/action_sort_order"
|
android:title="@string/action_sort_order"
|
||||||
app:showAsAction="ifRoom">
|
app:showAsAction="ifRoom">
|
||||||
<menu></menu>
|
<menu></menu>
|
||||||
|
|
|
@ -853,6 +853,7 @@
|
||||||
<string name="try_retro_music_premium">Try Retro Music Premium</string>
|
<string name="try_retro_music_premium">Try Retro Music Premium</string>
|
||||||
<string name="share_summary">Share the app with your friends and family</string>
|
<string name="share_summary">Share the app with your friends and family</string>
|
||||||
<string name="help_summary">Need more help?</string>
|
<string name="help_summary">Need more help?</string>
|
||||||
|
<string name="gradient">Gradient</string>
|
||||||
|
|
||||||
<plurals name="albumSongs">
|
<plurals name="albumSongs">
|
||||||
<item quantity="one">Song</item>
|
<item quantity="one">Song</item>
|
||||||
|
|
Loading…
Reference in a new issue