Fixes many issues

release
Laurent 3 years ago
parent 929127cb8f
commit 30867eb258
  1. 22
      LeCountdown/AppDelegate.swift
  2. 10
      LeCountdown/Conductor.swift
  3. 6
      LeCountdown/CountdownScheduler.swift
  4. 8
      LeCountdown/Model/Model+Extensions.swift
  5. 7
      LeCountdown/Views/Alarm/NewAlarmView.swift
  6. 6
      LeCountdown/Views/Components/SoundImageFormView.swift
  7. 17
      LeCountdown/Views/Components/SoundSelectionView.swift
  8. 11
      LeCountdown/Views/Components/TimerModel.swift
  9. 30
      LeCountdown/Views/Countdown/NewCountdownView.swift

@ -24,12 +24,8 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
print("didReceive notification")
let notificationId = response.notification.request.identifier
let components = notificationId.components(separatedBy: CountdownScheduler.notificationIdSeparator)
if components.count == 2 {
Conductor.maestro.cancelCountdown(id: components[0])
}
let timerId = self._timerId(notificationId: response.notification.request.identifier)
Conductor.maestro.cancelCountdown(id: timerId)
}
@ -37,7 +33,19 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
print("willPresent notification")
completionHandler([.banner])
Conductor.maestro.notifyUser(countdownId: notification.request.identifier)
let timerId = self._timerId(notificationId: notification.request.identifier)
Conductor.maestro.notifyUser(countdownId: timerId)
}
fileprivate func _timerId(notificationId: String) -> String {
let components = notificationId.components(separatedBy: CountdownScheduler.notificationIdSeparator)
if components.count == 2 {
return components[0]
} else {
fatalError("bad notification format : \(notificationId)")
}
}
}

@ -52,7 +52,6 @@ class Conductor: ObservableObject {
fileprivate var _cleanupTimers: [String : Timer] = [:]
func removeLiveTimer(id: String) {
self.stopSoundIfPossible()
self.liveTimers.removeAll(where: { $0.id == id })
}
@ -64,7 +63,9 @@ class Conductor: ObservableObject {
// add countdown if not present
for liveCountdown in liveCountdowns {
if self.liveTimers.first(where: { $0.id == liveCountdown.id }) == nil {
if let livetimer = self.liveTimers.first(where: { $0.id == liveCountdown.id }) {
self.liveTimers.replace([livetimer], with: [liveCountdown])
} else {
self.liveTimers.append(liveCountdown)
}
}
@ -180,7 +181,8 @@ class Conductor: ObservableObject {
let context = PersistenceController.shared.container.viewContext
var coolSound: Sound? = nil
switch context.object(stringId: timerId) {
let timer = context.object(stringId: timerId)
switch timer {
case let cd as Countdown:
coolSound = cd.coolSound
case let sw as Stopwatch:
@ -199,6 +201,8 @@ class Conductor: ObservableObject {
print("error = \(error)")
// TODO: manage error
}
} else {
print("No sound to play!")
}
}

@ -42,7 +42,11 @@ class CountdownScheduler {
}
content.body = body
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: countdown.soundName))
let sound = countdown.soundName
print("Selected sound = \(sound)")
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: sound))
content.interruptionLevel = .critical
content.relevanceScore = 1.0

@ -46,9 +46,9 @@ extension AbstractTimer {
extension AbstractSoundTimer {
var sounds: [Sound] {
var sounds: Set<Sound> {
if let soundList {
return soundList.enumItems()
return Set(soundList.enumItems())
}
return []
}
@ -60,7 +60,7 @@ extension AbstractSoundTimer {
// return []
// }
func setSounds(_ sounds: [Sound]) {
func setSounds(_ sounds: Set<Sound>) {
self.soundList = sounds.stringRepresentation
}
@ -160,7 +160,7 @@ extension String {
}
extension Array where Element : RawRepresentable<Int> {
extension Sequence where Element : RawRepresentable<Int> {
var stringRepresentation: String {
let ids = self.compactMap { formatter.string(from: NSNumber(value: $0.rawValue)) }

@ -36,9 +36,6 @@ struct AlarmEditView: View {
@State var nameString: String = ""
@State var sounds: [Sound] = [.trainhorn]
@State var playlists: [Playlist] = []
@State var soundRepeatCount: Int16 = 0
@State var image: CoolPic = .pic1
@ -152,7 +149,7 @@ struct AlarmEditView: View {
self.nameString = name
}
self.sounds = alarm.sounds
// self.sounds = alarm.sounds
// self.playlists = alarm.playlists
if let image = alarm.image, let coolpic = CoolPic(rawValue: image) {
@ -183,7 +180,7 @@ struct AlarmEditView: View {
a.fireDate = self.time
a.image = self.image.rawValue
a.setSounds(self.sounds)
// a.setSounds(self.sounds)
// a.setPlaylists(self.playlists)
a.repeatCount = self.soundRepeatCount

@ -60,7 +60,11 @@ struct SoundImageFormView : View {
NavigationLink {
PlaylistsView().environmentObject(self.model)
} label: {
Text("Sound")
HStack {
Text("Sound")
Spacer()
Text(self.model.soundSelection)
}
}
Picker("Repeat Count", selection: self.repeatCountBinding!) {

@ -18,7 +18,7 @@ struct PlaylistsView: View {
PlaylistSectionView(playlist: playlist)
.environmentObject(self.model)
}
}
}.navigationTitle("Sounds")
}
@ -34,7 +34,7 @@ struct PlaylistSectionView: View {
Section {
let sounds = SoundCatalog.main.sounds(for: self.playlist)
List(sounds) { sound in
ForEach(sounds) { sound in
ToggleRow(item: sound, selected: self.model.binding(sound: sound)) { selected in
self.model.selectSound(sound, selected: selected)
}
@ -116,7 +116,7 @@ struct SoundSelectionView: View {
}
struct PlaylistsView_Previews: PreviewProvider {
static func soundBinding(sound: Sound) -> Binding<Bool> {
return .constant(true)
}
@ -126,23 +126,16 @@ struct PlaylistsView_Previews: PreviewProvider {
static var previews: some View {
PlaylistsView()
.environmentObject(SoundHolderPlaceholder())
.environmentObject(TimerModel())
}
}
struct PlaylistSectionView_Previews: PreviewProvider {
static func soundBinding(sound: Sound) -> Binding<Bool> {
return .constant(true)
}
static func playlistBinding(playlist: Playlist) -> Binding<Bool> {
return .constant(true)
}
static var previews: some View {
Form {
PlaylistSectionView(playlist: .stephanBodzin)
.environmentObject(SoundHolderPlaceholder())
.environmentObject(TimerModel())
}
}
}

@ -21,6 +21,17 @@ class TimerModel : ObservableObject, SoundHolder {
@Published var playlists: Set<Playlist> = []
@Published var sounds: Set<Sound> = []
var soundSelection: String {
if !sounds.isEmpty {
if sounds.count == 1 {
return sounds.first!.localizedString
} else {
return "\(sounds.count) \(NSLocalizedString("sounds", comment: "sounds"))"
}
}
return ""
}
func binding(sound: Sound) -> Binding<Bool> {
return Binding<Bool>(get: {
return self.sounds.contains(sound)

@ -38,9 +38,6 @@ struct CountdownEditView : View {
@State var minutesString: String = ""
@State var nameString: String = ""
@State var playlists: Set<Playlist> = []
@State var sounds: Set<Sound> = []
@State var soundRepeatCount: Int16 = 0
@State var image: CoolPic = .pic1
@ -140,26 +137,6 @@ struct CountdownEditView : View {
}
// MARK: - Bindings
func playlistBinding(playlist: Playlist) -> Binding<Bool> {
Binding<Bool>(
get: { self.playlists.contains(playlist) },
set: { if $0 { self.playlists.insert(playlist) }
else { self.playlists.remove(playlist) }
}
)
}
func soundBinding(sound: Sound) -> Binding<Bool> {
Binding<Bool>(
get: { self.sounds.contains(sound) },
set: { if $0 { self.sounds.insert(sound) }
else { self.sounds.remove(sound) }
}
)
}
// MARK: - Business
fileprivate func _onAppear() {
@ -170,6 +147,8 @@ struct CountdownEditView : View {
if let countdown {
print("self.soundList = \(countdown.soundList)")
let minutes = Int(countdown.duration / 60.0)
let seconds = countdown.duration - Double(minutes * 60)
@ -185,7 +164,7 @@ struct CountdownEditView : View {
self.nameString = name
}
// self.sounds = countdown.sounds
self.model.sounds = countdown.sounds
// if let sound = Sound(rawValue: Int(countdown.sound)) {
// self.sound = sound
@ -230,7 +209,8 @@ struct CountdownEditView : View {
}
cd.image = self.image.rawValue
// cd.setSounds(self.sounds)
cd.setSounds(self.model.sounds)
// cd.setPlaylists(self.playlists)
cd.repeatCount = self.soundRepeatCount

Loading…
Cancel
Save