commit
e7ed4ed62f
55 changed files with 243 additions and 202 deletions
|
@ -15,7 +15,7 @@ android {
|
||||||
|
|
||||||
applicationId "code.name.monkey.retromusic"
|
applicationId "code.name.monkey.retromusic"
|
||||||
versionCode 10564
|
versionCode 10564
|
||||||
versionName '5.7.0'
|
versionName '5.7.1'
|
||||||
|
|
||||||
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
|
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,13 +60,37 @@
|
||||||
{style-placeholder}
|
{style-placeholder}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<div>
|
||||||
|
<h5>February 1, 2022</h5>
|
||||||
|
<h2>v5.7.1</h2>
|
||||||
|
<h3>What's New</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Added option to disable changing song by swiping anywhere on the now playing screen</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Fixed</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Fixed Playlist save on A11+</li>
|
||||||
|
<li>Fixed Just Black theme</li>
|
||||||
|
<li>Fixed some UI issues</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Improved</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Improvements to search</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h5>January 25, 2022</h5>
|
<h5>January 25, 2022</h5>
|
||||||
<h2>v5.7.0</h2>
|
<h2>v5.7.0<span class="tag"><i>Beta</i></span></h2>
|
||||||
<h3>What's New</h3>
|
<h3>What's New</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Added Android Auto</li>
|
<li>Added Android Auto</li>
|
||||||
|
|
|
@ -55,6 +55,7 @@ object Constants {
|
||||||
)
|
)
|
||||||
const val NUMBER_OF_TOP_TRACKS = 99
|
const val NUMBER_OF_TOP_TRACKS = 99
|
||||||
}
|
}
|
||||||
|
|
||||||
const val EXTRA_PLAYLIST_TYPE = "type"
|
const val EXTRA_PLAYLIST_TYPE = "type"
|
||||||
const val EXTRA_GENRE = "extra_genre"
|
const val EXTRA_GENRE = "extra_genre"
|
||||||
const val EXTRA_PLAYLIST = "extra_playlist"
|
const val EXTRA_PLAYLIST = "extra_playlist"
|
||||||
|
@ -161,4 +162,5 @@ const val CUSTOM_FONT = "custom_font"
|
||||||
const val APPBAR_MODE = "appbar_mode"
|
const val APPBAR_MODE = "appbar_mode"
|
||||||
const val WALLPAPER_ACCENT = "wallpaper_accent"
|
const val WALLPAPER_ACCENT = "wallpaper_accent"
|
||||||
const val SCREEN_ON_LYRICS = "screen_on_lyrics"
|
const val SCREEN_ON_LYRICS = "screen_on_lyrics"
|
||||||
const val CIRCLE_PLAY_BUTTON = "circle_play_button"
|
const val CIRCLE_PLAY_BUTTON = "circle_play_button"
|
||||||
|
const val SWIPE_ANYWHERE_NOW_PLAYING = "swipe_anywhere_now_playing"
|
|
@ -24,7 +24,9 @@ import code.name.monkey.appthemehelper.util.VersionUtils
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
||||||
import code.name.monkey.retromusic.databinding.ActivityLockScreenBinding
|
import code.name.monkey.retromusic.databinding.ActivityLockScreenBinding
|
||||||
import code.name.monkey.retromusic.extensions.*
|
import code.name.monkey.retromusic.extensions.hideStatusBar
|
||||||
|
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
|
||||||
|
import code.name.monkey.retromusic.extensions.whichFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenControlsFragment
|
import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenControlsFragment
|
||||||
import code.name.monkey.retromusic.glide.GlideApp
|
import code.name.monkey.retromusic.glide.GlideApp
|
||||||
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
||||||
|
|
|
@ -39,7 +39,6 @@ import code.name.monkey.retromusic.extensions.*
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor
|
import com.anjlab.android.iab.v3.BillingProcessor
|
||||||
import com.anjlab.android.iab.v3.PurchaseInfo
|
import com.anjlab.android.iab.v3.PurchaseInfo
|
||||||
import com.anjlab.android.iab.v3.SkuDetails
|
import com.anjlab.android.iab.v3.SkuDetails
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,10 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||||
import code.name.monkey.retromusic.Constants
|
import code.name.monkey.retromusic.Constants
|
||||||
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
|
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
|
||||||
import code.name.monkey.retromusic.databinding.ActivityWhatsNewBinding
|
import code.name.monkey.retromusic.databinding.ActivityWhatsNewBinding
|
||||||
import code.name.monkey.retromusic.extensions.*
|
import code.name.monkey.retromusic.extensions.accentColor
|
||||||
|
import code.name.monkey.retromusic.extensions.drawAboveSystemBars
|
||||||
|
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
|
||||||
|
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil.lastVersion
|
import code.name.monkey.retromusic.util.PreferenceUtil.lastVersion
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
import code.name.monkey.retromusic.util.RetroUtil
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
|
|
|
@ -11,7 +11,6 @@ import com.google.android.gms.cast.framework.CastContext
|
||||||
import com.google.android.gms.cast.framework.CastSession
|
import com.google.android.gms.cast.framework.CastSession
|
||||||
import com.google.android.gms.common.ConnectionResult
|
import com.google.android.gms.common.ConnectionResult
|
||||||
import com.google.android.gms.common.GoogleApiAvailability
|
import com.google.android.gms.common.GoogleApiAvailability
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
|
abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
|
||||||
|
|
|
@ -351,10 +351,10 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateColor() {
|
private fun updateColor() {
|
||||||
libraryViewModel.paletteColor.observe(this, { color ->
|
libraryViewModel.paletteColor.observe(this) { color ->
|
||||||
this.paletteColor = color
|
this.paletteColor = color
|
||||||
onPaletteColorChanged()
|
onPaletteColorChanged()
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false, hideBottomSheet: Boolean = MusicPlayerRemote.playingQueue.isEmpty()) {
|
fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false, hideBottomSheet: Boolean = MusicPlayerRemote.playingQueue.isEmpty()) {
|
||||||
|
|
|
@ -51,7 +51,9 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
||||||
|
|
||||||
private fun updateTheme() {
|
private fun updateTheme() {
|
||||||
setTheme(ThemeManager.getThemeResValue())
|
setTheme(ThemeManager.getThemeResValue())
|
||||||
setDefaultNightMode(ThemeManager.getNightMode())
|
if (PreferenceUtil.materialYou) {
|
||||||
|
setDefaultNightMode(ThemeManager.getNightMode())
|
||||||
|
}
|
||||||
|
|
||||||
if (PreferenceUtil.isCustomFont) {
|
if (PreferenceUtil.isCustomFont) {
|
||||||
setTheme(R.style.FontThemeOverlay)
|
setTheme(R.style.FontThemeOverlay)
|
||||||
|
|
|
@ -41,7 +41,6 @@ import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class ArtistAdapter(
|
class ArtistAdapter(
|
||||||
override val activity: FragmentActivity,
|
override val activity: FragmentActivity,
|
||||||
|
|
|
@ -16,7 +16,6 @@ import code.name.monkey.retromusic.util.RetroColorUtil
|
||||||
import com.afollestad.materialcab.attached.AttachedCab
|
import com.afollestad.materialcab.attached.AttachedCab
|
||||||
import com.afollestad.materialcab.attached.destroy
|
import com.afollestad.materialcab.attached.destroy
|
||||||
import com.afollestad.materialcab.attached.isActive
|
import com.afollestad.materialcab.attached.isActive
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
abstract class AbsMultiSelectAdapter<V : RecyclerView.ViewHolder?, I>(
|
abstract class AbsMultiSelectAdapter<V : RecyclerView.ViewHolder?, I>(
|
||||||
open val activity: FragmentActivity, private val ICabHolder: ICabHolder?, @MenuRes menuRes: Int
|
open val activity: FragmentActivity, private val ICabHolder: ICabHolder?, @MenuRes menuRes: Int
|
||||||
|
|
|
@ -19,14 +19,13 @@ import android.view.View
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.db.PlaylistEntity
|
import code.name.monkey.retromusic.db.PlaylistEntity
|
||||||
import code.name.monkey.retromusic.db.toSongEntity
|
import code.name.monkey.retromusic.db.toSongEntity
|
||||||
import code.name.monkey.retromusic.db.toSongsEntity
|
import code.name.monkey.retromusic.db.toSongsEntity
|
||||||
import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
|
import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
|
||||||
import code.name.monkey.retromusic.extensions.applyColor
|
import code.name.monkey.retromusic.extensions.accentColor
|
||||||
import code.name.monkey.retromusic.extensions.applyOutlineColor
|
import code.name.monkey.retromusic.extensions.accentOutlineColor
|
||||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||||
|
@ -48,7 +47,6 @@ class OrderablePlaylistSongAdapter(
|
||||||
DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
||||||
|
|
||||||
val libraryViewModel: LibraryViewModel by activity.viewModel()
|
val libraryViewModel: LibraryViewModel by activity.viewModel()
|
||||||
val tempDataSet = dataSet
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.setHasStableIds(true)
|
this.setHasStableIds(true)
|
||||||
|
@ -63,8 +61,6 @@ class OrderablePlaylistSongAdapter(
|
||||||
} else {
|
} else {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||||
|
@ -77,19 +73,18 @@ class OrderablePlaylistSongAdapter(
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
||||||
if (holder.itemViewType == OFFSET_ITEM) {
|
if (holder.itemViewType == OFFSET_ITEM) {
|
||||||
val color = ThemeStore.accentColor(activity)
|
|
||||||
val viewHolder = holder as ViewHolder
|
val viewHolder = holder as ViewHolder
|
||||||
viewHolder.playAction?.let {
|
viewHolder.playAction?.let {
|
||||||
it.setOnClickListener {
|
it.setOnClickListener {
|
||||||
MusicPlayerRemote.openQueue(dataSet, 0, true)
|
MusicPlayerRemote.openQueue(dataSet, 0, true)
|
||||||
}
|
}
|
||||||
it.applyOutlineColor(color)
|
it.accentOutlineColor()
|
||||||
}
|
}
|
||||||
viewHolder.shuffleAction?.let {
|
viewHolder.shuffleAction?.let {
|
||||||
it.setOnClickListener {
|
it.setOnClickListener {
|
||||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
||||||
}
|
}
|
||||||
it.applyColor(color)
|
it.accentColor()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
super.onBindViewHolder(holder, position - 1)
|
super.onBindViewHolder(holder, position - 1)
|
||||||
|
@ -132,18 +127,10 @@ class OrderablePlaylistSongAdapter(
|
||||||
init {
|
init {
|
||||||
dragView?.isVisible = true
|
dragView?.isVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(v: View?) {
|
|
||||||
if (itemViewType == OFFSET_ITEM) {
|
|
||||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
super.onClick(v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
|
override fun onCheckCanStartDrag(holder: ViewHolder, position: Int, x: Int, y: Int): Boolean {
|
||||||
if (dataSet.size == 0 or 1) {
|
if (dataSet.size == 0 or 1 || isInQuickSelectMode) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val dragHandle = holder.dragView ?: return false
|
val dragHandle = holder.dragView ?: return false
|
||||||
|
@ -161,7 +148,6 @@ class OrderablePlaylistSongAdapter(
|
||||||
dataSet.add(toPosition - 1, dataSet.removeAt(fromPosition - 1))
|
dataSet.add(toPosition - 1, dataSet.removeAt(fromPosition - 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange {
|
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange {
|
||||||
return ItemDraggableRange(1, itemCount - 1)
|
return ItemDraggableRange(1, itemCount - 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import androidx.fragment.app.FragmentActivity
|
||||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class SimpleSongAdapter(
|
class SimpleSongAdapter(
|
||||||
context: FragmentActivity,
|
context: FragmentActivity,
|
||||||
|
|
|
@ -25,7 +25,6 @@ import code.name.monkey.retromusic.service.MusicService
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,7 +8,6 @@ import com.google.android.gms.cast.framework.SessionProvider
|
||||||
import com.google.android.gms.cast.framework.media.CastMediaOptions
|
import com.google.android.gms.cast.framework.media.CastMediaOptions
|
||||||
import com.google.android.gms.cast.framework.media.MediaIntentReceiver
|
import com.google.android.gms.cast.framework.media.MediaIntentReceiver
|
||||||
import com.google.android.gms.cast.framework.media.NotificationOptions
|
import com.google.android.gms.cast.framework.media.NotificationOptions
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
class CastOptionsProvider : OptionsProvider {
|
class CastOptionsProvider : OptionsProvider {
|
||||||
|
|
|
@ -21,9 +21,10 @@ fun Fragment.createNewFile(
|
||||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult())
|
registerForActivityResult(ActivityResultContracts.StartActivityForResult())
|
||||||
{ result: ActivityResult ->
|
{ result: ActivityResult ->
|
||||||
if (result.resultCode == Activity.RESULT_OK) {
|
if (result.resultCode == Activity.RESULT_OK) {
|
||||||
context?.contentResolver?.openOutputStream(result.data?.data!!)?.use { os->
|
write(
|
||||||
write(os, result.data?.data)
|
context?.contentResolver?.openOutputStream(result.data?.data!!),
|
||||||
}
|
result.data?.data
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,9 +122,9 @@ class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
||||||
itemAnimator = DefaultItemAnimator()
|
itemAnimator = DefaultItemAnimator()
|
||||||
adapter = contributorAdapter
|
adapter = contributorAdapter
|
||||||
}
|
}
|
||||||
libraryViewModel.fetchContributors().observe(viewLifecycleOwner, { contributors ->
|
libraryViewModel.fetchContributors().observe(viewLifecycleOwner) { contributors ->
|
||||||
contributorAdapter.swapData(contributors)
|
contributorAdapter.swapData(contributors)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
|
|
@ -122,7 +122,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
||||||
binding.toolbar.title = " "
|
binding.toolbar.title = " "
|
||||||
ViewCompat.setTransitionName(binding.albumCoverContainer, arguments.extraAlbumId.toString())
|
ViewCompat.setTransitionName(binding.albumCoverContainer, arguments.extraAlbumId.toString())
|
||||||
postponeEnterTransition()
|
postponeEnterTransition()
|
||||||
detailsViewModel.getAlbum().observe(viewLifecycleOwner, {
|
detailsViewModel.getAlbum().observe(viewLifecycleOwner) {
|
||||||
requireView().doOnPreDraw {
|
requireView().doOnPreDraw {
|
||||||
startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
||||||
} else {
|
} else {
|
||||||
ViewCompat.setTransitionName(binding.artistImage, album.artistId.toString())
|
ViewCompat.setTransitionName(binding.artistImage, album.artistId.toString())
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
binding.artistImage.setOnClickListener { artistView ->
|
binding.artistImage.setOnClickListener { artistView ->
|
||||||
|
@ -236,17 +236,17 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
||||||
simpleSongAdapter.swapDataSet(album.songs)
|
simpleSongAdapter.swapDataSet(album.songs)
|
||||||
if (albumArtistExists) {
|
if (albumArtistExists) {
|
||||||
detailsViewModel.getAlbumArtist(album.albumArtist.toString())
|
detailsViewModel.getAlbumArtist(album.albumArtist.toString())
|
||||||
.observe(viewLifecycleOwner, {
|
.observe(viewLifecycleOwner) {
|
||||||
loadArtistImage(it)
|
loadArtistImage(it)
|
||||||
})
|
}
|
||||||
} else {
|
} else {
|
||||||
detailsViewModel.getArtist(album.artistId).observe(viewLifecycleOwner, {
|
detailsViewModel.getArtist(album.artistId).observe(viewLifecycleOwner) {
|
||||||
loadArtistImage(it)
|
loadArtistImage(it)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
detailsViewModel.getAlbumInfo(album).observe(viewLifecycleOwner, { result ->
|
detailsViewModel.getAlbumInfo(album).observe(viewLifecycleOwner) { result ->
|
||||||
when (result) {
|
when (result) {
|
||||||
is Result.Loading -> {
|
is Result.Loading -> {
|
||||||
println("Loading")
|
println("Loading")
|
||||||
|
@ -258,7 +258,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
||||||
aboutAlbum(result.data)
|
aboutAlbum(result.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun moreAlbums(albums: List<Album>) {
|
private fun moreAlbums(albums: List<Album>) {
|
||||||
|
@ -305,9 +305,9 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadArtistImage(artist: Artist) {
|
private fun loadArtistImage(artist: Artist) {
|
||||||
detailsViewModel.getMoreAlbums(artist).observe(viewLifecycleOwner, {
|
detailsViewModel.getMoreAlbums(artist).observe(viewLifecycleOwner) {
|
||||||
moreAlbums(it)
|
moreAlbums(it)
|
||||||
})
|
}
|
||||||
GlideApp.with(requireContext()).asBitmapPalette().artistImageOptions(artist)
|
GlideApp.with(requireContext()).asBitmapPalette().artistImageOptions(artist)
|
||||||
//.forceDownload(PreferenceUtil.isAllowedToDownloadMetadata())
|
//.forceDownload(PreferenceUtil.isAllowedToDownloadMetadata())
|
||||||
.load(
|
.load(
|
||||||
|
|
|
@ -48,12 +48,12 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
libraryViewModel.getAlbums().observe(viewLifecycleOwner, {
|
libraryViewModel.getAlbums().observe(viewLifecycleOwner) {
|
||||||
if (it.isNotEmpty())
|
if (it.isNotEmpty())
|
||||||
adapter?.swapDataSet(it)
|
adapter?.swapDataSet(it)
|
||||||
else
|
else
|
||||||
adapter?.swapDataSet(listOf())
|
adapter?.swapDataSet(listOf())
|
||||||
})
|
}
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||||
if (!handleBackPress()) {
|
if (!handleBackPress()) {
|
||||||
remove()
|
remove()
|
||||||
|
|
|
@ -92,12 +92,12 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
||||||
(artistId ?: artistName).toString()
|
(artistId ?: artistName).toString()
|
||||||
)
|
)
|
||||||
postponeEnterTransition()
|
postponeEnterTransition()
|
||||||
detailsViewModel.getArtist().observe(viewLifecycleOwner, {
|
detailsViewModel.getArtist().observe(viewLifecycleOwner) {
|
||||||
requireView().doOnPreDraw {
|
requireView().doOnPreDraw {
|
||||||
startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
}
|
}
|
||||||
showArtist(it)
|
showArtist(it)
|
||||||
})
|
}
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
|
|
||||||
binding.fragmentArtistContent.playAction.apply {
|
binding.fragmentArtistContent.playAction.apply {
|
||||||
|
@ -180,13 +180,13 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
||||||
biography = null
|
biography = null
|
||||||
this.lang = lang
|
this.lang = lang
|
||||||
detailsViewModel.getArtistInfo(name, lang, null)
|
detailsViewModel.getArtistInfo(name, lang, null)
|
||||||
.observe(viewLifecycleOwner, { result ->
|
.observe(viewLifecycleOwner) { result ->
|
||||||
when (result) {
|
when (result) {
|
||||||
is Result.Loading -> println("Loading")
|
is Result.Loading -> println("Loading")
|
||||||
is Result.Error -> println("Error")
|
is Result.Error -> println("Error")
|
||||||
is Result.Success -> artistInfo(result.data)
|
is Result.Success -> artistInfo(result.data)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun artistInfo(lastFmArtist: LastFmArtist?) {
|
private fun artistInfo(lastFmArtist: LastFmArtist?) {
|
||||||
|
|
|
@ -49,12 +49,12 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
||||||
IArtistClickListener, IAlbumArtistClickListener, ICabHolder {
|
IArtistClickListener, IAlbumArtistClickListener, ICabHolder {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
libraryViewModel.getArtists().observe(viewLifecycleOwner, {
|
libraryViewModel.getArtists().observe(viewLifecycleOwner) {
|
||||||
if (it.isNotEmpty())
|
if (it.isNotEmpty())
|
||||||
adapter?.swapDataSet(it)
|
adapter?.swapDataSet(it)
|
||||||
else
|
else
|
||||||
adapter?.swapDataSet(listOf())
|
adapter?.swapDataSet(listOf())
|
||||||
})
|
}
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||||
if (!handleBackPress()) {
|
if (!handleBackPress()) {
|
||||||
remove()
|
remove()
|
||||||
|
|
|
@ -41,7 +41,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
|
||||||
_binding = FragmentBackupBinding.bind(view)
|
_binding = FragmentBackupBinding.bind(view)
|
||||||
initAdapter()
|
initAdapter()
|
||||||
setupRecyclerview()
|
setupRecyclerview()
|
||||||
backupViewModel.backupsLiveData.observe(this) {
|
backupViewModel.backupsLiveData.observe(viewLifecycleOwner) {
|
||||||
if (it.isNotEmpty())
|
if (it.isNotEmpty())
|
||||||
backupAdapter?.swapDataset(it)
|
backupAdapter?.swapDataset(it)
|
||||||
else
|
else
|
||||||
|
|
|
@ -315,11 +315,13 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requireView().setOnTouchListener(
|
requireView().setOnTouchListener(
|
||||||
SwipeDetector(
|
if (PreferenceUtil.swipeAnywhereToChangeSong) {
|
||||||
requireContext(),
|
SwipeDetector(
|
||||||
playerAlbumCoverFragment?.viewPager,
|
requireContext(),
|
||||||
requireView()
|
playerAlbumCoverFragment?.viewPager,
|
||||||
)
|
requireView()
|
||||||
|
)
|
||||||
|
} else null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,11 +86,11 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
||||||
} else {
|
} else {
|
||||||
binding.shuffleButton.isVisible = false
|
binding.shuffleButton.isVisible = false
|
||||||
}
|
}
|
||||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner, {
|
libraryViewModel.getFabMargin().observe(viewLifecycleOwner) {
|
||||||
binding.shuffleButton.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
binding.shuffleButton.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
bottomMargin = it
|
bottomMargin = it
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun onShuffleClicked() {
|
open fun onShuffleClicked() {
|
||||||
|
|
|
@ -62,9 +62,9 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
|
||||||
genre = arguments.extraGenre
|
genre = arguments.extraGenre
|
||||||
binding.toolbar.title = arguments.extraGenre.name
|
binding.toolbar.title = arguments.extraGenre.name
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
detailsViewModel.getSongs().observe(viewLifecycleOwner, {
|
detailsViewModel.getSongs().observe(viewLifecycleOwner) {
|
||||||
songs(it)
|
songs(it)
|
||||||
})
|
}
|
||||||
postponeEnterTransition()
|
postponeEnterTransition()
|
||||||
view.doOnPreDraw {
|
view.doOnPreDraw {
|
||||||
startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
|
|
|
@ -40,12 +40,12 @@ GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
|
||||||
IGenreClickListener {
|
IGenreClickListener {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
libraryViewModel.getGenre().observe(viewLifecycleOwner, {
|
libraryViewModel.getGenre().observe(viewLifecycleOwner) {
|
||||||
if (it.isNotEmpty())
|
if (it.isNotEmpty())
|
||||||
adapter?.swapDataSet(it)
|
adapter?.swapDataSet(it)
|
||||||
else
|
else
|
||||||
adapter?.swapDataSet(listOf())
|
adapter?.swapDataSet(listOf())
|
||||||
})
|
}
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||||
remove()
|
remove()
|
||||||
requireActivity().onBackPressed()
|
requireActivity().onBackPressed()
|
||||||
|
|
|
@ -77,12 +77,12 @@ class HomeFragment :
|
||||||
layoutManager = LinearLayoutManager(mainActivity)
|
layoutManager = LinearLayoutManager(mainActivity)
|
||||||
adapter = homeAdapter
|
adapter = homeAdapter
|
||||||
}
|
}
|
||||||
libraryViewModel.getHome().observe(viewLifecycleOwner, {
|
libraryViewModel.getHome().observe(viewLifecycleOwner) {
|
||||||
homeAdapter.swapData(it)
|
homeAdapter.swapData(it)
|
||||||
})
|
}
|
||||||
libraryViewModel.getSuggestions().observe(viewLifecycleOwner, {
|
libraryViewModel.getSuggestions().observe(viewLifecycleOwner) {
|
||||||
loadSuggestions(it)
|
loadSuggestions(it)
|
||||||
})
|
}
|
||||||
|
|
||||||
loadProfile()
|
loadProfile()
|
||||||
setupTitle()
|
setupTitle()
|
||||||
|
|
|
@ -32,6 +32,7 @@ import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.transition.Fade
|
import androidx.transition.Fade
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
|
@ -50,12 +51,16 @@ import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||||
import code.name.monkey.retromusic.lyrics.LrcView
|
import code.name.monkey.retromusic.lyrics.LrcView
|
||||||
import code.name.monkey.retromusic.model.AudioTagInfo
|
import code.name.monkey.retromusic.model.AudioTagInfo
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.*
|
import code.name.monkey.retromusic.util.FileUtils
|
||||||
|
import code.name.monkey.retromusic.util.LyricUtil
|
||||||
|
import code.name.monkey.retromusic.util.RetroUtil
|
||||||
|
import code.name.monkey.retromusic.util.UriUtil
|
||||||
import com.afollestad.materialdialogs.input.input
|
import com.afollestad.materialdialogs.input.input
|
||||||
import com.google.android.material.color.MaterialColors
|
import com.google.android.material.color.MaterialColors
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import com.google.android.material.transition.platform.MaterialContainerTransform
|
import com.google.android.material.transition.platform.MaterialContainerTransform
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.jaudiotagger.audio.AudioFileIO
|
import org.jaudiotagger.audio.AudioFileIO
|
||||||
import org.jaudiotagger.tag.FieldKey
|
import org.jaudiotagger.tag.FieldKey
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -177,6 +182,20 @@ class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onPlayingMetaChanged() {
|
||||||
|
super.onPlayingMetaChanged()
|
||||||
|
updateTitleSong()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onServiceConnected() {
|
||||||
|
super.onServiceConnected()
|
||||||
|
updateTitleSong()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateTitleSong() {
|
||||||
|
song = MusicPlayerRemote.currentSong
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupToolbar() {
|
private fun setupToolbar() {
|
||||||
mainActivity.setSupportActionBar(binding.toolbar)
|
mainActivity.setSupportActionBar(binding.toolbar)
|
||||||
ToolbarContentTintHelper.colorBackButton(binding.toolbar)
|
ToolbarContentTintHelper.colorBackButton(binding.toolbar)
|
||||||
|
@ -191,6 +210,12 @@ class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) {
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
inflater.inflate(R.menu.menu_search, menu)
|
inflater.inflate(R.menu.menu_search, menu)
|
||||||
|
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||||
|
requireContext(),
|
||||||
|
binding.toolbar,
|
||||||
|
menu,
|
||||||
|
ATHToolbarActivity.getToolbarBackgroundColor(binding.toolbar)
|
||||||
|
)
|
||||||
return super.onCreateOptionsMenu(menu, inflater)
|
return super.onCreateOptionsMenu(menu, inflater)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,11 +114,11 @@ class UserInfoFragment : Fragment() {
|
||||||
view.doOnPreDraw {
|
view.doOnPreDraw {
|
||||||
startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
}
|
}
|
||||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner, {
|
libraryViewModel.getFabMargin().observe(viewLifecycleOwner) {
|
||||||
binding.next.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
binding.next.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
bottomMargin = it
|
bottomMargin = it
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadProfile() {
|
private fun loadProfile() {
|
||||||
|
|
|
@ -14,12 +14,10 @@
|
||||||
*/
|
*/
|
||||||
package code.name.monkey.retromusic.fragments.player.blur
|
package code.name.monkey.retromusic.fragments.player.blur
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.animation.DecelerateInterpolator
|
import android.view.animation.DecelerateInterpolator
|
||||||
import android.view.animation.LinearInterpolator
|
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
@ -29,6 +27,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
import code.name.monkey.appthemehelper.util.TintHelper
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.databinding.FragmentBlurPlayerPlaybackControlsBinding
|
import code.name.monkey.retromusic.databinding.FragmentBlurPlayerPlaybackControlsBinding
|
||||||
|
import code.name.monkey.retromusic.extensions.applyColor
|
||||||
import code.name.monkey.retromusic.extensions.getSongInfo
|
import code.name.monkey.retromusic.extensions.getSongInfo
|
||||||
import code.name.monkey.retromusic.extensions.hide
|
import code.name.monkey.retromusic.extensions.hide
|
||||||
import code.name.monkey.retromusic.extensions.show
|
import code.name.monkey.retromusic.extensions.show
|
||||||
|
@ -36,7 +35,6 @@ import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||||
|
|
||||||
|
@ -134,7 +132,7 @@ class BlurPlaybackControlsFragment :
|
||||||
binding.text.setTextColor(lastPlaybackControlsColor)
|
binding.text.setTextColor(lastPlaybackControlsColor)
|
||||||
binding.songInfo.setTextColor(lastDisabledPlaybackControlsColor)
|
binding.songInfo.setTextColor(lastDisabledPlaybackControlsColor)
|
||||||
|
|
||||||
TintHelper.setTintAuto(binding.progressSlider, lastPlaybackControlsColor, false)
|
binding.progressSlider.applyColor(lastPlaybackControlsColor)
|
||||||
volumeFragment?.setTintableColor(lastPlaybackControlsColor)
|
volumeFragment?.setTintableColor(lastPlaybackControlsColor)
|
||||||
setFabColor(lastPlaybackControlsColor)
|
setFabColor(lastPlaybackControlsColor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,12 @@
|
||||||
*/
|
*/
|
||||||
package code.name.monkey.retromusic.fragments.player.flat
|
package code.name.monkey.retromusic.fragments.player.flat
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.animation.DecelerateInterpolator
|
import android.view.animation.DecelerateInterpolator
|
||||||
import android.view.animation.LinearInterpolator
|
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
|
import android.widget.TextView
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||||
|
@ -35,7 +34,6 @@ import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
|
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
|
||||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||||
|
|
||||||
|
@ -60,6 +58,12 @@ class FlatPlaybackControlsFragment :
|
||||||
override val previousButton: ImageButton?
|
override val previousButton: ImageButton?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
|
override val songTotalTime: TextView
|
||||||
|
get() = binding.songTotalTime
|
||||||
|
|
||||||
|
override val songCurrentProgress: TextView
|
||||||
|
get() = binding.songCurrentProgress
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
_binding = FragmentFlatPlayerPlaybackControlsBinding.bind(view)
|
_binding = FragmentFlatPlayerPlaybackControlsBinding.bind(view)
|
||||||
|
|
|
@ -132,7 +132,7 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full) {
|
||||||
|
|
||||||
private fun updateArtistImage() {
|
private fun updateArtistImage() {
|
||||||
libraryViewModel.artist(MusicPlayerRemote.currentSong.artistId)
|
libraryViewModel.artist(MusicPlayerRemote.currentSong.artistId)
|
||||||
.observe(viewLifecycleOwner, { artist ->
|
.observe(viewLifecycleOwner) { artist ->
|
||||||
if (artist.id != -1L) {
|
if (artist.id != -1L) {
|
||||||
GlideApp.with(requireActivity()).asBitmapPalette().artistImageOptions(artist)
|
GlideApp.with(requireActivity()).asBitmapPalette().artistImageOptions(artist)
|
||||||
.load(RetroGlideExtension.getArtistModel(artist))
|
.load(RetroGlideExtension.getArtistModel(artist))
|
||||||
|
@ -142,7 +142,7 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueueChanged() {
|
override fun onQueueChanged() {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package code.name.monkey.retromusic.fragments.playlists
|
package code.name.monkey.retromusic.fragments.playlists
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
@ -20,7 +19,6 @@ import code.name.monkey.retromusic.db.PlaylistWithSongs
|
||||||
import code.name.monkey.retromusic.db.toSongs
|
import code.name.monkey.retromusic.db.toSongs
|
||||||
import code.name.monkey.retromusic.extensions.dip
|
import code.name.monkey.retromusic.extensions.dip
|
||||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||||
import code.name.monkey.retromusic.extensions.updateMargin
|
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
|
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
|
||||||
|
@ -51,7 +49,6 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
||||||
private var _binding: FragmentPlaylistDetailBinding? = null
|
private var _binding: FragmentPlaylistDetailBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
|
||||||
private lateinit var playlist: PlaylistWithSongs
|
private lateinit var playlist: PlaylistWithSongs
|
||||||
private lateinit var playlistSongAdapter: OrderablePlaylistSongAdapter
|
private lateinit var playlistSongAdapter: OrderablePlaylistSongAdapter
|
||||||
|
|
||||||
|
@ -67,9 +64,9 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
||||||
playlist = arguments.extraPlaylist
|
playlist = arguments.extraPlaylist
|
||||||
binding.toolbar.title = playlist.playlistEntity.playlistName
|
binding.toolbar.title = playlist.playlistEntity.playlistName
|
||||||
setUpRecyclerView()
|
setUpRecyclerView()
|
||||||
viewModel.getSongs().observe(viewLifecycleOwner, {
|
viewModel.getSongs().observe(viewLifecycleOwner) {
|
||||||
songs(it.toSongs())
|
songs(it.toSongs())
|
||||||
})
|
}
|
||||||
postponeEnterTransition()
|
postponeEnterTransition()
|
||||||
requireView().doOnPreDraw { startPostponedEnterTransition() }
|
requireView().doOnPreDraw { startPostponedEnterTransition() }
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||||
|
@ -157,7 +154,6 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
||||||
fun songs(songs: List<Song>) {
|
fun songs(songs: List<Song>) {
|
||||||
binding.progressIndicator.hide()
|
binding.progressIndicator.hide()
|
||||||
if (songs.isNotEmpty()) {
|
if (songs.isNotEmpty()) {
|
||||||
Log.i("Updated", songs[0].title)
|
|
||||||
playlistSongAdapter.swapDataSet(songs)
|
playlistSongAdapter.swapDataSet(songs)
|
||||||
} else {
|
} else {
|
||||||
showEmptyView()
|
showEmptyView()
|
||||||
|
|
|
@ -40,12 +40,12 @@ class PlaylistsFragment :
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
libraryViewModel.getPlaylists().observe(viewLifecycleOwner, {
|
libraryViewModel.getPlaylists().observe(viewLifecycleOwner) {
|
||||||
if (it.isNotEmpty())
|
if (it.isNotEmpty())
|
||||||
adapter?.swapDataSet(it)
|
adapter?.swapDataSet(it)
|
||||||
else
|
else
|
||||||
adapter?.swapDataSet(listOf())
|
adapter?.swapDataSet(listOf())
|
||||||
})
|
}
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||||
remove()
|
remove()
|
||||||
requireActivity().onBackPressed()
|
requireActivity().onBackPressed()
|
||||||
|
|
|
@ -88,19 +88,19 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
query = savedInstanceState.getString(QUERY)
|
query = savedInstanceState.getString(QUERY)
|
||||||
}
|
}
|
||||||
libraryViewModel.getSearchResult().observe(viewLifecycleOwner, {
|
libraryViewModel.getSearchResult().observe(viewLifecycleOwner) {
|
||||||
showData(it)
|
showData(it)
|
||||||
})
|
}
|
||||||
setupChips()
|
setupChips()
|
||||||
postponeEnterTransition()
|
postponeEnterTransition()
|
||||||
view.doOnPreDraw {
|
view.doOnPreDraw {
|
||||||
startPostponedEnterTransition()
|
startPostponedEnterTransition()
|
||||||
}
|
}
|
||||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner, {
|
libraryViewModel.getFabMargin().observe(viewLifecycleOwner) {
|
||||||
binding.keyboardPopup.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
binding.keyboardPopup.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
bottomMargin = it
|
bottomMargin = it
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
KeyboardVisibilityEvent.setEventListener(requireActivity(), viewLifecycleOwner) {
|
KeyboardVisibilityEvent.setEventListener(requireActivity(), viewLifecycleOwner) {
|
||||||
if (it) {
|
if (it) {
|
||||||
binding.keyboardPopup.isGone = true
|
binding.keyboardPopup.isGone = true
|
||||||
|
@ -192,6 +192,7 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
||||||
R.id.chip_albums -> Filter.ALBUMS
|
R.id.chip_albums -> Filter.ALBUMS
|
||||||
R.id.chip_album_artists -> Filter.ALBUM_ARTISTS
|
R.id.chip_album_artists -> Filter.ALBUM_ARTISTS
|
||||||
R.id.chip_genres -> Filter.GENRES
|
R.id.chip_genres -> Filter.GENRES
|
||||||
|
R.id.chip_playlists -> Filter.PLAYLISTS
|
||||||
else -> Filter.NO_FILTER
|
else -> Filter.NO_FILTER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,6 +246,7 @@ enum class Filter {
|
||||||
ALBUMS,
|
ALBUMS,
|
||||||
ALBUM_ARTISTS,
|
ALBUM_ARTISTS,
|
||||||
GENRES,
|
GENRES,
|
||||||
|
PLAYLISTS,
|
||||||
NO_FILTER
|
NO_FILTER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,12 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
||||||
ICabHolder {
|
ICabHolder {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
libraryViewModel.getSongs().observe(viewLifecycleOwner, {
|
libraryViewModel.getSongs().observe(viewLifecycleOwner) {
|
||||||
if (it.isNotEmpty())
|
if (it.isNotEmpty())
|
||||||
adapter?.swapDataSet(it)
|
adapter?.swapDataSet(it)
|
||||||
else
|
else
|
||||||
adapter?.swapDataSet(listOf())
|
adapter?.swapDataSet(listOf())
|
||||||
})
|
}
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||||
if (!handleBackPress()) {
|
if (!handleBackPress()) {
|
||||||
remove()
|
remove()
|
||||||
|
|
|
@ -72,17 +72,17 @@ object M3UWriter : M3UConstants {
|
||||||
it.songPrimaryKey
|
it.songPrimaryKey
|
||||||
}.toSongs()
|
}.toSongs()
|
||||||
if (songs.isNotEmpty()) {
|
if (songs.isNotEmpty()) {
|
||||||
outputStream.bufferedWriter().use{ bw->
|
outputStream.use { os ->
|
||||||
bw.write(M3UConstants.HEADER)
|
os.bufferedWriter().use { bw->
|
||||||
songs.forEach {
|
bw.write(M3UConstants.HEADER)
|
||||||
bw.newLine()
|
songs.forEach {
|
||||||
bw.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title)
|
bw.newLine()
|
||||||
bw.newLine()
|
bw.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title)
|
||||||
bw.write(it.data)
|
bw.newLine()
|
||||||
|
bw.write(it.data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outputStream.flush()
|
|
||||||
outputStream.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.repository.RealSongRepository
|
import code.name.monkey.retromusic.repository.RealSongRepository
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.inject
|
import org.koin.core.component.inject
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object SearchQueryHelper : KoinComponent {
|
object SearchQueryHelper : KoinComponent {
|
||||||
private const val TITLE_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.TITLE + ") = ?"
|
private const val TITLE_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.TITLE + ") = ?"
|
||||||
|
|
|
@ -36,7 +36,6 @@ import android.widget.Scroller
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,19 +16,19 @@ package code.name.monkey.retromusic.repository
|
||||||
|
|
||||||
import android.content.ContentResolver
|
import android.content.ContentResolver
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.net.Uri
|
|
||||||
import android.provider.BaseColumns
|
import android.provider.BaseColumns
|
||||||
import android.provider.MediaStore.Audio.Genres
|
import android.provider.MediaStore.Audio.Genres
|
||||||
import code.name.monkey.retromusic.Constants.IS_MUSIC
|
import code.name.monkey.retromusic.Constants.IS_MUSIC
|
||||||
import code.name.monkey.retromusic.Constants.baseProjection
|
import code.name.monkey.retromusic.Constants.baseProjection
|
||||||
import code.name.monkey.retromusic.extensions.getLong
|
import code.name.monkey.retromusic.extensions.getLong
|
||||||
import code.name.monkey.retromusic.extensions.getString
|
|
||||||
import code.name.monkey.retromusic.extensions.getStringOrNull
|
import code.name.monkey.retromusic.extensions.getStringOrNull
|
||||||
import code.name.monkey.retromusic.model.Genre
|
import code.name.monkey.retromusic.model.Genre
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
|
|
||||||
interface GenreRepository {
|
interface GenreRepository {
|
||||||
|
fun genres(query: String): List<Genre>
|
||||||
|
|
||||||
fun genres(): List<Genre>
|
fun genres(): List<Genre>
|
||||||
|
|
||||||
fun songs(genreId: Long): List<Song>
|
fun songs(genreId: Long): List<Song>
|
||||||
|
@ -41,6 +41,10 @@ class RealGenreRepository(
|
||||||
private val songRepository: RealSongRepository
|
private val songRepository: RealSongRepository
|
||||||
) : GenreRepository {
|
) : GenreRepository {
|
||||||
|
|
||||||
|
override fun genres(query: String): List<Genre> {
|
||||||
|
return getGenresFromCursor(makeGenreCursor(query))
|
||||||
|
}
|
||||||
|
|
||||||
override fun genres(): List<Genre> {
|
override fun genres(): List<Genre> {
|
||||||
return getGenresFromCursor(makeGenreCursor())
|
return getGenresFromCursor(makeGenreCursor())
|
||||||
}
|
}
|
||||||
|
@ -57,18 +61,23 @@ class RealGenreRepository(
|
||||||
return songRepository.song(makeGenreSongCursor(genreId))
|
return songRepository.song(makeGenreSongCursor(genreId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getSongCount(genreId: Long): Int {
|
||||||
|
contentResolver.query(
|
||||||
|
Genres.Members.getContentUri("external", genreId),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
).use {
|
||||||
|
return it?.count ?: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getGenreFromCursor(cursor: Cursor): Genre {
|
private fun getGenreFromCursor(cursor: Cursor): Genre {
|
||||||
val id = cursor.getLong(Genres._ID)
|
val id = cursor.getLong(Genres._ID)
|
||||||
val name = cursor.getStringOrNull(Genres.NAME)
|
val name = cursor.getStringOrNull(Genres.NAME)
|
||||||
val songCount = songs(id).size
|
val songCount = getSongCount(id)
|
||||||
return Genre(id, name ?: "", songCount)
|
return Genre(id, name ?: "", songCount)
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getGenreFromCursorWithOutSongs(cursor: Cursor): Genre {
|
|
||||||
val id = cursor.getLong(Genres._ID)
|
|
||||||
val name = cursor.getString(Genres.NAME)
|
|
||||||
return Genre(id, name, -1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSongsWithNoGenre(): List<Song> {
|
private fun getSongsWithNoGenre(): List<Song> {
|
||||||
|
@ -77,28 +86,6 @@ class RealGenreRepository(
|
||||||
return songRepository.songs(songRepository.makeSongCursor(selection, null))
|
return songRepository.songs(songRepository.makeSongCursor(selection, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hasSongsWithNoGenre(): Boolean {
|
|
||||||
val allSongsCursor = songRepository.makeSongCursor(null, null)
|
|
||||||
val allSongsWithGenreCursor = makeAllSongsWithGenreCursor()
|
|
||||||
|
|
||||||
if (allSongsCursor == null || allSongsWithGenreCursor == null) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val hasSongsWithNoGenre = allSongsCursor.count > allSongsWithGenreCursor.count
|
|
||||||
allSongsCursor.close()
|
|
||||||
allSongsWithGenreCursor.close()
|
|
||||||
return hasSongsWithNoGenre
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun makeAllSongsWithGenreCursor(): Cursor? {
|
|
||||||
println(Genres.EXTERNAL_CONTENT_URI.toString())
|
|
||||||
return contentResolver.query(
|
|
||||||
Uri.parse("content://media/external/audio/genres/all/members"),
|
|
||||||
arrayOf(Genres.Members.AUDIO_ID), null, null, null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun makeGenreSongCursor(genreId: Long): Cursor? {
|
private fun makeGenreSongCursor(genreId: Long): Cursor? {
|
||||||
return try {
|
return try {
|
||||||
contentResolver.query(
|
contentResolver.query(
|
||||||
|
@ -121,37 +108,13 @@ class RealGenreRepository(
|
||||||
val genre = getGenreFromCursor(cursor)
|
val genre = getGenreFromCursor(cursor)
|
||||||
if (genre.songCount > 0) {
|
if (genre.songCount > 0) {
|
||||||
genres.add(genre)
|
genres.add(genre)
|
||||||
} else {
|
|
||||||
// try to remove the empty genre from the media store
|
|
||||||
try {
|
|
||||||
contentResolver.delete(
|
|
||||||
Genres.EXTERNAL_CONTENT_URI,
|
|
||||||
Genres._ID + " == " + genre.id,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} while (cursor.moveToNext())
|
} while (cursor.moveToNext())
|
||||||
}
|
}
|
||||||
cursor.close()
|
|
||||||
}
|
}
|
||||||
return genres
|
return genres
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGenresFromCursorForSearch(cursor: Cursor?): List<Genre> {
|
|
||||||
val genres = mutableListOf<Genre>()
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
do {
|
|
||||||
genres.add(getGenreFromCursorWithOutSongs(cursor))
|
|
||||||
} while (cursor.moveToNext())
|
|
||||||
}
|
|
||||||
cursor?.close()
|
|
||||||
return genres
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun makeGenreCursor(): Cursor? {
|
private fun makeGenreCursor(): Cursor? {
|
||||||
val projection = arrayOf(Genres._ID, Genres.NAME)
|
val projection = arrayOf(Genres._ID, Genres.NAME)
|
||||||
return try {
|
return try {
|
||||||
|
@ -166,4 +129,19 @@ class RealGenreRepository(
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun makeGenreCursor(query: String): Cursor? {
|
||||||
|
val projection = arrayOf(Genres._ID, Genres.NAME)
|
||||||
|
return try {
|
||||||
|
contentResolver.query(
|
||||||
|
Genres.EXTERNAL_CONTENT_URI,
|
||||||
|
projection,
|
||||||
|
Genres.NAME + " = ?",
|
||||||
|
arrayOf(query),
|
||||||
|
PreferenceUtil.genreSortOrder
|
||||||
|
)
|
||||||
|
} catch (e: SecurityException) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ package code.name.monkey.retromusic.repository
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
|
import code.name.monkey.retromusic.db.PlaylistEntity
|
||||||
import code.name.monkey.retromusic.fragments.search.Filter
|
import code.name.monkey.retromusic.fragments.search.Filter
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.Album
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.Artist
|
||||||
|
@ -29,20 +30,23 @@ class RealSearchRepository(
|
||||||
private val roomRepository: RoomRepository,
|
private val roomRepository: RoomRepository,
|
||||||
private val genreRepository: GenreRepository,
|
private val genreRepository: GenreRepository,
|
||||||
) {
|
) {
|
||||||
fun searchAll(context: Context, query: String?, filter: Filter): MutableList<Any> {
|
suspend fun searchAll(context: Context, query: String?, filter: Filter): MutableList<Any> {
|
||||||
val results = mutableListOf<Any>()
|
val results = mutableListOf<Any>()
|
||||||
if (query.isNullOrEmpty()) return results
|
if (query.isNullOrEmpty()) return results
|
||||||
query.let { searchString ->
|
query.let { searchString ->
|
||||||
|
|
||||||
|
/** Songs **/
|
||||||
val songs: List<Song> = if (filter == Filter.SONGS || filter == Filter.NO_FILTER) {
|
val songs: List<Song> = if (filter == Filter.SONGS || filter == Filter.NO_FILTER) {
|
||||||
songRepository.songs(searchString)
|
songRepository.songs(searchString)
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (songs.isNotEmpty()) {
|
if (songs.isNotEmpty()) {
|
||||||
results.add(context.resources.getString(R.string.songs))
|
results.add(context.resources.getString(R.string.songs))
|
||||||
results.addAll(songs)
|
results.addAll(songs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Artists **/
|
||||||
val artists: List<Artist> =
|
val artists: List<Artist> =
|
||||||
if (filter == Filter.ARTISTS || filter == Filter.NO_FILTER) {
|
if (filter == Filter.ARTISTS || filter == Filter.NO_FILTER) {
|
||||||
artistRepository.artists(searchString)
|
artistRepository.artists(searchString)
|
||||||
|
@ -53,6 +57,8 @@ class RealSearchRepository(
|
||||||
results.add(context.resources.getString(R.string.artists))
|
results.add(context.resources.getString(R.string.artists))
|
||||||
results.addAll(artists)
|
results.addAll(artists)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Albums **/
|
||||||
val albums: List<Album> = if (filter == Filter.ALBUMS || filter == Filter.NO_FILTER) {
|
val albums: List<Album> = if (filter == Filter.ALBUMS || filter == Filter.NO_FILTER) {
|
||||||
albumRepository.albums(searchString)
|
albumRepository.albums(searchString)
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,6 +68,8 @@ class RealSearchRepository(
|
||||||
results.add(context.resources.getString(R.string.albums))
|
results.add(context.resources.getString(R.string.albums))
|
||||||
results.addAll(albums)
|
results.addAll(albums)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Album-Artists **/
|
||||||
val albumArtists: List<Artist> =
|
val albumArtists: List<Artist> =
|
||||||
if (filter == Filter.ALBUM_ARTISTS || filter == Filter.NO_FILTER) {
|
if (filter == Filter.ALBUM_ARTISTS || filter == Filter.NO_FILTER) {
|
||||||
artistRepository.albumArtists(searchString)
|
artistRepository.albumArtists(searchString)
|
||||||
|
@ -72,11 +80,10 @@ class RealSearchRepository(
|
||||||
results.add(context.resources.getString(R.string.album_artist))
|
results.add(context.resources.getString(R.string.album_artist))
|
||||||
results.addAll(albumArtists)
|
results.addAll(albumArtists)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Genres **/
|
||||||
val genres: List<Genre> = if (filter == Filter.GENRES || filter == Filter.NO_FILTER) {
|
val genres: List<Genre> = if (filter == Filter.GENRES || filter == Filter.NO_FILTER) {
|
||||||
genreRepository.genres().filter { genre ->
|
genreRepository.genres(query)
|
||||||
genre.name.lowercase()
|
|
||||||
.contains(searchString.lowercase())
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
@ -84,14 +91,21 @@ class RealSearchRepository(
|
||||||
results.add(context.resources.getString(R.string.genres))
|
results.add(context.resources.getString(R.string.genres))
|
||||||
results.addAll(genres)
|
results.addAll(genres)
|
||||||
}
|
}
|
||||||
/* val playlist = roomRepository.playlists().filter { playlist ->
|
|
||||||
playlist.playlistName.toLowerCase(Locale.getDefault())
|
/** Playlists **/
|
||||||
.contains(searchString.toLowerCase(Locale.getDefault()))
|
val playlist: List<PlaylistEntity> =
|
||||||
}
|
if (filter == Filter.PLAYLISTS || filter == Filter.NO_FILTER) {
|
||||||
if (playlist.isNotEmpty()) {
|
roomRepository.playlists().filter { playlist ->
|
||||||
results.add(context.getString(R.string.playlists))
|
playlist.playlistName.lowercase().contains(searchString.lowercase())
|
||||||
results.addAll(playlist)
|
}
|
||||||
}*/
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playlist.isNotEmpty()) {
|
||||||
|
results.add(context.getString(R.string.playlists))
|
||||||
|
results.addAll(playlist)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import androidx.annotation.ColorInt;
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.content.res.ResourcesCompat;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -100,7 +101,7 @@ public class ImageUtil {
|
||||||
|
|
||||||
public static Drawable getVectorDrawable(
|
public static Drawable getVectorDrawable(
|
||||||
@NonNull Resources res, @DrawableRes int resId, @Nullable Resources.Theme theme) {
|
@NonNull Resources res, @DrawableRes int resId, @Nullable Resources.Theme theme) {
|
||||||
return res.getDrawable(resId, theme);
|
return ResourcesCompat.getDrawable(res,resId, theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Makes sure that {@code mTempBuffer} has at least length {@code size}. */
|
/** Makes sure that {@code mTempBuffer} has at least length {@code size}. */
|
||||||
|
|
|
@ -35,7 +35,6 @@ import java.io.IOException
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.security.NoSuchAlgorithmException
|
import java.security.NoSuchAlgorithmException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.LinkedHashMap
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates that the calling package is authorized to browse a [MediaBrowserServiceCompat].
|
* Validates that the calling package is authorized to browse a [MediaBrowserServiceCompat].
|
||||||
|
|
|
@ -708,6 +708,9 @@ object PreferenceUtil {
|
||||||
|
|
||||||
val circlePlayButton
|
val circlePlayButton
|
||||||
get() = sharedPreferences.getBoolean(CIRCLE_PLAY_BUTTON, false)
|
get() = sharedPreferences.getBoolean(CIRCLE_PLAY_BUTTON, false)
|
||||||
|
|
||||||
|
val swipeAnywhereToChangeSong
|
||||||
|
get() = sharedPreferences.getBoolean(SWIPE_ANYWHERE_NOW_PLAYING, true)
|
||||||
}
|
}
|
||||||
enum class LyricsType {
|
enum class LyricsType {
|
||||||
REPLACE_COVER, OVER_COVER
|
REPLACE_COVER, OVER_COVER
|
||||||
|
|
|
@ -26,13 +26,6 @@ object ThemeManager {
|
||||||
fun getNightMode(): Int = when (App.getContext().generalThemeValue) {
|
fun getNightMode(): Int = when (App.getContext().generalThemeValue) {
|
||||||
LIGHT -> AppCompatDelegate.MODE_NIGHT_NO
|
LIGHT -> AppCompatDelegate.MODE_NIGHT_NO
|
||||||
DARK -> AppCompatDelegate.MODE_NIGHT_YES
|
DARK -> AppCompatDelegate.MODE_NIGHT_YES
|
||||||
BLACK -> {
|
|
||||||
if (PreferenceUtil.baseTheme == "dark") {
|
|
||||||
AppCompatDelegate.MODE_NIGHT_YES
|
|
||||||
} else {
|
|
||||||
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -222,7 +222,7 @@ public class SeekArc extends View {
|
||||||
* provides notifications of when the user starts and stops a touch gesture within the SeekArc.
|
* provides notifications of when the user starts and stops a touch gesture within the SeekArc.
|
||||||
*
|
*
|
||||||
* @param l The seek bar notification listener
|
* @param l The seek bar notification listener
|
||||||
* @see SeekArc.OnSeekBarChangeListener
|
* @see SeekArc.OnSeekArcChangeListener
|
||||||
*/
|
*/
|
||||||
public void setOnSeekArcChangeListener(OnSeekArcChangeListener l) {
|
public void setOnSeekArcChangeListener(OnSeekArcChangeListener l) {
|
||||||
mOnSeekArcChangeListener = l;
|
mOnSeekArcChangeListener = l;
|
||||||
|
|
|
@ -3,7 +3,6 @@ package code.name.monkey.retromusic.views.insets
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
import code.name.monkey.retromusic.extensions.drawAboveSystemBarsWithPadding
|
import code.name.monkey.retromusic.extensions.drawAboveSystemBarsWithPadding
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
import code.name.monkey.retromusic.util.RetroUtil
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<code.name.monkey.retromusic.views.insets.InsetsConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -83,14 +83,16 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/albumRecyclerView"/>
|
app:layout_constraintTop_toBottomOf="@id/albumRecyclerView"/>
|
||||||
|
|
||||||
<ImageButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/song_sort_order"
|
android:id="@+id/song_sort_order"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:background="@null"
|
style="@style/Widget.Material3.Button.IconButton"
|
||||||
android:padding="8dp"
|
app:iconTint="?colorControlNormal"
|
||||||
android:src="@drawable/ic_sort"
|
app:iconSize="24dp"
|
||||||
|
android:background="?roundSelector"
|
||||||
|
app:icon="@drawable/ic_sort"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/songTitle"
|
app:layout_constraintBottom_toBottomOf="@+id/songTitle"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/songTitle"
|
app:layout_constraintStart_toEndOf="@id/songTitle"
|
||||||
|
@ -206,4 +208,4 @@
|
||||||
android:layout_height="72dp"
|
android:layout_height="72dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/listeners" />
|
app:layout_constraintTop_toBottomOf="@id/listeners" />
|
||||||
</code.name.monkey.retromusic.views.insets.InsetsConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -26,14 +26,12 @@
|
||||||
android:id="@+id/progressSlider"
|
android:id="@+id/progressSlider"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="8"
|
|
||||||
android:paddingVertical="@dimen/seekbar_padding"
|
android:paddingVertical="@dimen/seekbar_padding"
|
||||||
android:splitTrack="false"
|
android:splitTrack="false"
|
||||||
android:thumb="@drawable/switch_square"
|
android:thumb="@drawable/switch_square"
|
||||||
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
||||||
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:ignore="RtlHardcoded,UnusedAttribute"
|
|
||||||
tools:progress="20" />
|
tools:progress="20" />
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
|
|
@ -117,6 +117,13 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/genres" />
|
android:text="@string/genres" />
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:id="@+id/chip_playlists"
|
||||||
|
style="@style/SearchChipStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/playlists" />
|
||||||
</com.google.android.material.chip.ChipGroup>
|
</com.google.android.material.chip.ChipGroup>
|
||||||
|
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
|
android:background="?rectSelector"
|
||||||
android:transitionGroup="true">
|
android:transitionGroup="true">
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/dummy_view"
|
android:id="@+id/dummy_view"
|
||||||
|
|
|
@ -347,6 +347,7 @@
|
||||||
<string name="pref_summary_remember_tab">Navigate to the last used tab on start</string>
|
<string name="pref_summary_remember_tab">Navigate to the last used tab on start</string>
|
||||||
<string name="pref_summary_show_lyrics">Display synced lyrics over album cover</string>
|
<string name="pref_summary_show_lyrics">Display synced lyrics over album cover</string>
|
||||||
<string name="pref_summary_suggestions">Show New Music Mix on homescreen</string>
|
<string name="pref_summary_suggestions">Show New Music Mix on homescreen</string>
|
||||||
|
<string name="pref_summary_swipe_anywhere_now_playing">Enables changing song by swiping anywhere on the now playing screen</string>
|
||||||
<string name="pref_summary_toggle_full_screen">Immersive mode</string>
|
<string name="pref_summary_toggle_full_screen">Immersive mode</string>
|
||||||
<string name="pref_summary_toggle_headset">Start playing immediately after headphones are connected</string>
|
<string name="pref_summary_toggle_headset">Start playing immediately after headphones are connected</string>
|
||||||
<string name="pref_summary_toggle_shuffle">Shuffle mode will turn off when playing a new list of songs</string>
|
<string name="pref_summary_toggle_shuffle">Shuffle mode will turn off when playing a new list of songs</string>
|
||||||
|
@ -390,6 +391,7 @@
|
||||||
<string name="pref_title_remember_tab">Remember last tab</string>
|
<string name="pref_title_remember_tab">Remember last tab</string>
|
||||||
<string name="pref_title_show_lyrics">Show lyrics</string>
|
<string name="pref_title_show_lyrics">Show lyrics</string>
|
||||||
<string name="pref_title_suggestions">Show suggestions</string>
|
<string name="pref_title_suggestions">Show suggestions</string>
|
||||||
|
<string name="pref_title_swipe_anywhere_now_playing">Swipe anywhere to change song</string>
|
||||||
<string name="pref_title_tab_text_mode">Tab titles mode</string>
|
<string name="pref_title_tab_text_mode">Tab titles mode</string>
|
||||||
<string name="pref_title_toggle_carousel_effect">Carousel effect</string>
|
<string name="pref_title_toggle_carousel_effect">Carousel effect</string>
|
||||||
<string name="pref_title_toggle_full_screen">Fullscreen app</string>
|
<string name="pref_title_toggle_full_screen">Fullscreen app</string>
|
||||||
|
|
|
@ -207,7 +207,6 @@
|
||||||
<item name="android:textSize">16sp</item>
|
<item name="android:textSize">16sp</item>
|
||||||
<item name="checkedIconEnabled">true</item>
|
<item name="checkedIconEnabled">true</item>
|
||||||
<item name="chipEndPadding">10dp</item>
|
<item name="chipEndPadding">10dp</item>
|
||||||
<item name="chipIconEnabled">true</item>
|
|
||||||
<item name="chipMinHeight">40dp</item>
|
<item name="chipMinHeight">40dp</item>
|
||||||
<item name="chipStartPadding">10dp</item>
|
<item name="chipStartPadding">10dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<item name="popupMenuBackground">@drawable/popup_background</item>
|
<item name="popupMenuBackground">@drawable/popup_background</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.RetroMusic.Base.Black" parent="Theme.Material3.DayNight.NoActionBar">
|
<style name="Theme.RetroMusic.Base.Black" parent="Theme.Material3.Dark.NoActionBar">
|
||||||
<item name="roundSelector">@drawable/round_selector</item>
|
<item name="roundSelector">@drawable/round_selector</item>
|
||||||
<item name="rectSelector">@drawable/rect_selector</item>
|
<item name="rectSelector">@drawable/rect_selector</item>
|
||||||
<item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item>
|
<item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item>
|
||||||
|
|
|
@ -42,6 +42,13 @@
|
||||||
android:layout="@layout/list_item_view_switch_no_title"
|
android:layout="@layout/list_item_view_switch_no_title"
|
||||||
android:title="@string/pref_title_circle_button" />
|
android:title="@string/pref_title_circle_button" />
|
||||||
|
|
||||||
|
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="swipe_anywhere_now_playing"
|
||||||
|
android:layout="@layout/list_item_view_switch"
|
||||||
|
android:summary="@string/pref_summary_swipe_anywhere_now_playing"
|
||||||
|
android:title="@string/pref_title_swipe_anywhere_now_playing" />
|
||||||
|
|
||||||
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory
|
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory
|
||||||
android:layout="@layout/preference_category_title"
|
android:layout="@layout/preference_category_title"
|
||||||
android:title="@string/pref_header_album">
|
android:title="@string/pref_header_album">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue