Chat View Refinement

Nucleic-Session: 4E56990A-96AE-4597-9140-753CB82E769D
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-05 01:13:16 -07:00
co-authored by Nucleic
parent 3c26b29505
commit 48283674fa
@@ -131,9 +131,54 @@ struct SessionDetailView: View {
}
}
/// The ⋯ menu: the diff viewer for everyone, then the control-scope session actions.
@ViewBuilder
private func sessionMenu(_ summary: WireSessionSummary) -> some View {
private var sessionMenu: some View {
Menu {
Button { showDiff = true } label: {
Label(diffLabel, systemImage: "plus.forwardslash.minus")
}
if let summary, store.canControl {
Divider()
sessionActions(summary)
}
} label: {
Image(systemName: "ellipsis.circle")
}
}
/// "View changes" with the live +/− counts when the host projects them, so the menu hints
/// whether there's anything to look at before opening the sheet.
private var diffLabel: String {
guard let stat = summary?.diffStat, stat.filesChanged > 0 else { return "View changes" }
return "View changes · +\(stat.added) −\(stat.removed)"
}
/// The diff, presented as a sheet from the ⋯ menu — a viewer you visit, not a mode the
/// chat lives in.
private var diffSheet: some View {
NavigationStack {
Group {
if store.capabilities.canFetchDiff || store.openDiff != nil {
SessionDiffView(diff: store.openDiff, loading: store.diffLoading)
.onAppear { store.fetchDiff(sessionID) }
} else {
// Older host with no on-demand diff — the stat summary is all it projects.
DiffSummaryView(diffStat: summary?.diffStat)
}
}
.navigationTitle("Changes")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Done") { showDiff = false }
}
}
}
}
@ViewBuilder
private func sessionActions(_ summary: WireSessionSummary) -> some View {
Button { renameDraft = summary.title; showRename = true } label: {
Label("Rename", systemImage: "pencil")
}