From d85761a82f72df65cdb18a6588148385a08ef509 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 27 Feb 2023 15:00:05 +0100 Subject: [PATCH] Add tips --- LeCountdown.xcodeproj/project.pbxproj | 14 ++++++- LeCountdown/LeCountdownApp.swift | 2 +- LeCountdown/Utils/Preferences.swift | 9 +++++ LeCountdown/Utils/Tip.swift | 29 +++++++++++++++ LeCountdown/Views/ContentView.swift | 13 +++++++ LeCountdown/Views/PresetsView.swift | 6 +-- LeCountdown/Views/Reusable/TipView.swift | 47 ++++++++++++++++++++++++ 7 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 LeCountdown/Utils/Tip.swift create mode 100644 LeCountdown/Views/Reusable/TipView.swift diff --git a/LeCountdown.xcodeproj/project.pbxproj b/LeCountdown.xcodeproj/project.pbxproj index bbf515b..3f21876 100644 --- a/LeCountdown.xcodeproj/project.pbxproj +++ b/LeCountdown.xcodeproj/project.pbxproj @@ -80,6 +80,10 @@ C473C31A29A926F50056B38A /* LaunchWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = C473C31C29A926F50056B38A /* LaunchWidget.intentdefinition */; }; C473C32C29AA330E0056B38A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473C32A29AA330E0056B38A /* Localizable.strings */; }; C473C33029ACADC80056B38A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473C32A29AA330E0056B38A /* Localizable.strings */; }; + C473C33929ACDBD70056B38A /* TipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C473C33829ACDBD70056B38A /* TipView.swift */; }; + C473C33A29ACDBD70056B38A /* TipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C473C33829ACDBD70056B38A /* TipView.swift */; }; + C473C33C29ACEC4F0056B38A /* Tip.swift in Sources */ = {isa = PBXBuildFile; fileRef = C473C33B29ACEC4F0056B38A /* Tip.swift */; }; + C473C33D29ACEC4F0056B38A /* Tip.swift in Sources */ = {isa = PBXBuildFile; fileRef = C473C33B29ACEC4F0056B38A /* Tip.swift */; }; C4742B5729840F6400D5D950 /* CoolPic.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4742B5629840F6400D5D950 /* CoolPic.swift */; }; C4742B59298411E800D5D950 /* CountdownFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4742B58298411E800D5D950 /* CountdownFormView.swift */; }; C4742B5B298414B000D5D950 /* ImageSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4742B5A298414B000D5D950 /* ImageSelectionView.swift */; }; @@ -304,6 +308,8 @@ C473C32829AA30890056B38A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/SiriIntents.strings; sourceTree = ""; }; C473C32929AA30890056B38A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/LaunchWidget.strings; sourceTree = ""; }; C473C32B29AA330E0056B38A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + C473C33829ACDBD70056B38A /* TipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipView.swift; sourceTree = ""; }; + C473C33B29ACEC4F0056B38A /* Tip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tip.swift; sourceTree = ""; }; C4742B5629840F6400D5D950 /* CoolPic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoolPic.swift; sourceTree = ""; }; C4742B58298411E800D5D950 /* CountdownFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountdownFormView.swift; sourceTree = ""; }; C4742B5A298414B000D5D950 /* ImageSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageSelectionView.swift; sourceTree = ""; }; @@ -575,9 +581,10 @@ C4BA2B5A299FFAB000CB4FBA /* Logger.swift */, C4BA2B2C299E2DEE00CB4FBA /* Preferences.swift */, C438C81029829EAF00BF3EF9 /* PropertyWrappers.swift */, + C4BA2B7229A60CF000CB4FBA /* Shortcut.swift */, C40FDB612992985C0042A390 /* TextToSpeechRecorder.swift */, C4060DF4297AE9A7003FAB80 /* TimeInterval+Extensions.swift */, - C4BA2B7229A60CF000CB4FBA /* Shortcut.swift */, + C473C33B29ACEC4F0056B38A /* Tip.swift */, C4BA2B7829A65C1400CB4FBA /* UIDevice+Extensions.swift */, ); path = Utils; @@ -734,6 +741,7 @@ C4BA2ADA299549BC00CB4FBA /* TimerModel.swift */, C4BA2B2E299E69A000CB4FBA /* View+Extension.swift */, C4742B5E2984205000D5D950 /* ViewModifiers.swift */, + C473C33829ACDBD70056B38A /* TipView.swift */, ); path = Reusable; sourceTree = ""; @@ -988,9 +996,11 @@ C4BA2AF12996A11900CB4FBA /* CustomSound+CoreDataClass.swift in Sources */, C4060DC2297AE73B003FAB80 /* ContentView.swift in Sources */, C438C7C12980228B00BF3EF9 /* CountdownScheduler.swift in Sources */, + C473C33C29ACEC4F0056B38A /* Tip.swift in Sources */, C498E5A3298D720600E90DE0 /* TestView.swift in Sources */, C4BA2B06299A8F8D00CB4FBA /* PresetsView.swift in Sources */, C473C31329A925D50056B38A /* SiriIntents.intentdefinition in Sources */, + C473C33929ACDBD70056B38A /* TipView.swift in Sources */, C445FA8F2987B83B0054D761 /* SoundPlayer.swift in Sources */, C4F8B1A7298AC2FC005C86A5 /* AbstractSoundTimer+CoreDataClass.swift in Sources */, C438C7C929803CA000BF3EF9 /* AppDelegate.swift in Sources */, @@ -1111,6 +1121,7 @@ C473C2F729A8DB6F0056B38A /* Preferences.swift in Sources */, C4BA2B38299F82FF00CB4FBA /* Fakes.swift in Sources */, C438C7F529812BB200BF3EF9 /* IntentHandler.swift in Sources */, + C473C33D29ACEC4F0056B38A /* Tip.swift in Sources */, C4F8B19C298AC288005C86A5 /* AbstractTimer+CoreDataProperties.swift in Sources */, C4BA2B1C299BE6A100CB4FBA /* IntervalGroup+CoreDataClass.swift in Sources */, C4BA2B1F299BE6A100CB4FBA /* Countdown+CoreDataProperties.swift in Sources */, @@ -1144,6 +1155,7 @@ C473C2F529A8DAF30056B38A /* PropertyWrappers.swift in Sources */, C473C2F029A8CFFC0056B38A /* TimerRouter.swift in Sources */, C438C800298130E900BF3EF9 /* IntentDataProvider.swift in Sources */, + C473C33A29ACDBD70056B38A /* TipView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/LeCountdown/LeCountdownApp.swift b/LeCountdown/LeCountdownApp.swift index 9e66ae0..24754ca 100644 --- a/LeCountdown/LeCountdownApp.swift +++ b/LeCountdown/LeCountdownApp.swift @@ -74,7 +74,7 @@ struct LeCountdownApp: App { fileprivate func _onAppear() { - Logger.log("Locale = \(Locale.preferredLanguages.first)") +// Logger.log("Locale = \(Locale.preferredLanguages.first)") Sound.computeSoundDurationsIfNecessary() diff --git a/LeCountdown/Utils/Preferences.swift b/LeCountdown/Utils/Preferences.swift index fa5235b..031f063 100644 --- a/LeCountdown/Utils/Preferences.swift +++ b/LeCountdown/Utils/Preferences.swift @@ -13,6 +13,7 @@ enum PreferenceKey: String { case showSilentModeAlert case soundDurations case lastSoundPlayed + case tips } class Preferences { @@ -20,6 +21,7 @@ class Preferences { @UserDefault(PreferenceKey.countdowns.rawValue, defaultValue: [:]) static var savedCountdowns: [String : DateInterval] @UserDefault(PreferenceKey.soundDurations.rawValue, defaultValue: [:]) static var soundDurations: [Int : TimeInterval] @UserDefault(PreferenceKey.lastSoundPlayed.rawValue, defaultValue: [:]) static var lastSelectedSound: [String : Int] + @UserDefault(PreferenceKey.tips.rawValue, defaultValue: nil) static var lastShownTip: Int? static var hideSilentModeAlerts: Bool { return UserDefaults.standard.bool(forKey: PreferenceKey.showSilentModeAlert.rawValue) @@ -29,4 +31,11 @@ class Preferences { UserDefaults.standard.setValue(true, forKey: PreferenceKey.showSilentModeAlert.rawValue) } + static var tipToShow: Tip? { + if let tipRawValue = self.lastShownTip, let tip = Tip(rawValue: tipRawValue) { + return Tip(rawValue: tip.rawValue + 1) + } + return Tip.allCases.first + } + } diff --git a/LeCountdown/Utils/Tip.swift b/LeCountdown/Utils/Tip.swift new file mode 100644 index 0000000..139998b --- /dev/null +++ b/LeCountdown/Utils/Tip.swift @@ -0,0 +1,29 @@ +// +// TipsManager.swift +// LeCountdown +// +// Created by Laurent Morvillier on 27/02/2023. +// + +import Foundation + +enum Tip: Int, CaseIterable, Identifiable { + case siri + case widget + + var id: Int { self.rawValue } + + var localizedString: String { + switch self { + case .widget: return NSLocalizedString("You can add widget for your timers and countdowns by modifying your home or lock screen", comment: "") + case .siri: return NSLocalizedString("You can ask Siri to create and launch countdowns and stopwatches", comment: "") + } + } + + var pictoName: String { + switch self { + case .siri: return "wave.3.right" //"dot.radiowaves.right" + case .widget: return "app.badge" + } + } +} diff --git a/LeCountdown/Views/ContentView.swift b/LeCountdown/Views/ContentView.swift index 0379191..745b69d 100644 --- a/LeCountdown/Views/ContentView.swift +++ b/LeCountdown/Views/ContentView.swift @@ -55,6 +55,8 @@ struct ContentView: View { @State private var isEditing: Bool = false + @State private var tipsShown: Bool = false + fileprivate let itemSpacing: CGFloat = 10.0 var body: some View { @@ -86,6 +88,12 @@ struct ContentView: View { } }.padding(.horizontal, itemSpacing) + if !self.tipsShown, let tip = Preferences.tipToShow { + TipView(tip: tip) { + self._hideTip(tip) + }.padding() + } + if !conductor.liveTimers.isEmpty { LiveTimerListView() .environment(\.managedObjectContext, viewContext) @@ -155,6 +163,11 @@ struct ContentView: View { // MARK: - Business + fileprivate func _hideTip(_ tip: Tip) { + Preferences.lastShownTip = tip.rawValue + self.tipsShown = true + } + fileprivate func _reorder(from: IndexSet, to: Int) { var timers: [AbstractTimer] = Array(self.timers) timers.move(fromOffsets: from, toOffset: to) diff --git a/LeCountdown/Views/PresetsView.swift b/LeCountdown/Views/PresetsView.swift index 6204804..14a806e 100644 --- a/LeCountdown/Views/PresetsView.swift +++ b/LeCountdown/Views/PresetsView.swift @@ -191,9 +191,9 @@ struct PresetsView: View { Spacer() }.frame(height: 40.0) - SeparatorView() - Text("You can ask Siri to create and launch countdowns and stopwatches") - .font(.callout) +// SeparatorView() +// Text("You can ask Siri to create and launch countdowns and stopwatches") +// .font(.callout) SeparatorView() Text("Presets") diff --git a/LeCountdown/Views/Reusable/TipView.swift b/LeCountdown/Views/Reusable/TipView.swift new file mode 100644 index 0000000..c02ab23 --- /dev/null +++ b/LeCountdown/Views/Reusable/TipView.swift @@ -0,0 +1,47 @@ +// +// TipView.swift +// LeCountdown +// +// Created by Laurent Morvillier on 27/02/2023. +// + +import SwiftUI + +struct TipView: View { + + var tip: Tip + + var handler: () -> () + + var body: some View { + + HStack { + Image(systemName: tip.pictoName) + Text(tip.localizedString).padding(.trailing) + Spacer() + Button { + self.handler() + } label: { + Image(systemName: "xmark.circle.fill") + .padding(8.0) + }.foregroundColor(.white) + + } + .padding(12.0) + .foregroundColor(.white) + .background(.cyan) + .cornerRadius(16.0) + } +} + +struct TipView_Previews: PreviewProvider { + + static var previews: some View { + + VStack { + ForEach(Tip.allCases) { tip in + TipView(tip: tip, handler: {}) + } + } + } +}