Skip to content

Commit

Permalink
Fix deleting playlists, adding songs to playlist & track being auto l…
Browse files Browse the repository at this point in the history
…iked
  • Loading branch information
brahmkshatriya committed Sep 1, 2024
1 parent 5a50f73 commit a9473bd
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 70 deletions.
5 changes: 4 additions & 1 deletion app/src/main/java/dev/brahmkshatriya/echo/EchoApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import dev.brahmkshatriya.echo.plugger.MusicExtensionRepo
import dev.brahmkshatriya.echo.plugger.RequiredExtensionsException
import dev.brahmkshatriya.echo.plugger.TrackerExtension
import dev.brahmkshatriya.echo.plugger.TrackerExtensionRepo
import dev.brahmkshatriya.echo.ui.exception.ExceptionFragment.Companion.getDetails
import dev.brahmkshatriya.echo.ui.exception.ExceptionFragment.Companion.getTitle
import dev.brahmkshatriya.echo.ui.settings.LookFragment.Companion.AMOLED_KEY
import dev.brahmkshatriya.echo.ui.settings.LookFragment.Companion.COLOR_KEY
import dev.brahmkshatriya.echo.ui.settings.LookFragment.Companion.CUSTOM_THEME_KEY
Expand Down Expand Up @@ -102,7 +104,8 @@ class EchoApplication : Application() {

scope.launch {
throwableFlow.collect {
it.printStackTrace()
println(getTitle(it))
println(getDetails(it))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ import dev.brahmkshatriya.echo.playback.MediaItemUtils.clientId
import dev.brahmkshatriya.echo.playback.MediaItemUtils.track
import dev.brahmkshatriya.echo.plugger.MusicExtension
import dev.brahmkshatriya.echo.plugger.getExtension
import dev.brahmkshatriya.echo.ui.exception.ExceptionFragment.Companion.toExceptionDetails
import dev.brahmkshatriya.echo.utils.getSerialized
import dev.brahmkshatriya.echo.utils.putSerialized
import dev.brahmkshatriya.echo.viewmodels.ExtensionViewModel.Companion.noClient
import dev.brahmkshatriya.echo.viewmodels.ExtensionViewModel.Companion.searchNotSupported
import dev.brahmkshatriya.echo.viewmodels.ExtensionViewModel.Companion.trackNotSupported
Expand Down Expand Up @@ -129,7 +131,8 @@ class PlayerSessionCallback(
runCatching { client.likeTrack(track, rating.isThumbsUp) }
}.getOrElse {
return@future SessionResult(
SessionError.ERROR_UNKNOWN, bundleOf("error" to it)
SessionError.ERROR_UNKNOWN,
Bundle().apply { putSerialized("error", it.toExceptionDetails(context)) }
)
}
val newItem = item.run {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class AddToPlaylistViewModel @Inject constructor(
val dismiss = MutableSharedFlow<Unit>()
fun addToPlaylists() = viewModelScope.launch {
saving = true
println("selectedPlaylists: ${selectedPlaylists.joinToString(", ") { it.title }}")
addToPlaylists(
extensionListFlow, messageFlow, app, clientId, selectedPlaylists, tracks
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class EditPlaylistViewModel @Inject constructor(
val client = extension?.client
if (client !is LibraryClient) return@launch
withContext(Dispatchers.IO) {
originalList = tryWith(extension.info) { client.loadTracks(playlist).loadAll() }
?: emptyList()
originalList =
tryWith(extension.info) { client.loadTracks(playlist).loadAll() } ?: emptyList()
currentTracks.value = originalList
loading = null
loadingFlow.emit(null)
Expand All @@ -51,8 +51,7 @@ class EditPlaylistViewModel @Inject constructor(
}

private suspend fun libraryClient(
clientId: String,
block: suspend (client: LibraryClient) -> Unit
clientId: String, block: suspend (client: LibraryClient) -> Unit
) {
client(clientId, block)
}
Expand Down Expand Up @@ -99,9 +98,8 @@ class EditPlaylistViewModel @Inject constructor(
}
}

fun deletePlaylist(clientId: String, playlist: Playlist) = viewModelScope.launch {
fun deletePlaylist(clientId: String, playlist: Playlist) =
deletePlaylist(extensionListFlow, mutableMessageFlow, context, clientId, playlist)
}

private fun mergeActions(actions: MutableList<ListAction<Track>>) {
var i = 0
Expand All @@ -124,8 +122,7 @@ class EditPlaylistViewModel @Inject constructor(
}

fun onEditorExit(
clientId: String,
playlist: Playlist
clientId: String, playlist: Playlist
) = viewModelScope.launch(Dispatchers.IO) {
if (loading == true) return@launch
loading = true
Expand Down Expand Up @@ -187,7 +184,7 @@ class EditPlaylistViewModel @Inject constructor(
}

companion object {
suspend fun CatchingViewModel.deletePlaylist(
fun CatchingViewModel.deletePlaylist(
extensionListFlow: MutableStateFlow<List<MusicExtension>?>,
mutableMessageFlow: MutableSharedFlow<SnackBar.Message>,
context: Context,
Expand All @@ -197,8 +194,12 @@ class EditPlaylistViewModel @Inject constructor(
val extension = extensionListFlow.getExtension(clientId) ?: return
val client = extension.client
if (client !is LibraryClient) return
withContext(Dispatchers.IO) {
tryWith(extension.info) { client.deletePlaylist(playlist) } ?: return@withContext
viewModelScope.launch(Dispatchers.IO) {
tryWith(extension.info) {
println("deleting playlist : ${playlist.title}")
client.deletePlaylist(playlist)
println("deleted playlist : ${playlist.title}")
}
mutableMessageFlow.emit(SnackBar.Message(context.getString(R.string.playlist_deleted)))
}
}
Expand All @@ -219,17 +220,22 @@ class EditPlaylistViewModel @Inject constructor(
playlists.forEach { playlist ->
tryWith(extension.info) {
check(playlist.isEditable)
val tracks = client.loadTracks(playlist).loadAll()
listener?.onEnterPlaylistEditor(playlist, tracks)
client.addTracksToPlaylist(playlist, tracks, tracks.size, new)
listener?.onExitPlaylistEditor(playlist, tracks)
}
val loaded = client.loadPlaylist(playlist)
println("loaded : $loaded")
val tracks = client.loadTracks(loaded).loadAll()
println("tracks: ${tracks.size}")
listener?.onEnterPlaylistEditor(loaded, tracks)
client.addTracksToPlaylist(loaded, tracks, tracks.size, new)
println("added to ${loaded.title}")
listener?.onExitPlaylistEditor(loaded, tracks)
Unit
} ?: return@withContext
}
val message =
if (playlists.size != 1) context.getString(R.string.saved_to_playlists)
else context.getString(R.string.saved_to_playlist, playlists.first().title)
messageFlow.emit(SnackBar.Message(message))
}
val message = if (playlists.size == 1)
context.getString(R.string.saved_to_playlist, playlists.first())
else context.getString(R.string.saved_to_playlists)
messageFlow.emit(SnackBar.Message(message))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class ExceptionFragment : Fragment() {
fun Context.getTitle(throwable: Throwable): String = when (throwable) {
is IncompatibleClassChangeError -> getString(R.string.extension_out_of_date)
is UnknownHostException, is UnresolvedAddressException -> getString(R.string.no_internet)
is PlayerViewModel.PlayerException -> getTitle(throwable.cause)
is PlayerViewModel.PlayerException -> throwable.details.title
is AppException -> throwable.run {
when (this) {
is AppException.Unauthorized ->
Expand All @@ -114,7 +114,7 @@ Client Id : ${throwable.mediaItem?.clientId}
Track : ${throwable.mediaItem?.track}
Stream : ${throwable.mediaItem?.run { track.audioStreamables.getOrNull(audioIndex) }}
${getDetails(throwable.cause)}
${throwable.details.causedBy}
""".trimIndent()

is AppException -> """
Expand Down Expand Up @@ -143,6 +143,8 @@ ${getDetails(throwable.cause)}
return newInstance(details)
}

fun Throwable.toExceptionDetails(context: Context) =
ExceptionDetails(context.getTitle(this), context.getDetails(this))
}

@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class ItemBottomSheet : BottomSheetDialogFragment() {
} else {
binding.recyclerView.adapter = ActionAdapter(getActions(item, true))
}
observe(viewModel.shareLink) {
observe(playerViewModel.shareLink) {
requireContext().copyToClipboard(it, it)
}
}
Expand Down Expand Up @@ -173,7 +173,7 @@ class ItemBottomSheet : BottomSheetDialogFragment() {
else null,
if (client is LibraryClient && item.playlist.isEditable)
ItemAction.Resource(R.drawable.ic_delete, R.string.delete_playlist) {
viewModel.deletePlaylist(clientId, item.playlist)
playerViewModel.deletePlaylist(clientId, item.playlist)
}
else null,
) + item.playlist.authors.map {
Expand Down Expand Up @@ -262,7 +262,7 @@ class ItemBottomSheet : BottomSheetDialogFragment() {
R.string.share
) {
val shareClient = client as ShareClient
viewModel.onShare(shareClient, item)
playerViewModel.onShare(shareClient, item)
} else null
)

Expand Down
24 changes: 0 additions & 24 deletions app/src/main/java/dev/brahmkshatriya/echo/ui/item/ItemViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package dev.brahmkshatriya.echo.ui.item

import android.app.Application
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
Expand All @@ -9,7 +8,6 @@ import dev.brahmkshatriya.echo.common.clients.AlbumClient
import dev.brahmkshatriya.echo.common.clients.ArtistClient
import dev.brahmkshatriya.echo.common.clients.ArtistFollowClient
import dev.brahmkshatriya.echo.common.clients.PlaylistClient
import dev.brahmkshatriya.echo.common.clients.ShareClient
import dev.brahmkshatriya.echo.common.clients.TrackClient
import dev.brahmkshatriya.echo.common.clients.UserClient
import dev.brahmkshatriya.echo.common.helpers.PagedData
Expand All @@ -23,10 +21,8 @@ import dev.brahmkshatriya.echo.common.models.Track
import dev.brahmkshatriya.echo.plugger.ExtensionInfo
import dev.brahmkshatriya.echo.plugger.GenericExtension
import dev.brahmkshatriya.echo.plugger.MusicExtension
import dev.brahmkshatriya.echo.ui.editplaylist.EditPlaylistViewModel.Companion.deletePlaylist
import dev.brahmkshatriya.echo.ui.paging.toFlow
import dev.brahmkshatriya.echo.viewmodels.CatchingViewModel
import dev.brahmkshatriya.echo.viewmodels.SnackBar
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -38,8 +34,6 @@ import javax.inject.Inject
class ItemViewModel @Inject constructor(
throwableFlow: MutableSharedFlow<Throwable>,
val extensionListFlow: MutableStateFlow<List<MusicExtension>?>,
private val mutableMessageFlow: MutableSharedFlow<SnackBar.Message>,
private val context: Application
) : CatchingViewModel(throwableFlow) {

var item: EchoMediaItem? = null
Expand Down Expand Up @@ -106,24 +100,6 @@ class ItemViewModel @Inject constructor(
}
}

val shareLink = MutableSharedFlow<String>()
fun onShare(client: ShareClient, item: EchoMediaItem) {
viewModelScope.launch(Dispatchers.IO) {
val link = when (item) {
is EchoMediaItem.Lists.AlbumItem -> client.onShare(item.album)
is EchoMediaItem.Lists.PlaylistItem -> client.onShare(item.playlist)
is EchoMediaItem.Profile.ArtistItem -> client.onShare(item.artist)
is EchoMediaItem.Profile.UserItem -> client.onShare(item.user)
is EchoMediaItem.TrackItem -> client.onShare(item.track)
}
shareLink.emit(link)
}
}

fun deletePlaylist(clientId: String, playlist: Playlist) = viewModelScope.launch {
deletePlaylist(extensionListFlow, mutableMessageFlow, context, clientId, playlist)
}

private val songsFlow = MutableStateFlow<PagingData<Track>?>(null)
val songsLiveData = songsFlow.asLiveData()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ class PlayerTrackAdapter(

binding.bgInfoTitle.setTextColor(colors.text)
binding.bgInfoArtist.setTextColor(colors.text)
Glide.with(binding.bgImage).load(bitmap)
.apply(RequestOptions.bitmapTransform(BlurTransformation(2, 4)))
.into(binding.bgImage)
runCatching {
Glide.with(binding.bgImage).load(bitmap)
.apply(RequestOptions.bitmapTransform(BlurTransformation(2, 4)))
.into(binding.bgImage)
}
}

binding.collapsedContainer.root.setOnClickListener {
Expand Down Expand Up @@ -212,20 +214,21 @@ class PlayerTrackAdapter(
}

binding.playerControls.trackHeart.run {
viewModel.isLiked.value = item.isLiked
isChecked = item.isLiked
val client = viewModel.extensionListFlow.getExtension(clientId)?.client
val isLibrary = client is LibraryClient
isVisible = isLibrary

val likeListener = viewModel.likeListener
if (isLibrary) {
val likeListener = viewModel.likeListener
addOnCheckedStateChangedListener(likeListener)
observeCurrent(viewModel.isLiked) {
it ?: return@observeCurrent
likeListener.enabled = false
binding.playerControls.trackHeart.isChecked = it ?: false
binding.playerControls.trackHeart.isChecked = it
likeListener.enabled = true
}
} else removeOnCheckedStateChangedListener(viewModel.likeListener)
} else removeOnCheckedStateChangedListener(likeListener)
viewModel.isLiked.value = item.isLiked
}

binding.playerControls.seekBar.apply {
Expand Down Expand Up @@ -344,7 +347,7 @@ class PlayerTrackAdapter(
val repeatModes = listOf(REPEAT_MODE_OFF, REPEAT_MODE_ALL, REPEAT_MODE_ONE)
var currRepeatMode = viewModel.repeatMode.value
fun changeRepeatDrawable(repeatMode: Int) = binding.playerControls.trackRepeat.run {
if(currRepeatMode == repeatMode) {
if (currRepeatMode == repeatMode) {
icon = drawables[repeatModes.indexOf(repeatMode)]
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.Timeline
import androidx.media3.exoplayer.ExoPlayer
import dev.brahmkshatriya.echo.ui.exception.ExceptionFragment.Companion.toExceptionDetails
import dev.brahmkshatriya.echo.viewmodels.PlayerViewModel
import kotlinx.coroutines.launch

Expand Down Expand Up @@ -107,6 +108,6 @@ class PlayerUiListener(
}

override fun onPlayerError(error: PlaybackException) {
viewModel.createException(error)
viewModel.createException(error.toExceptionDetails(viewModel.app))
}
}
Loading

0 comments on commit a9473bd

Please sign in to comment.