Fixes issue when running multiple countdowns at the same time

main
Laurent 3 years ago
parent 0e388c6a21
commit 604e167faa
  1. 25
      LeCountdown/Conductor.swift
  2. 2
      LeCountdown/Intent/StartTimerIntent.swift
  3. 2
      LeCountdown/Intent/TimerShortcuts.swift
  4. 2
      LeCountdown/LeCountdownApp.swift
  5. 10
      LeCountdown/Sound/DelaySoundPlayer.swift
  6. 2
      LeCountdown/Views/LiveTimerListView.swift

@ -20,14 +20,16 @@ fileprivate enum Const: String {
case confirmationSound = "PVP_Stab_Oneshot_Bleep_Em.wav"
}
typealias TimerID = String
class Conductor: ObservableObject {
static let maestro: Conductor = Conductor()
@Published var soundPlayer: SoundPlayer? = nil
var delaySoundPlayer: DelaySoundPlayer? = nil
var delayedSoundPlayers: [TimerID : DelaySoundPlayer] = [:]
@UserDefault(PreferenceKey.countdowns.rawValue, defaultValue: [:]) static var savedCountdowns: [String : DateInterval]
@UserDefault(PreferenceKey.stopwatches.rawValue, defaultValue: [:]) static var savedStopwatches: [String : Date]
@ -138,9 +140,9 @@ class Conductor: ObservableObject {
// }
}
func cancelCountdown(id: String) {
func cancelCountdown(id: TimerID) {
CountdownScheduler.master.cancelCurrentNotifications(countdownId: id)
self.stopSoundIfPossible()
self.cancelSoundPlayer(id: id)
self.cancelledCountdowns.append(id)
self._endCountdown(countdownId: id, cancel: true)
}
@ -163,7 +165,9 @@ class Conductor: ObservableObject {
let soundFile = try SoundFile(fullName: countdown.soundName)
let soundPlayer = DelaySoundPlayer(soundFile: soundFile)
self.delaySoundPlayer = soundPlayer
self.delayedSoundPlayers[countdown.stringId] = soundPlayer
try soundPlayer.start(in: countdown.duration,
repeatCount: Int(countdown.repeatCount))
@ -221,7 +225,7 @@ class Conductor: ObservableObject {
fileprivate func _cleanupCountdowns() {
let now = Date()
for (key, value) in self.currentCountdowns {
if value.end < now {
if value.end < now || self.cancelledCountdowns.contains(key) {
self._endCountdown(countdownId: key, cancel: false)
}
}
@ -268,7 +272,14 @@ class Conductor: ObservableObject {
}
}
func stopSoundIfPossible() {
func cancelSoundPlayer(id: TimerID) {
if let soundPlayer = self.delayedSoundPlayers[id] {
soundPlayer.stop()
self.delayedSoundPlayers.removeValue(forKey: id)
}
}
func stopMainPlayersIfPossible() {
self.soundPlayer?.stop()
self.soundPlayer = nil
}

@ -20,7 +20,7 @@ struct StartTimerIntent: AppIntent, CustomIntentMigratedAppIntent {
var timer: TimerIdentifierAppEntity?
static var parameterSummary: some ParameterSummary {
Summary()
Summary("")
}
func perform() async throws -> some IntentResult & ProvidesDialog & ShowsSnippetView {

@ -11,8 +11,8 @@ struct TimerShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(intent: StartTimerIntent(), phrases: [
"\(.applicationName) \(\.$timer)",
"Start \(\.$timer) with \(.applicationName)",
"\(.applicationName) \(\.$timer)",
"Launch \(\.$timer) with \(.applicationName)",
"Start \(.applicationName)",
"Launch \(.applicationName)"

@ -68,7 +68,7 @@ struct LeCountdownApp: App {
.onChange(of: scenePhase) { newPhase in
switch newPhase {
case .inactive:
Conductor.maestro.stopSoundIfPossible()
Conductor.maestro.stopMainPlayersIfPossible()
case .active:
Logger.log("onChange(of: scenePhase) active")
Logger.log(Conductor.maestro.currentCountdowns.count)

@ -46,15 +46,7 @@ import AVFoundation
// MARK: - Delegate
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
do {
self.stop()
try audioSession.setActive(false)
} catch {
Logger.error(error)
}
self.stop()
Logger.log("audioPlayerDidFinishPlaying: successfully = \(flag)")
}

@ -121,7 +121,7 @@ struct LiveCountdownView: View {
HStack {
let running = self.date > context.date
let cancelled = conductor.cancelledCountdowns.contains(where: { $0 == self.countdown.stringId })
let cancelled = self.conductor.cancelledCountdowns.contains(where: { $0 == self.countdown.stringId })
VStack(alignment: .leading) {

Loading…
Cancel
Save