fix(onboarding): clearer bubbles and tighter composer
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user