feat: group meetings by date, improve preview

This commit is contained in:
Owen Gretzinger
2025-07-10 19:25:49 -04:00
parent fe2e22e795
commit 264163bc74
+74 -29
View File
@@ -14,14 +14,23 @@ struct MeetingListView: View {
description: Text("Start a new meeting to begin transcribing") description: Text("Start a new meeting to begin transcribing")
) )
} else { } else {
ForEach(viewModel.meetings) { meeting in ForEach(groupedMeetings, id: \.day) { dayGroup in
NavigationLink(value: meeting) { Section {
MeetingRowView(meeting: meeting) ForEach(dayGroup.meetings) { meeting in
} NavigationLink(value: meeting) {
} MeetingRowView(meeting: meeting)
.onDelete { indexSet in }
for index in indexSet { }
viewModel.deleteMeeting(viewModel.meetings[index]) .onDelete { indexSet in
for index in indexSet {
viewModel.deleteMeeting(dayGroup.meetings[index])
}
}
} header: {
Text(dayGroup.day)
.font(.subheadline)
.fontWeight(.medium)
.foregroundColor(.primary)
} }
} }
} }
@@ -50,38 +59,74 @@ struct MeetingListView: View {
} }
} }
} }
private var groupedMeetings: [DayGroup] {
let calendar = Calendar.current
let now = Date()
let grouped = Dictionary(grouping: viewModel.meetings) { meeting in
calendar.startOfDay(for: meeting.date)
}
return grouped.map { (date, meetings) in
let dayString: String
if calendar.isDateInToday(date) {
dayString = "Today"
} else if calendar.isDateInYesterday(date) {
dayString = "Yesterday"
} else if calendar.isDate(date, equalTo: now, toGranularity: .weekOfYear) {
dayString = date.formatted(.dateTime.weekday(.wide))
} else {
dayString = date.formatted(.dateTime.weekday(.wide).month(.abbreviated).day())
}
return DayGroup(day: dayString, date: date, meetings: meetings.sorted { $0.date > $1.date })
}.sorted { $0.date > $1.date }
}
}
struct DayGroup {
let day: String
let date: Date
let meetings: [Meeting]
} }
struct MeetingRowView: View { struct MeetingRowView: View {
let meeting: Meeting let meeting: Meeting
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 4) { HStack {
// Show title if exists, otherwise show date VStack(alignment: .leading, spacing: 6) {
if !meeting.title.isEmpty { // Title or default
Text(meeting.title) Text(meeting.title.isEmpty ? "Untitled meeting" : meeting.title)
.font(.headline) .font(.headline)
.lineLimit(1) .lineLimit(1)
Text(meeting.date, style: .date) // Notes preview or placeholder
.font(.caption) HStack {
.foregroundColor(.secondary) if !meeting.generatedNotes.isEmpty {
} else { Text(meeting.generatedNotes.replacingOccurrences(of: "\n", with: " ").trimmingCharacters(in: .whitespacesAndNewlines))
Text(meeting.date, style: .date) .font(.subheadline)
.font(.headline) .foregroundColor(.secondary)
.lineLimit(1)
} else {
Text("No notes yet")
.font(.subheadline)
.foregroundColor(.secondary)
.italic()
}
Spacer()
}
.padding(.trailing, 20)
} }
if !meeting.transcript.isEmpty { Spacer()
Text(meeting.transcript)
.font(.caption) // Date on the right
.foregroundColor(.secondary) Text(meeting.date, style: .time)
.lineLimit(2) .font(.caption)
} else { .foregroundColor(.secondary)
Text("No transcript")
.font(.caption)
.foregroundColor(.secondary)
.italic()
}
} }
.padding(.vertical, 4) .padding(.vertical, 4)
} }