Improvements

main
Laurent 3 years ago
parent 09cd5815f2
commit 1739393345
  1. 17
      LeCountdown/Model/Model+Extensions.swift
  2. 2
      LeCountdown/Sound/DelaySoundPlayer.swift
  3. 1
      LeCountdown/Utils/Codable+Extensions.swift
  4. 5
      LeCountdown/Utils/Preferences.swift
  5. 7
      LeCountdown/Utils/TimeInterval+Extensions.swift
  6. 30
      LeCountdown/Views/ContentView.swift
  7. 8
      LeCountdown/Views/Reusable/MailView.swift
  8. 23
      LeCountdown/Views/SettingsView.swift
  9. 2
      LeCountdown/Views/TimersView.swift
  10. 1
      LeCountdown/en.lproj/Localizable.strings
  11. 1
      LeCountdown/fr.lproj/Localizable.strings

@ -32,10 +32,6 @@ extension AbstractSoundTimer {
return self.playables.reduce(Set<Sound>()) { $0.union($1.soundList) }
}
// func setSounds(_ sounds: Set<Sound>) {
// self.soundList = sounds.stringRepresentation
// }
var confirmationSounds: Set<Sound> {
if let confirmationSoundList {
return Set(confirmationSoundList.enumItems())
@ -53,15 +49,22 @@ extension AbstractSoundTimer {
sounds = sounds.filter { !$0.isRestricted }
}
// remove last played sound if the playlist has at least 3 sounds
// remove last played sound if at least 3 sounds remains
if sounds.count > 2,
let lastSoundId = Preferences.lastSoundPlayed,
let lastSound = Sound(rawValue: lastSoundId) {
sounds.remove(lastSound)
}
// remove last played sound by timer if the playlist has at least 3 sounds
if sounds.count > 2,
let lastSoundId = Preferences.lastSelectedSound[self.stringId],
let lastSoundId = Preferences.lastSelectedSoundByTimer[self.stringId],
let lastSound = Sound(rawValue: lastSoundId) {
sounds.remove(lastSound)
}
if let random = sounds.randomElement() {
Preferences.lastSelectedSound[self.stringId] = random.id
Preferences.lastSelectedSoundByTimer[self.stringId] = random.id
Preferences.lastSoundPlayed = random.id
return random
}

@ -47,7 +47,7 @@ import AVFoundation
Logger.log("self._player.deviceCurrentTime = \(self._player.deviceCurrentTime)")
let time: TimeInterval = self._player.deviceCurrentTime + duration
let result = self._player.play(atTime: time)
FileLogger.log("play \(String(describing: self._player.url)) >atTime: \(time), result = \(result), isMainThread = \(Thread.isMainThread)")
FileLogger.log("play \(String(describing: self._player.url)) >atTime: \(time.timeFormatted), result = \(result), isMainThread = \(Thread.isMainThread)")
if !result {
throw SoundPlayerError.playReturnedFalse

@ -19,6 +19,7 @@ extension Encodable {
var jsonData: Data? {
let encoder: JSONEncoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
return try encoder.encode(self)
} catch {

@ -15,6 +15,7 @@ enum PreferenceKey: String {
case playCancellationSound
case showSilentModeAlert
case soundDurations
case lastSoundPlayedByTimer
case lastSoundPlayed
case tips
case timerSiriTips
@ -26,7 +27,9 @@ class Preferences {
@UserDefault(PreferenceKey.countdowns.rawValue, defaultValue: [:]) static var savedCountdowns: [String : DateInterval]
@UserDefault(PreferenceKey.soundDurations.rawValue, defaultValue: [:]) static var soundDurations: [String : TimeInterval]
@UserDefault(PreferenceKey.lastSoundPlayed.rawValue, defaultValue: [:]) static var lastSelectedSound: [String : Int]
@UserDefault(PreferenceKey.lastSoundPlayedByTimer.rawValue, defaultValue: [:]) static var lastSelectedSoundByTimer: [String : Int]
@UserDefault(PreferenceKey.lastSoundPlayed.rawValue, defaultValue: nil) static var lastSoundPlayed: 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

@ -48,4 +48,11 @@ extension TimeInterval {
Int((self*100).truncatingRemainder(dividingBy: 100))
}
var timeFormatted: String {
let dateformatter = DateFormatter()
dateformatter.dateStyle = .none
dateformatter.timeStyle = .short
return dateformatter.string(from: Date(timeIntervalSince1970: self))
}
}

@ -168,7 +168,6 @@ struct MainToolbarView: ToolbarContent {
@State var showAddSheet: Bool = false
@State var showTimerSheet: Bool = false
@State var showStopwatchSheet: Bool = false
@State var showLogsSheet: Bool = false
var body: some ToolbarContent {
ToolbarItem(placement: .navigationBarLeading) {
@ -181,18 +180,18 @@ struct MainToolbarView: ToolbarContent {
}
}
ToolbarItemGroup(placement: .navigationBarTrailing) {
Button {
withAnimation {
self.showLogsSheet.toggle()
}
} label: {
Image(systemName: "list.dash")
}
.sheet(isPresented: self.$showLogsSheet, content: {
NavigationStack {
LogsView().navigationTitle("Logs")
}
})
// Button {
// withAnimation {
// self.showLogsSheet.toggle()
// }
// } label: {
// Image(systemName: "list.dash")
// }
// .sheet(isPresented: self.$showLogsSheet, content: {
// NavigationStack {
// LogsView().navigationTitle("Logs")
// }
// })
if self.haveRecords() {
Button {
withAnimation {
@ -219,7 +218,7 @@ struct MainToolbarView: ToolbarContent {
}
.sheet(isPresented: self.$showSettingsSheet, content: {
SettingsView()
.presentationDetents([.height(240.0)])
.presentationDetents([.height(280.0)])
})
Button {
withAnimation {
@ -301,12 +300,11 @@ class TimerSpot : Identifiable, Equatable {
struct Toolbar_Previews: PreviewProvider {
static var previews: some View {
NavigationStack {
Text("Hello")
Text(NSLocalizedString("Disclaimer", comment: "")).padding(32.0).multilineTextAlignment(.center)
}
.navigationTitle("Title")
.toolbar {
MainToolbarView(isEditing: .constant(false))
}
}
}

@ -46,6 +46,14 @@ struct MailView: UIViewControllerRepresentable {
vc.mailComposeDelegate = context.coordinator
vc.setSubject(Bundle.main.applicationName)
vc.setToRecipients(["laurent@staxriver.com"])
let lastLogs = FileLogger.main.logs.suffix(40).reversed()
let logs = lastLogs.map { $0.date.formattedDateTime + "\n" + $0.content }
let content = logs.joined(separator: "\n")
if let logsData = content.data(using: .utf8) {
vc.addAttachmentData(logsData, mimeType: "text/plain", fileName: "logs.txt")
}
return vc
}

@ -14,18 +14,19 @@ struct SettingsView: View {
@State var defaultVolume: Float = Preferences.defaultVolume
@State var showMailView: Bool = false
@State var showLogsSheet: Bool = false
var body: some View {
Form {
Toggle("Play confirmation sound", isOn: self.$confirmationSound)
.onChange(of: self.confirmationSound) { newValue in
Preferences.playConfirmationSound = newValue
}
Preferences.playConfirmationSound = newValue
}
Toggle("Play cancellation sound", isOn: self.$cancellationSound)
.onChange(of: self.cancellationSound) { newValue in
Preferences.playCancellationSound = newValue
}
Preferences.playCancellationSound = newValue
}
HStack {
Text("Default Volume")
Spacer()
@ -40,6 +41,18 @@ struct SettingsView: View {
} label: {
Text("Contact us")
}
Button {
withAnimation {
self.showLogsSheet.toggle()
}
} label: {
Text("Logs")
}
.sheet(isPresented: self.$showLogsSheet, content: {
NavigationStack {
LogsView().navigationTitle("Logs")
}
})
}.sheet(isPresented: $showMailView) {
MailView(isShowing: $showMailView)
}

@ -68,7 +68,7 @@ struct TimersView: View {
}
.padding(.horizontal, itemSpacing)
} else {
Text("You'll find your timers here. Start by creating them on the left screen")
Text("Disclaimer")
.padding()
.multilineTextAlignment(.center)
}

@ -1 +1,2 @@
"You'll find your timers here. Start by creating them on the left screen" = "You'll find your timers here.\nStart by creating using the top right button!";
"Disclaimer" = "This is a beta version of Enchant.\n\nPlease don't depend on the app for critical events :)\n\n If you ever encounter an issue, please let me know about it by going in the settings.";

@ -265,3 +265,4 @@
"Default Volume" = "Volume par défaut";
"Cancel %@" = "Annuler %@";
"Calendar" = "Calendrier";
"Disclaimer" = "Ceci est une version beta d'Enchante.\n\nVeillez à ne dépendre de l'app pour des évènements trop critiques :)\n\n Si jamais vous rencontrez un problème, merci de me contacter en allant dans les réglages.";

Loading…
Cancel
Save