fix(onboarding): clearer bubbles and tighter composer

This commit is contained in:
Peter Steinberger
2025-12-20 22:03:24 +00:00
parent 98ff213708
commit 238c0c1b86
3 changed files with 70 additions and 10 deletions

View File

@@ -41,7 +41,7 @@ struct ClawdisChatComposer: View {
.lineLimit(2) .lineLimit(2)
} }
} }
.padding(8) .padding(self.composerPadding)
.background( .background(
RoundedRectangle(cornerRadius: 18, style: .continuous) RoundedRectangle(cornerRadius: 18, style: .continuous)
.fill(ClawdisChatTheme.composerBackground) .fill(ClawdisChatTheme.composerBackground)
@@ -144,9 +144,9 @@ struct ClawdisChatComposer: View {
self.sendButton self.sendButton
} }
} }
.padding(8) .padding(self.editorPadding)
} }
.frame(minHeight: 44, idealHeight: 44, maxHeight: 96) .frame(minHeight: self.editorMinHeight, idealHeight: self.editorMinHeight, maxHeight: self.editorMaxHeight)
} }
private var connectionPill: some View { private var connectionPill: some View {
@@ -179,7 +179,7 @@ struct ClawdisChatComposer: View {
ChatComposerTextView(text: self.$viewModel.input) { ChatComposerTextView(text: self.$viewModel.input) {
self.viewModel.send() self.viewModel.send()
} }
.frame(minHeight: 32, idealHeight: 32, maxHeight: 72) .frame(minHeight: self.textMinHeight, idealHeight: self.textMinHeight, maxHeight: self.textMaxHeight)
.padding(.horizontal, 6) .padding(.horizontal, 6)
.padding(.vertical, 4) .padding(.vertical, 4)
#else #else
@@ -254,6 +254,30 @@ struct ClawdisChatComposer: View {
self.style == .standard self.style == .standard
} }
private var composerPadding: CGFloat {
self.style == .onboarding ? 6 : 8
}
private var editorPadding: CGFloat {
self.style == .onboarding ? 6 : 8
}
private var editorMinHeight: CGFloat {
self.style == .onboarding ? 38 : 44
}
private var editorMaxHeight: CGFloat {
self.style == .onboarding ? 72 : 96
}
private var textMinHeight: CGFloat {
self.style == .onboarding ? 28 : 32
}
private var textMaxHeight: CGFloat {
self.style == .onboarding ? 60 : 72
}
#if os(macOS) #if os(macOS)
private func pickFilesMac() { private func pickFilesMac() {
let panel = NSOpenPanel() let panel = NSOpenPanel()

View File

@@ -77,6 +77,7 @@ private struct ChatMessageBody: View {
.background(self.bubbleBackground) .background(self.bubbleBackground)
.overlay(self.bubbleBorder) .overlay(self.bubbleBorder)
.clipShape(RoundedRectangle(cornerRadius: ChatUIConstants.bubbleCorner, style: .continuous)) .clipShape(RoundedRectangle(cornerRadius: ChatUIConstants.bubbleCorner, style: .continuous))
.shadow(color: self.bubbleShadowColor, radius: self.bubbleShadowRadius, y: self.bubbleShadowYOffset)
} }
private var primaryText: String { private var primaryText: String {
@@ -101,10 +102,33 @@ private struct ChatMessageBody: View {
} }
private var bubbleBorder: some View { private var bubbleBorder: some View {
RoundedRectangle(cornerRadius: ChatUIConstants.bubbleCorner, style: .continuous) let borderColor: Color
.strokeBorder( let lineWidth: CGFloat
self.isUser ? Color.white.opacity(0.12) : Color.black.opacity(0.08), if self.isUser {
lineWidth: self.isUser ? 0.5 : 1) borderColor = Color.white.opacity(0.12)
lineWidth = 0.5
} else if self.style == .onboarding {
borderColor = ClawdisChatTheme.onboardingAssistantBorder
lineWidth = 0.8
} else {
borderColor = Color.black.opacity(0.08)
lineWidth = 1
}
return RoundedRectangle(cornerRadius: ChatUIConstants.bubbleCorner, style: .continuous)
.strokeBorder(borderColor, lineWidth: lineWidth)
}
private var bubbleShadowColor: Color {
self.style == .onboarding && !self.isUser ? Color.black.opacity(0.28) : .clear
}
private var bubbleShadowRadius: CGFloat {
self.style == .onboarding && !self.isUser ? 6 : 0
}
private var bubbleShadowYOffset: CGFloat {
self.style == .onboarding && !self.isUser ? 2 : 0
} }
} }
@@ -243,7 +267,9 @@ private struct MarkdownTextView: View {
of: "(?<!\\n)\\n(?!\\n)", of: "(?<!\\n)\\n(?!\\n)",
with: " \\n", with: " \\n",
options: .regularExpression) options: .regularExpression)
if let attributed = try? AttributedString(markdown: normalized) { let options = AttributedString.MarkdownParsingOptions(
interpretedSyntax: .inlineOnlyPreservingWhitespace)
if let attributed = try? AttributedString(markdown: normalized, options: options) {
Text(attributed) Text(attributed)
.font(.system(size: 14)) .font(.system(size: 14))
.foregroundStyle(self.textColor) .foregroundStyle(self.textColor)

View File

@@ -49,12 +49,22 @@ enum ClawdisChatTheme {
static var onboardingAssistantBubble: Color { static var onboardingAssistantBubble: Color {
#if os(macOS) #if os(macOS)
Color(nsColor: .controlBackgroundColor).opacity(0.92) let base = NSColor.controlBackgroundColor
let blended = base.blended(withFraction: 0.22, of: .white) ?? base
return Color(nsColor: blended)
#else #else
Color(uiColor: .secondarySystemBackground) Color(uiColor: .secondarySystemBackground)
#endif #endif
} }
static var onboardingAssistantBorder: Color {
#if os(macOS)
Color.white.opacity(0.12)
#else
Color.white.opacity(0.12)
#endif
}
static var userText: Color { .white } static var userText: Color { .white }
static var assistantText: Color { static var assistantText: Color {