fix: disable button while starting up recording to prevent crashes (#45)

This commit is contained in:
Owen Gretzinger
2025-07-25 17:00:23 -04:00
committed by GitHub
parent a52df5b598
commit c8f52cdb1f
2 changed files with 15 additions and 2 deletions
@@ -23,6 +23,8 @@ class MeetingViewModel: ObservableObject {
@Published var isGeneratingNotes = false @Published var isGeneratingNotes = false
@Published var errorMessage: String? @Published var errorMessage: String?
@Published private var recordingStateChanged = false // Trigger SwiftUI updates @Published private var recordingStateChanged = false // Trigger SwiftUI updates
@Published var isValidatingKey = false // Indicates API key validation in progress
@Published var isStartingRecording = false // Indicates recording start in progress
// Computed property that always uses the direct RecordingSessionManager check // Computed property that always uses the direct RecordingSessionManager check
var isRecording: Bool { var isRecording: Bool {
@@ -86,6 +88,10 @@ class MeetingViewModel: ObservableObject {
Publishers.CombineLatest(recordingSessionManager.$isRecording, recordingSessionManager.$activeMeetingId) Publishers.CombineLatest(recordingSessionManager.$isRecording, recordingSessionManager.$activeMeetingId)
.sink { [weak self] (isRecording, activeMeetingId) in .sink { [weak self] (isRecording, activeMeetingId) in
guard let self = self else { return } guard let self = self else { return }
// If recording started for this meeting, end starting state
if isRecording && activeMeetingId == self.meeting.id {
self.isStartingRecording = false
}
// Toggle the dummy property to trigger SwiftUI re-render // Toggle the dummy property to trigger SwiftUI re-render
self.recordingStateChanged.toggle() self.recordingStateChanged.toggle()
} }
@@ -143,6 +149,8 @@ class MeetingViewModel: ObservableObject {
} }
func toggleRecording() { func toggleRecording() {
// Prevent duplicate actions while validating API key or starting recording
if isValidatingKey || isStartingRecording { return }
// Use the same computed isRecording property for perfect consistency // Use the same computed isRecording property for perfect consistency
if isRecording { if isRecording {
stopRecording() stopRecording()
@@ -153,8 +161,11 @@ class MeetingViewModel: ObservableObject {
func startRecording() { func startRecording() {
// Validate API key before starting recording // Validate API key before starting recording
isValidatingKey = true
isStartingRecording = true
Task { Task {
let validationResult = await APIKeyValidator.shared.validateCurrentAPIKey() let validationResult = await APIKeyValidator.shared.validateCurrentAPIKey()
defer { isValidatingKey = false }
switch validationResult { switch validationResult {
case .success(): case .success():
@@ -163,6 +174,8 @@ class MeetingViewModel: ObservableObject {
case .failure(let error): case .failure(let error):
// Show error message // Show error message
errorMessage = error.localizedDescription errorMessage = error.localizedDescription
// Cancel starting if validation failed
isStartingRecording = false
print("❌ API key validation failed: \(error.localizedDescription)") print("❌ API key validation failed: \(error.localizedDescription)")
} }
} }
+1 -1
View File
@@ -297,7 +297,7 @@ struct MeetingDetailContentView: View {
.cornerRadius(8) .cornerRadius(8)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.disabled(cannotStartRecording) .disabled(cannotStartRecording || viewModel.isValidatingKey || viewModel.isStartingRecording)
.help(cannotStartRecording ? "Another meeting is currently being recorded" : "Start or stop recording for this meeting") .help(cannotStartRecording ? "Another meeting is currently being recorded" : "Start or stop recording for this meeting")
Button(action: { Button(action: {