2021-07-12 10:14:26 +02:00
|
|
|
package audio.funkwhale.ffa.activities
|
2019-08-19 16:50:33 +02:00
|
|
|
|
|
|
|
import android.os.Bundle
|
|
|
|
import android.view.View
|
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
2021-09-10 13:36:28 +02:00
|
|
|
import androidx.appcompat.widget.SearchView
|
2020-09-04 16:56:31 +02:00
|
|
|
import androidx.lifecycle.Lifecycle
|
2020-06-25 01:26:15 +02:00
|
|
|
import androidx.lifecycle.lifecycleScope
|
2019-08-19 16:50:33 +02:00
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
2021-09-10 13:36:28 +02:00
|
|
|
import audio.funkwhale.ffa.adapters.FavoriteListener
|
2021-07-12 10:14:26 +02:00
|
|
|
import audio.funkwhale.ffa.adapters.SearchAdapter
|
2021-07-16 10:03:52 +02:00
|
|
|
import audio.funkwhale.ffa.databinding.ActivitySearchBinding
|
2021-07-12 10:14:26 +02:00
|
|
|
import audio.funkwhale.ffa.fragments.AddToPlaylistDialog
|
|
|
|
import audio.funkwhale.ffa.fragments.AlbumsFragment
|
|
|
|
import audio.funkwhale.ffa.fragments.ArtistsFragment
|
2021-08-22 09:48:33 +02:00
|
|
|
import audio.funkwhale.ffa.model.Album
|
|
|
|
import audio.funkwhale.ffa.model.Artist
|
2021-09-09 09:56:15 +02:00
|
|
|
import audio.funkwhale.ffa.repositories.AlbumsSearchRepository
|
|
|
|
import audio.funkwhale.ffa.repositories.ArtistsSearchRepository
|
|
|
|
import audio.funkwhale.ffa.repositories.FavoritesRepository
|
|
|
|
import audio.funkwhale.ffa.repositories.Repository
|
|
|
|
import audio.funkwhale.ffa.repositories.TracksSearchRepository
|
|
|
|
import audio.funkwhale.ffa.utils.Command
|
|
|
|
import audio.funkwhale.ffa.utils.CommandBus
|
|
|
|
import audio.funkwhale.ffa.utils.Event
|
|
|
|
import audio.funkwhale.ffa.utils.EventBus
|
|
|
|
import audio.funkwhale.ffa.utils.getMetadata
|
|
|
|
import audio.funkwhale.ffa.utils.untilNetwork
|
2020-07-11 17:41:41 +02:00
|
|
|
import com.google.android.exoplayer2.offline.Download
|
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
import kotlinx.coroutines.flow.collect
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
import kotlinx.coroutines.withContext
|
2019-11-16 16:50:28 +01:00
|
|
|
import java.net.URLEncoder
|
2021-09-09 09:56:15 +02:00
|
|
|
import java.util.Locale
|
2019-08-19 16:50:33 +02:00
|
|
|
|
|
|
|
class SearchActivity : AppCompatActivity() {
|
2020-05-29 13:19:28 +02:00
|
|
|
private lateinit var adapter: SearchAdapter
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
private lateinit var artistsRepository: ArtistsSearchRepository
|
|
|
|
private lateinit var albumsRepository: AlbumsSearchRepository
|
|
|
|
private lateinit var tracksRepository: TracksSearchRepository
|
|
|
|
private lateinit var favoritesRepository: FavoritesRepository
|
|
|
|
private lateinit var binding: ActivitySearchBinding
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2020-06-22 21:48:31 +02:00
|
|
|
var done = 0
|
|
|
|
|
2019-08-19 16:50:33 +02:00
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
|
2021-09-17 19:14:18 +02:00
|
|
|
artistsRepository = ArtistsSearchRepository(this@SearchActivity, "")
|
|
|
|
albumsRepository = AlbumsSearchRepository(this@SearchActivity, "")
|
|
|
|
tracksRepository = TracksSearchRepository(this@SearchActivity, "")
|
|
|
|
favoritesRepository = FavoritesRepository(this@SearchActivity)
|
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
binding = ActivitySearchBinding.inflate(layoutInflater)
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-07-16 10:03:52 +02:00
|
|
|
setContentView(binding.root)
|
|
|
|
|
|
|
|
binding.search.requestFocus()
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onResume() {
|
|
|
|
super.onResume()
|
|
|
|
|
2020-09-04 16:56:31 +02:00
|
|
|
lifecycleScope.launch(Dispatchers.Main) {
|
|
|
|
CommandBus.get().collect { command ->
|
|
|
|
when (command) {
|
|
|
|
is Command.AddToPlaylist -> if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
|
2021-07-16 10:03:52 +02:00
|
|
|
AddToPlaylistDialog.show(
|
|
|
|
layoutInflater,
|
|
|
|
this@SearchActivity,
|
|
|
|
lifecycleScope,
|
|
|
|
command.tracks
|
|
|
|
)
|
2020-09-04 16:56:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-11 17:41:41 +02:00
|
|
|
lifecycleScope.launch(Dispatchers.IO) {
|
|
|
|
EventBus.get().collect { message ->
|
|
|
|
when (message) {
|
|
|
|
is Event.DownloadChanged -> refreshDownloadedTrack(message.download)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-12 09:16:11 +02:00
|
|
|
adapter =
|
|
|
|
SearchAdapter(
|
|
|
|
layoutInflater,
|
|
|
|
this,
|
|
|
|
SearchResultClickListener(),
|
|
|
|
FavoriteListener(favoritesRepository)
|
|
|
|
).also {
|
|
|
|
binding.results.layoutManager = LinearLayoutManager(this)
|
|
|
|
binding.results.adapter = it
|
|
|
|
}
|
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
binding.search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
2020-05-29 10:32:09 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
override fun onQueryTextSubmit(rawQuery: String?): Boolean {
|
|
|
|
binding.search.clearFocus()
|
2020-06-22 21:48:31 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
rawQuery?.let {
|
|
|
|
done = 0
|
2019-11-16 16:50:28 +01:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
val query = URLEncoder.encode(it, "UTF-8")
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
artistsRepository.query = query.lowercase(Locale.ROOT)
|
|
|
|
albumsRepository.query = query.lowercase(Locale.ROOT)
|
|
|
|
tracksRepository.query = query.lowercase(Locale.ROOT)
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
binding.searchSpinner.visibility = View.VISIBLE
|
|
|
|
binding.searchEmpty.visibility = View.GONE
|
|
|
|
binding.searchNoResults.visibility = View.GONE
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
adapter.artists.clear()
|
|
|
|
adapter.albums.clear()
|
|
|
|
adapter.tracks.clear()
|
|
|
|
adapter.notifyDataSetChanged()
|
2020-05-29 13:19:28 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
artistsRepository.fetch(Repository.Origin.Network.origin)
|
|
|
|
.untilNetwork(lifecycleScope) { artists, _, _, _ ->
|
|
|
|
done++
|
2020-05-29 13:19:28 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
adapter.artists.addAll(artists)
|
|
|
|
refresh()
|
|
|
|
}
|
2020-05-29 13:19:28 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
albumsRepository.fetch(Repository.Origin.Network.origin)
|
|
|
|
.untilNetwork(lifecycleScope) { albums, _, _, _ ->
|
|
|
|
done++
|
2020-05-29 13:19:28 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
adapter.albums.addAll(albums)
|
|
|
|
refresh()
|
|
|
|
}
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
tracksRepository.fetch(Repository.Origin.Network.origin)
|
|
|
|
.untilNetwork(lifecycleScope) { tracks, _, _, _ ->
|
|
|
|
done++
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
adapter.tracks.addAll(tracks)
|
|
|
|
refresh()
|
|
|
|
}
|
2021-09-09 09:56:15 +02:00
|
|
|
}
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-09-10 13:36:28 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onQueryTextChange(newText: String?) = true
|
|
|
|
})
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
2019-11-21 22:13:59 +01:00
|
|
|
|
2020-06-22 21:48:31 +02:00
|
|
|
private fun refresh() {
|
|
|
|
adapter.notifyDataSetChanged()
|
|
|
|
|
|
|
|
if (adapter.artists.size + adapter.albums.size + adapter.tracks.size == 0) {
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.searchNoResults.visibility = View.VISIBLE
|
2020-06-22 21:48:31 +02:00
|
|
|
} else {
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.searchNoResults.visibility = View.GONE
|
2020-06-22 21:48:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (done == 3) {
|
2021-07-16 10:03:52 +02:00
|
|
|
binding.searchSpinner.visibility = View.INVISIBLE
|
2020-06-22 21:48:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-11 17:41:41 +02:00
|
|
|
private suspend fun refreshDownloadedTrack(download: Download) {
|
|
|
|
if (download.state == Download.STATE_COMPLETED) {
|
|
|
|
download.getMetadata()?.let { info ->
|
2021-07-16 10:03:52 +02:00
|
|
|
adapter.tracks.withIndex().associate { it.value to it.index }
|
|
|
|
.filter { it.key.id == info.id }.toList().getOrNull(0)?.let { match ->
|
|
|
|
withContext(Dispatchers.Main) {
|
|
|
|
adapter.tracks[match.second].downloaded = true
|
|
|
|
adapter.notifyItemChanged(
|
|
|
|
adapter.getPositionOf(
|
|
|
|
SearchAdapter.ResultType.Track,
|
|
|
|
match.second
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
2020-07-11 17:41:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-30 14:12:04 +02:00
|
|
|
inner class SearchResultClickListener : SearchAdapter.OnSearchResultClickListener {
|
|
|
|
override fun onArtistClick(holder: View?, artist: Artist) {
|
|
|
|
ArtistsFragment.openAlbums(this@SearchActivity, artist)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onAlbumClick(holder: View?, album: Album) {
|
|
|
|
AlbumsFragment.openTracks(this@SearchActivity, album)
|
|
|
|
}
|
|
|
|
}
|
2021-07-02 13:55:49 +02:00
|
|
|
}
|