AlarmAudioSection.swift 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. //
  2. // AlarmAudioSection.swift
  3. // LoopFollow
  4. //
  5. // Created by Jonas Björkert on 2025-05-12.
  6. // Copyright © 2025 Jon Fawcett. All rights reserved.
  7. //
  8. import SwiftUI
  9. struct AlarmAudioSection: View {
  10. @Binding var alarm: Alarm
  11. @State private var showingTonePicker = false
  12. var body: some View {
  13. Section(header: Text("Alert Sound")) {
  14. Button {
  15. showingTonePicker = true
  16. } label: {
  17. HStack {
  18. Text("Tone")
  19. Spacer()
  20. Text(alarm.soundFile.displayName)
  21. .foregroundColor(.secondary)
  22. Image(systemName: "chevron.right")
  23. .foregroundColor(.secondary)
  24. }
  25. }
  26. .buttonStyle(.plain)
  27. .sheet(isPresented: $showingTonePicker) {
  28. TonePickerSheet(selected: $alarm.soundFile)
  29. }
  30. AlarmEnumMenuPicker(title: "Play", selection: $alarm.playSoundOption)
  31. AlarmEnumMenuPicker(title: "Repeat", selection: $alarm.repeatSoundOption)
  32. }
  33. }
  34. }
  35. struct AlarmEnumMenuPicker<E: CaseIterable & Hashable & DayNightDisplayable>: View {
  36. let title: String
  37. @Binding var selection: E
  38. var body: some View {
  39. HStack {
  40. Text(title)
  41. Spacer()
  42. Picker("", selection: $selection) {
  43. ForEach(Array(E.allCases), id: \.self) { option in
  44. Text(option.displayName).tag(option)
  45. }
  46. }
  47. }
  48. }
  49. }
  50. private struct TonePickerSheet: View {
  51. @Binding var selected: SoundFile
  52. @Environment(\.dismiss) private var dismiss
  53. var body: some View {
  54. NavigationView {
  55. List {
  56. ForEach(SoundFile.allCases) { tone in
  57. Button {
  58. selected = tone
  59. AlarmSound.setSoundFile(str: tone.rawValue)
  60. AlarmSound.stop()
  61. AlarmSound.playTest()
  62. } label: {
  63. HStack {
  64. Text(tone.displayName)
  65. if tone == selected {
  66. Spacer()
  67. Image(systemName: "checkmark")
  68. .foregroundColor(.accentColor)
  69. }
  70. }
  71. }
  72. }
  73. }
  74. .navigationTitle("Choose Tone")
  75. .toolbar {
  76. ToolbarItem(placement: .confirmationAction) {
  77. Button("Done") {
  78. AlarmSound.stop()
  79. dismiss()
  80. }
  81. }
  82. }
  83. }
  84. }
  85. }