feat: add meeting deletion
This commit is contained in:
@@ -20,6 +20,13 @@ class MeetingListViewModel: ObservableObject {
|
||||
self?.loadMeetings()
|
||||
}
|
||||
.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() {
|
||||
|
||||
@@ -5,6 +5,7 @@ import Combine
|
||||
// Add notification name for meeting saved events
|
||||
extension Notification.Name {
|
||||
static let meetingSaved = Notification.Name("MeetingSaved")
|
||||
static let meetingDeleted = Notification.Name("MeetingDeleted")
|
||||
}
|
||||
|
||||
enum MeetingViewTab: String, CaseIterable {
|
||||
@@ -27,6 +28,7 @@ class MeetingViewModel: ObservableObject {
|
||||
@Published var isRecording = false
|
||||
@Published var selectedTab: MeetingViewTab = .myNotes
|
||||
@Published var recordingState: RecordingState = .idle
|
||||
@Published var isDeleted = false
|
||||
|
||||
private let audioManager = AudioManager()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
@@ -129,6 +131,7 @@ class MeetingViewModel: ObservableObject {
|
||||
}
|
||||
|
||||
func saveMeeting() {
|
||||
if isDeleted { return }
|
||||
print("💾 Saving meeting: \(meeting.id)")
|
||||
let success = LocalStorageManager.shared.saveMeeting(meeting)
|
||||
print("💾 Save result: \(success ? "SUCCESS" : "FAILED")")
|
||||
@@ -162,4 +165,12 @@ class MeetingViewModel: ObservableObject {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ struct CollapsedTranscriptChunkView: View {
|
||||
|
||||
struct MeetingDetailView: View {
|
||||
@StateObject private var viewModel: MeetingViewModel
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var showDeleteAlert = false
|
||||
|
||||
init(meeting: Meeting) {
|
||||
self._viewModel = StateObject(wrappedValue: MeetingViewModel(meeting: meeting))
|
||||
@@ -37,12 +39,33 @@ struct MeetingDetailView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 20) {
|
||||
// Meeting Title
|
||||
TextField("Meeting Title", text: $viewModel.meeting.title)
|
||||
.font(.title2)
|
||||
.fontWeight(.semibold)
|
||||
.textFieldStyle(.plain)
|
||||
.padding(.bottom, 10)
|
||||
// Meeting Title with Menu
|
||||
HStack {
|
||||
TextField("Meeting Title", text: $viewModel.meeting.title)
|
||||
.font(.title2)
|
||||
.fontWeight(.semibold)
|
||||
.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
|
||||
HStack {
|
||||
@@ -121,6 +144,15 @@ struct MeetingDetailView: View {
|
||||
} message: {
|
||||
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 {
|
||||
viewModel.saveMeeting()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user