PlayerAndroid/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt

364 lines
11 KiB
Kotlin
Raw Normal View History

2020-10-06 08:46:04 +00:00
/*
* Copyright (c) 2020 Hemanth Savarla.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*/
2020-05-23 15:09:07 +00:00
package code.name.monkey.retromusic.fragments
import android.animation.ValueAnimator
2020-10-08 19:44:10 +00:00
import android.widget.Toast
2020-10-17 07:58:13 +00:00
import androidx.lifecycle.*
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.db.*
2020-05-23 15:09:07 +00:00
import code.name.monkey.retromusic.fragments.ReloadType.*
2021-09-26 11:39:46 +00:00
import code.name.monkey.retromusic.fragments.search.Filter
2020-08-21 14:19:15 +00:00
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
2020-10-17 07:58:13 +00:00
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.repository.RealRepository
2021-09-24 07:31:53 +00:00
import code.name.monkey.retromusic.util.DensityUtil
2020-09-14 01:42:12 +00:00
import code.name.monkey.retromusic.util.PreferenceUtil
2020-05-23 15:09:07 +00:00
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
2020-07-20 19:05:48 +00:00
class LibraryViewModel(
2020-08-21 14:19:15 +00:00
private val repository: RealRepository
) : ViewModel(), IMusicServiceEventListener {
2020-05-23 15:09:07 +00:00
2020-09-17 17:56:59 +00:00
private val _paletteColor = MutableLiveData<Int>()
private val home = MutableLiveData<List<Home>>()
2020-07-28 19:18:34 +00:00
private val albums = MutableLiveData<List<Album>>()
private val songs = MutableLiveData<List<Song>>()
private val artists = MutableLiveData<List<Artist>>()
2020-09-05 14:03:12 +00:00
private val playlists = MutableLiveData<List<PlaylistWithSongs>>()
2020-09-05 20:13:45 +00:00
private val legacyPlaylists = MutableLiveData<List<Playlist>>()
2020-07-28 19:18:34 +00:00
private val genres = MutableLiveData<List<Genre>>()
private val searchResults = MutableLiveData<List<Any>>()
private val fabMargin = MutableLiveData<Int>(0)
2020-09-17 17:56:59 +00:00
val paletteColor: LiveData<Int> = _paletteColor
init {
loadLibraryContent()
}
2020-09-05 14:03:12 +00:00
private fun loadLibraryContent() = viewModelScope.launch(IO) {
2020-09-09 12:37:25 +00:00
fetchHomeSections()
2020-09-05 14:03:12 +00:00
fetchSongs()
fetchAlbums()
fetchArtists()
fetchGenres()
fetchPlaylists()
2020-05-23 15:09:07 +00:00
}
fun getSearchResult(): LiveData<List<Any>> = searchResults
2020-09-05 14:03:12 +00:00
fun getSongs(): LiveData<List<Song>> {
return songs
2020-05-23 15:09:07 +00:00
}
2020-09-05 14:03:12 +00:00
fun getAlbums(): LiveData<List<Album>> {
return albums
}
fun getArtists(): LiveData<List<Artist>> {
return artists
}
fun getPlaylists(): LiveData<List<PlaylistWithSongs>> {
return playlists
}
2020-09-05 20:13:45 +00:00
fun getLegacyPlaylist(): LiveData<List<Playlist>> {
return legacyPlaylists
}
2020-09-05 14:03:12 +00:00
fun getGenre(): LiveData<List<Genre>> {
return genres
}
2020-05-23 15:09:07 +00:00
2020-09-05 14:03:12 +00:00
fun getHome(): LiveData<List<Home>> {
return home
}
2020-05-23 15:09:07 +00:00
2021-09-24 07:31:53 +00:00
fun getFabMargin(): LiveData<Int> {
return fabMargin
}
2020-09-05 14:03:12 +00:00
private fun fetchSongs() {
viewModelScope.launch(IO) {
songs.postValue(repository.allSongs())
2020-05-23 15:09:07 +00:00
}
2020-09-05 14:03:12 +00:00
}
2020-05-25 22:40:40 +00:00
2020-09-05 14:03:12 +00:00
private fun fetchAlbums() {
viewModelScope.launch(IO) {
albums.postValue(repository.fetchAlbums())
2020-05-23 15:09:07 +00:00
}
2020-09-05 14:03:12 +00:00
}
2020-05-23 15:09:07 +00:00
2020-09-05 14:03:12 +00:00
private fun fetchArtists() {
2020-09-14 01:42:12 +00:00
if (PreferenceUtil.albumArtistsOnly) {
viewModelScope.launch(IO) {
artists.postValue(repository.albumArtists())
}
} else {
viewModelScope.launch(IO) {
artists.postValue(repository.fetchArtists())
}
2020-05-23 15:09:07 +00:00
}
2020-09-05 14:03:12 +00:00
}
private fun fetchPlaylists() {
viewModelScope.launch(IO) {
playlists.postValue(repository.fetchPlaylistWithSongs())
}
2020-09-05 14:03:12 +00:00
}
2020-05-23 15:09:07 +00:00
2020-09-05 20:13:45 +00:00
private fun fetchLegacyPlaylist() {
viewModelScope.launch(IO) {
legacyPlaylists.postValue(repository.fetchLegacyPlaylist())
}
}
2020-09-05 14:03:12 +00:00
private fun fetchGenres() {
viewModelScope.launch(IO) {
genres.postValue(repository.fetchGenres())
2020-05-23 15:09:07 +00:00
}
2020-09-05 14:03:12 +00:00
}
2020-05-23 15:09:07 +00:00
fun fetchHomeSections() {
2020-09-05 14:03:12 +00:00
viewModelScope.launch(IO) {
home.postValue(repository.homeSections())
}
}
2020-08-13 08:24:36 +00:00
2021-09-26 11:39:46 +00:00
fun search(query: String?, filter: Filter) {
2020-10-17 07:58:13 +00:00
viewModelScope.launch(IO) {
2021-09-26 11:39:46 +00:00
val result = repository.search(query, filter)
searchResults.postValue(result)
2020-10-17 07:58:13 +00:00
}
}
2020-05-23 15:09:07 +00:00
fun forceReload(reloadType: ReloadType) = viewModelScope.launch {
when (reloadType) {
2020-09-05 14:03:12 +00:00
Songs -> fetchSongs()
Albums -> fetchAlbums()
Artists -> fetchArtists()
HomeSections -> fetchHomeSections()
Playlists -> fetchPlaylists()
Genres -> fetchGenres()
2020-05-23 15:09:07 +00:00
}
}
2020-07-28 19:18:34 +00:00
fun updateColor(newColor: Int) {
2020-09-17 17:56:59 +00:00
_paletteColor.postValue(newColor)
2020-07-28 19:18:34 +00:00
}
2020-05-23 15:09:07 +00:00
override fun onMediaStoreChanged() {
2020-08-13 08:24:36 +00:00
println("onMediaStoreChanged")
2020-09-09 12:37:25 +00:00
loadLibraryContent()
2020-05-23 15:09:07 +00:00
}
2020-08-13 08:24:36 +00:00
override fun onServiceConnected() {
println("onServiceConnected")
}
override fun onServiceDisconnected() {
println("onServiceDisconnected")
}
override fun onQueueChanged() {
println("onQueueChanged")
}
override fun onPlayingMetaChanged() {
println("onPlayingMetaChanged")
}
override fun onPlayStateChanged() {
println("onPlayStateChanged")
}
override fun onRepeatModeChanged() {
println("onRepeatModeChanged")
}
override fun onShuffleModeChanged() {
println("onShuffleModeChanged")
}
2020-07-28 19:18:34 +00:00
override fun onFavoriteStateChanged() {
println("onFavoriteStateChanged")
}
fun shuffleSongs() = viewModelScope.launch(IO) {
val songs = repository.allSongs()
MusicPlayerRemote.openAndShuffleQueue(
songs,
true
)
}
fun renameRoomPlaylist(playListId: Long, name: String) = viewModelScope.launch(IO) {
repository.renameRoomPlaylist(playListId, name)
}
fun deleteSongsInPlaylist(songs: List<SongEntity>) {
viewModelScope.launch(IO) {
repository.deleteSongsInPlaylist(songs)
forceReload(Playlists)
}
}
fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>) = viewModelScope.launch(IO) {
2020-09-10 19:22:10 +00:00
repository.deletePlaylistSongs(playlists)
}
fun deleteRoomPlaylist(playlists: List<PlaylistEntity>) = viewModelScope.launch(IO) {
repository.deleteRoomPlaylist(playlists)
}
suspend fun albumById(id: Long) = repository.albumById(id)
suspend fun artistById(id: Long) = repository.artistById(id)
suspend fun favoritePlaylist() = repository.favoritePlaylist()
suspend fun isFavoriteSong(song: SongEntity) = repository.isFavoriteSong(song)
suspend fun insertSongs(songs: List<SongEntity>) = repository.insertSongs(songs)
suspend fun removeSongFromPlaylist(songEntity: SongEntity) =
repository.removeSongFromPlaylist(songEntity)
2020-10-08 19:44:10 +00:00
private suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity> =
2020-09-05 20:13:45 +00:00
repository.checkPlaylistExists(playlistName)
2020-10-08 19:44:10 +00:00
private suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long =
2020-09-05 20:13:45 +00:00
repository.createPlaylist(playlistEntity)
2020-09-09 12:37:25 +00:00
fun importPlaylists() = viewModelScope.launch(IO) {
val playlists = repository.fetchLegacyPlaylist()
playlists.forEach { playlist ->
2020-09-10 19:22:10 +00:00
val playlistEntity = repository.checkPlaylistExists(playlist.name).firstOrNull()
2020-09-09 12:37:25 +00:00
if (playlistEntity != null) {
val songEntities = playlist.getSongs().map {
it.toSongEntity(playlistEntity.playListId)
}
repository.insertSongs(songEntities)
} else {
val playListId = createPlaylist(PlaylistEntity(playlistName = playlist.name))
2020-09-09 12:37:25 +00:00
val songEntities = playlist.getSongs().map {
it.toSongEntity(playListId)
2020-09-09 12:37:25 +00:00
}
repository.insertSongs(songEntities)
}
forceReload(Playlists)
}
}
fun deleteTracks(songs: List<Song>) = viewModelScope.launch(IO) {
repository.deleteSongs(songs)
2020-09-10 19:22:10 +00:00
fetchPlaylists()
loadLibraryContent()
2020-09-09 12:37:25 +00:00
}
2020-09-17 17:56:59 +00:00
fun recentSongs(): LiveData<List<Song>> = liveData {
emit(repository.recentSongs())
}
fun playCountSongs(): LiveData<List<Song>> = liveData {
emit(repository.playCountSongs().map {
it.toSong()
})
}
fun artists(type: Int): LiveData<List<Artist>> = liveData {
when (type) {
TOP_ARTISTS -> emit(repository.topArtists())
RECENT_ARTISTS -> {
emit(repository.recentArtists())
}
}
}
fun albums(type: Int): LiveData<List<Album>> = liveData {
when (type) {
TOP_ALBUMS -> emit(repository.topAlbums())
RECENT_ALBUMS -> {
emit(repository.recentAlbums())
}
}
}
fun artist(artistId: Long): LiveData<Artist> = liveData {
emit(repository.artistById(artistId))
}
2020-09-24 10:53:23 +00:00
fun fetchContributors(): LiveData<List<Contributor>> = liveData {
emit(repository.contributor())
}
fun observableHistorySongs() = repository.observableHistorySongs()
fun favorites() = repository.favorites()
fun clearSearchResult() {
viewModelScope.launch {
searchResults.postValue(emptyList())
}
}
2020-10-08 19:44:10 +00:00
fun addToPlaylist(playlistName: String, songs: List<Song>) {
viewModelScope.launch(IO) {
val playlists = checkPlaylistExists(playlistName)
if (playlists.isEmpty()) {
2020-10-17 07:58:13 +00:00
val playlistId: Long =
createPlaylist(PlaylistEntity(playlistName = playlistName))
2020-10-08 19:44:10 +00:00
insertSongs(songs.map { it.toSongEntity(playlistId) })
forceReload(Playlists)
} else {
val playlist = playlists.firstOrNull()
if (playlist != null) {
insertSongs(songs.map {
it.toSongEntity(playListId = playlist.playListId)
})
}
Toast.makeText(
App.getContext(),
"Adding songs to $playlistName",
Toast.LENGTH_SHORT
).show()
}
}
}
2021-09-24 07:31:53 +00:00
fun setFabMargin(bottomMargin: Int) {
val currentValue = DensityUtil.dip2px(App.getContext(), 16F) +
bottomMargin
if (currentValue != fabMargin.value) {
ValueAnimator.ofInt(fabMargin.value!!, currentValue).apply {
addUpdateListener {
fabMargin.postValue(
it.animatedValue as Int
)
}
start()
}
}
2021-09-24 07:31:53 +00:00
}
2020-05-23 15:09:07 +00:00
}
enum class ReloadType {
Songs,
Albums,
Artists,
2020-08-20 09:52:38 +00:00
HomeSections,
Playlists,
Genres,
2020-10-06 08:46:04 +00:00
}