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

150 lines
3.4 KiB

//
// Countdown+Extension.swift
// LeCountdown
//
// Created by Laurent Morvillier on 25/01/2023.
//
import Foundation
import SwiftUI
import CoreData
extension AbstractSoundTimer {
var sounds: Set<Sound> {
if let soundList {
return Set(soundList.enumItems())
}
return []
}
func setSounds(_ sounds: Set<Sound>) {
self.soundList = sounds.stringRepresentation
}
var coolSound: Sound {
var sounds = self.sounds
// remove last played sound if the playlist has at least 3 sounds
if sounds.count > 2,
let lastSoundId = Preferences.lastSelectedSound[self.stringId],
let lastSound = Sound(rawValue: lastSoundId) {
sounds.remove(lastSound)
}
if let random = sounds.randomElement() {
Preferences.lastSelectedSound[self.stringId] = random.id
return random
}
return Sound.default
}
var soundName: String {
return self.coolSound.soundName
}
}
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 = "Running"
stopwatch.activity = activity
return stopwatch
}
}
extension Record {
var count: Double { return 1.0 }
public override func didChangeValue(forKey key: String) {
super.didChangeValue(forKey: key)
switch key {
case "start", "end":
self.preCompute()
default:
break
}
}
func preCompute() {
if let start {
self.year = Int16(start.year)
self.month = Int16(start.month)
if let end {
self.duration = end.timeIntervalSince(start)
}
}
}
var formattedDay: String {
if let start {
return start.formatted(date: .abbreviated, time: .omitted)
}
return ""
}
var details: String {
if let start, let end {
return "\(start.formatted()) - \(end.formatted())"
} 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)
}
}