Visual changes to Search
parent
fb603bc0c5
commit
4054d89f46
|
@ -19,6 +19,7 @@ import androidx.lifecycle.*
|
|||
import code.name.monkey.retromusic.*
|
||||
import code.name.monkey.retromusic.db.*
|
||||
import code.name.monkey.retromusic.fragments.ReloadType.*
|
||||
import code.name.monkey.retromusic.fragments.search.Filter
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
|
||||
import code.name.monkey.retromusic.model.*
|
||||
|
@ -139,9 +140,9 @@ class LibraryViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun search(query: String?, filters: List<Boolean>) {
|
||||
fun search(query: String?, filter: Filter) {
|
||||
viewModelScope.launch(IO) {
|
||||
val result = repository.search(query, filters)
|
||||
val result = repository.search(query, filter)
|
||||
searchResults.postValue(result)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import android.text.TextWatcher
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.CompoundButton
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.core.view.*
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -36,14 +36,17 @@ import code.name.monkey.retromusic.adapter.SearchAdapter
|
|||
import code.name.monkey.retromusic.databinding.FragmentSearchBinding
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.views.addAlpha
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWatcher,
|
||||
CompoundButton.OnCheckedChangeListener {
|
||||
ChipGroup.OnCheckedChangeListener {
|
||||
companion object {
|
||||
const val QUERY = "query"
|
||||
const val REQ_CODE_SPEECH_INPUT = 9001
|
||||
|
@ -96,27 +99,22 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
|
||||
private fun setupChips() {
|
||||
val chips = binding.searchFilterGroup.children.map { it as Chip }
|
||||
val states = arrayOf(
|
||||
intArrayOf(-android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_checked)
|
||||
)
|
||||
if (!PreferenceUtil.materialYou) {
|
||||
val states = arrayOf(
|
||||
intArrayOf(-android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_checked)
|
||||
)
|
||||
|
||||
val colors = intArrayOf(
|
||||
android.R.color.transparent,
|
||||
ThemeStore.accentColor(requireContext())
|
||||
)
|
||||
val colors = intArrayOf(
|
||||
android.R.color.transparent,
|
||||
ThemeStore.accentColor(requireContext()).addAlpha(0.5F)
|
||||
)
|
||||
|
||||
chips.forEach {
|
||||
it.chipBackgroundColor = ColorStateList(states, colors)
|
||||
it.chipIconTint = ColorStateList.valueOf(ThemeStore.textColorPrimary(requireContext()))
|
||||
it.chipStrokeColor =
|
||||
ColorStateList.valueOf(ThemeStore.textColorSecondary(requireContext()))
|
||||
.withAlpha(30)
|
||||
it.closeIconTint =
|
||||
ColorStateList.valueOf(ThemeStore.textColorPrimaryInverse(requireContext()))
|
||||
it.chipStrokeWidth = 2F
|
||||
it.setOnCheckedChangeListener(this)
|
||||
chips.forEach {
|
||||
it.chipBackgroundColor = ColorStateList(states, colors)
|
||||
}
|
||||
}
|
||||
binding.searchFilterGroup.setOnCheckedChangeListener(this)
|
||||
}
|
||||
|
||||
private fun showData(data: List<Any>) {
|
||||
|
@ -168,13 +166,18 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
TransitionManager.beginDelayedTransition(binding.appBarLayout)
|
||||
binding.voiceSearch.isGone = query.isNotEmpty()
|
||||
binding.clearText.isVisible = query.isNotEmpty()
|
||||
val filters = getFilters()
|
||||
libraryViewModel.search(query, filters)
|
||||
val filter = getFilter()
|
||||
libraryViewModel.search(query, filter)
|
||||
}
|
||||
|
||||
private fun getFilters(): List<Boolean> {
|
||||
return binding.searchFilterGroup.children.toList().map {
|
||||
(it as Chip).isChecked
|
||||
private fun getFilter(): Filter {
|
||||
return when (binding.searchFilterGroup.checkedChipId) {
|
||||
R.id.chip_audio -> Filter.SONGS
|
||||
R.id.chip_artists -> Filter.ARTISTS
|
||||
R.id.chip_albums -> Filter.ALBUMS
|
||||
R.id.chip_album_artists -> Filter.ALBUM_ARTISTS
|
||||
R.id.chip_genres -> Filter.GENRES
|
||||
else -> Filter.NO_FILTER
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,28 +224,20 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
|
||||
val checkedChip = (buttonView as Chip)
|
||||
checkedChip.isCloseIconVisible = isChecked
|
||||
if (isChecked) {
|
||||
val color = ThemeStore.textColorPrimaryInverse(requireContext())
|
||||
checkedChip.apply {
|
||||
setTextColor(color)
|
||||
chipIconTint = ColorStateList.valueOf(color)
|
||||
chipStrokeWidth = 0F
|
||||
}
|
||||
} else {
|
||||
val color = ThemeStore.textColorPrimary(requireContext())
|
||||
checkedChip.apply {
|
||||
setTextColor(color)
|
||||
chipIconTint = ColorStateList.valueOf(color)
|
||||
chipStrokeWidth = 2F
|
||||
}
|
||||
}
|
||||
override fun onCheckedChanged(group: ChipGroup?, @IdRes checkedId: Int) {
|
||||
search(binding.searchView.text.toString())
|
||||
}
|
||||
}
|
||||
|
||||
enum class Filter {
|
||||
SONGS,
|
||||
ARTISTS,
|
||||
ALBUMS,
|
||||
ALBUM_ARTISTS,
|
||||
GENRES,
|
||||
NO_FILTER
|
||||
}
|
||||
|
||||
fun TextInputEditText.clearText() {
|
||||
text = null
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import androidx.lifecycle.LiveData
|
|||
import androidx.lifecycle.Transformations
|
||||
import code.name.monkey.retromusic.*
|
||||
import code.name.monkey.retromusic.db.*
|
||||
import code.name.monkey.retromusic.fragments.search.Filter
|
||||
import code.name.monkey.retromusic.model.*
|
||||
import code.name.monkey.retromusic.model.smartplaylist.NotPlayedPlaylist
|
||||
import code.name.monkey.retromusic.network.LastFMService
|
||||
|
@ -51,7 +52,7 @@ interface Repository {
|
|||
suspend fun albumArtists(): List<Artist>
|
||||
suspend fun fetchLegacyPlaylist(): List<Playlist>
|
||||
suspend fun fetchGenres(): List<Genre>
|
||||
suspend fun search(query: String?, filters: List<Boolean>): MutableList<Any>
|
||||
suspend fun search(query: String?, filter: Filter): MutableList<Any>
|
||||
suspend fun getPlaylistSongs(playlist: Playlist): List<Song>
|
||||
suspend fun getGenre(genreId: Long): List<Song>
|
||||
suspend fun artistInfo(name: String, lang: String?, cache: String?): Result<LastFmArtist>
|
||||
|
@ -163,8 +164,8 @@ class RealRepository(
|
|||
|
||||
override suspend fun allSongs(): List<Song> = songRepository.songs()
|
||||
|
||||
override suspend fun search(query: String?, filters: List<Boolean>): MutableList<Any> =
|
||||
searchRepository.searchAll(context, query, filters)
|
||||
override suspend fun search(query: String?, filter: Filter): MutableList<Any> =
|
||||
searchRepository.searchAll(context, query, filter)
|
||||
|
||||
override suspend fun getPlaylistSongs(playlist: Playlist): List<Song> =
|
||||
if (playlist is AbsCustomPlaylist) {
|
||||
|
|
|
@ -16,6 +16,7 @@ package code.name.monkey.retromusic.repository
|
|||
|
||||
import android.content.Context
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.fragments.search.Filter
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
|
@ -28,11 +29,11 @@ class RealSearchRepository(
|
|||
private val roomRepository: RoomRepository,
|
||||
private val genreRepository: GenreRepository,
|
||||
) {
|
||||
fun searchAll(context: Context, query: String?, filters: List<Boolean>): MutableList<Any> {
|
||||
fun searchAll(context: Context, query: String?, filter: Filter): MutableList<Any> {
|
||||
val results = mutableListOf<Any>()
|
||||
query?.let { searchString ->
|
||||
val isAll = !filters.contains(true)
|
||||
val songs: List<Song> = if (filters[0] || isAll) {
|
||||
if (query.isNullOrEmpty()) return results
|
||||
query.let { searchString ->
|
||||
val songs: List<Song> = if (filter == Filter.SONGS || filter == Filter.NO_FILTER) {
|
||||
songRepository.songs(searchString)
|
||||
} else {
|
||||
emptyList()
|
||||
|
@ -42,16 +43,17 @@ class RealSearchRepository(
|
|||
results.add(context.resources.getString(R.string.songs))
|
||||
results.addAll(songs)
|
||||
}
|
||||
val artists: List<Artist> = if (filters[1] || isAll) {
|
||||
artistRepository.artists(searchString)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
val artists: List<Artist> =
|
||||
if (filter == Filter.ARTISTS || filter == Filter.NO_FILTER) {
|
||||
artistRepository.artists(searchString)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
if (artists.isNotEmpty()) {
|
||||
results.add(context.resources.getString(R.string.artists))
|
||||
results.addAll(artists)
|
||||
}
|
||||
val albums: List<Album> = if (filters[2] || isAll) {
|
||||
val albums: List<Album> = if (filter == Filter.ALBUMS || filter == Filter.NO_FILTER) {
|
||||
albumRepository.albums(searchString)
|
||||
} else {
|
||||
emptyList()
|
||||
|
@ -60,16 +62,17 @@ class RealSearchRepository(
|
|||
results.add(context.resources.getString(R.string.albums))
|
||||
results.addAll(albums)
|
||||
}
|
||||
val albumArtists: List<Artist> = if (filters[3] || isAll) {
|
||||
artistRepository.albumArtists(searchString)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
val albumArtists: List<Artist> =
|
||||
if (filter == Filter.ALBUM_ARTISTS || filter == Filter.NO_FILTER) {
|
||||
artistRepository.albumArtists(searchString)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
if (albumArtists.isNotEmpty()) {
|
||||
results.add(context.resources.getString(R.string.album_artist))
|
||||
results.addAll(albumArtists)
|
||||
}
|
||||
val genres: List<Genre> = if (filters[4] || isAll) {
|
||||
val genres: List<Genre> = if (filter == Filter.GENRES || filter == Filter.NO_FILTER) {
|
||||
genreRepository.genres().filter { genre ->
|
||||
genre.name.lowercase()
|
||||
.contains(searchString.lowercase())
|
||||
|
@ -82,13 +85,13 @@ class RealSearchRepository(
|
|||
results.addAll(genres)
|
||||
}
|
||||
/* val playlist = roomRepository.playlists().filter { playlist ->
|
||||
playlist.playlistName.toLowerCase(Locale.getDefault())
|
||||
.contains(searchString.toLowerCase(Locale.getDefault()))
|
||||
}
|
||||
if (playlist.isNotEmpty()) {
|
||||
results.add(context.getString(R.string.playlists))
|
||||
results.addAll(playlist)
|
||||
}*/
|
||||
playlist.playlistName.toLowerCase(Locale.getDefault())
|
||||
.contains(searchString.toLowerCase(Locale.getDefault()))
|
||||
}
|
||||
if (playlist.isNotEmpty()) {
|
||||
results.add(context.getString(R.string.playlists))
|
||||
results.addAll(playlist)
|
||||
}*/
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
|
|
@ -88,89 +88,43 @@
|
|||
android:id="@+id/searchFilterGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:singleLine="true">
|
||||
app:singleLine="true"
|
||||
app:singleSelection="true">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_audio"
|
||||
style="@style/Widget.MaterialComponents.Chip.Filter"
|
||||
style="@style/SearchChipStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/songs"
|
||||
android:textSize="16sp"
|
||||
app:checkedIconEnabled="false"
|
||||
app:chipEndPadding="10dp"
|
||||
app:chipIcon="@drawable/ic_audiotrack"
|
||||
app:chipIconEnabled="true"
|
||||
app:chipMinHeight="40dp"
|
||||
app:chipStartPadding="10dp"
|
||||
app:iconEndPadding="5dp" />
|
||||
|
||||
android:text="@string/songs" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_artists"
|
||||
style="@style/Widget.MaterialComponents.Chip.Filter"
|
||||
style="@style/SearchChipStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/artists"
|
||||
android:textSize="16sp"
|
||||
app:checkedIconEnabled="false"
|
||||
app:chipEndPadding="10dp"
|
||||
app:chipIcon="@drawable/ic_artist"
|
||||
app:chipIconEnabled="true"
|
||||
app:chipMinHeight="40dp"
|
||||
app:chipStartPadding="10dp"
|
||||
app:iconEndPadding="5dp" />
|
||||
android:text="@string/artists" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_albums"
|
||||
style="@style/Widget.MaterialComponents.Chip.Filter"
|
||||
style="@style/SearchChipStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/albums"
|
||||
android:textSize="16sp"
|
||||
app:checkedIconEnabled="false"
|
||||
app:chipEndPadding="10dp"
|
||||
app:chipIcon="@drawable/ic_album"
|
||||
app:chipIconEnabled="true"
|
||||
app:chipMinHeight="40dp"
|
||||
app:chipStartPadding="10dp"
|
||||
app:iconEndPadding="5dp" />
|
||||
android:text="@string/albums" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_album_artists"
|
||||
style="@style/Widget.MaterialComponents.Chip.Filter"
|
||||
style="@style/SearchChipStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/album_artist"
|
||||
android:textSize="16sp"
|
||||
app:checkedIconEnabled="false"
|
||||
app:chipEndPadding="10dp"
|
||||
app:chipIcon="@drawable/ic_album_artist"
|
||||
app:chipIconEnabled="true"
|
||||
app:chipMinHeight="40dp"
|
||||
app:chipStartPadding="10dp"
|
||||
app:iconEndPadding="5dp" />
|
||||
|
||||
android:text="@string/album_artist" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_genres"
|
||||
style="@style/Widget.MaterialComponents.Chip.Filter"
|
||||
style="@style/SearchChipStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/genres"
|
||||
android:textSize="16sp"
|
||||
app:checkedIconEnabled="false"
|
||||
app:chipEndPadding="10dp"
|
||||
app:chipIcon="@drawable/ic_guitar"
|
||||
app:chipIconEnabled="true"
|
||||
app:chipMinHeight="40dp"
|
||||
app:chipStartPadding="10dp"
|
||||
app:iconEndPadding="5dp" />
|
||||
android:text="@string/genres" />
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
|
|
@ -212,6 +212,16 @@
|
|||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">5%</item>
|
||||
</style>
|
||||
|
||||
<style name="SearchChipStyle" parent="Widget.Material3.Chip.Filter">
|
||||
<item name="android:checked">false</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="checkedIconEnabled">true</item>
|
||||
<item name="chipEndPadding">10dp</item>
|
||||
<item name="chipIconEnabled">true</item>
|
||||
<item name="chipMinHeight">40dp</item>
|
||||
<item name="chipStartPadding">10dp</item>
|
||||
</style>
|
||||
<!--Bottom Sheet Dialog Style-->
|
||||
<style name="BottomSheetDialogStyle" parent="Theme.Design.BottomSheetDialog">
|
||||
<item name="android:windowIsFloating">false</item>
|
||||
|
|
Loading…
Reference in New Issue