Twelve: Add play next/add to queue
diff --git a/app/src/main/java/org/lineageos/twelve/fragments/AudioBottomSheetDialogFragment.kt b/app/src/main/java/org/lineageos/twelve/fragments/AudioBottomSheetDialogFragment.kt
index 4d5c294..f2fed77 100644
--- a/app/src/main/java/org/lineageos/twelve/fragments/AudioBottomSheetDialogFragment.kt
+++ b/app/src/main/java/org/lineageos/twelve/fragments/AudioBottomSheetDialogFragment.kt
@@ -39,10 +39,12 @@
 
     // Views
     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)
     private val albumTitleTextView by getViewProperty<TextView>(R.id.albumTitleTextView)
     private val openAlbumListItem by getViewProperty<ListItem>(R.id.openAlbumListItem)
     private val openArtistListItem by getViewProperty<ListItem>(R.id.openArtistListItem)
+    private val playNextListItem by getViewProperty<ListItem>(R.id.playNextListItem)
     private val removeFromPlaylistListItem by getViewProperty<ListItem>(R.id.removeFromPlaylistListItem)
     private val titleTextView by getViewProperty<TextView>(R.id.titleTextView)
 
@@ -109,6 +111,18 @@
                     artistNameTextView.text = audio.artistName
                     albumTitleTextView.text = audio.albumTitle
 
+                    addToQueueListItem.setOnClickListener {
+                        viewModel.addToQueue(audio)
+
+                        findNavController().navigateUp()
+                    }
+
+                    playNextListItem.setOnClickListener {
+                        viewModel.playNext(audio)
+
+                        findNavController().navigateUp()
+                    }
+
                     openAlbumListItem.setOnClickListener {
                         findNavController().navigate(
                             R.id.action_audioBottomSheetDialogFragment_to_fragment_album,
diff --git a/app/src/main/java/org/lineageos/twelve/viewmodels/AudioViewModel.kt b/app/src/main/java/org/lineageos/twelve/viewmodels/AudioViewModel.kt
index 75cf379..d5c394a 100644
--- a/app/src/main/java/org/lineageos/twelve/viewmodels/AudioViewModel.kt
+++ b/app/src/main/java/org/lineageos/twelve/viewmodels/AudioViewModel.kt
@@ -17,6 +17,7 @@
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
+import org.lineageos.twelve.models.Audio
 import org.lineageos.twelve.models.RequestStatus
 
 open class AudioViewModel(application: Application) : TwelveViewModel(application) {
@@ -39,6 +40,19 @@
         this.audioUri.value = audioUri
     }
 
+    fun addToQueue(audio: Audio) = viewModelScope.launch {
+        mediaController.value?.addMediaItem(audio.toMedia3MediaItem())
+    }
+
+    fun playNext(audio: Audio) = viewModelScope.launch {
+        mediaController.value?.let { controller ->
+            controller.addMediaItem(
+                controller.currentMediaItemIndex + 1,
+                audio.toMedia3MediaItem()
+            )
+        }
+    }
+
     fun addToPlaylist(playlistUri: Uri) = viewModelScope.launch {
         audioUri.value?.let {
             mediaRepository.addAudioToPlaylist(playlistUri, it)
diff --git a/app/src/main/res/drawable/ic_add_to_queue.xml b/app/src/main/res/drawable/ic_add_to_queue.xml
new file mode 100644
index 0000000..8480d0f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_add_to_queue.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     SPDX-FileCopyrightText: Material Design Authors / Google LLC
+     SPDX-License-Identifier: Apache-2.0
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="#000000"
+    android:viewportWidth="960"
+    android:viewportHeight="960">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M440,600L520,600L520,480L640,480L640,400L520,400L520,280L440,280L440,400L320,400L320,480L440,480L440,600ZM320,840L320,760L160,760Q127,760 103.5,736.5Q80,713 80,680L80,200Q80,167 103.5,143.5Q127,120 160,120L800,120Q833,120 856.5,143.5Q880,167 880,200L880,680Q880,713 856.5,736.5Q833,760 800,760L640,760L640,840L320,840ZM160,680L800,680Q800,680 800,680Q800,680 800,680L800,200Q800,200 800,200Q800,200 800,200L160,200Q160,200 160,200Q160,200 160,200L160,680Q160,680 160,680Q160,680 160,680ZM160,680Q160,680 160,680Q160,680 160,680L160,200Q160,200 160,200Q160,200 160,200L160,200Q160,200 160,200Q160,200 160,200L160,680Q160,680 160,680Q160,680 160,680Z" />
+
+</vector>
diff --git a/app/src/main/res/drawable/ic_queue_play_next.xml b/app/src/main/res/drawable/ic_queue_play_next.xml
new file mode 100644
index 0000000..ee303e5
--- /dev/null
+++ b/app/src/main/res/drawable/ic_queue_play_next.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     SPDX-FileCopyrightText: Material Design Authors / Google LLC
+     SPDX-License-Identifier: Apache-2.0
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="#000000"
+    android:viewportWidth="960"
+    android:viewportHeight="960">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M780,900L720,840L840,720L720,600L780,540L960,720L780,900ZM320,840L320,760L160,760Q127,760 103.5,736.5Q80,713 80,680L80,200Q80,167 103.5,143.5Q127,120 160,120L800,120Q833,120 856.5,143.5Q880,167 880,200L880,480L800,480L800,200Q800,200 800,200Q800,200 800,200L160,200Q160,200 160,200Q160,200 160,200L160,680Q160,680 160,680Q160,680 160,680L680,680L680,760L600,760L600,840L320,840ZM440,600L520,600L520,480L640,480L640,400L520,400L520,280L440,280L440,400L320,400L320,480L440,480L440,600ZM160,680L160,680Q160,680 160,680Q160,680 160,680L160,200Q160,200 160,200Q160,200 160,200L160,200Q160,200 160,200Q160,200 160,200L160,680L160,680Z" />
+
+</vector>
diff --git a/app/src/main/res/layout/fragment_audio_bottom_sheet_dialog.xml b/app/src/main/res/layout/fragment_audio_bottom_sheet_dialog.xml
index 800acbf..7521b81 100644
--- a/app/src/main/res/layout/fragment_audio_bottom_sheet_dialog.xml
+++ b/app/src/main/res/layout/fragment_audio_bottom_sheet_dialog.xml
@@ -46,6 +46,20 @@
         android:layout_height="wrap_content" />
 
     <org.lineageos.twelve.ui.views.ListItem
+        android:id="@+id/addToQueueListItem"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:headlineText="@string/audio_add_to_queue"
+        app:leadingIconImage="@drawable/ic_add_to_queue" />
+
+    <org.lineageos.twelve.ui.views.ListItem
+        android:id="@+id/playNextListItem"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:headlineText="@string/audio_play_next"
+        app:leadingIconImage="@drawable/ic_queue_play_next" />
+
+    <org.lineageos.twelve.ui.views.ListItem
         android:id="@+id/removeFromPlaylistListItem"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1a78196..929ddd6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -61,6 +61,8 @@
     <string name="artist_appears_in_playlist_header">Appears in playlist</string>
 
     <!-- Audio info bottom sheet dialog fragment -->
+    <string name="audio_play_next">Play next</string>
+    <string name="audio_add_to_queue">Add to queue</string>
     <string name="audio_remove_from_playlist">Remove from playlist</string>
     <string name="audio_add_or_remove_from_playlists">Add or remove from playlists</string>
     <string name="open_album">Open album</string>