You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
LeCountdown/LeCountdown/Model/Model+Extensions.swift

179 lines
3.9 KiB

//
// Countdown+Extension.swift
// LeCountdown
//
// Created by Laurent Morvillier on 25/01/2023.
//
import Foundation
import SwiftUI
import CoreData
enum TimerError: Error {
case notificationAuthorizationMissing
}
extension AbstractTimer {
var displayName: String {
return self.name ?? self.coolpic.emoji
}
var name: String? {
return self.activity?.name
}
var url: URL {
if let url = URL(string: self.stringId) {
return url
} else {
fatalError("Can't produce url with \(self.stringId)")
}
}
var coolpic: CoolPic {
if let image, let coolpic = CoolPic(rawValue: image) {
return coolpic
}
return CoolPic.allCases[0]
}
var imageName: String {
return self.coolpic.rawValue
}
}
extension AbstractSoundTimer {
var sounds: Set<Sound> {
if let soundList {
return Set(soundList.enumItems())
}
return []
}
// var playlists: [Playlist] {
// if let playlistList {
// return playlistList.enumItems()
// }
// return []
// }
func setSounds(_ sounds: Set<Sound>) {
self.soundList = sounds.stringRepresentation
}
// func setPlaylists(_ playlists: [Playlist]) {
// self.playlistList = playlists.stringRepresentation
// }
var coolSound: Sound {
var allSounds: [Sound] = []
allSounds.append(contentsOf: self.sounds)
return allSounds.randomElement() ?? Sound.allCases[0]
}
var soundName: String {
return self.coolSound.soundName
}
}
extension Countdown {
static func fake(context: NSManagedObjectContext) -> Countdown {
let cd = Countdown(context: context)
cd.duration = 4 * 60.0
let activity = Activity(context: context)
activity.name = "Tea"
cd.activity = activity
return cd
}
}
extension Alarm {
static func fake(context: NSManagedObjectContext) -> Alarm {
let alarm = Alarm(context: context)
alarm.fireDate = Date()
let activity = Activity(context: context)
activity.name = "Wakeup"
alarm.activity = activity
return alarm
}
}
extension Stopwatch {
var coolSound: Sound? {
return Sound(rawValue: Int(self.sound)) ?? nil
}
static func fake(context: NSManagedObjectContext) -> Stopwatch {
let stopwatch = Stopwatch(context: context)
let activity = Activity(context: context)
activity.name = "Run"
stopwatch.activity = activity
return stopwatch
}
}
extension Record {
var details: String {
if let start, let end {
return "\(start) - \(end)"
} else {
return "no details"
}
}
}
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)) ?? "--"
}
}
extension CustomSound : Localized {
var localizedString: String {
return self.text ?? ""
}
}
// MARK: - Storage convenience
fileprivate let separator = "|"
fileprivate let formatter: NumberFormatter = NumberFormatter()
extension String {
func enumItems<T : RawRepresentable<Int>>() -> [T] {
let ids: [String] = self.components(separatedBy: separator)
let intIds: [Int] = ids.compactMap { formatter.number(from: $0)?.intValue }
return intIds.compactMap { T(rawValue: $0) }
}
}
extension Sequence where Element : RawRepresentable<Int> {
var stringRepresentation: String {
let ids = self.compactMap { formatter.string(from: NSNumber(value: $0.rawValue)) }
return ids.joined(separator: separator)
}
}