[Cleanup] ViewModel cleanup, fixed coroutine dispatchers for some functions

This commit is contained in:
Prathamesh More 2022-04-12 19:14:48 +05:30
parent 8b100b4a17
commit eb21c07f5b
10 changed files with 55 additions and 93 deletions

View file

@ -69,41 +69,23 @@ class LibraryViewModel(
fun getSearchResult(): LiveData<List<Any>> = searchResults fun getSearchResult(): LiveData<List<Any>> = searchResults
fun getSongs(): LiveData<List<Song>> { fun getSongs(): LiveData<List<Song>> = songs
return songs
}
fun getAlbums(): LiveData<List<Album>> { fun getAlbums(): LiveData<List<Album>> = albums
return albums
}
fun getArtists(): LiveData<List<Artist>> { fun getArtists(): LiveData<List<Artist>> = artists
return artists
}
fun getPlaylists(): LiveData<List<PlaylistWithSongs>> { fun getPlaylists(): LiveData<List<PlaylistWithSongs>> = playlists
return playlists
}
fun getLegacyPlaylist(): LiveData<List<Playlist>> { fun getLegacyPlaylist(): LiveData<List<Playlist>> = legacyPlaylists
return legacyPlaylists
}
fun getGenre(): LiveData<List<Genre>> { fun getGenre(): LiveData<List<Genre>> = genres
return genres
}
fun getHome(): LiveData<List<Home>> { fun getHome(): LiveData<List<Home>> = home
return home
}
fun getSuggestions(): LiveData<List<Song>> { fun getSuggestions(): LiveData<List<Song>> = suggestions
return suggestions
}
fun getFabMargin(): LiveData<Int> { fun getFabMargin(): LiveData<Int> = fabMargin
return fabMargin
}
private suspend fun fetchSongs() { private suspend fun fetchSongs() {
songs.postValue(repository.allSongs()) songs.postValue(repository.allSongs())
@ -111,7 +93,6 @@ class LibraryViewModel(
private suspend fun fetchAlbums() { private suspend fun fetchAlbums() {
albums.postValue(repository.fetchAlbums()) albums.postValue(repository.fetchAlbums())
} }
private suspend fun fetchArtists() { private suspend fun fetchArtists() {
@ -273,29 +254,22 @@ class LibraryViewModel(
loadLibraryContent() loadLibraryContent()
} }
fun recentSongs(): LiveData<List<Song>> = liveData { fun recentSongs(): LiveData<List<Song>> = liveData(IO) {
emit(repository.recentSongs()) emit(repository.recentSongs())
} }
fun playCountSongs(): LiveData<List<Song>> = liveData { fun playCountSongs(): LiveData<List<Song>> = liveData(IO) {
val songs = repository.playCountSongs().map { repository.playCountSongs().forEach { song ->
it.toSong()
}
emit(songs)
// Cleaning up deleted or moved songs
withContext(IO) {
songs.forEach { song ->
if (!File(song.data).exists() || song.id == -1L) { if (!File(song.data).exists() || song.id == -1L) {
repository.deleteSongInPlayCount(song.toPlayCount()) repository.deleteSongInPlayCount(song)
} }
} }
emit(repository.playCountSongs().map { emit(repository.playCountSongs().map {
it.toSong() it.toSong()
}) })
} }
}
fun artists(type: Int): LiveData<List<Artist>> = liveData { fun artists(type: Int): LiveData<List<Artist>> = liveData(IO) {
when (type) { when (type) {
TOP_ARTISTS -> emit(repository.topArtists()) TOP_ARTISTS -> emit(repository.topArtists())
RECENT_ARTISTS -> { RECENT_ARTISTS -> {
@ -304,7 +278,7 @@ class LibraryViewModel(
} }
} }
fun albums(type: Int): LiveData<List<Album>> = liveData { fun albums(type: Int): LiveData<List<Album>> = liveData(IO) {
when (type) { when (type) {
TOP_ALBUMS -> emit(repository.topAlbums()) TOP_ALBUMS -> emit(repository.topAlbums())
RECENT_ALBUMS -> { RECENT_ALBUMS -> {
@ -313,29 +287,25 @@ class LibraryViewModel(
} }
} }
fun artist(artistId: Long): LiveData<Artist> = liveData { fun artist(artistId: Long): LiveData<Artist> = liveData(IO) {
emit(repository.artistById(artistId)) emit(repository.artistById(artistId))
} }
fun fetchContributors(): LiveData<List<Contributor>> = liveData { fun fetchContributors(): LiveData<List<Contributor>> = liveData(IO) {
emit(repository.contributor()) emit(repository.contributor())
} }
fun observableHistorySongs(): LiveData<List<Song>> { fun observableHistorySongs(): LiveData<List<Song>> {
val songs = repository.historySong().map { viewModelScope.launch(IO) {
it.toSong() repository.historySong().forEach { song ->
}
songHistory.value = songs
// Cleaning up deleted or moved songs
viewModelScope.launch {
songs.forEach { song ->
if (!File(song.data).exists() || song.id == -1L) { if (!File(song.data).exists() || song.id == -1L) {
repository.deleteSongInHistory(song.id) repository.deleteSongInHistory(song.id)
} }
} }
}
songHistory.value = repository.historySong().map { songHistory.postValue(repository.historySong().map {
it.toSong() it.toSong()
})
} }
return songHistory return songHistory
} }
@ -366,9 +336,7 @@ class LibraryViewModel(
fun favorites() = repository.favorites() fun favorites() = repository.favorites()
fun clearSearchResult() { fun clearSearchResult() {
viewModelScope.launch { searchResults.value = emptyList()
searchResults.postValue(emptyList())
}
} }
fun addToPlaylist(playlistName: String, songs: List<Song>) { fun addToPlaylist(playlistName: String, songs: List<Song>) {
@ -396,11 +364,13 @@ class LibraryViewModel(
} }
forceReload(Playlists) forceReload(Playlists)
withContext(Main) { withContext(Main) {
Toast.makeText(App.getContext(), App.getContext().getString( Toast.makeText(
App.getContext(), App.getContext().getString(
R.string.added_song_count_to_playlist, R.string.added_song_count_to_playlist,
songs.size, songs.size,
playlistName playlistName
), Toast.LENGTH_SHORT).show() ), Toast.LENGTH_SHORT
).show()
} }
} }
} }

View file

@ -52,7 +52,7 @@ class AlbumDetailsViewModel(
emit(artist) emit(artist)
} }
fun getAlbumInfo(album: Album): LiveData<Result<LastFmAlbum>> = liveData { fun getAlbumInfo(album: Album): LiveData<Result<LastFmAlbum>> = liveData(IO) {
emit(Result.Loading) emit(Result.Loading)
emit(repository.albumInfo(album.artistName, album.title)) emit(repository.albumInfo(album.artistName, album.title))
} }

View file

@ -47,7 +47,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
else else
backupAdapter?.swapDataset(listOf()) backupAdapter?.swapDataset(listOf())
} }
backupViewModel.loadBackups(requireContext()) backupViewModel.loadBackups()
val openFilePicker = registerForActivityResult(ActivityResultContracts.OpenDocument()) { val openFilePicker = registerForActivityResult(ActivityResultContracts.OpenDocument()) {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
it?.let { it?.let {
@ -98,7 +98,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
// Text submitted with the action button // Text submitted with the action button
lifecycleScope.launch { lifecycleScope.launch {
BackupHelper.createBackup(requireContext(), text.sanitize()) BackupHelper.createBackup(requireContext(), text.sanitize())
backupViewModel.loadBackups(requireContext()) backupViewModel.loadBackups()
} }
} }
positiveButton(android.R.string.ok) positiveButton(android.R.string.ok)
@ -128,7 +128,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
backupViewModel.loadBackups(requireContext()) backupViewModel.loadBackups()
return true return true
} }
R.id.action_share -> { R.id.action_share -> {
@ -149,7 +149,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
File(file.parent, "$text${BackupHelper.APPEND_EXTENSION}") File(file.parent, "$text${BackupHelper.APPEND_EXTENSION}")
if (!renamedFile.exists()) { if (!renamedFile.exists()) {
file.renameTo(renamedFile) file.renameTo(renamedFile)
backupViewModel.loadBackups(requireContext()) backupViewModel.loadBackups()
} else { } else {
Toast.makeText( Toast.makeText(
requireContext(), requireContext(),

View file

@ -20,7 +20,7 @@ class BackupViewModel : ViewModel() {
private val backupsMutableLiveData = MutableLiveData<List<File>>() private val backupsMutableLiveData = MutableLiveData<List<File>>()
val backupsLiveData: LiveData<List<File>> = backupsMutableLiveData val backupsLiveData: LiveData<List<File>> = backupsMutableLiveData
fun loadBackups(context: Context) { fun loadBackups() {
BackupHelper.getBackupRoot().listFiles { _, name -> BackupHelper.getBackupRoot().listFiles { _, name ->
return@listFiles name.endsWith(BackupHelper.BACKUP_EXTENSION) return@listFiles name.endsWith(BackupHelper.BACKUP_EXTENSION)
}?.toList()?.let { }?.toList()?.let {

View file

@ -22,6 +22,7 @@ import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository import code.name.monkey.retromusic.repository.RealRepository
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -44,7 +45,7 @@ class GenreDetailsViewModel(
loadGenreSongs(genre) loadGenreSongs(genre)
} }
private fun loadGenreSongs(genre: Genre) = viewModelScope.launch { private fun loadGenreSongs(genre: Genre) = viewModelScope.launch(IO) {
val songs = realRepository.getGenre(genre.id) val songs = realRepository.getGenre(genre.id)
withContext(Main) { _playListSongs.postValue(songs) } withContext(Main) { _playListSongs.postValue(songs) }
} }

View file

@ -21,6 +21,7 @@ import android.view.MenuItem
import android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM import android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM
import android.view.View import android.view.View
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.text.parseAsHtml import androidx.core.text.parseAsHtml
import androidx.core.view.doOnLayout import androidx.core.view.doOnLayout
@ -29,7 +30,6 @@ import androidx.core.view.isVisible
import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.ATHToolbarActivity import code.name.monkey.appthemehelper.common.ATHToolbarActivity
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
@ -77,12 +77,12 @@ class HomeFragment :
layoutManager = LinearLayoutManager(mainActivity) layoutManager = LinearLayoutManager(mainActivity)
adapter = homeAdapter adapter = homeAdapter
} }
libraryViewModel.getHome().observe(viewLifecycleOwner) {
homeAdapter.swapData(it)
}
libraryViewModel.getSuggestions().observe(viewLifecycleOwner) { libraryViewModel.getSuggestions().observe(viewLifecycleOwner) {
loadSuggestions(it) loadSuggestions(it)
} }
libraryViewModel.getHome().observe(viewLifecycleOwner) {
homeAdapter.swapData(it)
}
loadProfile() loadProfile()
setupTitle() setupTitle()
@ -110,7 +110,6 @@ class HomeFragment :
button.setLines(maxLineCount) button.setLines(maxLineCount)
} }
} }
} }
private fun setupListeners() { private fun setupListeners() {
@ -218,16 +217,12 @@ class HomeFragment :
} }
fun setSharedAxisXTransitions() { fun setSharedAxisXTransitions() {
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).apply { exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).addTarget(CoordinatorLayout::class.java)
addTarget(binding.root)
}
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
} }
private fun setSharedAxisYTransitions() { private fun setSharedAxisYTransitions() {
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Y, true).apply { exitTransition = MaterialSharedAxis(MaterialSharedAxis.Y, true).addTarget(CoordinatorLayout::class.java)
addTarget(binding.root)
}
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Y, false) reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Y, false)
} }
@ -246,7 +241,7 @@ class HomeFragment :
binding.suggestions.image7, binding.suggestions.image7,
binding.suggestions.image8 binding.suggestions.image8
) )
val color = ThemeStore.accentColor(requireContext()) val color = accentColor()
binding.suggestions.message.apply { binding.suggestions.message.apply {
setTextColor(color) setTextColor(color)
setOnClickListener { setOnClickListener {

View file

@ -15,14 +15,10 @@
package code.name.monkey.retromusic.fragments.playlists package code.name.monkey.retromusic.fragments.playlists
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import code.name.monkey.retromusic.db.PlaylistWithSongs import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.SongEntity import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.repository.RealRoomRepository
class PlaylistDetailsViewModel( class PlaylistDetailsViewModel(
private val realRepository: RealRepository, private val realRepository: RealRepository,

View file

@ -585,7 +585,7 @@ object PreferenceUtil {
4 -> VerticalFlipTransformation() 4 -> VerticalFlipTransformation()
5 -> HingeTransformation() 5 -> HingeTransformation()
6 -> VerticalStackTransformer() 6 -> VerticalStackTransformer()
else -> NormalPageTransformer() else -> ViewPager.PageTransformer { _, _ -> }
} }
} }

View file

@ -8,7 +8,7 @@
<item>@string/horizontal_flip</item> <item>@string/horizontal_flip</item>
<item>@string/hinge</item> <item>@string/hinge</item>
<item>@string/stack</item> <item>@string/stack</item>
<item>@string/classic</item> <item>@string/simple</item>
</array> </array>
<string-array name="pref_album_cover_transform_values"> <string-array name="pref_album_cover_transform_values">