From f01b7437e122a5d2aae6ed33ac12514fdee46824 Mon Sep 17 00:00:00 2001 From: Andrew Blakeslee Moore Date: Sun, 5 Jul 2026 04:55:27 -0700 Subject: [PATCH] Add New Chat Button Nucleic-Session: BB7AA593-185A-4A8F-A3DA-598EE63874E2 Co-authored-by: Nucleic --- .../NucleicRemote/Views/SessionsView.swift | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/NucleicRemote/NucleicRemote/Views/SessionsView.swift b/NucleicRemote/NucleicRemote/Views/SessionsView.swift index 9f515fd..81ad3bb 100644 --- a/NucleicRemote/NucleicRemote/Views/SessionsView.swift +++ b/NucleicRemote/NucleicRemote/Views/SessionsView.swift @@ -89,10 +89,50 @@ struct SessionsView: View { } } } + // A floating "new chat" affordance in the lower-right, mirroring the Mac's per-project + // "New chat" button. Picks a project + prompt in a sheet, then kicks off the chat. + .overlay(alignment: .bottomTrailing) { + if canStartChat { newChatButton } + } + .sheet(isPresented: $showNewChat) { + NavigationStack { + ScrollView { + StartChatComposer(onStart: { showNewChat = false }) + .padding() + } + .navigationTitle("New chat") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button("Cancel") { showNewChat = false } + } + } + } + .presentationDetents([.medium, .large]) + } .safeAreaInset(edge: .bottom) { ConnectionChip().padding(.bottom, 8) } } } + /// The circular plus button, styled to match the transcript's jump-to-bottom FAB: an accent + /// disc with a soft shadow, floated clear of the connection chip. + private var newChatButton: some View { + Button { + showNewChat = true + } label: { + Image(systemName: "plus") + .font(.system(size: 22, weight: .semibold)) + .foregroundStyle(.white) + .frame(width: 56, height: 56) + .background(Palette.accent, in: .circle) + .shadow(color: .black.opacity(0.25), radius: 6, y: 2) + } + .buttonStyle(.plain) + .padding(.trailing, 20) + .padding(.bottom, 20) + .accessibilityLabel("New chat") + } + /// Push the session a notification tap asked for, then clear the request. private func consumeRoute() { guard let route = store.pendingRoute else { return }