Message Queue Display

Nucleic-Session: 4714846A-A598-4711-AA38-640B40927DF4
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-01 18:34:18 -07:00
co-authored by Nucleic
parent 687a024373
commit 63054a4629
@@ -210,6 +210,56 @@ struct SessionDetailView: View {
.padding()
}
}
/// A queued follow-up shown above the composer: its text (or attachment names) with the
/// attachments as chips, and — at control scope — a ✕ that cancels just this message.
@ViewBuilder
private func queuedMessageRow(_ message: QueuedMessage) -> some View {
VStack(alignment: .leading, spacing: 4) {
HStack(spacing: 6) {
Image(systemName: "clock").foregroundStyle(.secondary)
Text(queuedRowText(message)).lineLimit(1).truncationMode(.tail)
.foregroundStyle(.secondary)
Spacer(minLength: 8)
if store.canControl {
Button {
// Refill the composer for editing (text only — the phone can't stage the
// host's files) unless the user has already started typing; then drop it.
if draft.trimmingCharacters(in: .whitespaces).isEmpty { draft = message.text }
store.cancelQueuedMessage(sessionID, message.id)
} label: {
Image(systemName: "xmark.circle.fill").foregroundStyle(.secondary)
}
.buttonStyle(.plain)
.disabled(!store.connectivity.isLive)
}
}
.font(.footnote)
if !message.attachments.isEmpty {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 6) {
ForEach(message.attachments) { attachment in
Label(attachment.filename, systemImage: "doc")
.font(.caption2)
.lineLimit(1)
.padding(.horizontal, 7).padding(.vertical, 3)
.background(.quaternary, in: .capsule)
}
}
}
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 8).padding(.vertical, 6)
.background(.quaternary.opacity(0.4), in: .rect(cornerRadius: 10))
}
/// The one-line label for a queued pill: the message text, or — for an attachment-only
/// message — the attachment names (the chips below repeat them), so it's never blank.
private func queuedRowText(_ message: QueuedMessage) -> String {
if !message.text.isEmpty { return message.text }
return message.attachments.map(\.filename).joined(separator: ", ")
}
}
struct TranscriptList: View {