diff --git a/LeCountdown/Info.plist b/LeCountdown/Info.plist index 105b512..a24dcda 100644 --- a/LeCountdown/Info.plist +++ b/LeCountdown/Info.plist @@ -2,6 +2,8 @@ + CFBundleDisplayName + Enchant ITSAppUsesNonExemptEncryption BGTaskSchedulerPermittedIdentifiers @@ -25,7 +27,7 @@ LaunchTimerIntent SelectTimerIntent - app.kikai.NewCountdown + app.enchant.NewCountdown UIApplicationSceneManifest diff --git a/LeCountdown/Utils/Extensions.swift b/LeCountdown/Utils/Extensions.swift index 50359a2..83afa42 100644 --- a/LeCountdown/Utils/Extensions.swift +++ b/LeCountdown/Utils/Extensions.swift @@ -22,13 +22,6 @@ extension String { } -//extension Sequence where Element : RawRepresentable { -// var stringRepresentation: String { -// let ids = self.compactMap { formatter.string(from: NSNumber(value: $0.rawValue)) } -// return ids.joined(separator: separator) -// } -//} - extension Sequence where Element : StringRepresentable { var stringRepresentation: String { let ids = self.compactMap { $0.stringValue } @@ -43,3 +36,14 @@ protocol StringRepresentable { extension String: StringRepresentable { var stringValue: String { self } } + +extension Bundle { + var applicationName: String { + if let displayName: String = self.localizedInfoDictionary?["CFBundleDisplayName"] as? String { + return displayName + } else if let name: String = self.localizedInfoDictionary?["CFBundleName"] as? String { + return name + } + return "No Name Found" + } +} diff --git a/LeCountdown/Utils/Shortcut.swift b/LeCountdown/Utils/Shortcut.swift index c127d49..677a972 100644 --- a/LeCountdown/Utils/Shortcut.swift +++ b/LeCountdown/Utils/Shortcut.swift @@ -13,7 +13,7 @@ import UniformTypeIdentifiers enum Shortcut: String { - case newCountdown = "app.kikai.NewCountdown" + case newCountdown = "app.enchant.NewCountdown" var userActivity: NSUserActivity { let activity = NSUserActivity(activityType: self.rawValue) diff --git a/LeCountdown/Utils/TimeInterval+Extensions.swift b/LeCountdown/Utils/TimeInterval+Extensions.swift index 36b4010..61da2e2 100644 --- a/LeCountdown/Utils/TimeInterval+Extensions.swift +++ b/LeCountdown/Utils/TimeInterval+Extensions.swift @@ -10,12 +10,17 @@ import Foundation extension TimeInterval { var hourMinuteSecond: String { - return String(format:"%d:%02d:%02d", hour, minute, second) + let h = self.hour + if h > 0 { + return String(format:"%d:%02d:%02d", hour, minute, second) + } else { + return self.minuteSecond + } } var hourMinuteSecondHS: String { let h = self.hour - if h > 1 { + if h > 0 { return String(format:"%d:%02d:%02d", hour, minute, second) } else { return String(format:"%02d:%02d.%02d", minute, second, hundredth) diff --git a/LeCountdown/Views/Countdown/CountdownDialView.swift b/LeCountdown/Views/Countdown/CountdownDialView.swift index 8c36a33..59833aa 100644 --- a/LeCountdown/Views/Countdown/CountdownDialView.swift +++ b/LeCountdown/Views/Countdown/CountdownDialView.swift @@ -22,7 +22,7 @@ struct CountdownDialView: View { Text(countdown.activity?.name?.uppercased() ?? "") .foregroundColor(isEditing ? .white : .black) .multilineTextAlignment(.leading) - Text(countdown.duration.minuteSecond) + Text(countdown.duration.hourMinuteSecond) .fontWeight(.semibold) .foregroundColor(.accentColor) } diff --git a/LeCountdown/Views/Countdown/CountdownFormView.swift b/LeCountdown/Views/Countdown/CountdownFormView.swift index e88124a..7629f79 100644 --- a/LeCountdown/Views/Countdown/CountdownFormView.swift +++ b/LeCountdown/Views/Countdown/CountdownFormView.swift @@ -9,6 +9,7 @@ import SwiftUI enum CountdownField: Int, Hashable { case name + case hours case minutes case seconds } @@ -19,9 +20,11 @@ struct CountdownFormView : View { @EnvironmentObject var model: TimerModel + var nameBinding: Binding + var secondsBinding: Binding var minutesBinding: Binding - var nameBinding: Binding + var hoursBinding: Binding var imageBinding: Binding @@ -32,15 +35,27 @@ struct CountdownFormView : View { var body: some View { Group { - Section("Name") { + Section { TextField("Name", text: nameBinding) .focused($focusedField, equals: .name) .onSubmit { self.focusNextField($focusedField) - } + } header: { + Text("Name") + } footer: { + if !self.nameBinding.wrappedValue.isEmpty { + Text("Ask Siri: \(Bundle.main.applicationName) \(self.nameBinding.wrappedValue)!") + } } - Section("Duration") { + + Section { + TextField("Hours", text: hoursBinding) + .keyboardType(.numberPad) + .focused($focusedField, equals: .hours) + .onSubmit { + self.focusNextField($focusedField) + } TextField("Minutes", text: minutesBinding) .keyboardType(.numberPad) .focused($focusedField, equals: .minutes) @@ -53,6 +68,8 @@ struct CountdownFormView : View { .onSubmit { self.focusedField = nil } + } header: { + LabeledContent("Duration", value: self.duration().hourMinuteSecond).font(.footnote) } SoundFormView( @@ -64,6 +81,23 @@ struct CountdownFormView : View { } + func duration() -> TimeInterval { + let formatter = NumberFormatter() + var hours: Int = 0 + var minutes: Int = 0 + var seconds: Int = 0 + if let h = formatter.number(from: hoursBinding.wrappedValue) { + hours = h.intValue + } + if let m = formatter.number(from: minutesBinding.wrappedValue) { + minutes = m.intValue + } + if let s = formatter.number(from: secondsBinding.wrappedValue) { + seconds = s.intValue + } + return Double(seconds) + 60 * Double(minutes) + 60 * 60 * Double(hours) + } + } struct CountdownFormView_Previews: PreviewProvider { @@ -74,9 +108,10 @@ struct CountdownFormView_Previews: PreviewProvider { Form { CountdownFormView( + nameBinding: .constant(""), secondsBinding: .constant(""), minutesBinding: .constant(""), - nameBinding: .constant(""), + hoursBinding: .constant(""), imageBinding: .constant(.pic3), repeatCountBinding: .constant(2), intervalRepeatBinding: .constant(2)) diff --git a/LeCountdown/Views/Countdown/NewCountdownView.swift b/LeCountdown/Views/Countdown/NewCountdownView.swift index 0190545..093219c 100644 --- a/LeCountdown/Views/Countdown/NewCountdownView.swift +++ b/LeCountdown/Views/Countdown/NewCountdownView.swift @@ -51,10 +51,12 @@ struct CountdownEditView : View { var preset: Preset? = nil @Binding var isPresented: Bool - + + @State var nameString: String = "" + @State var secondsString: String = "" @State var minutesString: String = "" - @State var nameString: String = "" + @State var hoursString: String = "" @State var soundRepeatCount: Int16 = 0 @State var image: CoolPic = .pic1 @@ -115,9 +117,10 @@ struct CountdownEditView : View { CountdownFormView( focusedField: _focusedField, + nameBinding: $nameString, secondsBinding: $secondsString, minutesBinding: $minutesString, - nameBinding: $nameString, + hoursBinding: $hoursString, imageBinding: $image, repeatCountBinding: $soundRepeatCount) .environmentObject(self.model) @@ -250,13 +253,16 @@ struct CountdownEditView : View { fileprivate func _loadCountdown(_ countdown: Countdown) { - let minutes = Int(countdown.duration / 60.0) - let seconds = countdown.duration - Double(minutes * 60) + let hours = Int(countdown.duration / 3600.0) + let minutes = countdown.duration - Double(hours * 3600) + let seconds = countdown.duration - Double(hours * 3600) - Double(minutes * 60) + if hours > 0 { + self.hoursString = self._numberFormatter.string(from: NSNumber(value: hours)) ?? "" + } if minutes > 0 { self.minutesString = self._numberFormatter.string(from: NSNumber(value: minutes)) ?? "" } - if seconds > 0 { self.secondsString = self._numberFormatter.string(from: NSNumber(value: seconds)) ?? "" } @@ -285,6 +291,10 @@ struct CountdownEditView : View { return self._numberFormatter.number(from: self.minutesString)?.doubleValue ?? 0.0 } + fileprivate var _hours: Double { + return self._numberFormatter.number(from: self.hoursString)?.doubleValue ?? 0.0 + } + fileprivate func _cancel() { self.viewContext.rollback() self.isPresented = false @@ -299,10 +309,9 @@ struct CountdownEditView : View { cd = Countdown(context: viewContext) } - cd.duration = self._minutes * 60.0 + self._seconds + cd.duration = self._hours * 3600.0 + self._minutes * 60.0 + self._seconds if self._isNewCountdown { let max: Int16 - do { let request = AbstractTimer.fetchRequest() let timers = try viewContext.fetch(request) @@ -312,7 +321,6 @@ struct CountdownEditView : View { } else { max = 0 } - } catch { max = 0 } @@ -346,7 +354,6 @@ struct CountdownEditView : View { } else { cd.activity = CoreDataRequests.getOrCreateActivity(name: trimmed) } - } self._saveContext() diff --git a/LeCountdown/Views/Reusable/MailView.swift b/LeCountdown/Views/Reusable/MailView.swift index cac0e2b..b490b35 100644 --- a/LeCountdown/Views/Reusable/MailView.swift +++ b/LeCountdown/Views/Reusable/MailView.swift @@ -55,14 +55,3 @@ struct MailView: UIViewControllerRepresentable { } } - -fileprivate extension Bundle { - var applicationName: String { - if let displayName: String = self.infoDictionary?["CFBundleDisplayName"] as? String { - return displayName - } else if let name: String = self.infoDictionary?["CFBundleName"] as? String { - return name - } - return "" - } -} diff --git a/LeCountdown/fr.lproj/Localizable.strings b/LeCountdown/fr.lproj/Localizable.strings index 9dd86e7..fd11244 100644 --- a/LeCountdown/fr.lproj/Localizable.strings +++ b/LeCountdown/fr.lproj/Localizable.strings @@ -258,3 +258,4 @@ "month" = "mois"; "year" = "an"; "Get fully enchanted" = "Enchantement permanent"; +"Ask Siri: %@ %@!" = "Dites à Siri: %@ %@!";