Skip to content

Commit

Permalink
Twelve: MediaItemBottomSheetDialog: Handle favorites
Browse files Browse the repository at this point in the history
Change-Id: Ice8b35e9c5e22d27650aae022f16204a7fe1e4be
  • Loading branch information
SebaUbuntu committed Mar 4, 2025
1 parent c282206 commit b669300
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class MediaItemBottomSheetDialogFragment : BottomSheetDialogFragment(
private val viewModel by viewModels<MediaItemViewModel>()

// Views
private val addOrRemoveFromFavoritesListItem by getViewProperty<ListItem>(R.id.addOrRemoveFromFavoritesListItem)
private val addOrRemoveFromPlaylistsListItem by getViewProperty<ListItem>(R.id.addOrRemoveFromPlaylistsListItem)
private val addToQueueListItem by getViewProperty<ListItem>(R.id.addToQueueListItem)
private val artistNameTextView by getViewProperty<TextView>(R.id.artistNameTextView)
Expand Down Expand Up @@ -116,6 +117,14 @@ class MediaItemBottomSheetDialogFragment : BottomSheetDialogFragment(
findNavController().navigateUp()
}

addOrRemoveFromFavoritesListItem.setOnClickListener {
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
viewModel.toggleFavorites()
}
}
}

removeFromPlaylistListItem.setOnClickListener {
viewLifecycleOwner.lifecycleScope.launch {
fullscreenLoadingProgressBar.withProgress {
Expand Down Expand Up @@ -242,6 +251,25 @@ class MediaItemBottomSheetDialogFragment : BottomSheetDialogFragment(
placeholderImageView.isVisible = true
thumbnailImageView.isVisible = false
}

when (mediaItem) {
is Audio -> {
addOrRemoveFromFavoritesListItem.setHeadlineText(
when (mediaItem.isFavorite) {
true -> R.string.remove_from_favorites
false -> R.string.add_to_favorites
}
)
addOrRemoveFromFavoritesListItem.setLeadingIconImage(
when (mediaItem.isFavorite) {
true -> R.drawable.ic_heart_filled
false -> R.drawable.ic_heart_unfilled
}
)
}

else -> {}
}
}

is FlowResult.Error -> {
Expand All @@ -268,6 +296,12 @@ class MediaItemBottomSheetDialogFragment : BottomSheetDialogFragment(
}
}

launch {
viewModel.canToggleFavorite.collectLatest { canToggleFavorite ->
addOrRemoveFromFavoritesListItem.isVisible = canToggleFavorite
}
}

launch {
viewModel.canAddOrRemoveFromPlaylists.collectLatest { canAddOrRemoveFromPlaylists ->
addOrRemoveFromPlaylistsListItem.isVisible = canAddOrRemoveFromPlaylists
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,23 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
import org.lineageos.twelve.ext.resources
import org.lineageos.twelve.models.Album
import org.lineageos.twelve.models.Audio
import org.lineageos.twelve.models.Error
import org.lineageos.twelve.models.FlowResult
import org.lineageos.twelve.models.FlowResult.Companion.asFlowResult
import org.lineageos.twelve.models.FlowResult.Companion.foldLatest
import org.lineageos.twelve.models.FlowResult.Companion.mapLatestData
import org.lineageos.twelve.models.FlowResult.Companion.mapLatestDataOrNull
import org.lineageos.twelve.models.MediaType
import org.lineageos.twelve.models.Playlist
import org.lineageos.twelve.models.Result
import org.lineageos.twelve.models.Result.Companion.map

class MediaItemViewModel(application: Application) : TwelveViewModel(application) {
Expand Down Expand Up @@ -107,6 +111,21 @@ class MediaItemViewModel(application: Application) : TwelveViewModel(application
initialValue = listOf(),
)

@OptIn(ExperimentalCoroutinesApi::class)
private val playlist = playlistUri
.flatMapLatest { playlistUri ->
playlistUri?.let {
mediaRepository.playlist(it)
} ?: flowOf(Result.Error(Error.NOT_FOUND))
}
.asFlowResult()
.flowOn(Dispatchers.IO)
.stateIn(
viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = FlowResult.Loading(),
)

val showQueueButtons = combine(
tracks,
fromNowPlaying
Expand All @@ -118,10 +137,19 @@ class MediaItemViewModel(application: Application) : TwelveViewModel(application
initialValue = false,
)

val canRemoveFromPlaylist = combine(
mediaType,
playlistUri,
) { mediaType, playlistUri -> mediaType == MediaType.AUDIO && playlistUri != null }
@OptIn(ExperimentalCoroutinesApi::class)
val canToggleFavorite = mediaType
.mapLatest { it == MediaType.AUDIO }
.flowOn(Dispatchers.IO)
.stateIn(
viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = false,
)

val canRemoveFromPlaylist = combine(mediaType, playlist) { mediaType, playlist ->
mediaType == MediaType.AUDIO && playlist.getOrNull()?.first?.type == Playlist.Type.PLAYLIST
}
.flowOn(Dispatchers.IO)
.stateIn(
viewModelScope,
Expand Down Expand Up @@ -250,6 +278,16 @@ class MediaItemViewModel(application: Application) : TwelveViewModel(application
}
}

suspend fun toggleFavorites() {
mediaItem.value.getOrNull()?.let {
val audio = it as? Audio ?: return@let

withContext(Dispatchers.IO) {
mediaRepository.setFavorite(audio.uri, !audio.isFavorite)
}
}
}

suspend fun removeAudioFromPlaylist() {
uri.value?.takeIf { mediaType.value == MediaType.AUDIO }?.let {
playlistUri.value?.let { playlistUri ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@
app:headlineText="@string/audio_play_next"
app:leadingIconImage="@drawable/ic_queue_play_next" />

<org.lineageos.twelve.ui.views.ListItem
android:id="@+id/addOrRemoveFromFavoritesListItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:headlineText="@string/add_to_favorites"
app:leadingIconImage="@drawable/ic_favorite" />

<org.lineageos.twelve.ui.views.ListItem
android:id="@+id/removeFromPlaylistListItem"
android:layout_width="match_parent"
Expand Down

0 comments on commit b669300

Please sign in to comment.