mirror of
https://github.com/apognu/otter
synced 2025-02-18 19:50:35 +01:00
#81: added save current queue to playlist.
This commit is contained in:
parent
785fa6ce19
commit
6bdefa1936
@ -382,7 +382,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
is Command.RefreshTrack -> refreshCurrentTrack(command.track)
|
is Command.RefreshTrack -> refreshCurrentTrack(command.track)
|
||||||
|
|
||||||
is Command.AddToPlaylist -> if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
|
is Command.AddToPlaylist -> if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
|
||||||
AddToPlaylistDialog.show(this@MainActivity, lifecycleScope, command.track)
|
AddToPlaylistDialog.show(this@MainActivity, lifecycleScope, command.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ class SearchActivity : AppCompatActivity() {
|
|||||||
CommandBus.get().collect { command ->
|
CommandBus.get().collect { command ->
|
||||||
when (command) {
|
when (command) {
|
||||||
is Command.AddToPlaylist -> if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
|
is Command.AddToPlaylist -> if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
|
||||||
AddToPlaylistDialog.show(this@SearchActivity, lifecycleScope, command.track)
|
AddToPlaylistDialog.show(this@SearchActivity, lifecycleScope, command.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ class SearchAdapter(private val context: Context?, private val listener: OnSearc
|
|||||||
R.id.track_add_to_queue -> CommandBus.send(Command.AddToQueue(listOf(track)))
|
R.id.track_add_to_queue -> CommandBus.send(Command.AddToQueue(listOf(track)))
|
||||||
R.id.track_play_next -> CommandBus.send(Command.PlayNext(track))
|
R.id.track_play_next -> CommandBus.send(Command.PlayNext(track))
|
||||||
R.id.track_pin -> CommandBus.send(Command.PinTrack(track))
|
R.id.track_pin -> CommandBus.send(Command.PinTrack(track))
|
||||||
R.id.track_add_to_playlist -> CommandBus.send(Command.AddToPlaylist(track))
|
R.id.track_add_to_playlist -> CommandBus.send(Command.AddToPlaylist(listOf(track)))
|
||||||
R.id.queue_remove -> CommandBus.send(Command.RemoveFromQueue(track))
|
R.id.queue_remove -> CommandBus.send(Command.RemoveFromQueue(track))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
|
|||||||
R.id.track_add_to_queue -> CommandBus.send(Command.AddToQueue(listOf(track)))
|
R.id.track_add_to_queue -> CommandBus.send(Command.AddToQueue(listOf(track)))
|
||||||
R.id.track_play_next -> CommandBus.send(Command.PlayNext(track))
|
R.id.track_play_next -> CommandBus.send(Command.PlayNext(track))
|
||||||
R.id.track_pin -> CommandBus.send(Command.PinTrack(track))
|
R.id.track_pin -> CommandBus.send(Command.PinTrack(track))
|
||||||
R.id.track_add_to_playlist -> CommandBus.send(Command.AddToPlaylist(track))
|
R.id.track_add_to_playlist -> CommandBus.send(Command.AddToPlaylist(listOf(track)))
|
||||||
R.id.queue_remove -> CommandBus.send(Command.RemoveFromQueue(track))
|
R.id.queue_remove -> CommandBus.send(Command.RemoveFromQueue(track))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
object AddToPlaylistDialog {
|
object AddToPlaylistDialog {
|
||||||
fun show(activity: Activity, lifecycleScope: CoroutineScope, track: Track) {
|
fun show(activity: Activity, lifecycleScope: CoroutineScope, tracks: List<Track>) {
|
||||||
val dialog = AlertDialog.Builder(activity).run {
|
val dialog = AlertDialog.Builder(activity).run {
|
||||||
setTitle(activity.getString(R.string.playlist_add_to))
|
setTitle(activity.getString(R.string.playlist_add_to))
|
||||||
setView(activity.layoutInflater.inflate(R.layout.dialog_add_to_playlist, null))
|
setView(activity.layoutInflater.inflate(R.layout.dialog_add_to_playlist, null))
|
||||||
@ -42,7 +42,7 @@ object AddToPlaylistDialog {
|
|||||||
|
|
||||||
lifecycleScope.launch(IO) {
|
lifecycleScope.launch(IO) {
|
||||||
repository.new(name)?.let { id ->
|
repository.new(name)?.let { id ->
|
||||||
repository.add(id, track)
|
repository.add(id, tracks)
|
||||||
|
|
||||||
withContext(Main) {
|
withContext(Main) {
|
||||||
Toast.makeText(activity, activity.getString(R.string.playlist_added_to, name), Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, activity.getString(R.string.playlist_added_to, name), Toast.LENGTH_SHORT).show()
|
||||||
@ -55,7 +55,7 @@ object AddToPlaylistDialog {
|
|||||||
|
|
||||||
val adapter = PlaylistsAdapter(activity, object : PlaylistsAdapter.OnPlaylistClickListener {
|
val adapter = PlaylistsAdapter(activity, object : PlaylistsAdapter.OnPlaylistClickListener {
|
||||||
override fun onClick(holder: View?, playlist: Playlist) {
|
override fun onClick(holder: View?, playlist: Playlist) {
|
||||||
repository.add(playlist.id, track)
|
repository.add(playlist.id, tracks)
|
||||||
|
|
||||||
Toast.makeText(activity, activity.getString(R.string.playlist_added_to, playlist.name), Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, activity.getString(R.string.playlist_added_to, playlist.name), Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
|
@ -44,6 +44,12 @@ class LandscapeQueueFragment : Fragment() {
|
|||||||
CommandBus.send(Command.ShuffleQueue)
|
CommandBus.send(Command.ShuffleQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queue_save.setOnClickListener {
|
||||||
|
adapter?.data?.let {
|
||||||
|
CommandBus.send(Command.AddToPlaylist(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
queue_clear.setOnClickListener {
|
queue_clear.setOnClickListener {
|
||||||
CommandBus.send(Command.ClearQueue)
|
CommandBus.send(Command.ClearQueue)
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,12 @@ class QueueFragment : BottomSheetDialogFragment() {
|
|||||||
CommandBus.send(Command.ShuffleQueue)
|
CommandBus.send(Command.ShuffleQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queue_save.setOnClickListener {
|
||||||
|
adapter?.data?.let {
|
||||||
|
CommandBus.send(Command.AddToPlaylist(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
queue_clear.setOnClickListener {
|
queue_clear.setOnClickListener {
|
||||||
CommandBus.send(Command.ClearQueue)
|
CommandBus.send(Command.ClearQueue)
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,8 @@ class ManagementPlaylistsRepository(override val context: Context?) : Repository
|
|||||||
return result.get().id
|
return result.get().id
|
||||||
}
|
}
|
||||||
|
|
||||||
fun add(id: Int, track: Track) {
|
fun add(id: Int, tracks: List<Track>) {
|
||||||
val body = PlaylistAdd(listOf(track.id), false)
|
val body = PlaylistAdd(tracks.map { it.id }, false)
|
||||||
|
|
||||||
val request = Fuel.post(mustNormalizeUrl("/api/v1/playlists/${id}/add/")).apply {
|
val request = Fuel.post(mustNormalizeUrl("/api/v1/playlists/${id}/add/")).apply {
|
||||||
if (!Settings.isAnonymous()) {
|
if (!Settings.isAnonymous()) {
|
||||||
|
@ -22,7 +22,7 @@ sealed class Command {
|
|||||||
class Seek(val progress: Int) : Command()
|
class Seek(val progress: Int) : Command()
|
||||||
|
|
||||||
class AddToQueue(val tracks: List<Track>) : Command()
|
class AddToQueue(val tracks: List<Track>) : Command()
|
||||||
class AddToPlaylist(val track: Track) : Command()
|
class AddToPlaylist(val tracks: List<Track>) : Command()
|
||||||
class PlayNext(val track: Track) : Command()
|
class PlayNext(val track: Track) : Command()
|
||||||
class ReplaceQueue(val queue: List<Track>, val fromRadio: Boolean = false) : Command()
|
class ReplaceQueue(val queue: List<Track>, val fromRadio: Boolean = false) : Command()
|
||||||
class RemoveFromQueue(val track: Track) : Command()
|
class RemoveFromQueue(val track: Track) : Command()
|
||||||
|
10
app/src/main/res/drawable/playlist.xml
Normal file
10
app/src/main/res/drawable/playlist.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M4,10h12v2L4,12zM4,6h12v2L4,8zM4,14h8v2L4,16zM14,14v6l5,-3z"/>
|
||||||
|
</vector>
|
@ -222,8 +222,8 @@
|
|||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/now_playing_details_previous"
|
android:id="@+id/now_playing_details_previous"
|
||||||
style="@style/IconButton"
|
style="@style/IconButton"
|
||||||
android:layout_width="48dp"
|
android:layout_width="32dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="32dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:contentDescription="@string/control_previous"
|
android:contentDescription="@string/control_previous"
|
||||||
android:src="@drawable/previous" />
|
android:src="@drawable/previous" />
|
||||||
@ -240,8 +240,8 @@
|
|||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/now_playing_details_next"
|
android:id="@+id/now_playing_details_next"
|
||||||
style="@style/IconButton"
|
style="@style/IconButton"
|
||||||
android:layout_width="48dp"
|
android:layout_width="32dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="32dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:contentDescription="@string/control_next"
|
android:contentDescription="@string/control_next"
|
||||||
android:src="@drawable/next" />
|
android:src="@drawable/next" />
|
||||||
|
@ -13,32 +13,45 @@
|
|||||||
android:paddingHorizontal="8dp"
|
android:paddingHorizontal="8dp"
|
||||||
android:paddingVertical="4dp">
|
android:paddingVertical="4dp">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/queue_save"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.Icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:backgroundTint="@color/colorPrimary"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/playback_queue_save"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:icon="@drawable/playlist"
|
||||||
|
app:iconTint="@android:color/white"
|
||||||
|
app:rippleColor="@color/ripple" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/queue_shuffle"
|
android:id="@+id/queue_shuffle"
|
||||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="4dp"
|
android:layout_marginHorizontal="4dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/playback_shuffle"
|
android:text="@string/playback_shuffle"
|
||||||
android:textColor="@color/colorPrimary"
|
android:textColor="@color/controlForeground"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
app:icon="@drawable/shuffle"
|
app:icon="@drawable/shuffle"
|
||||||
app:iconTint="@color/colorPrimary"
|
app:iconTint="@color/controlForeground"
|
||||||
app:rippleColor="@color/ripple" />
|
app:rippleColor="@color/ripple" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/queue_clear"
|
android:id="@+id/queue_clear"
|
||||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
|
style="@style/AppTheme.IconButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
android:layout_marginStart="4dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="0"
|
||||||
android:text="@string/playback_queue_clear"
|
|
||||||
android:textColor="@color/colorPrimary"
|
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
app:icon="@drawable/delete"
|
app:icon="@drawable/delete"
|
||||||
app:iconTint="@color/colorPrimary"
|
app:iconTint="@color/controlForeground"
|
||||||
app:rippleColor="@color/ripple" />
|
app:rippleColor="@color/ripple" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
<string name="playback_queue_play_next">Prochaine écoute</string>
|
<string name="playback_queue_play_next">Prochaine écoute</string>
|
||||||
<string name="playback_queue_download">Télécharger</string>
|
<string name="playback_queue_download">Télécharger</string>
|
||||||
<string name="playback_queue_clear">Effacer</string>
|
<string name="playback_queue_clear">Effacer</string>
|
||||||
|
<string name="playback_queue_save">Enregistrer</string>
|
||||||
<string name="manage_add_to_favorites">Ajouter aux favoris</string>
|
<string name="manage_add_to_favorites">Ajouter aux favoris</string>
|
||||||
<string name="control_toggle">Lecture / pause</string>
|
<string name="control_toggle">Lecture / pause</string>
|
||||||
<string name="control_previous">Piste précédente</string>
|
<string name="control_previous">Piste précédente</string>
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
<string name="playback_queue_play_next">Play next</string>
|
<string name="playback_queue_play_next">Play next</string>
|
||||||
<string name="playback_queue_download">Download</string>
|
<string name="playback_queue_download">Download</string>
|
||||||
<string name="playback_queue_clear">Clear</string>
|
<string name="playback_queue_clear">Clear</string>
|
||||||
|
<string name="playback_queue_save">Save</string>
|
||||||
<string name="manage_add_to_favorites">Add to favorites</string>
|
<string name="manage_add_to_favorites">Add to favorites</string>
|
||||||
<string name="control_toggle">Toggle playback</string>
|
<string name="control_toggle">Toggle playback</string>
|
||||||
<string name="control_previous">Previous track</string>
|
<string name="control_previous">Previous track</string>
|
||||||
|
@ -105,4 +105,14 @@
|
|||||||
<item name="android:textColor">@android:color/white</item>
|
<item name="android:textColor">@android:color/white</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="AppTheme.IconButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
|
||||||
|
<item name="iconPadding">0dp</item>
|
||||||
|
<item name="android:insetBottom">0dp</item>
|
||||||
|
<item name="android:paddingLeft">12dp</item>
|
||||||
|
<item name="android:paddingRight">12dp</item>
|
||||||
|
<item name="android:minWidth">43dp</item>
|
||||||
|
<item name="android:minHeight">43dp</item>
|
||||||
|
<item name="android:background">@android:color/transparent</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user