Item list to support big screen
Fix search for playlist
Fix playlist crash
This commit is contained in:
Hemanth S 2020-09-27 02:09:07 +05:30
parent f2e290d274
commit 209e3d58eb
80 changed files with 1025 additions and 448 deletions

View file

@ -28,16 +28,7 @@ class LockScreenActivity : AbsMusicServiceActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
} else {
this.window.addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
)
}
lockScreenInit()
setContentView(R.layout.activity_lock_screen)
hideStatusBar()
setStatusbarColorAuto()
@ -77,6 +68,19 @@ class LockScreenActivity : AbsMusicServiceActivity() {
}
}
private fun lockScreenInit() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
val keyguardManager: KeyguardManager = getSystemService(KeyguardManager::class.java)
keyguardManager.requestDismissKeyguard(this, null)
} else {
this.window.addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
)
}
}
override fun onPlayingMetaChanged() {
super.onPlayingMetaChanged()
updateSongs()

View file

@ -22,6 +22,7 @@ import code.name.monkey.retromusic.util.AppRater
import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import org.koin.android.ext.android.get
class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener {
companion object {
@ -37,6 +38,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
setupNavigationController()
if (!hasPermissions()) {
findNavController(R.id.fragment_container).navigate(R.id.permissionFragment)
}
@ -49,7 +51,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
updateTabs()
//NavigationUI.setupWithNavController(getBottomNavigationView(), findNavController(R.id.fragment_container))
setupNavigationController()
}
private fun setupNavigationController() {
@ -121,8 +123,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
val id = parseLongFromIntent(intent, "playlistId", "playlist")
if (id >= 0L) {
val position: Int = intent.getIntExtra("position", 0)
val songs: List<Song> =
PlaylistSongsLoader.getPlaylistSongList(this@MainActivity, id)
val songs: List<Song> = PlaylistSongsLoader.getPlaylistSongList(get(), id)
MusicPlayerRemote.openQueue(songs, position, true)
handled = true
}
@ -130,8 +131,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
val id = parseLongFromIntent(intent, "albumId", "album")
if (id >= 0L) {
val position: Int = intent.getIntExtra("position", 0)
val songs = libraryViewModel.albumById(id).songs
MusicPlayerRemote.openQueue(
libraryViewModel.albumById(id).songs,
songs,
position,
true
)
@ -141,8 +143,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
val id = parseLongFromIntent(intent, "artistId", "artist")
if (id >= 0L) {
val position: Int = intent.getIntExtra("position", 0)
val songs: List<Song> = libraryViewModel.artistById(id).songs
MusicPlayerRemote.openQueue(
libraryViewModel.artistById(id).songs,
songs,
position,
true
)

View file

@ -13,7 +13,6 @@ import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.ThemedFastScroller
import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
@ -21,6 +20,7 @@ import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeMana
import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
import kotlinx.android.synthetic.main.activity_playing_queue.*
import kotlinx.android.synthetic.main.activity_playing_queue.title as NoImageTitle
open class PlayingQueueActivity : AbsMusicServiceActivity() {
@ -31,13 +31,6 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
private var playingQueueAdapter: PlayingQueueAdapter? = null
private lateinit var linearLayoutManager: LinearLayoutManager
private fun getUpNextAndQueueTime(): String {
val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)
return MusicUtil.buildInfoString(
resources.getString(R.string.up_next),
MusicUtil.getReadableDurationString(duration)
)
}
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
@ -54,7 +47,6 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
clearQueue.setOnClickListener {
MusicPlayerRemote.clearQueue()
}
checkForPadding()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -107,7 +99,8 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
ThemedFastScroller.create(recyclerView)
}
private fun checkForPadding() {
override fun onServiceConnected() {
updateCurrentSong()
}
override fun onQueueChanged() {
@ -115,7 +108,6 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
finish()
return
}
checkForPadding()
updateQueue()
updateCurrentSong()
}
@ -126,7 +118,9 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
}
private fun updateCurrentSong() {
toolbar.subtitle = getUpNextAndQueueTime()
NoImageTitle.text = MusicPlayerRemote.currentSong.title
text.text = MusicPlayerRemote.currentSong.artistName
text2?.text = MusicPlayerRemote.currentSong.albumName
}
override fun onPlayingMetaChanged() {
@ -136,7 +130,6 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
private fun updateQueuePosition() {
playingQueueAdapter?.setCurrent(MusicPlayerRemote.position)
resetToCurrentPosition()
toolbar.subtitle = getUpNextAndQueueTime()
}
private fun updateQueue() {
@ -174,7 +167,6 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
}
private fun setupToolbar() {
toolbar.subtitle = getUpNextAndQueueTime()
toolbar.setBackgroundColor(surfaceColor())
setSupportActionBar(toolbar)
clearQueue.backgroundTintList = ColorStateList.valueOf(accentColor())

View file

@ -1,6 +1,5 @@
package code.name.monkey.retromusic.adapter
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -23,14 +22,12 @@ class GenreAdapter(
var dataSet: List<Genre>,
private val mItemLayoutRes: Int
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
val colors = listOf<Int>(Color.RED, Color.BLUE)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(activity).inflate(mItemLayoutRes, parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val genre = dataSet[position]
holder.title?.text = genre.name
holder.text?.text = String.format(
Locale.getDefault(),

View file

@ -4,12 +4,15 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.glide.AlbumGlideRequest
import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -19,6 +22,7 @@ import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
import code.name.monkey.retromusic.repository.PlaylistSongsLoader
import code.name.monkey.retromusic.util.MusicUtil
import com.bumptech.glide.Glide
import java.util.*
class SearchAdapter(
private val activity: FragmentActivity,
@ -34,7 +38,7 @@ class SearchAdapter(
if (dataSet[position] is Album) return ALBUM
if (dataSet[position] is Artist) return ARTIST
if (dataSet[position] is Genre) return GENRE
if (dataSet[position] is Playlist) return PLAYLIST
if (dataSet[position] is PlaylistWithSongs) return PLAYLIST
return if (dataSet[position] is Song) SONG else HEADER
}
@ -56,42 +60,52 @@ class SearchAdapter(
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when (getItemViewType(position)) {
ALBUM -> {
val album = dataSet.get(position) as Album
holder. imageTextContainer?.isVisible = true
val album = dataSet[position] as Album
holder.title?.text = album.title
holder.text?.text = album.artistName
AlbumGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.checkIgnoreMediaStore().build().into(holder.image)
}
ARTIST -> {
val artist = dataSet.get(position) as Artist
holder. imageTextContainer?.isVisible = true
val artist = dataSet[position] as Artist
holder.title?.text = artist.name
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
ArtistGlideRequest.Builder.from(Glide.with(activity), artist).build()
.into(holder.image)
}
SONG -> {
val song = dataSet.get(position) as Song
val song = dataSet[position] as Song
holder.title?.text = song.title
holder.text?.text = song.albumName
}
GENRE -> {
val genre = dataSet.get(position) as Genre
val genre = dataSet[position] as Genre
holder.title?.text = genre.name
holder.text?.text = String.format(
Locale.getDefault(),
"%d %s",
genre.songCount,
if (genre.songCount > 1) activity.getString(R.string.songs) else activity.getString(
R.string.song
)
)
}
PLAYLIST -> {
val playlist = dataSet.get(position) as Playlist
holder.title?.text = playlist.name
holder.text?.text = MusicUtil.getPlaylistInfoString(activity, getSongs(playlist))
val playlist = dataSet[position] as PlaylistWithSongs
holder.title?.text = playlist.playlistEntity.playlistName
holder.text?.text = MusicUtil.playlistInfoString(activity, playlist.songs)
}
else -> {
holder.title?.text = dataSet.get(position).toString()
holder.title?.text = dataSet[position].toString()
holder.title?.setTextColor(ThemeStore.accentColor(activity))
}
}
}
private fun getSongs(playlist: Playlist): java.util.ArrayList<Song> {
val songs = java.util.ArrayList<Song>()
private fun getSongs(playlist: Playlist): List<Song> {
val songs = mutableListOf<Song>()
if (playlist is AbsSmartPlaylist) {
songs.addAll(playlist.getSongs())
} else {
@ -107,7 +121,7 @@ class SearchAdapter(
inner class ViewHolder(itemView: View, itemViewType: Int) : MediaEntryViewHolder(itemView) {
init {
itemView.setOnLongClickListener(null)
imageTextContainer?.isInvisible = true
if (itemViewType == SONG) {
menu?.visibility = View.VISIBLE
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
@ -156,7 +170,7 @@ class SearchAdapter(
)
}
SONG -> {
val playList = ArrayList<Song>()
val playList = mutableListOf<Song>()
playList.add(item as Song)
MusicPlayerRemote.openQueue(playList, 0, true)
}

View file

@ -16,7 +16,6 @@ package code.name.monkey.retromusic.adapter.base;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
@ -41,15 +40,13 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
@Nullable
public ImageView image;
@Nullable
public ImageView artistImage;
@Nullable
public ImageView playerImage;
@Nullable
public ViewGroup imageContainer;
@Nullable
public MaterialCardView imageContainerCard;
@ -77,6 +74,9 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
@Nullable
public TextView text;
@Nullable
public TextView text2;
@Nullable
public TextView time;
@ -87,6 +87,7 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
super(itemView);
title = itemView.findViewById(R.id.title);
text = itemView.findViewById(R.id.text);
text2 = itemView.findViewById(R.id.text2);
image = itemView.findViewById(R.id.image);
artistImage = itemView.findViewById(R.id.artistImage);
@ -94,7 +95,6 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
time = itemView.findViewById(R.id.time);
imageText = itemView.findViewById(R.id.imageText);
imageContainer = itemView.findViewById(R.id.imageContainer);
imageTextContainer = itemView.findViewById(R.id.imageTextContainer);
imageContainerCard = itemView.findViewById(R.id.imageContainerCard);

View file

@ -4,14 +4,14 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.ICabHolder
import code.name.monkey.retromusic.model.Song
abstract class AbsOffsetSongAdapter(
activity: AppCompatActivity,
activity: FragmentActivity,
dataSet: MutableList<Song>,
@LayoutRes itemLayoutRes: Int,
ICabHolder: ICabHolder?

View file

@ -173,7 +173,7 @@ class PlayingQueueAdapter(
}
override fun onGetSwipeReactionType(holder: ViewHolder, position: Int, x: Int, y: Int): Int {
return if (onCheckCanStartDrag(holder!!, position, x, y)) {
return if (onCheckCanStartDrag(holder, position, x, y)) {
SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H
} else {
SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H

View file

@ -2,22 +2,21 @@ package code.name.monkey.retromusic.adapter.song
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import androidx.navigation.findNavController
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.toSongEntity
import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
import code.name.monkey.retromusic.interfaces.ICabHolder
import code.name.monkey.retromusic.model.Song
import com.google.android.material.button.MaterialButton
open class PlaylistSongAdapter(
activity: AppCompatActivity,
private val playlist: PlaylistEntity,
activity: FragmentActivity,
dataSet: MutableList<Song>,
itemLayoutRes: Int,
ICabHolder: ICabHolder?
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, ICabHolder) {
) : SongAdapter(activity, dataSet, itemLayoutRes, ICabHolder) {
init {
this.setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection)
@ -27,43 +26,21 @@ open class PlaylistSongAdapter(
return ViewHolder(view)
}
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
if (holder.itemViewType == OFFSET_ITEM) {
val viewHolder = holder as ViewHolder
viewHolder.playAction?.let {
it.setOnClickListener {
MusicPlayerRemote.openQueue(dataSet, 0, true)
}
}
viewHolder.shuffleAction?.let {
it.setOnClickListener {
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
}
}
} else {
super.onBindViewHolder(holder, position - 1)
}
}
open inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
open inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
override var songMenuRes: Int
get() = R.menu.menu_item_cannot_delete_single_songs_playlist_song
get() = R.menu.menu_item_playlist_song
set(value) {
super.songMenuRes = value
}
override fun onSongMenuItemClick(item: MenuItem): Boolean {
if (item.itemId == R.id.action_go_to_album) {
activity.findNavController(R.id.fragment_container)
.navigate(
R.id.albumDetailsFragment,
bundleOf(EXTRA_ALBUM_ID to song.albumId)
)
return true
when (item.itemId) {
R.id.action_remove_from_playlist -> {
RemoveSongFromPlaylistDialog.create(song.toSongEntity(playlist.playListId))
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
return true
}
}
return super.onSongMenuItemClick(item)
}

View file

@ -7,6 +7,7 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
@ -87,6 +88,7 @@ open class SongAdapter(
}
holder.title?.text = getSongTitle(song)
holder.text?.text = getSongText(song)
holder.text2?.text = getSongText(song)
loadAlbumCover(song, holder)
}
@ -121,6 +123,10 @@ open class SongAdapter(
return song.artistName
}
private fun getSongText2(song: Song): String? {
return song.albumName
}
override fun getItemCount(): Int {
return dataSet.size
}
@ -172,7 +178,7 @@ open class SongAdapter(
}
protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
if (image != null && image!!.visibility == View.VISIBLE) {
if (image != null && image!!.isVisible) {
when (item.itemId) {
R.id.action_go_to_album -> {
activity.findNavController(R.id.fragment_container)

View file

@ -2,6 +2,12 @@ package code.name.monkey.retromusic.db
import code.name.monkey.retromusic.model.Song
fun List<HistoryEntity>.fromHistoryToSongs(): List<Song> {
return map {
it.toSong()
}
}
fun List<SongEntity>.toSongs(): List<Song> {
return map {
it.toSong()
@ -131,3 +137,4 @@ fun List<Song>.toSongsEntity(playlistEntity: PlaylistEntity): List<SongEntity> {
it.toSongEntity(playlistEntity.playListId)
}
}

View file

@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.View
import android.widget.ImageView
import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@ -23,13 +22,12 @@ import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.state.NowPlayingPanelState
import code.name.monkey.retromusic.util.RetroUtil
import kotlinx.android.synthetic.main.fragment_playlist_detail.*
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail),
ArtistClickListener, AlbumClickListener {
private val args by navArgs<DetailListFragmentArgs>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
@ -55,7 +53,6 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
TOP_PLAYED_PLAYLIST -> topPlayed()
}
recyclerView.adapter?.registerAdapterDataObserver(object : AdapterDataObserver() {
override fun onChanged() {
super.onChanged()
@ -76,7 +73,7 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
adapter = songAdapter
layoutManager = linearLayoutManager()
}
libraryViewModel.recentSongs().observe(viewLifecycleOwner, Observer { songs ->
libraryViewModel.recentSongs().observe(viewLifecycleOwner, { songs ->
songAdapter.swapDataSet(songs)
})
}
@ -92,7 +89,7 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
adapter = songAdapter
layoutManager = linearLayoutManager()
}
libraryViewModel.playCountSongs().observe(viewLifecycleOwner, Observer { songs ->
libraryViewModel.playCountSongs().observe(viewLifecycleOwner, { songs ->
songAdapter.swapDataSet(songs)
})
}
@ -109,9 +106,8 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
adapter = songAdapter
layoutManager = linearLayoutManager()
}
libraryViewModel.observableHistorySongs().observe(viewLifecycleOwner, Observer {
val songs = it.map { historyEntity -> historyEntity.toSong() }
songAdapter.swapDataSet(songs)
libraryViewModel.observableHistorySongs().observe(viewLifecycleOwner, {
songAdapter.swapDataSet(it)
})
}
@ -170,8 +166,14 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
private fun gridLayoutManager(): GridLayoutManager =
GridLayoutManager(requireContext(), 2, GridLayoutManager.VERTICAL, false)
GridLayoutManager(requireContext(), gridCount(), GridLayoutManager.VERTICAL, false)
private fun gridCount(): Int {
if (RetroUtil.isTablet()) {
return if (RetroUtil.isLandscape()) 6 else 4
}
return 2
}
override fun onArtist(artistId: Long, imageView: ImageView) {
findNavController().navigate(

View file

@ -11,11 +11,8 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.state.NowPlayingPanelState
import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
@ -39,6 +36,10 @@ class LibraryViewModel(
panelState.postValue(state)
}
init {
loadLibraryContent()
}
private fun loadLibraryContent() = viewModelScope.launch(IO) {
fetchHomeSections()
fetchSongs()
@ -51,37 +52,30 @@ class LibraryViewModel(
fun getSearchResult(): LiveData<List<Any>> = searchResults
fun getSongs(): LiveData<List<Song>> {
fetchSongs()
return songs
}
fun getAlbums(): LiveData<List<Album>> {
fetchAlbums()
return albums
}
fun getArtists(): LiveData<List<Artist>> {
fetchArtists()
return artists
}
fun getPlaylists(): LiveData<List<PlaylistWithSongs>> {
fetchPlaylists()
return playlists
}
fun getLegacyPlaylist(): LiveData<List<Playlist>> {
fetchLegacyPlaylist()
return legacyPlaylists
}
fun getGenre(): LiveData<List<Genre>> {
fetchGenres()
return genres
}
fun getHome(): LiveData<List<Home>> {
fetchHomeSections()
return home
}
@ -261,10 +255,6 @@ class LibraryViewModel(
})
}
fun observableHistorySongs() = repository.observableHistorySongs()
fun favorites() = repository.favorites()
fun artists(type: Int): LiveData<List<Artist>> = liveData {
when (type) {
TOP_ARTISTS -> emit(repository.topArtists())
@ -283,12 +273,6 @@ class LibraryViewModel(
}
}
fun clearSearchResult() {
viewModelScope.launch {
searchResults.postValue(emptyList())
}
}
fun artist(artistId: Long): LiveData<Artist> = liveData {
emit(repository.artistById(artistId))
}
@ -296,6 +280,16 @@ class LibraryViewModel(
fun fetchContributors(): LiveData<List<Contributor>> = liveData {
emit(repository.contributor())
}
fun observableHistorySongs() = repository.observableHistorySongs()
fun favorites() = repository.favorites()
fun clearSearchResult() {
viewModelScope.launch {
searchResults.postValue(emptyList())
}
}
}
enum class ReloadType {

View file

@ -30,7 +30,6 @@ import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.extensions.applyColor
import code.name.monkey.retromusic.extensions.applyOutlineColor
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.AlbumGlideRequest
import code.name.monkey.retromusic.glide.ArtistGlideRequest
@ -57,7 +56,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
@ -69,7 +67,6 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
private val detailsViewModel by viewModel<AlbumDetailsViewModel> {
parametersOf(arguments.extraAlbumId)
}
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private lateinit var simpleSongAdapter: SimpleSongAdapter
private lateinit var album: Album

View file

@ -26,7 +26,6 @@ import code.name.monkey.retromusic.extensions.applyColor
import code.name.monkey.retromusic.extensions.applyOutlineColor
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.albums.AlbumClickListener
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.ArtistGlideRequest
@ -47,7 +46,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
@ -59,7 +57,6 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
private val detailsViewModel: ArtistDetailsViewModel by viewModel {
parametersOf(arguments.extraArtistId)
}
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private lateinit var artist: Artist
private lateinit var songAdapter: SimpleSongAdapter
private lateinit var albumAdapter: HorizontalAlbumAdapter

View file

@ -8,8 +8,11 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.fragments.LibraryViewModel
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
abstract class AbsMainActivityFragment(@LayoutRes layout: Int) : AbsMusicServiceFragment(layout) {
val libraryViewModel: LibraryViewModel by sharedViewModel()
val mainActivity: MainActivity
get() = activity as MainActivity

View file

@ -27,7 +27,6 @@ import code.name.monkey.retromusic.db.toSongEntity
import code.name.monkey.retromusic.dialogs.*
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -43,14 +42,12 @@ import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.io.FileNotFoundException
abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragment(layout),
Toolbar.OnMenuItemClickListener, IPaletteColorHolder, PlayerAlbumCoverFragment.Callbacks {
private var playerAlbumCoverFragment: PlayerAlbumCoverFragment? = null
protected val libraryViewModel by sharedViewModel<LibraryViewModel>()
override fun onMenuItemClick(
item: MenuItem

View file

@ -13,7 +13,6 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.state.NowPlayingPanelState
import code.name.monkey.retromusic.util.DensityUtil
@ -23,15 +22,12 @@ import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.fragment_main_recycler.*
import me.zhanghai.android.fastscroll.FastScroller
import me.zhanghai.android.fastscroll.FastScrollerBuilder
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : RecyclerView.LayoutManager> :
AbsMainActivityFragment(R.layout.fragment_main_recycler),
AppBarLayout.OnOffsetChangedListener {
val libraryViewModel: LibraryViewModel by sharedViewModel()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)

View file

@ -75,6 +75,7 @@ import code.name.monkey.retromusic.misc.DialogAsyncTask;
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.state.NowPlayingPanelState;
import code.name.monkey.retromusic.util.DensityUtil;
import code.name.monkey.retromusic.util.FileUtil;
import code.name.monkey.retromusic.util.PreferenceUtil;
@ -163,6 +164,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
getLibraryViewModel().setPanelState(NowPlayingPanelState.COLLAPSED_WITH);
getMainActivity().setSupportActionBar(toolbar);
getMainActivity().getSupportActionBar().setTitle(null);
setStatusBarColorAuto(view);

View file

@ -12,14 +12,12 @@ import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.SongAdapter
import code.name.monkey.retromusic.extensions.dipToPix
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.helper.menu.GenreMenuHelper
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.state.NowPlayingPanelState
import kotlinx.android.synthetic.main.fragment_playlist_detail.*
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
@ -29,7 +27,6 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
private val detailsViewModel: GenreDetailsViewModel by viewModel {
parametersOf(arguments.extraGenre)
}
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private lateinit var genre: Genre
private lateinit var songAdapter: SongAdapter

View file

@ -37,24 +37,23 @@ import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
import code.name.monkey.retromusic.extensions.findActivityNavController
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
import code.name.monkey.retromusic.glide.UserProfileGlideRequest
import code.name.monkey.retromusic.state.NowPlayingPanelState
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.abs_playlists.*
import kotlinx.android.synthetic.main.fragment_banner_home.*
import kotlinx.android.synthetic.main.home_content.*
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class HomeFragment :
AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home) {
private val libraryViewModel: LibraryViewModel by sharedViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITH)
mainActivity.setSupportActionBar(toolbar)
mainActivity.supportActionBar?.title = null
setStatusBarColorAuto(view)

View file

@ -15,18 +15,14 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.model.CategoryInfo
import code.name.monkey.retromusic.state.NowPlayingPanelState
import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_library.*
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)

View file

@ -5,26 +5,20 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.core.view.isVisible
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter
import code.name.monkey.retromusic.adapter.song.SongAdapter
import code.name.monkey.retromusic.adapter.song.PlaylistSongAdapter
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.toSongs
import code.name.monkey.retromusic.extensions.dipToPix
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.state.NowPlayingPanelState
import code.name.monkey.retromusic.util.PlaylistsUtil
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
import kotlinx.android.synthetic.main.fragment_playlist_detail.*
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
@ -33,12 +27,9 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
private val viewModel: PlaylistDetailsViewModel by viewModel {
parametersOf(arguments.extraPlaylist)
}
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private lateinit var playlist: PlaylistWithSongs
private lateinit var adapter: SongAdapter
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
private lateinit var playlist: PlaylistWithSongs
private lateinit var playlistSongAdapter: PlaylistSongAdapter
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
@ -58,39 +49,19 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
}
private fun setUpRecyclerView() {
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerViewDragDropManager = RecyclerViewDragDropManager()
val animator = RefactoredDefaultItemAnimator()
adapter =
OrderablePlaylistSongAdapter(
playlist.playlistEntity,
requireActivity(),
ArrayList(),
R.layout.item_list,
null,
object : OrderablePlaylistSongAdapter.OnMoveItemListener {
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
if (PlaylistsUtil.moveItem(
requireContext(),
playlist.playlistEntity.playListId,
fromPosition,
toPosition
)
) {
val song = adapter.dataSet.removeAt(fromPosition)
adapter.dataSet.add(toPosition, song)
adapter.notifyItemMoved(fromPosition, toPosition)
}
}
})
wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(adapter)
recyclerView.adapter = wrappedAdapter
recyclerView.itemAnimator = animator
recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
playlistSongAdapter = PlaylistSongAdapter(
playlist.playlistEntity,
requireActivity(),
ArrayList(),
R.layout.item_list,
null,
)
recyclerView.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = playlistSongAdapter
}
playlistSongAdapter.registerAdapterDataObserver(object :
RecyclerView.AdapterDataObserver() {
override fun onChanged() {
super.onChanged()
checkIsEmpty()
@ -100,10 +71,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
val menuRes =/* if (playlist is AbsCustomPlaylist)
R.menu.menu_smart_playlist_detail
else*/ R.menu.menu_playlist_detail
inflater.inflate(menuRes, menu)
inflater.inflate(R.menu.menu_playlist_detail, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -117,32 +85,14 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
private fun checkIsEmpty() {
checkForPadding()
empty.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
emptyText.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
empty.isVisible = playlistSongAdapter.itemCount == 0
emptyText.isVisible = playlistSongAdapter.itemCount == 0
}
override fun onPause() {
if (recyclerViewDragDropManager != null) {
recyclerViewDragDropManager!!.cancelDrag()
}
super.onPause()
}
override fun onDestroy() {
if (recyclerViewDragDropManager != null) {
recyclerViewDragDropManager!!.release()
recyclerViewDragDropManager = null
}
if (recyclerView != null) {
recyclerView!!.itemAnimator = null
recyclerView!!.adapter = null
}
if (wrappedAdapter != null) {
WrapperAdapterUtils.releaseAll(wrappedAdapter)
wrappedAdapter = null
}
recyclerView?.itemAnimator = null
recyclerView?.adapter = null
super.onDestroy()
}
@ -154,7 +104,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
fun songs(songs: List<Song>) {
progressIndicator.hide()
if (songs.isNotEmpty()) {
adapter.swapDataSet(songs)
playlistSongAdapter.swapDataSet(songs)
} else {
showEmptyView()
}

View file

@ -20,12 +20,10 @@ import code.name.monkey.retromusic.adapter.SearchAdapter
import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.dipToPix
import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.state.NowPlayingPanelState
import com.google.android.material.textfield.TextInputEditText
import kotlinx.android.synthetic.main.fragment_search.*
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.util.*
import kotlin.collections.ArrayList
@ -35,7 +33,6 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
const val REQ_CODE_SPEECH_INPUT = 9001
}
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private lateinit var searchAdapter: SearchAdapter
private var query: String? = null

View file

@ -33,7 +33,7 @@ class PlaylistSong(
override val artistName: String,
val playlistId: Long,
val idInPlayList: Long,
override val composer: String,
override val composer: String?,
override val albumArtist: String?
) : Song(
id = id,

View file

@ -16,9 +16,8 @@ package code.name.monkey.retromusic.repository
import android.content.Context
import android.database.Cursor
import android.provider.MediaStore
import android.provider.MediaStore.Audio.AudioColumns
import android.provider.MediaStore.Audio.Playlists.*
import android.provider.MediaStore.Audio.Playlists.Members
import code.name.monkey.retromusic.Constants.IS_MUSIC
import code.name.monkey.retromusic.extensions.getInt
import code.name.monkey.retromusic.extensions.getLong
@ -83,7 +82,7 @@ object PlaylistSongsLoader {
val artistId = cursor.getLong(AudioColumns.ARTIST_ID)
val artistName = cursor.getString(AudioColumns.ARTIST)
val idInPlaylist = cursor.getLong(Members._ID)
val composer = cursor.getString(AudioColumns.COMPOSER)
val composer = cursor.getStringOrNull(AudioColumns.COMPOSER)
val albumArtist = cursor.getStringOrNull("album_artist")
return PlaylistSong(
id,

View file

@ -16,6 +16,7 @@ package code.name.monkey.retromusic.repository
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.db.*
import code.name.monkey.retromusic.model.*
@ -39,7 +40,7 @@ interface Repository {
fun genresFlow(): Flow<Result<List<Genre>>>
fun historySong(): List<HistoryEntity>
fun favorites(): LiveData<List<SongEntity>>
fun observableHistorySongs(): LiveData<List<HistoryEntity>>
fun observableHistorySongs(): LiveData<List<Song>>
fun albumById(albumId: Long): Album
fun playlistSongs(playlistEntity: PlaylistEntity): LiveData<List<SongEntity>>
suspend fun fetchAlbums(): List<Album>
@ -97,6 +98,9 @@ interface Repository {
suspend fun blackListPaths(): List<BlackListStoreEntity>
suspend fun deleteSongs(songs: List<Song>)
suspend fun contributor(): List<Contributor>
suspend fun searchArtists(query: String): List<Artist>
suspend fun searchSongs(query: String): List<Song>
suspend fun searchAlbums(query: String): List<Album>
}
class RealRepository(
@ -115,11 +119,17 @@ class RealRepository(
) : Repository {
override suspend fun deleteSongs(songs: List<Song>) = roomRepository.deleteSongs(songs)
override suspend fun contributor(): List<Contributor> = localDataRepository.contributors()
override suspend fun searchSongs(query: String): List<Song> = songRepository.songs(query)
override suspend fun searchAlbums(query: String): List<Album> = albumRepository.albums(query)
override suspend fun searchArtists(query: String): List<Artist> =
artistRepository.artists(query)
override suspend fun fetchAlbums(): List<Album> = albumRepository.albums()
override suspend fun albumByIdAsync(albumId: Long): Album = albumRepository.album(albumId)
@ -311,8 +321,10 @@ class RealRepository(
override suspend fun blackListPaths(): List<BlackListStoreEntity> =
roomRepository.blackListPaths()
override fun observableHistorySongs(): LiveData<List<HistoryEntity>> =
roomRepository.observableHistorySongs()
override fun observableHistorySongs(): LiveData<List<Song>> =
Transformations.map(roomRepository.observableHistorySongs()) {
it.fromHistoryToSongs()
}
override fun historySong(): List<HistoryEntity> =
roomRepository.historySongs()

View file

@ -22,11 +22,11 @@ import java.util.*
class RealSearchRepository(
private val songRepository: SongRepository,
private val albumRepository: AlbumRepository,
private val artistRepository: RealArtistRepository,
private val artistRepository: ArtistRepository,
private val roomRepository: RoomRepository,
private val genreRepository: GenreRepository,
private val playlistRepository: PlaylistRepository
) {
fun searchAll(context: Context, query: String?): MutableList<Any> {
suspend fun searchAll(context: Context, query: String?): MutableList<Any> {
val results = mutableListOf<Any>()
query?.let { searchString ->
val songs = songRepository.songs(searchString)
@ -53,8 +53,8 @@ class RealSearchRepository(
results.add(context.resources.getString(R.string.genres))
results.addAll(genres)
}
val playlist = playlistRepository.playlists().filter { playlist ->
playlist.name.toLowerCase(Locale.getDefault())
val playlist = roomRepository.playlistWithSongs().filter { playlist ->
playlist.playlistEntity.playlistName.toLowerCase(Locale.getDefault())
.contains(searchString.toLowerCase(Locale.getDefault()))
}
if (playlist.isNotEmpty()) {

View file

@ -11,10 +11,50 @@
~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
~ See the GNU General Public License for more details.
-->
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
app:navigationIcon="@drawable/ic_search"
app:popupTheme="?attr/toolbarPopupTheme"
app:title="@null"
tools:ignore="UnusedAttribute">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/appNameText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold" />
</androidx.appcompat.widget.Toolbar>
<ViewStub
android:id="@+id/cab_stub"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height" />
</FrameLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/container"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
@ -108,4 +148,5 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageContainer" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -11,68 +11,109 @@
~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
~ See the GNU General Public License for more details.
-->
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/toolbar_margin_horizontal"
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
android:overScrollMode="never"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
app:liftOnScroll="true">
<code.name.monkey.retromusic.views.RetroShapeableImageView
android:id="@+id/userImage"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:retroCornerSize="21dp"
tools:srcCompat="@tools:sample/avatars" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="wrap_content"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:ellipsize="end"
android:text="@string/welcome"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toTopOf="@+id/userImage"
tools:text="@tools:sample/lorem" />
app:layout_scrollFlags="scroll|enterAlways">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/titleWelcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:padding="0dp"
android:textAppearance="@style/TextViewHeadline6"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/userImage"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@+id/text"
tools:text="@tools:sample/lorem" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
app:navigationIcon="@drawable/ic_search"
app:popupTheme="?attr/toolbarPopupTheme"
app:title="@null"
tools:ignore="UnusedAttribute">
<include
layout="@layout/home_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleWelcome" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/appNameText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold" />
</androidx.appcompat.widget.Toolbar>
<ViewStub
android:id="@+id/cab_stub"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height" />
</FrameLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/toolbar_margin_horizontal"
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
android:overScrollMode="never"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<code.name.monkey.retromusic.views.RetroShapeableImageView
android:id="@+id/userImage"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:retroCornerSize="21dp"
tools:srcCompat="@tools:sample/avatars" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:ellipsize="end"
android:text="@string/welcome"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toTopOf="@+id/userImage"
tools:text="@tools:sample/lorem" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/titleWelcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:padding="0dp"
android:textAppearance="@style/TextViewHeadline6"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/userImage"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@+id/text"
tools:text="@tools:sample/lorem" />
<include
layout="@layout/home_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleWelcome" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:orientation="vertical"
tools:ignore="UnusedAttribute">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/status_bar" />
</FrameLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="pin"
app:navigationIcon="@drawable/ic_keyboard_backspace_black"
app:title="@string/queue"
app:titleTextAppearance="@style/ToolbarTextAppearanceNormal"
tools:ignore="UnusedAttribute" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/nowPlaying"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="78dp"
android:paddingVertical="22dp"
android:text="@string/now_playing"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="76dp"
android:paddingEnd="8dp"
android:singleLine="true"
android:textAppearance="@style/TextViewSubtitle1"
app:layout_constraintBottom_toTopOf="@id/upNext"
app:layout_constraintEnd_toStartOf="@+id/text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/nowPlaying"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="8dp"
android:singleLine="true"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:textColorSecondary"
app:layout_constraintBottom_toTopOf="@id/upNext"
app:layout_constraintEnd_toStartOf="@+id/text2"
app:layout_constraintStart_toEndOf="@+id/title"
app:layout_constraintTop_toBottomOf="@id/nowPlaying"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="64dp"
android:singleLine="true"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:textColorSecondary"
app:layout_constraintBottom_toTopOf="@id/upNext"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/text"
app:layout_constraintTop_toBottomOf="@id/nowPlaying"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/upNext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="78dp"
android:paddingVertical="22dp"
android:text="@string/up_next"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingBottom="96dp"
android:scrollbars="none"
app:layout_constraintTop_toBottomOf="@id/upNext"
tools:listitem="@layout/item_queue" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.textview.MaterialTextView
android:id="@android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/empty"
android:textAppearance="@style/TextViewNormal"
android:textColor="?colorOnSecondary"
android:visibility="gone"
tools:visibility="visible" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/clearQueue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:text="@string/clear_playing_queue"
android:textAppearance="@style/TextViewHeadline6"
app:icon="@drawable/ic_clear_all" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
android:paddingHorizontal="64dp"
android:background="?rectSelector"
android:clickable="true"
android:focusable="true"
android:minHeight="?attr/listPreferredItemHeight"
android:orientation="horizontal"
tools:ignore="MissingPrefix">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/drag_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|start"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_drag_vertical"
app:tint="?attr/colorControlNormal"
tools:ignore="ContentDescription"
tools:visibility="visible" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/imageTextContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
app:cardCornerRadius="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/drag_view"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:scaleType="centerCrop"
tools:srcCompat="@tools:sample/backgrounds/scenic"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/imageText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:maxLines="1"
android:minHeight="40dp"
android:textAppearance="@style/TextViewSubtitle2"
android:visibility="gone"
tools:text="100"
tools:visibility="visible" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewSubtitle1"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="@id/imageTextContainer"
app:layout_constraintEnd_toStartOf="@id/text"
app:layout_constraintStart_toEndOf="@id/imageTextContainer"
app:layout_constraintTop_toTopOf="@id/imageTextContainer"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="@id/title"
app:layout_constraintEnd_toStartOf="@id/text2"
app:layout_constraintStart_toEndOf="@id/title"
app:layout_constraintTop_toTopOf="@id/title"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="@id/text"
app:layout_constraintEnd_toStartOf="@id/menu"
app:layout_constraintStart_toEndOf="@id/text"
app:layout_constraintTop_toTopOf="@id/text"
tools:text="@tools:sample/full_names" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/menu"
style="@style/OverFlowButton"
android:layout_gravity="center_vertical"
android:layout_weight="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="?attr/colorControlNormal" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2019 Hemanth Savarala.
~
~ Licensed under the GNU General Public License v3
~
~ This is free software: you can redistribute it and/or modify it under
~ the terms of the GNU General Public License as published by
~ the Free Software Foundation either version 3 of the License, or (at your option) any later version.
~
~ This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
~ See the GNU General Public License for more details.
-->
<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"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:background="?attr/rectSelector"
android:minHeight="64dp"
android:padding="14dp"
tools:ignore="UnusedAttribute">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/TextViewSubtitle1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/text2"
app:layout_constraintStart_toEndOf="@+id/title"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/text"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?rectSelector"
android:clickable="true"
android:focusable="true">
<FrameLayout
android:id="@+id/dummy_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
android:background="?rectSelector"
android:clickable="true"
android:focusable="true"
android:minHeight="?attr/listPreferredItemHeight"
android:orientation="horizontal"
tools:ignore="MissingPrefix">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/drag_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|start"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_drag_vertical"
app:tint="?attr/colorControlNormal"
tools:ignore="ContentDescription"
tools:visibility="visible" />
<FrameLayout
android:id="@+id/imageContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
app:cardCornerRadius="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/drag_view"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/imageText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:maxLines="1"
android:minWidth="36dp"
android:minHeight="40dp"
android:textAppearance="@style/TextViewSubtitle1"
android:visibility="gone"
tools:text="100"
tools:visibility="visible" />
</FrameLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="6dp"
android:textAppearance="@style/TextViewSubtitle1"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="@id/imageContainer"
app:layout_constraintEnd_toStartOf="@id/text"
app:layout_constraintStart_toEndOf="@id/imageContainer"
app:layout_constraintTop_toTopOf="@id/imageContainer"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="@id/title"
app:layout_constraintEnd_toStartOf="@id/text2"
app:layout_constraintStart_toEndOf="@id/title"
app:layout_constraintTop_toTopOf="@id/title"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="@id/text"
app:layout_constraintEnd_toStartOf="@id/menu"
app:layout_constraintStart_toEndOf="@id/text"
app:layout_constraintTop_toTopOf="@id/text"
tools:text="@tools:sample/full_names" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/menu"
style="@style/OverFlowButton"
android:layout_gravity="center_vertical"
android:layout_weight="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="?attr/colorControlNormal" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</FrameLayout>

View file

@ -37,15 +37,79 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingBottom="96dp"
android:scrollbars="none"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/nowPlaying"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="12dp"
android:text="@string/now_playing"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:paddingStart="72dp"
android:paddingEnd="16dp"
android:textAppearance="@style/TextViewSubtitle1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/nowPlaying"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:paddingStart="72dp"
android:paddingEnd="16dp"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:textColorSecondary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/upNext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="12dp"
android:text="@string/up_next"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingBottom="96dp"
android:scrollbars="none"
app:layout_constraintTop_toBottomOf="@id/upNext" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.textview.MaterialTextView
android:id="@android:id/empty"
@ -68,6 +132,5 @@
android:textAppearance="@style/TextViewHeadline6"
app:icon="@drawable/ic_clear_all" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
@ -20,85 +20,91 @@
android:layout_height="match_parent"
android:layout_gravity="center_vertical|start"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_drag_vertical"
app:tint="?attr/colorControlNormal"
tools:ignore="ContentDescription" />
tools:ignore="ContentDescription"
tools:visibility="visible" />
<FrameLayout
android:id="@+id/imageContainer"
<com.google.android.material.card.MaterialCardView
android:id="@+id/imageTextContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0"
android:paddingStart="16dp"
android:paddingEnd="0dp">
<com.google.android.material.card.MaterialCardView
android:id="@+id/imageTextContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
app:cardCornerRadius="6dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:scaleType="centerCrop"
tools:srcCompat="@tools:sample/backgrounds/scenic" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/imageText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:maxLines="1"
android:minHeight="40dp"
android:textAppearance="@style/TextViewSubtitle2"
android:visibility="gone"
tools:text="100"
tools:visibility="visible" />
</com.google.android.material.card.MaterialCardView>
</FrameLayout>
<LinearLayout
android:id="@+id/title_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1.0"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp">
android:layout_marginStart="16dp"
app:cardCornerRadius="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/drag_view"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:scaleType="centerCrop"
tools:srcCompat="@tools:sample/backgrounds/scenic"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:id="@+id/imageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:layout_height="match_parent"
android:gravity="center"
android:maxLines="1"
android:textAppearance="@style/TextViewSubtitle1"
android:textColor="?android:attr/textColorPrimary"
tools:text="@tools:sample/full_names" />
android:minHeight="40dp"
android:textAppearance="@style/TextViewSubtitle2"
android:visibility="gone"
tools:text="100"
tools:visibility="visible" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:attr/textColorSecondary"
tools:text="@tools:sample/full_names" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewSubtitle1"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toTopOf="@+id/text"
app:layout_constraintEnd_toStartOf="@id/menu"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/imageTextContainer"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/menu"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/imageTextContainer"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="@tools:sample/full_names" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/menu"
style="@style/OverFlowButton"
android:layout_gravity="center_vertical"
android:layout_weight="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="?attr/colorControlNormal" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -32,7 +32,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/first_names" />
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
@ -44,7 +44,6 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="@tools:sample/first_names" />
tools:text="@tools:sample/full_names" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -13,11 +13,16 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="64dp"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
android:background="?rectSelector"
android:clickable="true"
android:focusable="true"
android:minHeight="?attr/listPreferredItemHeight"
android:orientation="horizontal"
tools:ignore="MissingPrefix">
@ -26,71 +31,86 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|start"
android:padding="8dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_drag_vertical"
app:tint="?attr/colorControlNormal"
tools:ignore="ContentDescription"
tools:visibility="visible" />
<FrameLayout
android:id="@+id/imageContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0">
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
app:cardCornerRadius="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/drag_view"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/imageText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:maxLines="1"
android:minWidth="36dp"
android:minHeight="40dp"
android:textAppearance="@style/TextViewSubtitle1"
android:visibility="gone"
tools:text="1"
tools:text="100"
tools:visibility="visible" />
</FrameLayout>
<LinearLayout
android:id="@+id/title_container"
android:layout_width="match_parent"
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1.0"
android:orientation="vertical">
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewSubtitle1"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toTopOf="@+id/text"
app:layout_constraintEnd_toStartOf="@id/menu"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/imageContainer"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextViewSubtitle1"
android:textSize="16sp"
tools:text="Song name" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
tools:text="Song details" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="16dp"
android:textAppearance="@style/TextViewBody2"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/menu"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/imageContainer"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="@tools:sample/full_names" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/menu"
style="@style/OverFlowButton"
android:layout_gravity="center_vertical"
android:layout_weight="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="?attr/colorControlNormal" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</FrameLayout>

View file

@ -6,7 +6,8 @@
android:layout_height="wrap_content"
android:layout_gravity="start"
android:gravity="start"
android:paddingHorizontal="16dp"
android:layout_marginStart="@dimen/toolbar_margin_horizontal"
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
android:paddingVertical="12dp"
android:textAppearance="@style/TextViewOverline"
android:textStyle="bold"

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -370,7 +370,7 @@
<string name="profile">Profile</string>
<string name="purchase">Purchase</string>
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>
<string name="rate_on_google_play_summary">Love this app? Let us know in the Google Play Store how we can make it even better</string>
<string name="recent_albums">Recent albums</string>

View file

@ -604,7 +604,7 @@
<string name="purchase_summary">*Think before buying, don\'t ask for refund.</string>
<string name="queue">Queue</string>
<string name="queue">Playing Queue</string>
<string name="rate_app">Rate the app</string>