diff --git a/LeCountdown/AppDelegate.swift b/LeCountdown/AppDelegate.swift index 4496097..ee3f404 100644 --- a/LeCountdown/AppDelegate.swift +++ b/LeCountdown/AppDelegate.swift @@ -30,6 +30,7 @@ extension AppDelegate: UNUserNotificationCenterDelegate { completionHandler([.banner, .sound]) AppEnvironment.sun.endCountdown(countdownId: notification.request.identifier) + } } diff --git a/LeCountdown/CountdownScheduler.swift b/LeCountdown/CountdownScheduler.swift index b070b4e..071b43b 100644 --- a/LeCountdown/CountdownScheduler.swift +++ b/LeCountdown/CountdownScheduler.swift @@ -27,12 +27,14 @@ class CountdownScheduler { content.title = NSLocalizedString("It's time!", comment: "") let duration = countdown.duration - let minutes = duration / 60.0 + let body: String + if let name = countdown.activity?.name { + body = NSLocalizedString("Time's up for \(name)!", comment: "") + } else { + body = NSLocalizedString("Your \(duration.minuteSecond) countdown is over!", comment: "") + } - let minutesLabel = minutes > 1 ? NSLocalizedString("minutes", comment: "") : NSLocalizedString("minute", comment: "") - let isOrAre = minutes > 1 ? NSLocalizedString("are", comment: "") : NSLocalizedString("is", comment: "") - - content.body = NSLocalizedString("The \(minutes) \(minutesLabel) \(isOrAre) over!", comment: "") + content.body = body content.sound = UNNotificationSound.defaultCritical let trigger = UNTimeIntervalNotificationTrigger(timeInterval: duration, repeats: false) @@ -81,13 +83,17 @@ class AppEnvironment : ObservableObject { } func startCountdown(_ date: Date, countdown: Countdown) { - let dateInterval = DateInterval(start: Date(), end: date) - self.notificationDates[countdown.stringId] = dateInterval + DispatchQueue.main.async { + let dateInterval = DateInterval(start: Date(), end: date) + self.notificationDates[countdown.stringId] = dateInterval + } } func endCountdown(countdownId: String) { - self._recordActivityIfPossible(countdownId: countdownId) - self.notificationDates.removeValue(forKey: countdownId) + DispatchQueue.main.async { + self._recordActivityIfPossible(countdownId: countdownId) + self.notificationDates.removeValue(forKey: countdownId) + } } func cleanup() { diff --git a/LeCountdown/LeCountdownApp.swift b/LeCountdown/LeCountdownApp.swift index 924b8e0..e05da99 100644 --- a/LeCountdown/LeCountdownApp.swift +++ b/LeCountdown/LeCountdownApp.swift @@ -26,9 +26,7 @@ struct LeCountdownApp: App { } fileprivate func _willEnterForegroundNotification() { - DispatchQueue.main.async { - AppEnvironment.sun.cleanup() - } + AppEnvironment.sun.cleanup() } } diff --git a/LeCountdown/Model/Model+Extensions.swift b/LeCountdown/Model/Model+Extensions.swift index 2c425e4..ac9876d 100644 --- a/LeCountdown/Model/Model+Extensions.swift +++ b/LeCountdown/Model/Model+Extensions.swift @@ -10,7 +10,6 @@ import SwiftUI extension Countdown { - var name: String? { return self.activity?.name } @@ -28,3 +27,14 @@ extension Record { } } + +extension Activity { + + fileprivate static var formatter: NumberFormatter = NumberFormatter() + + var recordCount: String { + let count: Int = self.records?.count ?? 0 + return Activity.formatter.string(from: NSNumber(value: count)) ?? "--" + } + +} diff --git a/LeCountdown/Utils/PropertyWrappers.swift b/LeCountdown/Utils/PropertyWrappers.swift index d66e05c..05bfc71 100644 --- a/LeCountdown/Utils/PropertyWrappers.swift +++ b/LeCountdown/Utils/PropertyWrappers.swift @@ -8,7 +8,7 @@ import Foundation @propertyWrapper -struct UserDefault { +struct UserDefault { let key: String let defaultValue: T diff --git a/LeCountdown/Views/RecordsView.swift b/LeCountdown/Views/RecordsView.swift index ab67808..655fb6b 100644 --- a/LeCountdown/Views/RecordsView.swift +++ b/LeCountdown/Views/RecordsView.swift @@ -14,27 +14,36 @@ struct RecordsView: View { animation: .default) private var records: FetchedResults + @FetchRequest( + sortDescriptors: [NSSortDescriptor(keyPath: \Activity.name, ascending: true)], + predicate: NSPredicate(format: "records.@count > 0"), animation: .default) + private var activities: FetchedResults + var body: some View { - if records.isEmpty { - Text("You don't have any recorded activity yet") - } else { - List { - ForEach(records) { record in - HStack { - Text(record.activity?.name ?? "no activity") - Spacer() - Text(record.details) + Group { + if records.isEmpty { + Text("You don't have any recorded activity yet") + } else { + List { + ForEach(activities) { activity in + HStack { + Text(activity.name ?? "no activity") + Spacer() + Text(activity.recordCount) + } } } } - } + }.navigationTitle("Activities") } } struct RecordsView_Previews: PreviewProvider { static var previews: some View { - RecordsView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) + NavigationStack { + RecordsView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) + } } }