Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.widget.Toast
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.Toolbar
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.NavHostFragment
Expand All @@ -22,6 +23,7 @@ import com.simplecityapps.adapter.RecyclerAdapter
import com.simplecityapps.shuttle.R
import com.simplecityapps.shuttle.model.PlaylistSong
import com.simplecityapps.shuttle.sorting.PlaylistSongSortOrder
import com.simplecityapps.shuttle.ui.common.ContextualToolbarHelper
import com.simplecityapps.shuttle.ui.common.TagEditorMenuSanitiser
import com.simplecityapps.shuttle.ui.common.autoCleared
import com.simplecityapps.shuttle.ui.common.dialog.EditTextAlertDialog
Expand Down Expand Up @@ -67,10 +69,14 @@ class PlaylistDetailFragment :

private var toolbar: Toolbar? = null

private var contextualToolbar: Toolbar? = null

private var recyclerView: RecyclerView by autoCleared()

private var heroImage: ImageView by autoCleared()

private var contextualToolbarHelper: ContextualToolbarHelper<PlaylistSong> by autoCleared()

// Lifecycle

override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -94,9 +100,17 @@ class PlaylistDetailFragment :

recyclerView = view.findViewById(R.id.recyclerView)
toolbar = view.findViewById(R.id.toolbar)
contextualToolbar = view.findViewById(R.id.contextualToolbar)

playlistMenuView = PlaylistMenuView(requireContext(), playlistMenuPresenter, childFragmentManager)

contextualToolbarHelper = ContextualToolbarHelper()
contextualToolbarHelper.toolbar = toolbar
contextualToolbarHelper.contextualToolbar = contextualToolbar
contextualToolbarHelper.callback = contextualToolbarCallback

setupContextualToolbar()

adapter = RecyclerAdapter(viewLifecycleOwner.lifecycleScope)

toolbar?.let { toolbar ->
Expand Down Expand Up @@ -221,6 +235,59 @@ class PlaylistDetailFragment :
) {}
) {}

private fun setupContextualToolbar() {
contextualToolbar?.let { contextualToolbar ->
contextualToolbar.menu.clear()
contextualToolbar.inflateMenu(R.menu.menu_multi_select)
contextualToolbar.setOnMenuItemClickListener { menuItem ->
playlistMenuView.createPlaylistMenu(contextualToolbar.menu)
if (playlistMenuView.handleMenuItem(menuItem, PlaylistData.Songs(contextualToolbarHelper.selectedItems.map { it.song }.toList()))) {
contextualToolbarHelper.hide()
return@setOnMenuItemClickListener true
}
when (menuItem.itemId) {
R.id.queue -> {
presenter.addToQueue(contextualToolbarHelper.selectedItems.toList())
contextualToolbarHelper.hide()
true
}
R.id.editTags -> {
presenter.editTags(contextualToolbarHelper.selectedItems.toList())
contextualToolbarHelper.hide()
true
}
else -> false
}
}
}
}

private val contextualToolbarCallback =
object : ContextualToolbarHelper.Callback<PlaylistSong> {
override fun onCountChanged(count: Int) {
contextualToolbarHelper.contextualToolbar?.title =
Phrase.fromPlural(requireContext(), R.plurals.multi_select_items_selected, count)
.put("count", count)
.format()
contextualToolbarHelper.contextualToolbar?.menu?.let { menu ->
TagEditorMenuSanitiser.sanitise(menu, contextualToolbarHelper.selectedItems.map { it.song.mediaProvider }.distinct())
}
}

override fun onItemUpdated(
item: PlaylistSong,
isSelected: Boolean
) {
adapter.items
.filterIsInstance<PlaylistSongBinder>()
.firstOrNull { it.playlistSong.id == item.id }
?.let { viewBinder ->
viewBinder.selected = isSelected
adapter.notifyItemChanged(adapter.items.indexOf(viewBinder))
}
}
}

// PlaylistDetailContract.View Implementation

override fun setPlaylist(playlist: com.simplecityapps.shuttle.model.Playlist) {
Expand Down Expand Up @@ -266,7 +333,9 @@ class PlaylistDetailFragment :
imageLoader = imageLoader,
listener = songBinderListener,
showDragHandle = showDragHandle
)
).apply {
selected = contextualToolbarHelper.selectedItems.any { it.id == playlistSong.id }
}
}
)
}
Expand Down Expand Up @@ -320,13 +389,20 @@ class PlaylistDetailFragment :
index: Int,
playlistSong: PlaylistSong
) {
presenter.onSongClicked(playlistSong, index)
if (!contextualToolbarHelper.handleClick(playlistSong)) {
presenter.onSongClicked(playlistSong, index)
}
}

override fun onPlaylistSongLongClicked(
holder: PlaylistSongBinder.ViewHolder,
playlistSong: PlaylistSong
) {
if (contextualToolbarHelper.handleLongClick(playlistSong)) {
// Multi-select mode activated
return
}

val popupMenu = PopupMenu(requireContext(), holder.itemView)
popupMenu.inflate(R.menu.menu_popup_playlist_song)
TagEditorMenuSanitiser.sanitise(popupMenu.menu, listOf(playlistSong.song.mediaProvider))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,16 @@ interface PlaylistDetailContract {

fun addToQueue(playlistSong: PlaylistSong)

fun addToQueue(playlistSongs: List<PlaylistSong>)

fun playNext(playlistSong: PlaylistSong)

fun exclude(playlistSong: PlaylistSong)

fun editTags(playlistSong: PlaylistSong)

fun editTags(playlistSongs: List<PlaylistSong>)

fun remove(playlistSong: PlaylistSong)

fun delete(playlistSong: PlaylistSong)
Expand Down Expand Up @@ -189,6 +193,12 @@ constructor(
}
}

override fun addToQueue(playlistSongs: List<PlaylistSong>) {
launch {
playbackManager.addToQueue(playlistSongs.map { it.song })
}
}

override fun addToQueue(playlist: Playlist) {
launch {
playbackManager.addToQueue(playlistSongs.value.orEmpty().map { it.song })
Expand All @@ -214,6 +224,10 @@ constructor(
view?.showTagEditor(listOf(playlistSong))
}

override fun editTags(playlistSongs: List<PlaylistSong>) {
view?.showTagEditor(playlistSongs)
}

override fun remove(playlistSong: PlaylistSong) {
launch {
playlistRepository.removeFromPlaylist(playlist.value, listOf(playlistSong))
Expand Down
39 changes: 27 additions & 12 deletions android/app/src/main/res/layout/fragment_playlist_detail.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,36 @@
app:layout_collapseParallaxMultiplier="0.5"
tools:srcCompat="@drawable/ic_placeholder_playlist" />

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/rounded_background"
android:minHeight="?attr/actionBarSize"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:layout_collapseMode="pin"
app:navigationIcon="?attr/homeAsUpIndicator"
tools:subtitle="32 songs | 2:08:15"
tools:title="Favourites">

</androidx.appcompat.widget.Toolbar>
app:layout_collapseMode="pin">

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rounded_background"
android:minHeight="?attr/actionBarSize"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:navigationIcon="?attr/homeAsUpIndicator"
tools:subtitle="32 songs | 2:08:15"
tools:title="Favourites" />

<androidx.appcompat.widget.Toolbar
android:id="@+id/contextualToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rounded_background"
android:minHeight="?attr/actionBarSize"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:visibility="gone"
app:navigationIcon="?attr/homeAsUpIndicator" />

</FrameLayout>

</com.google.android.material.appbar.CollapsingToolbarLayout>

Expand Down