Timer plays sound when expired
This commit is contained in:
@@ -50,6 +50,7 @@
|
|||||||
A9CA6CEF2B4C086100F78AB5 /* RecipeExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CA6CEE2B4C086100F78AB5 /* RecipeExporter.swift */; };
|
A9CA6CEF2B4C086100F78AB5 /* RecipeExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CA6CEE2B4C086100F78AB5 /* RecipeExporter.swift */; };
|
||||||
A9CA6CF62B4C63F200F78AB5 /* TPPDF in Frameworks */ = {isa = PBXBuildFile; productRef = A9CA6CF52B4C63F200F78AB5 /* TPPDF */; };
|
A9CA6CF62B4C63F200F78AB5 /* TPPDF in Frameworks */ = {isa = PBXBuildFile; productRef = A9CA6CF52B4C63F200F78AB5 /* TPPDF */; };
|
||||||
A9D89AB02B4FE97800F49D92 /* TimerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D89AAF2B4FE97800F49D92 /* TimerView.swift */; };
|
A9D89AB02B4FE97800F49D92 /* TimerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D89AAF2B4FE97800F49D92 /* TimerView.swift */; };
|
||||||
|
A9FA2AB62B5079B200A43702 /* alarm_sound_0.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = A9FA2AB52B5079B200A43702 /* alarm_sound_0.mp3 */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@@ -115,6 +116,7 @@
|
|||||||
A7FB0D7D2B25C6A200A3469E /* V2LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = V2LoginView.swift; sourceTree = "<group>"; };
|
A7FB0D7D2B25C6A200A3469E /* V2LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = V2LoginView.swift; sourceTree = "<group>"; };
|
||||||
A9CA6CEE2B4C086100F78AB5 /* RecipeExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeExporter.swift; sourceTree = "<group>"; };
|
A9CA6CEE2B4C086100F78AB5 /* RecipeExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeExporter.swift; sourceTree = "<group>"; };
|
||||||
A9D89AAF2B4FE97800F49D92 /* TimerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerView.swift; sourceTree = "<group>"; };
|
A9D89AAF2B4FE97800F49D92 /* TimerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerView.swift; sourceTree = "<group>"; };
|
||||||
|
A9FA2AB52B5079B200A43702 /* alarm_sound_0.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = alarm_sound_0.mp3; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -147,6 +149,7 @@
|
|||||||
A70171752AA8E71900064C43 = {
|
A70171752AA8E71900064C43 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A9FA2AB42B50798800A43702 /* Resources */,
|
||||||
A781E75E2AE9133B00452F6F /* Screenshots */,
|
A781E75E2AE9133B00452F6F /* Screenshots */,
|
||||||
A70171802AA8E71900064C43 /* Nextcloud Cookbook iOS Client */,
|
A70171802AA8E71900064C43 /* Nextcloud Cookbook iOS Client */,
|
||||||
A70171922AA8E72000064C43 /* Nextcloud Cookbook iOS ClientTests */,
|
A70171922AA8E72000064C43 /* Nextcloud Cookbook iOS ClientTests */,
|
||||||
@@ -323,6 +326,14 @@
|
|||||||
path = RecipeExport;
|
path = RecipeExport;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
A9FA2AB42B50798800A43702 /* Resources */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
A9FA2AB52B5079B200A43702 /* alarm_sound_0.mp3 */,
|
||||||
|
);
|
||||||
|
path = Resources;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
@@ -438,6 +449,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
A9FA2AB62B5079B200A43702 /* alarm_sound_0.mp3 in Resources */,
|
||||||
A701718A2AA8E71F00064C43 /* Preview Assets.xcassets in Resources */,
|
A701718A2AA8E71F00064C43 /* Preview Assets.xcassets in Resources */,
|
||||||
A70171862AA8E71F00064C43 /* Assets.xcassets in Resources */,
|
A70171862AA8E71F00064C43 /* Assets.xcassets in Resources */,
|
||||||
A7AEAE642AD5521400135378 /* Localizable.xcstrings in Resources */,
|
A7AEAE642AD5521400135378 /* Localizable.xcstrings in Resources */,
|
||||||
|
|||||||
Binary file not shown.
@@ -2853,6 +2853,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Timer alert!" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"Title" : {
|
"Title" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -3161,6 +3164,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Your timer is expired!" : {
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version" : "1.0"
|
"version" : "1.0"
|
||||||
|
|||||||
@@ -623,4 +623,8 @@ extension MainViewModel {
|
|||||||
func getTimer(forRecipe recipeId: String, duration: DurationComponents) -> RecipeTimer {
|
func getTimer(forRecipe recipeId: String, duration: DurationComponents) -> RecipeTimer {
|
||||||
return timers[recipeId] ?? createTimer(forRecipe: recipeId, duration: duration)
|
return timers[recipeId] ?? createTimer(forRecipe: recipeId, duration: duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteTimer(forRecipe recipeId: String) {
|
||||||
|
timers.removeValue(forKey: recipeId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,13 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
import AVFoundation
|
||||||
|
|
||||||
|
|
||||||
struct TimerView: View {
|
struct TimerView: View {
|
||||||
@ObservedObject var timer: RecipeTimer
|
@ObservedObject var timer: RecipeTimer
|
||||||
|
@State var audioPlayer: AVAudioPlayer?
|
||||||
|
@State var presentTimerAlert: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
@@ -56,6 +59,31 @@ struct TimerView: View {
|
|||||||
RoundedRectangle(cornerRadius: 20)
|
RoundedRectangle(cornerRadius: 20)
|
||||||
.foregroundStyle(.ultraThickMaterial)
|
.foregroundStyle(.ultraThickMaterial)
|
||||||
}
|
}
|
||||||
|
.alert("Timer alert!", isPresented: $timer.timerExpired) {
|
||||||
|
Button {
|
||||||
|
timer.timerExpired = false
|
||||||
|
audioPlayer?.stop()
|
||||||
|
} label: {
|
||||||
|
Text("Your timer is expired!")
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
playSound()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func playSound() {
|
||||||
|
if let path = Bundle.main.path(forResource: "alarm_sound_0", ofType: "mp3") {
|
||||||
|
do {
|
||||||
|
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
|
||||||
|
audioPlayer?.prepareToPlay()
|
||||||
|
} catch {
|
||||||
|
// Handle the error
|
||||||
|
print("Error loading sound file.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
audioPlayer?.play()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +96,7 @@ class RecipeTimer: ObservableObject {
|
|||||||
private var pauseDate: Date?
|
private var pauseDate: Date?
|
||||||
@Published var timeElapsed: Double = 0
|
@Published var timeElapsed: Double = 0
|
||||||
@Published var isRunning: Bool = false
|
@Published var isRunning: Bool = false
|
||||||
|
@Published var timerExpired: Bool = false
|
||||||
private var timer: Timer.TimerPublisher?
|
private var timer: Timer.TimerPublisher?
|
||||||
private var timerCancellable: Cancellable?
|
private var timerCancellable: Cancellable?
|
||||||
|
|
||||||
@@ -95,6 +124,7 @@ class RecipeTimer: ObservableObject {
|
|||||||
self.timeElapsed = elapsed
|
self.timeElapsed = elapsed
|
||||||
self.duration.fromSeconds(Int(self.timeTotal - self.timeElapsed))
|
self.duration.fromSeconds(Int(self.timeTotal - self.timeElapsed))
|
||||||
} else {
|
} else {
|
||||||
|
self.timerExpired = true
|
||||||
self.timeElapsed = self.timeTotal
|
self.timeElapsed = self.timeTotal
|
||||||
self.duration.fromSeconds(Int(self.timeTotal - self.timeElapsed))
|
self.duration.fromSeconds(Int(self.timeTotal - self.timeElapsed))
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|||||||
BIN
Resources/alarm_sound_0.mp3
Normal file
BIN
Resources/alarm_sound_0.mp3
Normal file
Binary file not shown.
Reference in New Issue
Block a user