Message Queue Display
Nucleic-Session: 4714846A-A598-4711-AA38-640B40927DF4 Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user