search: add playlist results
Add playlist results to the search view.
This commit is contained in:
parent
06885ba264
commit
b2e899a211
4 changed files with 43 additions and 19 deletions
|
@ -43,6 +43,7 @@ class SearchAdapter(private val listener: SelectableListListener<Music>) :
|
|||
is Album -> AlbumViewHolder.VIEW_TYPE
|
||||
is Artist -> ArtistViewHolder.VIEW_TYPE
|
||||
is Genre -> GenreViewHolder.VIEW_TYPE
|
||||
is Playlist -> PlaylistViewHolder.VIEW_TYPE
|
||||
is BasicHeader -> BasicHeaderViewHolder.VIEW_TYPE
|
||||
else -> super.getItemViewType(position)
|
||||
}
|
||||
|
@ -53,6 +54,7 @@ class SearchAdapter(private val listener: SelectableListListener<Music>) :
|
|||
AlbumViewHolder.VIEW_TYPE -> AlbumViewHolder.from(parent)
|
||||
ArtistViewHolder.VIEW_TYPE -> ArtistViewHolder.from(parent)
|
||||
GenreViewHolder.VIEW_TYPE -> GenreViewHolder.from(parent)
|
||||
PlaylistViewHolder.VIEW_TYPE -> PlaylistViewHolder.from(parent)
|
||||
BasicHeaderViewHolder.VIEW_TYPE -> BasicHeaderViewHolder.from(parent)
|
||||
else -> error("Invalid item type $viewType")
|
||||
}
|
||||
|
@ -64,6 +66,7 @@ class SearchAdapter(private val listener: SelectableListListener<Music>) :
|
|||
is Album -> (holder as AlbumViewHolder).bind(item, listener)
|
||||
is Artist -> (holder as ArtistViewHolder).bind(item, listener)
|
||||
is Genre -> (holder as GenreViewHolder).bind(item, listener)
|
||||
is Playlist -> (holder as PlaylistViewHolder).bind(item, listener)
|
||||
is BasicHeader -> (holder as BasicHeaderViewHolder).bind(item)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.oxycblt.auxio.music.Album
|
|||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.Genre
|
||||
import org.oxycblt.auxio.music.Music
|
||||
import org.oxycblt.auxio.music.Playlist
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.music.info.Name
|
||||
|
||||
|
@ -33,8 +34,6 @@ import org.oxycblt.auxio.music.info.Name
|
|||
* Implements the fuzzy-ish searching algorithm used in the search view.
|
||||
*
|
||||
* @author Alexander Capehart
|
||||
*
|
||||
* TODO: Add playlists
|
||||
*/
|
||||
interface SearchEngine {
|
||||
/**
|
||||
|
@ -53,12 +52,14 @@ interface SearchEngine {
|
|||
* @param albums A list of [Album]s, null if empty.
|
||||
* @param artists A list of [Artist]s, null if empty.
|
||||
* @param genres A list of [Genre]s, null if empty.
|
||||
* @param playlists A list of [Playlist], null if empty.
|
||||
*/
|
||||
data class Items(
|
||||
val songs: List<Song>?,
|
||||
val albums: List<Album>?,
|
||||
val artists: List<Artist>?,
|
||||
val genres: List<Genre>?
|
||||
val genres: List<Genre>?,
|
||||
val playlists: List<Playlist>?
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -72,7 +73,8 @@ class SearchEngineImpl @Inject constructor(@ApplicationContext private val conte
|
|||
},
|
||||
albums = items.albums?.searchListImpl(query),
|
||||
artists = items.artists?.searchListImpl(query),
|
||||
genres = items.genres?.searchListImpl(query))
|
||||
genres = items.genres?.searchListImpl(query),
|
||||
playlists = items.playlists?.searchListImpl(query))
|
||||
|
||||
/**
|
||||
* Search a given [Music] list.
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.oxycblt.auxio.list.Item
|
|||
import org.oxycblt.auxio.list.Sort
|
||||
import org.oxycblt.auxio.music.*
|
||||
import org.oxycblt.auxio.music.device.DeviceLibrary
|
||||
import org.oxycblt.auxio.music.user.UserLibrary
|
||||
import org.oxycblt.auxio.playback.PlaybackSettings
|
||||
import org.oxycblt.auxio.util.logD
|
||||
|
||||
|
@ -73,7 +74,7 @@ constructor(
|
|||
}
|
||||
|
||||
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
||||
if (changes.deviceLibrary && musicRepository.deviceLibrary != null) {
|
||||
if (changes.deviceLibrary || changes.userLibrary) {
|
||||
search(lastQuery)
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +91,8 @@ constructor(
|
|||
lastQuery = query
|
||||
|
||||
val deviceLibrary = musicRepository.deviceLibrary
|
||||
if (query.isNullOrEmpty() || deviceLibrary == null) {
|
||||
val userLibrary = musicRepository.userLibrary
|
||||
if (query.isNullOrEmpty() || deviceLibrary == null || userLibrary == null) {
|
||||
logD("Search query is not applicable.")
|
||||
_searchResults.value = listOf()
|
||||
return
|
||||
|
@ -101,11 +103,16 @@ constructor(
|
|||
// Searching is time-consuming, so do it in the background.
|
||||
currentSearchJob =
|
||||
viewModelScope.launch {
|
||||
_searchResults.value = searchImpl(deviceLibrary, query).also { yield() }
|
||||
_searchResults.value =
|
||||
searchImpl(deviceLibrary, userLibrary, query).also { yield() }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun searchImpl(deviceLibrary: DeviceLibrary, query: String): List<Item> {
|
||||
private suspend fun searchImpl(
|
||||
deviceLibrary: DeviceLibrary,
|
||||
userLibrary: UserLibrary,
|
||||
query: String
|
||||
): List<Item> {
|
||||
val filterMode = searchSettings.searchFilterMode
|
||||
|
||||
val items =
|
||||
|
@ -115,33 +122,40 @@ constructor(
|
|||
deviceLibrary.songs,
|
||||
deviceLibrary.albums,
|
||||
deviceLibrary.artists,
|
||||
deviceLibrary.genres)
|
||||
deviceLibrary.genres,
|
||||
userLibrary.playlists)
|
||||
} else {
|
||||
SearchEngine.Items(
|
||||
songs = if (filterMode == MusicMode.SONGS) deviceLibrary.songs else null,
|
||||
albums = if (filterMode == MusicMode.ALBUMS) deviceLibrary.albums else null,
|
||||
artists = if (filterMode == MusicMode.ARTISTS) deviceLibrary.artists else null,
|
||||
genres = if (filterMode == MusicMode.GENRES) deviceLibrary.genres else null)
|
||||
genres = if (filterMode == MusicMode.GENRES) deviceLibrary.genres else null,
|
||||
playlists =
|
||||
if (filterMode == MusicMode.PLAYLISTS) userLibrary.playlists else null)
|
||||
}
|
||||
|
||||
val results = searchEngine.search(items, query)
|
||||
|
||||
return buildList {
|
||||
results.artists?.let { artists ->
|
||||
results.artists?.let {
|
||||
add(BasicHeader(R.string.lbl_artists))
|
||||
addAll(SORT.artists(artists))
|
||||
addAll(SORT.artists(it))
|
||||
}
|
||||
results.albums?.let { albums ->
|
||||
results.albums?.let {
|
||||
add(BasicHeader(R.string.lbl_albums))
|
||||
addAll(SORT.albums(albums))
|
||||
addAll(SORT.albums(it))
|
||||
}
|
||||
results.genres?.let { genres ->
|
||||
results.playlists?.let {
|
||||
add(BasicHeader(R.string.lbl_playlists))
|
||||
addAll(SORT.playlists(it))
|
||||
}
|
||||
results.genres?.let {
|
||||
add(BasicHeader(R.string.lbl_genres))
|
||||
addAll(SORT.genres(genres))
|
||||
addAll(SORT.genres(it))
|
||||
}
|
||||
results.songs?.let { songs ->
|
||||
results.songs?.let {
|
||||
add(BasicHeader(R.string.lbl_songs))
|
||||
addAll(SORT.songs(songs))
|
||||
addAll(SORT.songs(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +172,7 @@ constructor(
|
|||
MusicMode.ALBUMS -> R.id.option_filter_albums
|
||||
MusicMode.ARTISTS -> R.id.option_filter_artists
|
||||
MusicMode.GENRES -> R.id.option_filter_genres
|
||||
MusicMode.PLAYLISTS -> R.id.option_filter_all // TODO: Handle
|
||||
MusicMode.PLAYLISTS -> R.id.option_filter_playlists
|
||||
// Null maps to filtering nothing.
|
||||
null -> R.id.option_filter_all
|
||||
}
|
||||
|
@ -175,6 +189,7 @@ constructor(
|
|||
R.id.option_filter_albums -> MusicMode.ALBUMS
|
||||
R.id.option_filter_artists -> MusicMode.ARTISTS
|
||||
R.id.option_filter_genres -> MusicMode.GENRES
|
||||
R.id.option_filter_playlists -> MusicMode.PLAYLISTS
|
||||
// Null maps to filtering nothing.
|
||||
R.id.option_filter_all -> null
|
||||
else -> error("Invalid option ID provided")
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
android:id="@+id/option_filter_genres"
|
||||
android:title="@string/lbl_genres"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/option_filter_playlists"
|
||||
android:title="@string/lbl_playlists"
|
||||
app:showAsAction="never" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
|
|
Loading…
Reference in a new issue