Skip to content

Commit

Permalink
Allow searching artists and albums (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
chvp authored Jul 25, 2021
1 parent 4f1d68c commit 2f42199
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 59 deletions.
32 changes: 31 additions & 1 deletion app/src/main/java/me/vanpetegem/accentor/ui/albums/AlbumGrid.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,46 @@
package me.vanpetegem.accentor.ui.albums

import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.ScaffoldState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import me.vanpetegem.accentor.R
import me.vanpetegem.accentor.ui.main.BaseToolbar
import me.vanpetegem.accentor.ui.main.SearchToolbar
import me.vanpetegem.accentor.ui.util.FastScrollableGrid

@Composable
fun AlbumGrid(navController: NavController, albumsViewModel: AlbumsViewModel = hiltViewModel()) {
val albums by albumsViewModel.allAlbums.observeAsState()
val albums by albumsViewModel.filteredAlbums.observeAsState()
if (albums != null) {
FastScrollableGrid(albums!!, { it.firstCharacter().uppercase() }) { album -> AlbumCard(album, navController) }
}
}

@Composable
fun AlbumToolbar(scaffoldState: ScaffoldState, albumsViewModel: AlbumsViewModel = hiltViewModel()) {
val searching by albumsViewModel.searching.observeAsState()
if (searching ?: false) {
val query by albumsViewModel.query.observeAsState()
SearchToolbar(query ?: "", { albumsViewModel.setQuery(it) }) {
albumsViewModel.setSearching(false)
albumsViewModel.setQuery("")
}
} else {
BaseToolbar(
scaffoldState,
extraActions = {
IconButton(onClick = { albumsViewModel.setSearching(true) }) {
Icon(Icons.Filled.Search, contentDescription = stringResource(R.string.search))
}
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ package me.vanpetegem.accentor.ui.albums
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations.map
import androidx.lifecycle.Transformations.switchMap
import dagger.hilt.android.lifecycle.HiltViewModel
import java.text.Normalizer
import javax.inject.Inject
import me.vanpetegem.accentor.data.albums.Album
import me.vanpetegem.accentor.data.albums.AlbumRepository
Expand All @@ -14,4 +18,23 @@ class AlbumsViewModel @Inject constructor(
private val albumRepository: AlbumRepository,
) : AndroidViewModel(application) {
val allAlbums: LiveData<List<Album>> = albumRepository.allAlbums

private val _searching = MutableLiveData<Boolean>(false)
val searching: LiveData<Boolean> = _searching

private val _query = MutableLiveData<String>("")
val query: LiveData<String> = _query

val filteredAlbums: LiveData<List<Album>> = switchMap(allAlbums) { albums ->
map(query) { query ->
if (query.equals("")) {
albums
} else {
albums.filter { a -> a.normalizedTitle.contains(Normalizer.normalize(query, Normalizer.Form.NFKD), ignoreCase = true) }
}
}
}

fun setSearching(value: Boolean) { _searching.value = value }
fun setQuery(value: String) { _query.value = value }
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,46 @@
package me.vanpetegem.accentor.ui.artists

import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.ScaffoldState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import me.vanpetegem.accentor.R
import me.vanpetegem.accentor.ui.main.BaseToolbar
import me.vanpetegem.accentor.ui.main.SearchToolbar
import me.vanpetegem.accentor.ui.util.FastScrollableGrid

@Composable
fun ArtistGrid(navController: NavController, artistsViewModel: ArtistsViewModel = hiltViewModel()) {
val artists by artistsViewModel.allArtists.observeAsState()
val artists by artistsViewModel.filteredArtists.observeAsState()
if (artists != null) {
FastScrollableGrid(artists!!, { it.firstCharacter().uppercase() }) { artist -> ArtistCard(navController, artist) }
}
}

@Composable
fun ArtistToolbar(scaffoldState: ScaffoldState, artistsViewModel: ArtistsViewModel = hiltViewModel()) {
val searching by artistsViewModel.searching.observeAsState()
if (searching ?: false) {
val query by artistsViewModel.query.observeAsState()
SearchToolbar(query ?: "", { artistsViewModel.setQuery(it) }) {
artistsViewModel.setSearching(false)
artistsViewModel.setQuery("")
}
} else {
BaseToolbar(
scaffoldState,
extraActions = {
IconButton(onClick = { artistsViewModel.setSearching(true) }) {
Icon(Icons.Filled.Search, contentDescription = stringResource(R.string.search))
}
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ package me.vanpetegem.accentor.ui.artists
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations.map
import androidx.lifecycle.Transformations.switchMap
import dagger.hilt.android.lifecycle.HiltViewModel
import java.text.Normalizer
import javax.inject.Inject
import me.vanpetegem.accentor.data.artists.Artist
import me.vanpetegem.accentor.data.artists.ArtistRepository
Expand All @@ -14,4 +18,23 @@ class ArtistsViewModel @Inject constructor(
private val artistRepository: ArtistRepository,
) : AndroidViewModel(application) {
val allArtists: LiveData<List<Artist>> = artistRepository.allArtists

private val _searching = MutableLiveData<Boolean>(false)
val searching: LiveData<Boolean> = _searching

private val _query = MutableLiveData<String>("")
val query: LiveData<String> = _query

val filteredArtists: LiveData<List<Artist>> = switchMap(allArtists) { artists ->
map(query) { query ->
if (query.equals("")) {
artists
} else {
artists.filter { a -> a.normalizedName.contains(Normalizer.normalize(query, Normalizer.Form.NFKD), ignoreCase = true) }
}
}
}

fun setSearching(value: Boolean) { _searching.value = value }
fun setQuery(value: String) { _query.value = value }
}
Loading

0 comments on commit 2f42199

Please sign in to comment.