Refactor code

Moving business logic from UI to ViewModel class
This commit is contained in:
Hemanth S 2020-08-30 00:23:15 +05:30
parent c379342f6a
commit 2854b33d56
14 changed files with 155 additions and 198 deletions

View file

@ -10,21 +10,15 @@ import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.* import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.extensions.findNavController import code.name.monkey.retromusic.extensions.findNavController
import code.name.monkey.retromusic.helper.MusicPlayerRemote.openAndShuffleQueue import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicPlayerRemote.openQueue
import code.name.monkey.retromusic.helper.MusicPlayerRemote.playFromUri
import code.name.monkey.retromusic.helper.MusicPlayerRemote.shuffleMode
import code.name.monkey.retromusic.helper.SearchQueryHelper.getSongs import code.name.monkey.retromusic.helper.SearchQueryHelper.getSongs
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.PlaylistSongsLoader.getPlaylistSongList import code.name.monkey.retromusic.repository.PlaylistSongsLoader
import code.name.monkey.retromusic.repository.Repository
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.AppRater.appLaunched import code.name.monkey.retromusic.util.AppRater.appLaunched
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import java.util.*
class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener { class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener {
companion object { companion object {
@ -33,8 +27,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
const val APP_UPDATE_REQUEST_CODE = 9002 const val APP_UPDATE_REQUEST_CODE = 9002
} }
private val repository by inject<Repository>()
private var blockRequestPermissions = false private var blockRequestPermissions = false
override fun createContentView(): View { override fun createContentView(): View {
@ -95,63 +87,70 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
override fun onServiceConnected() { override fun onServiceConnected() {
super.onServiceConnected() super.onServiceConnected()
handlePlaybackIntent(intent)
}
private fun handlePlaybackIntent(intent: Intent?) {
if (intent == null) { if (intent == null) {
return return
} }
handlePlaybackIntent(intent)
}
private fun handlePlaybackIntent(intent: Intent) {
lifecycleScope.launch(IO) {
val uri = intent.data val uri = intent.data
val mimeType = intent.type val mimeType = intent.type
var handled = false var handled = false
if (intent.action != null && (intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) if (intent.action != null &&
intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
) { ) {
val songs: List<Song> = val songs: List<Song> = getSongs(intent.extras!!)
getSongs(intent.extras!!) if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
if (shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) { MusicPlayerRemote.openAndShuffleQueue(songs, true)
openAndShuffleQueue(songs, true)
} else { } else {
openQueue(songs, 0, true) MusicPlayerRemote.openQueue(songs, 0, true)
} }
handled = true handled = true
} }
if (uri != null && uri.toString().isNotEmpty()) { if (uri != null && uri.toString().isNotEmpty()) {
playFromUri(uri) MusicPlayerRemote.playFromUri(uri)
handled = true handled = true
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) { } else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt() val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt()
if (id >= 0) { if (id >= 0) {
val position = intent.getIntExtra("position", 0) val position = intent.getIntExtra("position", 0)
val songs: List<Song> = val songs: List<Song> =
ArrayList(getPlaylistSongList(this, id)) PlaylistSongsLoader.getPlaylistSongList(this@MainActivity, id)
openQueue(songs, position, true) MusicPlayerRemote.openQueue(songs, position, true)
handled = true handled = true
} }
} else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) { } else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "albumId", "album").toInt() val id = parseIdFromIntent(intent, "albumId", "album").toInt()
if (id >= 0) { if (id >= 0) {
lifecycleScope.launch(Dispatchers.Main) {
val position = intent.getIntExtra("position", 0) val position = intent.getIntExtra("position", 0)
openQueue(repository.albumById(id).songs!!, position, true) MusicPlayerRemote.openQueue(
libraryViewModel.albumById(id).songs!!,
position,
true
)
handled = true handled = true
} }
}
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) { } else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "artistId", "artist").toInt() val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
if (id >= 0) { if (id >= 0) {
lifecycleScope.launch {
val position = intent.getIntExtra("position", 0) val position = intent.getIntExtra("position", 0)
openQueue(repository.artistById(id).songs, position, true) MusicPlayerRemote.openQueue(
libraryViewModel.artistById(id).songs,
position,
true
)
handled = true handled = true
} }
} }
}
if (handled) { if (handled) {
setIntent(Intent()) setIntent(Intent())
} }
} }
}
private fun parseIdFromIntent( private fun parseIdFromIntent(
intent: Intent, longKey: String, intent: Intent, longKey: String,
stringKey: String stringKey: String

View file

@ -33,7 +33,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
} }
private val libraryViewModel by viewModel<LibraryViewModel>() protected val libraryViewModel by viewModel<LibraryViewModel>()
private lateinit var behavior: RetroBottomSheetBehavior<FrameLayout> private lateinit var behavior: RetroBottomSheetBehavior<FrameLayout>
private var miniPlayerFragment: MiniPlayerFragment? = null private var miniPlayerFragment: MiniPlayerFragment? = null
private var cps: NowPlayingScreen? = null private var cps: NowPlayingScreen? = null
@ -79,6 +79,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
libraryViewModel.paletteColorLiveData.observe(this, Observer { libraryViewModel.paletteColorLiveData.observe(this, Observer {
this.paletteColor = it this.paletteColor = it
miniPlayerFragment?.updateProgressBar(it)
onPaletteColorChanged() onPaletteColorChanged()
}) })
} }

View file

@ -15,15 +15,12 @@ import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType.Playlists import code.name.monkey.retromusic.fragments.ReloadType.Playlists
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class AddToRetroPlaylist : BottomSheetDialogFragment() { class AddToRetroPlaylist : BottomSheetDialogFragment() {
private val repository by inject<RealRepository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>() private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object { companion object {
@ -58,7 +55,7 @@ class AddToRetroPlaylist : BottomSheetDialogFragment() {
} else { } else {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
val songEntities = songs.toSongEntity(playlistEntities[which - 1]) val songEntities = songs.toSongEntity(playlistEntities[which - 1])
repository.insertSongs(songEntities) libraryViewModel.insertSongs(songEntities)
libraryViewModel.forceReload(Playlists) libraryViewModel.forceReload(Playlists)
} }
} }

View file

@ -5,7 +5,6 @@ import android.os.Bundle
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.EXTRA_PLAYLIST import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistEntity import code.name.monkey.retromusic.db.PlaylistEntity
@ -14,14 +13,10 @@ import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.repository.Repository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class DeleteRetroPlaylist : DialogFragment() { class DeleteRetroPlaylist : DialogFragment() {
private val repository by inject<Repository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>() private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object { companion object {
@ -63,12 +58,10 @@ class DeleteRetroPlaylist : DialogFragment() {
.setMessage(message) .setMessage(message)
.setNegativeButton(android.R.string.cancel, null) .setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_delete) { _, _ -> .setPositiveButton(R.string.action_delete) { _, _ ->
lifecycleScope.launch(Dispatchers.IO) { libraryViewModel.deleteSongsFromPlaylist(playlists)
repository.deleteSongsFromPlaylist(playlists) libraryViewModel.deleteRoomPlaylist(playlists)
repository.deleteRoomPlaylist(playlists)
libraryViewModel.forceReload(ReloadType.Playlists) libraryViewModel.forceReload(ReloadType.Playlists)
} }
}
.create() .create()
.colorButtons() .colorButtons()
} }

View file

@ -5,7 +5,6 @@ import android.os.Bundle
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.EXTRA_SONG import code.name.monkey.retromusic.EXTRA_SONG
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.SongEntity import code.name.monkey.retromusic.db.SongEntity
@ -14,14 +13,9 @@ import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType.Playlists import code.name.monkey.retromusic.fragments.ReloadType.Playlists
import code.name.monkey.retromusic.repository.Repository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class RemoveSongFromPlaylistDialog : DialogFragment() { class RemoveSongFromPlaylistDialog : DialogFragment() {
private val repository by inject<Repository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>() private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object { companion object {
@ -65,12 +59,9 @@ class RemoveSongFromPlaylistDialog : DialogFragment() {
return materialDialog(pair.first) return materialDialog(pair.first)
.setMessage(pair.second) .setMessage(pair.second)
.setPositiveButton(R.string.remove_action) { _, _ -> .setPositiveButton(R.string.remove_action) { _, _ ->
lifecycleScope.launch(Dispatchers.IO) { libraryViewModel.deleteSongsInPlaylist(songs)
//repository.removeSongFromPlaylist(songs)
repository.deleteSongsInPlaylist(songs)
libraryViewModel.forceReload(Playlists) libraryViewModel.forceReload(Playlists)
} }
}
.setNegativeButton(android.R.string.cancel, null) .setNegativeButton(android.R.string.cancel, null)
.create() .create()
.colorButtons() .colorButtons()

View file

@ -5,7 +5,6 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.EXTRA_PLAYLIST_ID import code.name.monkey.retromusic.EXTRA_PLAYLIST_ID
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistEntity import code.name.monkey.retromusic.db.PlaylistEntity
@ -15,16 +14,12 @@ import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.repository.Repository
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class RenameRetroPlaylistDialog : DialogFragment() { class RenameRetroPlaylistDialog : DialogFragment() {
private val repository by inject<Repository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>() private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object { companion object {
@ -50,10 +45,8 @@ class RenameRetroPlaylistDialog : DialogFragment() {
.setPositiveButton(R.string.action_rename) { _, _ -> .setPositiveButton(R.string.action_rename) { _, _ ->
val name = inputEditText.text.toString() val name = inputEditText.text.toString()
if (name.isNotEmpty()) { if (name.isNotEmpty()) {
lifecycleScope.launch(Dispatchers.IO) { libraryViewModel.renameRoomPlaylist(playlistEntity.playListId, name)
repository.renameRoomPlaylist(playlistEntity.playListId, name)
libraryViewModel.forceReload(ReloadType.Playlists) libraryViewModel.forceReload(ReloadType.Playlists)
}
} else { } else {
nameContainer.error = "Playlist name should'nt be empty" nameContainer.error = "Playlist name should'nt be empty"
} }

View file

@ -35,6 +35,7 @@ import code.name.monkey.retromusic.R
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.progressindicator.ProgressIndicator
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
@ -145,6 +146,17 @@ fun TextInputLayout.accentColor() {
isHintAnimationEnabled = true isHintAnimationEnabled = true
} }
fun ProgressIndicator.accentColor() {
val accentColor = ThemeStore.accentColor(context)
indicatorColors = intArrayOf(accentColor)
trackColor = ColorUtil.withAlpha(accentColor, 0.2f)
}
fun ProgressIndicator.applyColor(color: Int) {
indicatorColors = intArrayOf(color)
trackColor = ColorUtil.withAlpha(color, 0.2f)
}
fun TextInputEditText.accentColor() { fun TextInputEditText.accentColor() {
} }

View file

@ -4,7 +4,9 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import code.name.monkey.retromusic.db.PlaylistEntity
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.toPlayCount import code.name.monkey.retromusic.db.toPlayCount
import code.name.monkey.retromusic.fragments.ReloadType.* import code.name.monkey.retromusic.fragments.ReloadType.*
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -151,6 +153,38 @@ class LibraryViewModel(
println("onShuffleModeChanged") println("onShuffleModeChanged")
} }
fun shuffleSongs() = viewModelScope.launch(IO) {
val songs = repository.allSongs()
MusicPlayerRemote.openAndShuffleQueue(
songs,
true
)
}
fun renameRoomPlaylist(playListId: Int, name: String) = viewModelScope.launch(IO) {
repository.renameRoomPlaylist(playListId, name)
}
fun deleteSongsInPlaylist(songs: List<SongEntity>) = viewModelScope.launch(IO) {
repository.deleteSongsInPlaylist(songs)
}
fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>) = viewModelScope.launch(IO) {
repository.deleteSongsFromPlaylist(playlists)
}
fun deleteRoomPlaylist(playlists: List<PlaylistEntity>) = viewModelScope.launch(IO) {
repository.deleteRoomPlaylist(playlists)
}
suspend fun albumById(id: Int) = repository.albumById(id)
suspend fun artistById(id: Int) = 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)
} }
enum class ReloadType { enum class ReloadType {

View file

@ -11,18 +11,14 @@ import android.view.GestureDetector
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.textColorPrimary
import code.name.monkey.retromusic.extensions.textColorSecondary
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.ViewUtil
import kotlinx.android.synthetic.main.fragment_mini_player.* import kotlinx.android.synthetic.main.fragment_mini_player.*
import kotlin.math.abs import kotlin.math.abs
@ -67,7 +63,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
private fun setUpMiniPlayer() { private fun setUpMiniPlayer() {
setUpPlayPauseButton() setUpPlayPauseButton()
ViewUtil.setProgressDrawable(progressBar, ThemeStore.accentColor(requireContext())) progressBar.accentColor()
} }
private fun setUpPlayPauseButton() { private fun setUpPlayPauseButton() {
@ -129,6 +125,10 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
} }
} }
fun updateProgressBar(paletteColor: Int) {
progressBar.applyColor(paletteColor)
}
class FlingPlayBackController(context: Context) : View.OnTouchListener { class FlingPlayBackController(context: Context) : View.OnTouchListener {
private var flingPlayBackController: GestureDetector private var flingPlayBackController: GestureDetector

View file

@ -25,7 +25,7 @@ import code.name.monkey.retromusic.dialogs.*
import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.whichFragment import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType.Playlists import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.PaletteColorHolder import code.name.monkey.retromusic.interfaces.PaletteColorHolder
@ -35,13 +35,11 @@ import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.* import code.name.monkey.retromusic.util.*
import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.* import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.IO 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
import org.koin.android.ext.android.get import org.koin.android.ext.android.get
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.io.FileNotFoundException import java.io.FileNotFoundException
@ -75,7 +73,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
R.id.action_add_to_playlist -> { R.id.action_add_to_playlist -> {
lifecycleScope.launch(IO) { lifecycleScope.launch(IO) {
val playlists = get<RealRepository>().roomPlaylists() val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) { withContext(Main) {
AddToRetroPlaylist.create(playlists, song) AddToRetroPlaylist.create(playlists, song)
.show(childFragmentManager, "ADD_PLAYLIST") .show(childFragmentManager, "ADD_PLAYLIST")
} }
@ -161,20 +159,6 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
return false return false
} }
protected open fun toggleFavorite(song: Song) {
lifecycleScope.launch(IO) {
val playlist: PlaylistEntity = repository.favoritePlaylist().first()
val songEntity = song.toSongEntity(playlist.playListId)
val isFavorite = repository.isFavoriteSong(songEntity).isNotEmpty()
if (isFavorite) {
repository.removeSongFromPlaylist(songEntity)
} else {
repository.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
libraryViewModel.forceReload(Playlists)
}
requireContext().sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED))
}
}
abstract fun playerToolbar(): Toolbar? abstract fun playerToolbar(): Toolbar?
@ -196,15 +180,35 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
updateLyrics() updateLyrics()
} }
protected open fun toggleFavorite(song: Song) {
lifecycleScope.launch(IO) {
val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist().first()
val songEntity = song.toSongEntity(playlist.playListId)
val isFavorite = libraryViewModel.isFavoriteSong(songEntity).isNotEmpty()
if (isFavorite) {
libraryViewModel.removeSongFromPlaylist(songEntity)
} else {
libraryViewModel.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
libraryViewModel.forceReload(ReloadType.Playlists)
}
requireContext().sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED))
}
}
fun updateIsFavorite() { fun updateIsFavorite() {
lifecycleScope.launch(IO) { lifecycleScope.launch(IO) {
val playlist: PlaylistEntity = repository.favoritePlaylist().first() val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist().first()
val song = MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId) val song = MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId)
val isFavorite = repository.isFavoriteSong(song).isNotEmpty() val isFavorite = libraryViewModel.isFavoriteSong(song).isNotEmpty()
withContext(Dispatchers.Main) { withContext(Main) {
val icon = if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border val icon =
if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
val drawable = val drawable =
RetroUtil.getTintedVectorDrawable(requireContext(), icon, toolbarIconColor()) RetroUtil.getTintedVectorDrawable(
requireContext(),
icon,
toolbarIconColor()
)
if (playerToolbar() != null) { if (playerToolbar() != null) {
playerToolbar()?.menu?.findItem(R.id.action_toggle_favorite) playerToolbar()?.menu?.findItem(R.id.action_toggle_favorite)
?.setIcon(drawable)?.title = ?.setIcon(drawable)?.title =
@ -241,17 +245,6 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
open fun setLyrics(l: Lyrics?) { open fun setLyrics(l: Lyrics?) {
} }
private val repository by inject<RealRepository>()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
lifecycleScope.launch(IO) {
if (repository.checkPlaylistExists(getString(R.string.favorites)).isEmpty()) {
repository.createPlaylist(PlaylistEntity(getString(R.string.favorites)))
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
if (PreferenceUtil.isFullScreenMode && if (PreferenceUtil.isFullScreenMode &&

View file

@ -16,11 +16,9 @@ package code.name.monkey.retromusic.fragments.home
import android.app.ActivityOptions import android.app.ActivityOptions
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics
import android.view.View import android.view.View
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.HISTORY_PLAYLIST import code.name.monkey.retromusic.HISTORY_PLAYLIST
import code.name.monkey.retromusic.LAST_ADDED_PLAYLIST import code.name.monkey.retromusic.LAST_ADDED_PLAYLIST
@ -32,32 +30,19 @@ import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
import code.name.monkey.retromusic.glide.UserProfileGlideRequest import code.name.monkey.retromusic.glide.UserProfileGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.repository.Repository
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.abs_playlists.* import kotlinx.android.synthetic.main.abs_playlists.*
import kotlinx.android.synthetic.main.fragment_banner_home.* import kotlinx.android.synthetic.main.fragment_banner_home.*
import kotlinx.android.synthetic.main.home_content.* import kotlinx.android.synthetic.main.home_content.*
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class HomeFragment : class HomeFragment :
AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home) { AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home) {
private val repository by inject<Repository>()
private val libraryViewModel: LibraryViewModel by sharedViewModel() private val libraryViewModel: LibraryViewModel by sharedViewModel()
private val displayMetrics: DisplayMetrics
get() {
val display = mainActivity.windowManager.defaultDisplay
val metrics = DisplayMetrics()
display.getMetrics(metrics)
return metrics
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setStatusBarColorAuto(view) setStatusBarColorAuto(view)
@ -85,12 +70,7 @@ class HomeFragment :
} }
actionShuffle.setOnClickListener { actionShuffle.setOnClickListener {
lifecycleScope.launch { libraryViewModel.shuffleSongs()
MusicPlayerRemote.openAndShuffleQueue(
repository.allSongs(),
true
)
}
} }
history.setOnClickListener { history.setOnClickListener {

View file

@ -5,7 +5,6 @@ import android.annotation.SuppressLint
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.animation.LinearInterpolator import android.view.animation.LinearInterpolator
@ -18,7 +17,6 @@ import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RetroBottomSheetBehavior import code.name.monkey.retromusic.RetroBottomSheetBehavior
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
@ -61,7 +59,6 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
private var recyclerViewSwipeManager: RecyclerViewSwipeManager? = null private var recyclerViewSwipeManager: RecyclerViewSwipeManager? = null
private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null
private var playingQueueAdapter: PlayingQueueAdapter? = null private var playingQueueAdapter: PlayingQueueAdapter? = null
private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
private lateinit var linearLayoutManager: LinearLayoutManager private lateinit var linearLayoutManager: LinearLayoutManager
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() { private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
@ -218,9 +215,8 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
override fun toggleFavorite(song: Song) { override fun toggleFavorite(song: Song) {
super.toggleFavorite(song) super.toggleFavorite(song)
MusicUtil.toggleFavorite(requireContext(), song)
if (song.id == MusicPlayerRemote.currentSong.id) { if (song.id == MusicPlayerRemote.currentSong.id) {
updateFavorite() updateIsFavorite()
} }
} }
@ -268,6 +264,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
override fun onQueueChanged() { override fun onQueueChanged() {
super.onQueueChanged() super.onQueueChanged()
updateLabel() updateLabel()
playingQueueAdapter?.swapDataSet(MusicPlayerRemote.playingQueue)
} }
private fun updateSong() { private fun updateSong() {
@ -366,7 +363,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
} else { } else {
val title = MusicPlayerRemote.playingQueue[MusicPlayerRemote.position + 1].title val title = MusicPlayerRemote.playingQueue[MusicPlayerRemote.position + 1].title
nextSong.apply { nextSong.apply {
text = "Next: $title" text = title
show() show()
} }
} }
@ -472,36 +469,4 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong()) songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong()) songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
} }
@SuppressLint("StaticFieldLeak")
private fun updateFavorite() {
if (updateIsFavoriteTask != null) {
updateIsFavoriteTask?.cancel(false)
}
updateIsFavoriteTask =
object : AsyncTask<Song, Void, Boolean>() {
override fun doInBackground(vararg params: Song): Boolean? {
val activity = activity
return if (activity != null) {
MusicUtil.isFavorite(requireActivity(), params[0])
} else {
cancel(false)
null
}
}
override fun onPostExecute(isFavorite: Boolean?) {
val activity = activity
if (activity != null) {
val res = if (isFavorite!!)
R.drawable.ic_favorite
else
R.drawable.ic_favorite_border
val drawable = TintHelper.createTintedDrawable(activity, res, Color.WHITE)
songFavourite?.setImageDrawable(drawable)
}
}
}.execute(MusicPlayerRemote.currentSong)
}
} }

View file

@ -23,7 +23,6 @@ import code.name.monkey.retromusic.model.AbsCustomPlaylist
import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.PlaylistSong import code.name.monkey.retromusic.model.PlaylistSong
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import java.util.*
/** /**
* Created by hemanths on 16/08/17. * Created by hemanths on 16/08/17.
@ -43,8 +42,8 @@ object PlaylistSongsLoader {
} }
@JvmStatic @JvmStatic
fun getPlaylistSongList(context: Context, playlistId: Int): ArrayList<Song> { fun getPlaylistSongList(context: Context, playlistId: Int): List<Song> {
val songs = arrayListOf<Song>() val songs = mutableListOf<Song>()
val cursor = val cursor =
makePlaylistSongCursor( makePlaylistSongCursor(
context, context,

View file

@ -74,7 +74,8 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="spread"> app:layout_constraintWidth_default="spread"
tools:background="@color/md_red_500">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/queueIcon" android:id="@+id/queueIcon"
@ -100,8 +101,7 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_default="wrap" app:layout_constraintHeight_default="wrap"
app:layout_constraintStart_toEndOf="@id/queueIcon" app:layout_constraintStart_toEndOf="@id/queueIcon"
app:layout_constraintTop_toTopOf="@id/queueIcon" app:layout_constraintTop_toTopOf="@id/queueIcon" />
tools:text="@tools:sample/lorem/random" />
<androidx.appcompat.widget.AppCompatImageButton <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton" android:id="@+id/repeatButton"