Adds settings view

main
Laurent 3 years ago
parent 197ad6c400
commit 9d8db42edf
  1. 20
      LeCountdown.xcodeproj/project.pbxproj
  2. 12
      LeCountdown/Conductor.swift
  3. 2
      LeCountdown/Utils/Preferences.swift
  4. 19
      LeCountdown/Views/ContentView.swift
  5. 29
      LeCountdown/Views/SettingsView.swift
  6. 1
      LeCountdown/fr.lproj/Localizable.strings

@ -69,12 +69,6 @@
C473C2FB29A8DC3A0056B38A /* LaunchWidgetAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = C473C2F829A8DC0A0056B38A /* LaunchWidgetAttributes.swift */; };
C473C2FC29A8DC4B0056B38A /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BA2B6929A4BE1800CB4FBA /* Date+Extensions.swift */; };
C473C2FD29A8DC690056B38A /* CoreDataRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C80C2982847300BF3EF9 /* CoreDataRequests.swift */; };
C473C30329A91BB90056B38A /* en.xcloc in Resources */ = {isa = PBXBuildFile; fileRef = C473C30229A91BB90056B38A /* en.xcloc */; };
C473C30429A91BB90056B38A /* en.xcloc in Resources */ = {isa = PBXBuildFile; fileRef = C473C30229A91BB90056B38A /* en.xcloc */; };
C473C30529A91BB90056B38A /* en.xcloc in Resources */ = {isa = PBXBuildFile; fileRef = C473C30229A91BB90056B38A /* en.xcloc */; };
C473C30729A91BCC0056B38A /* fr.xcloc in Resources */ = {isa = PBXBuildFile; fileRef = C473C30629A91BCB0056B38A /* fr.xcloc */; };
C473C30829A91BCC0056B38A /* fr.xcloc in Resources */ = {isa = PBXBuildFile; fileRef = C473C30629A91BCB0056B38A /* fr.xcloc */; };
C473C30929A91BCC0056B38A /* fr.xcloc in Resources */ = {isa = PBXBuildFile; fileRef = C473C30629A91BCB0056B38A /* fr.xcloc */; };
C473C31829A926F50056B38A /* LaunchWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = C473C31C29A926F50056B38A /* LaunchWidget.intentdefinition */; };
C473C31929A926F50056B38A /* LaunchWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = C473C31C29A926F50056B38A /* LaunchWidget.intentdefinition */; };
C473C31A29A926F50056B38A /* LaunchWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = C473C31C29A926F50056B38A /* LaunchWidget.intentdefinition */; };
@ -170,6 +164,7 @@
C4E5D68429BB2425008E7465 /* SeparatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E5D68329BB2425008E7465 /* SeparatorView.swift */; };
C4E5D68629BB369E008E7465 /* TimersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E5D68529BB369E008E7465 /* TimersView.swift */; };
C4E5D68829BB3FE1008E7465 /* SiriTimerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E5D68729BB3FE1008E7465 /* SiriTimerView.swift */; };
C4E5D68A29BB7953008E7465 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E5D68929BB7953008E7465 /* SettingsView.swift */; };
C4F8B1532987FE6F005C86A5 /* LaunchWidgetLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7D72981216200BF3EF9 /* LaunchWidgetLiveActivity.swift */; };
C4F8B15729891271005C86A5 /* Conductor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F8B15629891271005C86A5 /* Conductor.swift */; };
C4F8B15929891528005C86A5 /* forest_stream.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C4F8B15829891528005C86A5 /* forest_stream.mp3 */; };
@ -316,8 +311,6 @@
C445FA942987D01C0054D761 /* train_horn.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = train_horn.mp3; sourceTree = "<group>"; };
C4636D9B29AF46BD00994E31 /* ActivityKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ActivityKit.framework; path = System/Library/Frameworks/ActivityKit.framework; sourceTree = SDKROOT; };
C473C2F829A8DC0A0056B38A /* LaunchWidgetAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchWidgetAttributes.swift; sourceTree = "<group>"; };
C473C30229A91BB90056B38A /* en.xcloc */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = en.xcloc; path = Localizations/en.xcloc; sourceTree = "<group>"; };
C473C30629A91BCB0056B38A /* fr.xcloc */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = fr.xcloc; path = Localizations/fr.xcloc; sourceTree = "<group>"; };
C473C32729AA307D0056B38A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/LaunchWidget.intentdefinition; sourceTree = "<group>"; };
C473C32929AA30890056B38A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/LaunchWidget.strings; sourceTree = "<group>"; };
C473C32B29AA330E0056B38A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -389,6 +382,7 @@
C4E5D68329BB2425008E7465 /* SeparatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorView.swift; sourceTree = "<group>"; };
C4E5D68529BB369E008E7465 /* TimersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimersView.swift; sourceTree = "<group>"; };
C4E5D68729BB3FE1008E7465 /* SiriTimerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiriTimerView.swift; sourceTree = "<group>"; };
C4E5D68929BB7953008E7465 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
C4F8B15629891271005C86A5 /* Conductor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conductor.swift; sourceTree = "<group>"; };
C4F8B15829891528005C86A5 /* forest_stream.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = forest_stream.mp3; sourceTree = "<group>"; };
C4F8B15E298961A7005C86A5 /* ReorderableForEach.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReorderableForEach.swift; sourceTree = "<group>"; };
@ -505,8 +499,6 @@
C4BA2B55299FFA3700CB4FBA /* Subscription */,
C4060DC3297AE73D003FAB80 /* Assets.xcassets */,
C438C80429813B3100BF3EF9 /* LeCountdown.entitlements */,
C473C30229A91BB90056B38A /* en.xcloc */,
C473C30629A91BCB0056B38A /* fr.xcloc */,
C473C32A29AA330E0056B38A /* Localizable.strings */,
C4E5D66F29B753D7008E7465 /* AppShortcuts.strings */,
C4060DCD297AE73D003FAB80 /* Info.plist */,
@ -634,6 +626,7 @@
C498E59E298D4DEA00E90DE0 /* LiveTimerListView.swift */,
C4BA2B03299A42EF00CB4FBA /* NewDataView.swift */,
C4BA2B05299A8F8D00CB4FBA /* PresetsView.swift */,
C4E5D68929BB7953008E7465 /* SettingsView.swift */,
C4E5D68529BB369E008E7465 /* TimersView.swift */,
C498E5A2298D720600E90DE0 /* TestView.swift */,
);
@ -945,7 +938,6 @@
buildActionMask = 2147483647;
files = (
C4060DC7297AE73D003FAB80 /* Preview Assets.xcassets in Resources */,
C473C30729A91BCC0056B38A /* fr.xcloc in Resources */,
C4BA2AEA2995AD1C00CB4FBA /* SEM_Synths_Loop4_Nothing_Like_You.wav in Resources */,
C473C32C29AA330E0056B38A /* Localizable.strings in Resources */,
C4E5D68229B93583008E7465 /* PVP_Stab_Oneshot_Bleep_Em.wav in Resources */,
@ -959,7 +951,6 @@
C4BA2AE02995ABD200CB4FBA /* HighChords_Loop_River.wav in Resources */,
C4E5D66D29B753D7008E7465 /* AppShortcuts.strings in Resources */,
C4060DC4297AE73D003FAB80 /* Assets.xcassets in Resources */,
C473C30329A91BB90056B38A /* en.xcloc in Resources */,
C4BA2AE62995AC3F00CB4FBA /* Loop_ToneSD_Boavista.wav in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -983,9 +974,7 @@
buildActionMask = 2147483647;
files = (
C445FA882984487F0054D761 /* Assets.xcassets in Resources */,
C473C30429A91BB90056B38A /* en.xcloc in Resources */,
C438C7DD2981216300BF3EF9 /* Assets.xcassets in Resources */,
C473C30829A91BCC0056B38A /* fr.xcloc in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -993,9 +982,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C473C30529A91BB90056B38A /* en.xcloc in Resources */,
C473C33029ACADC80056B38A /* Localizable.strings in Resources */,
C473C30929A91BCC0056B38A /* fr.xcloc in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1081,6 +1068,7 @@
C4BA2B43299FCB2B00CB4FBA /* RecordsView.swift in Sources */,
C4BA2B2F299E69A000CB4FBA /* View+Extension.swift in Sources */,
C4E5D68629BB369E008E7465 /* TimersView.swift in Sources */,
C4E5D68A29BB7953008E7465 /* SettingsView.swift in Sources */,
C4060DF7297AFEF2003FAB80 /* NewCountdownView.swift in Sources */,
C4060DCC297AE73D003FAB80 /* LeCountdown.xcdatamodeld in Sources */,
C4BA2B49299FCE0C00CB4FBA /* IntervalGroup+CoreDataProperties.swift in Sources */,

@ -162,14 +162,17 @@ class Conductor: ObservableObject {
let date = Date(timeIntervalSinceNow: countdown.duration)
let soundFile = try SoundFile(fullName: countdown.soundName)
self._playSound(Const.confirmationSound.rawValue)
let soundPlayer = DelaySoundPlayer(soundFile: soundFile)
self.delaySoundPlayer = soundPlayer
try soundPlayer.start(in: countdown.duration,
repeatCount: Int(countdown.repeatCount))
self.startCountdown(date, countdown: countdown)
if Preferences.playConfirmationSound {
self._playSound(Const.confirmationSound.rawValue)
}
handler(.success(date))
} catch {
Logger.error(error)
@ -184,6 +187,11 @@ class Conductor: ObservableObject {
DispatchQueue.main.async {
let now = Date()
Conductor.maestro.currentStopwatches[stopwatch.stringId] = now
if Preferences.playConfirmationSound {
self._playSound(Const.confirmationSound.rawValue)
}
self._launchLiveActivity(stopwatch: stopwatch, start: now)
// self._createTimerIntent(stopwatch)

@ -10,6 +10,7 @@ import Foundation
enum PreferenceKey: String {
case countdowns
case stopwatches
case playConfirmationSound
case showSilentModeAlert
case soundDurations
case lastSoundPlayed
@ -24,6 +25,7 @@ class Preferences {
@UserDefault(PreferenceKey.lastSoundPlayed.rawValue, defaultValue: [:]) static var lastSelectedSound: [String : Int]
@UserDefault(PreferenceKey.tips.rawValue, defaultValue: nil) static var lastShownTip: Int?
@UserDefault(PreferenceKey.timerSiriTips.rawValue, defaultValue: []) static var timerSiriTips: Set<String>
@UserDefault(PreferenceKey.playConfirmationSound.rawValue, defaultValue: true) static var playConfirmationSound: Bool
static var hideSilentModeAlerts: Bool {
return UserDefaults.standard.bool(forKey: PreferenceKey.showSilentModeAlert.rawValue)

@ -53,6 +53,8 @@ struct ContentView<T : AbstractTimer>: View {
@State private var tipsShown: Bool = false
@State private var siriTipShown: Bool = false
@State private var showSettingsSheet: Bool = false
var body: some View {
@ -98,10 +100,14 @@ struct ContentView<T : AbstractTimer>: View {
.alert("You need to accept notifications, please check your settings", isPresented: $boringContext.showPermissionAlert) {
PermissionAlertView()
}
.sheet(isPresented: $boringContext.isShowingNewData, content: {
.sheet(isPresented: self.$boringContext.isShowingNewData, content: {
})
.sheet(isPresented: self.$showSettingsSheet, content: {
SettingsView()
.presentationDetents([.height(100.0)])
})
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
ToolbarItem(placement: .navigationBarLeading) {
Button {
withAnimation {
self.isEditing.toggle()
@ -110,6 +116,15 @@ struct ContentView<T : AbstractTimer>: View {
Text(self.isEditing ? "Done" : "Edit")
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button {
withAnimation {
self.showSettingsSheet.toggle()
}
} label: {
Image(systemName: "gearshape.fill")
}
}
}
.onAppear {
self._askPermissions()

@ -0,0 +1,29 @@
//
// SettingsView.swift
// LeCountdown
//
// Created by Laurent Morvillier on 10/03/2023.
//
import SwiftUI
struct SettingsView: View {
@State var confirmationSound = Preferences.playConfirmationSound
var body: some View {
Form {
Toggle("Play confirmation sound", isOn: self.$confirmationSound).onChange(of: self.confirmationSound) { newValue in
Preferences.playConfirmationSound = newValue
}
}
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}

@ -248,3 +248,4 @@
"The timer has not been found in the app" = "Le minuteur n'a pas été trouvé dans l'app";
"In-app purchase disabled" = "Les achats in-app sont désactivés. Veuillez les activer si vous souhaitez vous abonner";
"You'll find your timers here. Start by creating them on the left screen" = "Vous retrouverez vos minuteurs ici. Commencez par en créer dans l'écran de gauche";
"Settings" = "Réglages";

Loading…
Cancel
Save