commit
e7ed4ed62f
55 changed files with 243 additions and 202 deletions
|
@ -15,7 +15,7 @@ android {
|
|||
|
||||
applicationId "code.name.monkey.retromusic"
|
||||
versionCode 10564
|
||||
versionName '5.7.0'
|
||||
versionName '5.7.1'
|
||||
|
||||
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
|
||||
}
|
||||
|
|
|
@ -60,13 +60,37 @@
|
|||
{style-placeholder}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<ul>
|
||||
<li>Added Android Auto</li>
|
||||
|
|
|
@ -55,6 +55,7 @@ object Constants {
|
|||
)
|
||||
const val NUMBER_OF_TOP_TRACKS = 99
|
||||
}
|
||||
|
||||
const val EXTRA_PLAYLIST_TYPE = "type"
|
||||
const val EXTRA_GENRE = "extra_genre"
|
||||
const val EXTRA_PLAYLIST = "extra_playlist"
|
||||
|
@ -161,4 +162,5 @@ const val CUSTOM_FONT = "custom_font"
|
|||
const val APPBAR_MODE = "appbar_mode"
|
||||
const val WALLPAPER_ACCENT = "wallpaper_accent"
|
||||
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.activities.base.AbsMusicServiceActivity
|
||||
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.glide.GlideApp
|
||||
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.PurchaseInfo
|
||||
import com.anjlab.android.iab.v3.SkuDetails
|
||||
import java.util.*
|
||||
|
||||
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.activities.base.AbsThemeActivity
|
||||
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.RetroUtil
|
||||
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.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
import java.util.*
|
||||
|
||||
|
||||
abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
|
||||
|
|
|
@ -351,10 +351,10 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
}
|
||||
|
||||
private fun updateColor() {
|
||||
libraryViewModel.paletteColor.observe(this, { color ->
|
||||
libraryViewModel.paletteColor.observe(this) { color ->
|
||||
this.paletteColor = color
|
||||
onPaletteColorChanged()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false, hideBottomSheet: Boolean = MusicPlayerRemote.playingQueue.isEmpty()) {
|
||||
|
|
|
@ -51,7 +51,9 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
|||
|
||||
private fun updateTheme() {
|
||||
setTheme(ThemeManager.getThemeResValue())
|
||||
setDefaultNightMode(ThemeManager.getNightMode())
|
||||
if (PreferenceUtil.materialYou) {
|
||||
setDefaultNightMode(ThemeManager.getNightMode())
|
||||
}
|
||||
|
||||
if (PreferenceUtil.isCustomFont) {
|
||||
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.color.MediaNotificationProcessor
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
import java.util.*
|
||||
|
||||
class ArtistAdapter(
|
||||
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.destroy
|
||||
import com.afollestad.materialcab.attached.isActive
|
||||
import java.util.*
|
||||
|
||||
abstract class AbsMultiSelectAdapter<V : RecyclerView.ViewHolder?, I>(
|
||||
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.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.db.PlaylistEntity
|
||||
import code.name.monkey.retromusic.db.toSongEntity
|
||||
import code.name.monkey.retromusic.db.toSongsEntity
|
||||
import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.applyOutlineColor
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.accentOutlineColor
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||
|
@ -48,7 +47,6 @@ class OrderablePlaylistSongAdapter(
|
|||
DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
||||
|
||||
val libraryViewModel: LibraryViewModel by activity.viewModel()
|
||||
val tempDataSet = dataSet
|
||||
|
||||
init {
|
||||
this.setHasStableIds(true)
|
||||
|
@ -63,8 +61,6 @@ class OrderablePlaylistSongAdapter(
|
|||
} else {
|
||||
-1
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun createViewHolder(view: View): SongAdapter.ViewHolder {
|
||||
|
@ -77,19 +73,18 @@ class OrderablePlaylistSongAdapter(
|
|||
|
||||
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
|
||||
if (holder.itemViewType == OFFSET_ITEM) {
|
||||
val color = ThemeStore.accentColor(activity)
|
||||
val viewHolder = holder as ViewHolder
|
||||
viewHolder.playAction?.let {
|
||||
it.setOnClickListener {
|
||||
MusicPlayerRemote.openQueue(dataSet, 0, true)
|
||||
}
|
||||
it.applyOutlineColor(color)
|
||||
it.accentOutlineColor()
|
||||
}
|
||||
viewHolder.shuffleAction?.let {
|
||||
it.setOnClickListener {
|
||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
|
||||
}
|
||||
it.applyColor(color)
|
||||
it.accentColor()
|
||||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position - 1)
|
||||
|
@ -132,18 +127,10 @@ class OrderablePlaylistSongAdapter(
|
|||
init {
|
||||
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 {
|
||||
if (dataSet.size == 0 or 1) {
|
||||
if (dataSet.size == 0 or 1 || isInQuickSelectMode) {
|
||||
return false
|
||||
}
|
||||
val dragHandle = holder.dragView ?: return false
|
||||
|
@ -161,7 +148,6 @@ class OrderablePlaylistSongAdapter(
|
|||
dataSet.add(toPosition - 1, dataSet.removeAt(fromPosition - 1))
|
||||
}
|
||||
|
||||
|
||||
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange {
|
||||
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.model.Song
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import java.util.*
|
||||
|
||||
class SimpleSongAdapter(
|
||||
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.PreferenceUtil
|
||||
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.MediaIntentReceiver
|
||||
import com.google.android.gms.cast.framework.media.NotificationOptions
|
||||
import java.util.*
|
||||
|
||||
|
||||
class CastOptionsProvider : OptionsProvider {
|
||||
|
|
|
@ -21,9 +21,10 @@ fun Fragment.createNewFile(
|
|||
registerForActivityResult(ActivityResultContracts.StartActivityForResult())
|
||||
{ result: ActivityResult ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
context?.contentResolver?.openOutputStream(result.data?.data!!)?.use { os->
|
||||
write(os, result.data?.data)
|
||||
}
|
||||
write(
|
||||
context?.contentResolver?.openOutputStream(result.data?.data!!),
|
||||
result.data?.data
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -122,9 +122,9 @@ class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
|||
itemAnimator = DefaultItemAnimator()
|
||||
adapter = contributorAdapter
|
||||
}
|
||||
libraryViewModel.fetchContributors().observe(viewLifecycleOwner, { contributors ->
|
||||
libraryViewModel.fetchContributors().observe(viewLifecycleOwner) { contributors ->
|
||||
contributorAdapter.swapData(contributors)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
|
|
@ -122,7 +122,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
binding.toolbar.title = " "
|
||||
ViewCompat.setTransitionName(binding.albumCoverContainer, arguments.extraAlbumId.toString())
|
||||
postponeEnterTransition()
|
||||
detailsViewModel.getAlbum().observe(viewLifecycleOwner, {
|
||||
detailsViewModel.getAlbum().observe(viewLifecycleOwner) {
|
||||
requireView().doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
} else {
|
||||
ViewCompat.setTransitionName(binding.artistImage, album.artistId.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setupRecyclerView()
|
||||
binding.artistImage.setOnClickListener { artistView ->
|
||||
|
@ -236,17 +236,17 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
simpleSongAdapter.swapDataSet(album.songs)
|
||||
if (albumArtistExists) {
|
||||
detailsViewModel.getAlbumArtist(album.albumArtist.toString())
|
||||
.observe(viewLifecycleOwner, {
|
||||
.observe(viewLifecycleOwner) {
|
||||
loadArtistImage(it)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
detailsViewModel.getArtist(album.artistId).observe(viewLifecycleOwner, {
|
||||
detailsViewModel.getArtist(album.artistId).observe(viewLifecycleOwner) {
|
||||
loadArtistImage(it)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
detailsViewModel.getAlbumInfo(album).observe(viewLifecycleOwner, { result ->
|
||||
detailsViewModel.getAlbumInfo(album).observe(viewLifecycleOwner) { result ->
|
||||
when (result) {
|
||||
is Result.Loading -> {
|
||||
println("Loading")
|
||||
|
@ -258,7 +258,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
aboutAlbum(result.data)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun moreAlbums(albums: List<Album>) {
|
||||
|
@ -305,9 +305,9 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
}
|
||||
|
||||
private fun loadArtistImage(artist: Artist) {
|
||||
detailsViewModel.getMoreAlbums(artist).observe(viewLifecycleOwner, {
|
||||
detailsViewModel.getMoreAlbums(artist).observe(viewLifecycleOwner) {
|
||||
moreAlbums(it)
|
||||
})
|
||||
}
|
||||
GlideApp.with(requireContext()).asBitmapPalette().artistImageOptions(artist)
|
||||
//.forceDownload(PreferenceUtil.isAllowedToDownloadMetadata())
|
||||
.load(
|
||||
|
|
|
@ -48,12 +48,12 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
libraryViewModel.getAlbums().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getAlbums().observe(viewLifecycleOwner) {
|
||||
if (it.isNotEmpty())
|
||||
adapter?.swapDataSet(it)
|
||||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
})
|
||||
}
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
|
|
|
@ -92,12 +92,12 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
(artistId ?: artistName).toString()
|
||||
)
|
||||
postponeEnterTransition()
|
||||
detailsViewModel.getArtist().observe(viewLifecycleOwner, {
|
||||
detailsViewModel.getArtist().observe(viewLifecycleOwner) {
|
||||
requireView().doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
showArtist(it)
|
||||
})
|
||||
}
|
||||
setupRecyclerView()
|
||||
|
||||
binding.fragmentArtistContent.playAction.apply {
|
||||
|
@ -180,13 +180,13 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
biography = null
|
||||
this.lang = lang
|
||||
detailsViewModel.getArtistInfo(name, lang, null)
|
||||
.observe(viewLifecycleOwner, { result ->
|
||||
.observe(viewLifecycleOwner) { result ->
|
||||
when (result) {
|
||||
is Result.Loading -> println("Loading")
|
||||
is Result.Error -> println("Error")
|
||||
is Result.Success -> artistInfo(result.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun artistInfo(lastFmArtist: LastFmArtist?) {
|
||||
|
|
|
@ -49,12 +49,12 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
IArtistClickListener, IAlbumArtistClickListener, ICabHolder {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
libraryViewModel.getArtists().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getArtists().observe(viewLifecycleOwner) {
|
||||
if (it.isNotEmpty())
|
||||
adapter?.swapDataSet(it)
|
||||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
})
|
||||
}
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
|
|
|
@ -41,7 +41,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
|
|||
_binding = FragmentBackupBinding.bind(view)
|
||||
initAdapter()
|
||||
setupRecyclerview()
|
||||
backupViewModel.backupsLiveData.observe(this) {
|
||||
backupViewModel.backupsLiveData.observe(viewLifecycleOwner) {
|
||||
if (it.isNotEmpty())
|
||||
backupAdapter?.swapDataset(it)
|
||||
else
|
||||
|
|
|
@ -315,11 +315,13 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
}
|
||||
}
|
||||
requireView().setOnTouchListener(
|
||||
SwipeDetector(
|
||||
requireContext(),
|
||||
playerAlbumCoverFragment?.viewPager,
|
||||
requireView()
|
||||
)
|
||||
if (PreferenceUtil.swipeAnywhereToChangeSong) {
|
||||
SwipeDetector(
|
||||
requireContext(),
|
||||
playerAlbumCoverFragment?.viewPager,
|
||||
requireView()
|
||||
)
|
||||
} else null
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -86,11 +86,11 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
} else {
|
||||
binding.shuffleButton.isVisible = false
|
||||
}
|
||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner) {
|
||||
binding.shuffleButton.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = it
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
open fun onShuffleClicked() {
|
||||
|
|
|
@ -62,9 +62,9 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
|
|||
genre = arguments.extraGenre
|
||||
binding.toolbar.title = arguments.extraGenre.name
|
||||
setupRecyclerView()
|
||||
detailsViewModel.getSongs().observe(viewLifecycleOwner, {
|
||||
detailsViewModel.getSongs().observe(viewLifecycleOwner) {
|
||||
songs(it)
|
||||
})
|
||||
}
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
|
|
|
@ -40,12 +40,12 @@ GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
|
|||
IGenreClickListener {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
libraryViewModel.getGenre().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getGenre().observe(viewLifecycleOwner) {
|
||||
if (it.isNotEmpty())
|
||||
adapter?.swapDataSet(it)
|
||||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
})
|
||||
}
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
|
|
|
@ -77,12 +77,12 @@ class HomeFragment :
|
|||
layoutManager = LinearLayoutManager(mainActivity)
|
||||
adapter = homeAdapter
|
||||
}
|
||||
libraryViewModel.getHome().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getHome().observe(viewLifecycleOwner) {
|
||||
homeAdapter.swapData(it)
|
||||
})
|
||||
libraryViewModel.getSuggestions().observe(viewLifecycleOwner, {
|
||||
}
|
||||
libraryViewModel.getSuggestions().observe(viewLifecycleOwner) {
|
||||
loadSuggestions(it)
|
||||
})
|
||||
}
|
||||
|
||||
loadProfile()
|
||||
setupTitle()
|
||||
|
|
|
@ -32,6 +32,7 @@ import androidx.fragment.app.FragmentActivity
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.transition.Fade
|
||||
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.VersionUtils
|
||||
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.model.AudioTagInfo
|
||||
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.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
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.tag.FieldKey
|
||||
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() {
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
ToolbarContentTintHelper.colorBackButton(binding.toolbar)
|
||||
|
@ -191,6 +210,12 @@ class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) {
|
|||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_search, menu)
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(),
|
||||
binding.toolbar,
|
||||
menu,
|
||||
ATHToolbarActivity.getToolbarBackgroundColor(binding.toolbar)
|
||||
)
|
||||
return super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
|
|
|
@ -114,11 +114,11 @@ class UserInfoFragment : Fragment() {
|
|||
view.doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner) {
|
||||
binding.next.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = it
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadProfile() {
|
||||
|
|
|
@ -14,12 +14,10 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.player.blur
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.ImageButton
|
||||
import android.widget.SeekBar
|
||||
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.retromusic.R
|
||||
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.hide
|
||||
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.goToArtist
|
||||
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.color.MediaNotificationProcessor
|
||||
|
||||
|
@ -134,7 +132,7 @@ class BlurPlaybackControlsFragment :
|
|||
binding.text.setTextColor(lastPlaybackControlsColor)
|
||||
binding.songInfo.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
|
||||
TintHelper.setTintAuto(binding.progressSlider, lastPlaybackControlsColor, false)
|
||||
binding.progressSlider.applyColor(lastPlaybackControlsColor)
|
||||
volumeFragment?.setTintableColor(lastPlaybackControlsColor)
|
||||
setFabColor(lastPlaybackControlsColor)
|
||||
}
|
||||
|
|
|
@ -14,13 +14,12 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.player.flat
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.ImageButton
|
||||
import android.widget.SeekBar
|
||||
import android.widget.TextView
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
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.MusicProgressViewUpdateHelper.Callback
|
||||
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.color.MediaNotificationProcessor
|
||||
|
||||
|
@ -60,6 +58,12 @@ class FlatPlaybackControlsFragment :
|
|||
override val previousButton: ImageButton?
|
||||
get() = null
|
||||
|
||||
override val songTotalTime: TextView
|
||||
get() = binding.songTotalTime
|
||||
|
||||
override val songCurrentProgress: TextView
|
||||
get() = binding.songCurrentProgress
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentFlatPlayerPlaybackControlsBinding.bind(view)
|
||||
|
|
|
@ -132,7 +132,7 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full) {
|
|||
|
||||
private fun updateArtistImage() {
|
||||
libraryViewModel.artist(MusicPlayerRemote.currentSong.artistId)
|
||||
.observe(viewLifecycleOwner, { artist ->
|
||||
.observe(viewLifecycleOwner) { artist ->
|
||||
if (artist.id != -1L) {
|
||||
GlideApp.with(requireActivity()).asBitmapPalette().artistImageOptions(artist)
|
||||
.load(RetroGlideExtension.getArtistModel(artist))
|
||||
|
@ -142,7 +142,7 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full) {
|
|||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onQueueChanged() {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package code.name.monkey.retromusic.fragments.playlists
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
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.extensions.dip
|
||||
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.helper.MusicPlayerRemote
|
||||
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 val binding get() = _binding!!
|
||||
|
||||
|
||||
private lateinit var playlist: PlaylistWithSongs
|
||||
private lateinit var playlistSongAdapter: OrderablePlaylistSongAdapter
|
||||
|
||||
|
@ -67,9 +64,9 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
playlist = arguments.extraPlaylist
|
||||
binding.toolbar.title = playlist.playlistEntity.playlistName
|
||||
setUpRecyclerView()
|
||||
viewModel.getSongs().observe(viewLifecycleOwner, {
|
||||
viewModel.getSongs().observe(viewLifecycleOwner) {
|
||||
songs(it.toSongs())
|
||||
})
|
||||
}
|
||||
postponeEnterTransition()
|
||||
requireView().doOnPreDraw { startPostponedEnterTransition() }
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
|
@ -157,7 +154,6 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
fun songs(songs: List<Song>) {
|
||||
binding.progressIndicator.hide()
|
||||
if (songs.isNotEmpty()) {
|
||||
Log.i("Updated", songs[0].title)
|
||||
playlistSongAdapter.swapDataSet(songs)
|
||||
} else {
|
||||
showEmptyView()
|
||||
|
|
|
@ -40,12 +40,12 @@ class PlaylistsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
libraryViewModel.getPlaylists().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getPlaylists().observe(viewLifecycleOwner) {
|
||||
if (it.isNotEmpty())
|
||||
adapter?.swapDataSet(it)
|
||||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
})
|
||||
}
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
|
|
|
@ -88,19 +88,19 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
if (savedInstanceState != null) {
|
||||
query = savedInstanceState.getString(QUERY)
|
||||
}
|
||||
libraryViewModel.getSearchResult().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getSearchResult().observe(viewLifecycleOwner) {
|
||||
showData(it)
|
||||
})
|
||||
}
|
||||
setupChips()
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getFabMargin().observe(viewLifecycleOwner) {
|
||||
binding.keyboardPopup.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = it
|
||||
}
|
||||
})
|
||||
}
|
||||
KeyboardVisibilityEvent.setEventListener(requireActivity(), viewLifecycleOwner) {
|
||||
if (it) {
|
||||
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_album_artists -> Filter.ALBUM_ARTISTS
|
||||
R.id.chip_genres -> Filter.GENRES
|
||||
R.id.chip_playlists -> Filter.PLAYLISTS
|
||||
else -> Filter.NO_FILTER
|
||||
}
|
||||
}
|
||||
|
@ -245,6 +246,7 @@ enum class Filter {
|
|||
ALBUMS,
|
||||
ALBUM_ARTISTS,
|
||||
GENRES,
|
||||
PLAYLISTS,
|
||||
NO_FILTER
|
||||
}
|
||||
|
||||
|
|
|
@ -42,12 +42,12 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
|||
ICabHolder {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
libraryViewModel.getSongs().observe(viewLifecycleOwner, {
|
||||
libraryViewModel.getSongs().observe(viewLifecycleOwner) {
|
||||
if (it.isNotEmpty())
|
||||
adapter?.swapDataSet(it)
|
||||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
})
|
||||
}
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
|
|
|
@ -72,17 +72,17 @@ object M3UWriter : M3UConstants {
|
|||
it.songPrimaryKey
|
||||
}.toSongs()
|
||||
if (songs.isNotEmpty()) {
|
||||
outputStream.bufferedWriter().use{ bw->
|
||||
bw.write(M3UConstants.HEADER)
|
||||
songs.forEach {
|
||||
bw.newLine()
|
||||
bw.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title)
|
||||
bw.newLine()
|
||||
bw.write(it.data)
|
||||
outputStream.use { os ->
|
||||
os.bufferedWriter().use { bw->
|
||||
bw.write(M3UConstants.HEADER)
|
||||
songs.forEach {
|
||||
bw.newLine()
|
||||
bw.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title)
|
||||
bw.newLine()
|
||||
bw.write(it.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
outputStream.flush()
|
||||
outputStream.close()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import code.name.monkey.retromusic.model.Song
|
|||
import code.name.monkey.retromusic.repository.RealSongRepository
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import java.util.*
|
||||
|
||||
object SearchQueryHelper : KoinComponent {
|
||||
private const val TITLE_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.TITLE + ") = ?"
|
||||
|
|
|
@ -36,7 +36,6 @@ import android.widget.Scroller
|
|||
import androidx.core.content.ContextCompat
|
||||
import code.name.monkey.retromusic.R
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,19 +16,19 @@ package code.name.monkey.retromusic.repository
|
|||
|
||||
import android.content.ContentResolver
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.provider.BaseColumns
|
||||
import android.provider.MediaStore.Audio.Genres
|
||||
import code.name.monkey.retromusic.Constants.IS_MUSIC
|
||||
import code.name.monkey.retromusic.Constants.baseProjection
|
||||
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.model.Genre
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
|
||||
interface GenreRepository {
|
||||
fun genres(query: String): List<Genre>
|
||||
|
||||
fun genres(): List<Genre>
|
||||
|
||||
fun songs(genreId: Long): List<Song>
|
||||
|
@ -41,6 +41,10 @@ class RealGenreRepository(
|
|||
private val songRepository: RealSongRepository
|
||||
) : GenreRepository {
|
||||
|
||||
override fun genres(query: String): List<Genre> {
|
||||
return getGenresFromCursor(makeGenreCursor(query))
|
||||
}
|
||||
|
||||
override fun genres(): List<Genre> {
|
||||
return getGenresFromCursor(makeGenreCursor())
|
||||
}
|
||||
|
@ -57,18 +61,23 @@ class RealGenreRepository(
|
|||
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 {
|
||||
val id = cursor.getLong(Genres._ID)
|
||||
val name = cursor.getStringOrNull(Genres.NAME)
|
||||
val songCount = songs(id).size
|
||||
val songCount = getSongCount(id)
|
||||
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> {
|
||||
|
@ -77,28 +86,6 @@ class RealGenreRepository(
|
|||
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? {
|
||||
return try {
|
||||
contentResolver.query(
|
||||
|
@ -121,37 +108,13 @@ class RealGenreRepository(
|
|||
val genre = getGenreFromCursor(cursor)
|
||||
if (genre.songCount > 0) {
|
||||
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())
|
||||
}
|
||||
cursor.close()
|
||||
}
|
||||
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? {
|
||||
val projection = arrayOf(Genres._ID, Genres.NAME)
|
||||
return try {
|
||||
|
@ -166,4 +129,19 @@ class RealGenreRepository(
|
|||
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 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.model.Album
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
|
@ -29,20 +30,23 @@ class RealSearchRepository(
|
|||
private val roomRepository: RoomRepository,
|
||||
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>()
|
||||
if (query.isNullOrEmpty()) return results
|
||||
query.let { searchString ->
|
||||
|
||||
/** Songs **/
|
||||
val songs: List<Song> = if (filter == Filter.SONGS || filter == Filter.NO_FILTER) {
|
||||
songRepository.songs(searchString)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
if (songs.isNotEmpty()) {
|
||||
results.add(context.resources.getString(R.string.songs))
|
||||
results.addAll(songs)
|
||||
}
|
||||
|
||||
/** Artists **/
|
||||
val artists: List<Artist> =
|
||||
if (filter == Filter.ARTISTS || filter == Filter.NO_FILTER) {
|
||||
artistRepository.artists(searchString)
|
||||
|
@ -53,6 +57,8 @@ class RealSearchRepository(
|
|||
results.add(context.resources.getString(R.string.artists))
|
||||
results.addAll(artists)
|
||||
}
|
||||
|
||||
/** Albums **/
|
||||
val albums: List<Album> = if (filter == Filter.ALBUMS || filter == Filter.NO_FILTER) {
|
||||
albumRepository.albums(searchString)
|
||||
} else {
|
||||
|
@ -62,6 +68,8 @@ class RealSearchRepository(
|
|||
results.add(context.resources.getString(R.string.albums))
|
||||
results.addAll(albums)
|
||||
}
|
||||
|
||||
/** Album-Artists **/
|
||||
val albumArtists: List<Artist> =
|
||||
if (filter == Filter.ALBUM_ARTISTS || filter == Filter.NO_FILTER) {
|
||||
artistRepository.albumArtists(searchString)
|
||||
|
@ -72,11 +80,10 @@ class RealSearchRepository(
|
|||
results.add(context.resources.getString(R.string.album_artist))
|
||||
results.addAll(albumArtists)
|
||||
}
|
||||
|
||||
/** Genres **/
|
||||
val genres: List<Genre> = if (filter == Filter.GENRES || filter == Filter.NO_FILTER) {
|
||||
genreRepository.genres().filter { genre ->
|
||||
genre.name.lowercase()
|
||||
.contains(searchString.lowercase())
|
||||
}
|
||||
genreRepository.genres(query)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
@ -84,14 +91,21 @@ class RealSearchRepository(
|
|||
results.add(context.resources.getString(R.string.genres))
|
||||
results.addAll(genres)
|
||||
}
|
||||
/* val playlist = roomRepository.playlists().filter { playlist ->
|
||||
playlist.playlistName.toLowerCase(Locale.getDefault())
|
||||
.contains(searchString.toLowerCase(Locale.getDefault()))
|
||||
}
|
||||
if (playlist.isNotEmpty()) {
|
||||
results.add(context.getString(R.string.playlists))
|
||||
results.addAll(playlist)
|
||||
}*/
|
||||
|
||||
/** Playlists **/
|
||||
val playlist: List<PlaylistEntity> =
|
||||
if (filter == Filter.PLAYLISTS || filter == Filter.NO_FILTER) {
|
||||
roomRepository.playlists().filter { playlist ->
|
||||
playlist.playlistName.lowercase().contains(searchString.lowercase())
|
||||
}
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
if (playlist.isNotEmpty()) {
|
||||
results.add(context.getString(R.string.playlists))
|
||||
results.addAll(playlist)
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import androidx.annotation.ColorInt;
|
|||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -100,7 +101,7 @@ public class ImageUtil {
|
|||
|
||||
public static Drawable getVectorDrawable(
|
||||
@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}. */
|
||||
|
|
|
@ -35,7 +35,6 @@ import java.io.IOException
|
|||
import java.security.MessageDigest
|
||||
import java.security.NoSuchAlgorithmException
|
||||
import java.util.*
|
||||
import kotlin.collections.LinkedHashMap
|
||||
|
||||
/**
|
||||
* Validates that the calling package is authorized to browse a [MediaBrowserServiceCompat].
|
||||
|
|
|
@ -708,6 +708,9 @@ object PreferenceUtil {
|
|||
|
||||
val circlePlayButton
|
||||
get() = sharedPreferences.getBoolean(CIRCLE_PLAY_BUTTON, false)
|
||||
|
||||
val swipeAnywhereToChangeSong
|
||||
get() = sharedPreferences.getBoolean(SWIPE_ANYWHERE_NOW_PLAYING, true)
|
||||
}
|
||||
enum class LyricsType {
|
||||
REPLACE_COVER, OVER_COVER
|
||||
|
|
|
@ -26,13 +26,6 @@ object ThemeManager {
|
|||
fun getNightMode(): Int = when (App.getContext().generalThemeValue) {
|
||||
LIGHT -> AppCompatDelegate.MODE_NIGHT_NO
|
||||
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
|
||||
}
|
||||
}
|
|
@ -222,7 +222,7 @@ public class SeekArc extends View {
|
|||
* provides notifications of when the user starts and stops a touch gesture within the SeekArc.
|
||||
*
|
||||
* @param l The seek bar notification listener
|
||||
* @see SeekArc.OnSeekBarChangeListener
|
||||
* @see SeekArc.OnSeekArcChangeListener
|
||||
*/
|
||||
public void setOnSeekArcChangeListener(OnSeekArcChangeListener l) {
|
||||
mOnSeekArcChangeListener = l;
|
||||
|
|
|
@ -3,7 +3,6 @@ package code.name.monkey.retromusic.views.insets
|
|||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.LinearLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import code.name.monkey.retromusic.extensions.drawAboveSystemBarsWithPadding
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?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:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -83,14 +83,16 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/albumRecyclerView"/>
|
||||
|
||||
<ImageButton
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/song_sort_order"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="@null"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_sort"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
app:iconTint="?colorControlNormal"
|
||||
app:iconSize="24dp"
|
||||
android:background="?roundSelector"
|
||||
app:icon="@drawable/ic_sort"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/songTitle"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/songTitle"
|
||||
|
@ -206,4 +208,4 @@
|
|||
android:layout_height="72dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
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:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="8"
|
||||
android:paddingVertical="@dimen/seekbar_padding"
|
||||
android:splitTrack="false"
|
||||
android:thumb="@drawable/switch_square"
|
||||
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
||||
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="RtlHardcoded,UnusedAttribute"
|
||||
tools:progress="20" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
|
|
|
@ -117,6 +117,13 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
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>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?rectSelector"
|
||||
android:transitionGroup="true">
|
||||
<FrameLayout
|
||||
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_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_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_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>
|
||||
|
@ -390,6 +391,7 @@
|
|||
<string name="pref_title_remember_tab">Remember last tab</string>
|
||||
<string name="pref_title_show_lyrics">Show lyrics</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_toggle_carousel_effect">Carousel effect</string>
|
||||
<string name="pref_title_toggle_full_screen">Fullscreen app</string>
|
||||
|
|
|
@ -207,7 +207,6 @@
|
|||
<item name="android:textSize">16sp</item>
|
||||
<item name="checkedIconEnabled">true</item>
|
||||
<item name="chipEndPadding">10dp</item>
|
||||
<item name="chipIconEnabled">true</item>
|
||||
<item name="chipMinHeight">40dp</item>
|
||||
<item name="chipStartPadding">10dp</item>
|
||||
</style>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<item name="popupMenuBackground">@drawable/popup_background</item>
|
||||
</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="rectSelector">@drawable/rect_selector</item>
|
||||
<item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item>
|
||||
|
|
|
@ -42,6 +42,13 @@
|
|||
android:layout="@layout/list_item_view_switch_no_title"
|
||||
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
|
||||
android:layout="@layout/preference_category_title"
|
||||
android:title="@string/pref_header_album">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue