Merge pull request #1233 from prathameshmm02/dev

Bug fixes
This commit is contained in:
Daksh P. Jain 2022-01-31 07:56:29 +05:30 committed by GitHub
commit e7ed4ed62f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 243 additions and 202 deletions

View file

@ -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')}\"")
}

View file

@ -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>

View file

@ -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"

View file

@ -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

View file

@ -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 {

View file

@ -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

View file

@ -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() {

View file

@ -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()) {

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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)
}

View file

@ -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,

View file

@ -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.*
/**

View file

@ -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 {

View file

@ -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
)
}
}

View file

@ -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() {

View file

@ -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(

View file

@ -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()

View file

@ -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?) {

View file

@ -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()

View file

@ -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

View file

@ -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
)
}

View file

@ -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() {

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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)
}

View file

@ -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() {

View file

@ -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)
}

View file

@ -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)

View file

@ -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() {

View file

@ -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()

View file

@ -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()

View file

@ -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
}

View file

@ -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()

View file

@ -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()
}
}

View file

@ -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 + ") = ?"

View file

@ -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
/**

View file

@ -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
}
}
}

View file

@ -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
}

View file

@ -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}. */

View file

@ -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].

View file

@ -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

View file

@ -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
}
}

View file

@ -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;

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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>

View file

@ -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"

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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">