feat: add meeting deletion

This commit is contained in:
Owen Gretzinger
2025-07-10 19:46:54 -04:00
parent 264163bc74
commit a99e080324
3 changed files with 56 additions and 6 deletions
@@ -20,6 +20,13 @@ class MeetingListViewModel: ObservableObject {
self?.loadMeetings() self?.loadMeetings()
} }
.store(in: &cancellables) .store(in: &cancellables)
NotificationCenter.default.publisher(for: .meetingDeleted)
.sink { [weak self] _ in
print("🔔 Meeting deleted notification received. Reloading meetings list...")
self?.loadMeetings()
}
.store(in: &cancellables)
} }
func loadMeetings() { func loadMeetings() {
@@ -5,6 +5,7 @@ import Combine
// Add notification name for meeting saved events // Add notification name for meeting saved events
extension Notification.Name { extension Notification.Name {
static let meetingSaved = Notification.Name("MeetingSaved") static let meetingSaved = Notification.Name("MeetingSaved")
static let meetingDeleted = Notification.Name("MeetingDeleted")
} }
enum MeetingViewTab: String, CaseIterable { enum MeetingViewTab: String, CaseIterable {
@@ -27,6 +28,7 @@ class MeetingViewModel: ObservableObject {
@Published var isRecording = false @Published var isRecording = false
@Published var selectedTab: MeetingViewTab = .myNotes @Published var selectedTab: MeetingViewTab = .myNotes
@Published var recordingState: RecordingState = .idle @Published var recordingState: RecordingState = .idle
@Published var isDeleted = false
private let audioManager = AudioManager() private let audioManager = AudioManager()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
@@ -129,6 +131,7 @@ class MeetingViewModel: ObservableObject {
} }
func saveMeeting() { func saveMeeting() {
if isDeleted { return }
print("💾 Saving meeting: \(meeting.id)") print("💾 Saving meeting: \(meeting.id)")
let success = LocalStorageManager.shared.saveMeeting(meeting) let success = LocalStorageManager.shared.saveMeeting(meeting)
print("💾 Save result: \(success ? "SUCCESS" : "FAILED")") print("💾 Save result: \(success ? "SUCCESS" : "FAILED")")
@@ -162,4 +165,12 @@ class MeetingViewModel: ObservableObject {
NSPasteboard.general.setString(content, forType: .string) NSPasteboard.general.setString(content, forType: .string)
} }
func deleteMeeting() {
let success = LocalStorageManager.shared.deleteMeeting(meeting)
if success {
isDeleted = true
NotificationCenter.default.post(name: .meetingDeleted, object: meeting)
}
}
} }
+38 -6
View File
@@ -30,6 +30,8 @@ struct CollapsedTranscriptChunkView: View {
struct MeetingDetailView: View { struct MeetingDetailView: View {
@StateObject private var viewModel: MeetingViewModel @StateObject private var viewModel: MeetingViewModel
@Environment(\.dismiss) private var dismiss
@State private var showDeleteAlert = false
init(meeting: Meeting) { init(meeting: Meeting) {
self._viewModel = StateObject(wrappedValue: MeetingViewModel(meeting: meeting)) self._viewModel = StateObject(wrappedValue: MeetingViewModel(meeting: meeting))
@@ -37,12 +39,33 @@ struct MeetingDetailView: View {
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 20) { VStack(alignment: .leading, spacing: 20) {
// Meeting Title // Meeting Title with Menu
TextField("Meeting Title", text: $viewModel.meeting.title) HStack {
.font(.title2) TextField("Meeting Title", text: $viewModel.meeting.title)
.fontWeight(.semibold) .font(.title2)
.textFieldStyle(.plain) .fontWeight(.semibold)
.padding(.bottom, 10) .textFieldStyle(.plain)
Spacer()
// Ellipsis menu
Menu {
Button("Delete Meeting", role: .destructive) {
showDeleteAlert = true
}
} label: {
Image(systemName: "ellipsis")
.resizable()
.scaledToFit()
.frame(width: 12, height: 12)
.foregroundColor(.secondary)
}
.labelStyle(.iconOnly)
.menuIndicator(.hidden)
.menuStyle(BorderlessButtonMenuStyle())
.frame(width: 20, height: 20)
}
.padding(.bottom, 10)
// Controls Section // Controls Section
HStack { HStack {
@@ -121,6 +144,15 @@ struct MeetingDetailView: View {
} message: { } message: {
Text(viewModel.errorMessage ?? "") Text(viewModel.errorMessage ?? "")
} }
.alert("Delete Meeting", isPresented: $showDeleteAlert) {
Button("Delete", role: .destructive) {
viewModel.deleteMeeting()
dismiss()
}
Button("Cancel", role: .cancel) { }
} message: {
Text("Are you sure you want to delete this meeting? This action cannot be undone.")
}
.onDisappear { .onDisappear {
viewModel.saveMeeting() viewModel.saveMeeting()
} }