Added playlist search

main
h4h13 2020-01-29 00:05:50 +05:30
parent 7850e0be46
commit f5f789bfb1
6 changed files with 91 additions and 99 deletions

View File

@ -13,10 +13,13 @@ import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.menu.SongMenuHelper import code.name.monkey.retromusic.helper.menu.SongMenuHelper
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@ -36,6 +39,7 @@ class SearchAdapter(
if (dataSet!![position] is Album) return ALBUM if (dataSet!![position] is Album) return ALBUM
if (dataSet!![position] is Artist) return ARTIST if (dataSet!![position] is Artist) return ARTIST
if (dataSet!![position] is Genre) return GENRE if (dataSet!![position] is Genre) return GENRE
if (dataSet!![position] is Playlist) return PLAYLIST
return if (dataSet!![position] is Song) SONG else HEADER return if (dataSet!![position] is Song) SONG else HEADER
} }
@ -76,6 +80,11 @@ class SearchAdapter(
val genre = dataSet?.get(position) as Genre val genre = dataSet?.get(position) as Genre
holder.title?.text = genre.name holder.title?.text = genre.name
} }
PLAYLIST -> {
val playlist = dataSet?.get(position) as Playlist
holder.title?.text = playlist.name
holder.text?.text = MusicUtil.getPlaylistInfoString(activity, getSongs(playlist))
}
else -> { else -> {
holder.title?.text = dataSet?.get(position).toString() holder.title?.text = dataSet?.get(position).toString()
holder.title?.setTextColor(ThemeStore.accentColor(activity)) holder.title?.setTextColor(ThemeStore.accentColor(activity))
@ -83,6 +92,16 @@ class SearchAdapter(
} }
} }
private fun getSongs(playlist: Playlist): java.util.ArrayList<Song> {
val songs = java.util.ArrayList<Song>()
if (playlist is AbsSmartPlaylist) {
songs.addAll(playlist.getSongs(activity))
} else {
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
}
return songs
}
override fun getItemCount(): Int { override fun getItemCount(): Int {
return dataSet!!.size return dataSet!!.size
} }
@ -131,6 +150,9 @@ class SearchAdapter(
GENRE -> { GENRE -> {
NavigationUtil.goToGenre(activity, item as Genre) NavigationUtil.goToGenre(activity, item as Genre)
} }
PLAYLIST -> {
NavigationUtil.goToPlaylistNew(activity, item as Playlist)
}
SONG -> { SONG -> {
val playList = ArrayList<Song>() val playList = ArrayList<Song>()
playList.add(item as Song) playList.add(item as Song)
@ -146,5 +168,6 @@ class SearchAdapter(
private const val ARTIST = 2 private const val ARTIST = 2
private const val SONG = 3 private const val SONG = 3
private const val GENRE = 4 private const val GENRE = 4
private const val PLAYLIST = 5
} }
} }

View File

@ -33,7 +33,7 @@ object GenreLoader {
} }
fun searchGenres(context: Context): ArrayList<Genre> { fun searchGenres(context: Context): ArrayList<Genre> {
return getGenresFromCursorForSearch(context, makeGenreCursor(context)); return getGenresFromCursorForSearch(context, makeGenreCursor(context))
} }
fun getSongs(context: Context, genreId: Int): ArrayList<Song> { fun getSongs(context: Context, genreId: Int): ArrayList<Song> {

View File

@ -20,9 +20,7 @@ import android.provider.BaseColumns
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.MediaStore.Audio.PlaylistsColumns import android.provider.MediaStore.Audio.PlaylistsColumns
import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Playlist
import io.reactivex.Observable import java.util.ArrayList
import java.util.*
/** /**
* Created by hemanths on 16/08/17. * Created by hemanths on 16/08/17.
@ -30,24 +28,8 @@ import java.util.*
object PlaylistLoader { object PlaylistLoader {
private fun getPlaylistFlowable( private fun getPlaylist(
cursor: Cursor? cursor: Cursor?
): Observable<Playlist> {
return Observable.create { e ->
var playlist = Playlist()
if (cursor != null && cursor.moveToFirst()) {
playlist = getPlaylistFromCursorImpl(cursor)
}
cursor?.close()
e.onNext(playlist)
e.onComplete()
}
}
fun getPlaylist(
cursor: Cursor?
): Playlist { ): Playlist {
var playlist = Playlist() var playlist = Playlist()
@ -58,66 +40,25 @@ object PlaylistLoader {
return playlist return playlist
} }
fun getPlaylistFlowable( fun searchPlaylist(context: Context, searchString: String): List<Playlist> {
context: Context, return getAllPlaylists(
playlistName: String makePlaylistCursor(
): Observable<Playlist> { context, PlaylistsColumns.NAME + "=?", arrayOf(searchString)
return getPlaylistFlowable(makePlaylistCursor( )
context, )
PlaylistsColumns.NAME + "=?",
arrayOf(playlistName)
))
} }
fun getPlaylist( fun getPlaylist(
context: Context, context: Context,
playlistName: String playlistName: String
): Playlist { ): Playlist {
return getPlaylist(makePlaylistCursor( return getPlaylist(
makePlaylistCursor(
context, context,
PlaylistsColumns.NAME + "=?", PlaylistsColumns.NAME + "=?",
arrayOf(playlistName) arrayOf(playlistName)
)) )
} )
fun getPlaylistFlowable(
context: Context,
playlistId: Int
): Observable<Playlist> {
return getPlaylistFlowable(makePlaylistCursor(
context,
BaseColumns._ID + "=?",
arrayOf(playlistId.toString())
))
}
fun getAllPlaylistsFlowoable(
context: Context
): Observable<ArrayList<Playlist>> {
return getAllPlaylistsFlowable(makePlaylistCursor(context, null, null))
}
fun getFavoritePlaylistFlowable(context: Context): Observable<ArrayList<Playlist>> {
return getAllPlaylistsFlowable(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
arrayOf(context.getString(code.name.monkey.retromusic.R.string.favorites))))
}
private fun getAllPlaylistsFlowable(cursor: Cursor?): Observable<ArrayList<Playlist>> {
return Observable.create { e ->
val playlists = ArrayList<Playlist>()
if (cursor != null && cursor.moveToFirst()) {
do {
playlists.add(getPlaylistFromCursorImpl(cursor))
} while (cursor.moveToNext())
}
cursor?.close()
e.onNext(playlists)
e.onComplete()
}
} }
fun getAllPlaylists(context: Context): ArrayList<Playlist> { fun getAllPlaylists(context: Context): ArrayList<Playlist> {
@ -125,10 +66,13 @@ object PlaylistLoader {
} }
fun getFavoritePlaylist(context: Context): ArrayList<Playlist> { fun getFavoritePlaylist(context: Context): ArrayList<Playlist> {
return getAllPlaylists(makePlaylistCursor( return getAllPlaylists(
makePlaylistCursor(
context, context,
PlaylistsColumns.NAME + "=?", PlaylistsColumns.NAME + "=?",
arrayOf(context.getString(code.name.monkey.retromusic.R.string.favorites)))) arrayOf(context.getString(code.name.monkey.retromusic.R.string.favorites))
)
)
} }
fun getAllPlaylists(cursor: Cursor?): ArrayList<Playlist> { fun getAllPlaylists(cursor: Cursor?): ArrayList<Playlist> {
@ -153,40 +97,44 @@ object PlaylistLoader {
} }
private fun makePlaylistCursor( private fun makePlaylistCursor(
context: Context, context: Context,
selection: String?, selection: String?,
values: Array<String>? values: Array<String>?
): Cursor? { ): Cursor? {
try { try {
return context.contentResolver.query( return context.contentResolver.query(
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
arrayOf(BaseColumns._ID, /* 0 */ arrayOf(
PlaylistsColumns.NAME), /* 1 */ BaseColumns._ID, /* 0 */
selection, PlaylistsColumns.NAME
values, ), /* 1 */
MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER) selection,
values,
MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER
)
} catch (e: SecurityException) { } catch (e: SecurityException) {
return null return null
} }
} }
fun getPlaylist( fun getPlaylist(
context: Context, context: Context,
playlistId: Int playlistId: Int
): Playlist { ): Playlist {
return getPlaylist(makePlaylistCursor( return getPlaylist(
makePlaylistCursor(
context, context,
BaseColumns._ID + "=?", BaseColumns._ID + "=?",
arrayOf(playlistId.toString()) arrayOf(playlistId.toString())
)) )
)
} }
private fun getPlaylistFromCursorImpl( private fun getPlaylistFromCursorImpl(
cursor: Cursor cursor: Cursor
): Playlist { ): Playlist {
val id = cursor.getInt(0) val id = cursor.getInt(0)
val name = cursor.getString(1) val name = cursor.getString(1)
return Playlist(id, name) return Playlist(id, name)
} }
} }

View File

@ -17,8 +17,7 @@ package code.name.monkey.retromusic.loaders
import android.content.Context import android.content.Context
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Genre
import java.util.* import java.util.Locale
object SearchLoader { object SearchLoader {
fun searchAll(context: Context, query: String?): MutableList<Any> { fun searchAll(context: Context, query: String?): MutableList<Any> {
@ -41,11 +40,24 @@ object SearchLoader {
results.add(context.resources.getString(R.string.albums)) results.add(context.resources.getString(R.string.albums))
results.addAll(albums) results.addAll(albums)
} }
val genres: List<Genre> = GenreLoader.searchGenres(context).filter { genre -> genre.name.toLowerCase(Locale.getDefault()).contains(searchString.toLowerCase(Locale.getDefault())) } val genres: List<Genre> = GenreLoader.searchGenres(context)
.filter { genre ->
genre.name.toLowerCase(Locale.getDefault())
.contains(searchString.toLowerCase(Locale.getDefault()))
}
if (genres.isNotEmpty()) { if (genres.isNotEmpty()) {
results.add(context.resources.getString(R.string.genres)) results.add(context.resources.getString(R.string.genres))
results.addAll(genres) results.addAll(genres)
} }
val playlist = PlaylistLoader.getAllPlaylists(context)
.filter { playlist ->
playlist.name.toLowerCase(Locale.getDefault())
.contains(searchString.toLowerCase(Locale.getDefault()))
}
if (playlist.isNotEmpty()) {
results.add(context.getString(R.string.playlists))
results.addAll(playlist)
}
} }
return results return results
} }

View File

@ -20,7 +20,11 @@ import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import kotlinx.coroutines.* import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -29,6 +33,7 @@ import kotlin.coroutines.CoroutineContext
*/ */
interface SearchView : BaseView { interface SearchView : BaseView {
fun showData(data: MutableList<Any>) fun showData(data: MutableList<Any>)
} }
@ -37,7 +42,7 @@ interface SearchPresenter : Presenter<SearchView> {
fun search(query: String?) fun search(query: String?)
class SearchPresenterImpl @Inject constructor( class SearchPresenterImpl @Inject constructor(
private val repository: Repository private val repository: Repository
) : PresenterImpl<SearchView>(), SearchPresenter, CoroutineScope { ) : PresenterImpl<SearchView>(), SearchPresenter, CoroutineScope {
override val coroutineContext: CoroutineContext override val coroutineContext: CoroutineContext

View File

@ -2,7 +2,11 @@
<com.google.android.material.textview.MaterialTextView xmlns:android="http://schemas.android.com/apk/res/android" <com.google.android.material.textview.MaterialTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/title" android:id="@+id/title"
style="@style/SubTitleTextAppearance" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start" android:layout_gravity="start"
android:gravity="start" android:gravity="start"
tools:text="Songs" /> android:padding="16dp"
android:textAppearance="@style/TextViewHeadline5"
android:textStyle="bold"
tools:text="@tools:sample/lorem" />