AddToPlaylistSheet.swift 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import SwiftData
  2. import SwiftUI
  3. /// "Add to Playlist" sheet — pick which playlist to add a track to.
  4. struct AddToPlaylistSheet: View {
  5. let track: Track
  6. @Environment(PlaylistViewModel.self) private var playlistVM
  7. @EnvironmentObject private var theme: AppTheme
  8. @Environment(\.modelContext) private var modelContext
  9. @Environment(\.dismiss) private var dismiss
  10. @Query(sort: \Playlist.dateModified, order: .reverse) private var playlists: [Playlist]
  11. @State private var showNewPlaylist = false
  12. @State private var newPlaylistName = ""
  13. var body: some View {
  14. NavigationStack {
  15. List {
  16. Section {
  17. Button {
  18. showNewPlaylist = true
  19. } label: {
  20. Label("New Playlist", systemImage: "plus.circle")
  21. .foregroundStyle(theme.accent)
  22. }
  23. }
  24. Section("Existing Playlists") {
  25. ForEach(playlists) { playlist in
  26. let isDuplicate = playlistVM.isDuplicate(track: track, in: playlist, context: modelContext)
  27. Button {
  28. playlistVM.addTrack(track, to: playlist, context: modelContext)
  29. dismiss()
  30. } label: {
  31. HStack {
  32. Circle()
  33. .fill(Color(hex: playlist.color) ?? theme.accent)
  34. .frame(width: 10, height: 10)
  35. Text(playlist.name)
  36. .foregroundStyle(theme.primaryText)
  37. Spacer()
  38. if isDuplicate {
  39. Text("Already added")
  40. .font(.caption)
  41. .foregroundStyle(theme.tertiaryText)
  42. }
  43. Text("\(playlist.trackCount)")
  44. .font(.caption)
  45. .foregroundStyle(theme.tertiaryText)
  46. }
  47. }
  48. .disabled(isDuplicate)
  49. .opacity(isDuplicate ? 0.5 : 1)
  50. }
  51. }
  52. }
  53. .navigationTitle("Add to Playlist")
  54. .navigationBarTitleDisplayMode(.inline)
  55. .toolbar {
  56. ToolbarItem(placement: .cancellationAction) {
  57. Button("Cancel") { dismiss() }
  58. }
  59. }
  60. .alert("New Playlist", isPresented: $showNewPlaylist) {
  61. TextField("Playlist name", text: $newPlaylistName)
  62. Button("Cancel", role: .cancel) { newPlaylistName = "" }
  63. Button("Create & Add") {
  64. guard !newPlaylistName.isEmpty else { return }
  65. let pl = playlistVM.createPlaylist(name: newPlaylistName, context: modelContext)
  66. playlistVM.addTrack(track, to: pl, context: modelContext)
  67. dismiss()
  68. }
  69. }
  70. }
  71. }
  72. }