From 21fc40bcf3e79134cac22fb5cd222d76bb29cb21 Mon Sep 17 00:00:00 2001 From: Stephen Heaps Date: Thu, 4 Jul 2024 08:26:46 -0400 Subject: [PATCH 1/3] Bump `leo-sf-symbols` for new `leo.send.filled` icon. Update input area to look "attached" to keyboard, tweak send icon, icon placement/padding. --- .../AIChat/Components/AIChatView.swift | 1 - .../Input/AIChatPromptInputView.swift | 89 ++++++++++++------- .../leo.send.filled.symbolset/Contents.json | 11 +++ package-lock.json | 14 +-- package.json | 2 +- 5 files changed, 76 insertions(+), 41 deletions(-) create mode 100644 ios/brave-ios/Sources/DesignSystem/Icons/Symbols.xcassets/leo.send.filled.symbolset/Contents.json diff --git a/ios/brave-ios/Sources/AIChat/Components/AIChatView.swift b/ios/brave-ios/Sources/AIChat/Components/AIChatView.swift index 80ac329cde8c..76cc9173e629 100644 --- a/ios/brave-ios/Sources/AIChat/Components/AIChatView.swift +++ b/ios/brave-ios/Sources/AIChat/Components/AIChatView.swift @@ -295,7 +295,6 @@ public struct AIChatView: View { model.requestInProgress || model.suggestionsStatus == .isGenerating || model.apiError == .contextLimitReached ) - .padding([.horizontal, .bottom], 8.0) } } .background(Color(braveSystemName: .containerBackground)) diff --git a/ios/brave-ios/Sources/AIChat/Components/Input/AIChatPromptInputView.swift b/ios/brave-ios/Sources/AIChat/Components/Input/AIChatPromptInputView.swift index ce405dc2f460..3731e9615e8a 100644 --- a/ios/brave-ios/Sources/AIChat/Components/Input/AIChatPromptInputView.swift +++ b/ios/brave-ios/Sources/AIChat/Components/Input/AIChatPromptInputView.swift @@ -107,57 +107,82 @@ struct AIChatPromptInputView: View { } icon: { Image(braveSystemName: "leo.slash") .foregroundStyle(Color(braveSystemName: .iconDefault)) - .padding(.horizontal, 1.0) + .padding(.horizontal, 8.0) .padding(.vertical, 4.0) - .padding([.leading, .trailing, .bottom]) + .padding(.bottom, 16.0) } .labelStyle(.iconOnly) } ) - Spacer() - - if prompt.isEmpty { - Button { - Task { @MainActor in - await activateSpeechRecognition() - } - } label: { - Label { - Text(Strings.AIChat.voiceInputButtonTitle) - .foregroundStyle(Color(braveSystemName: .textPrimary)) - } icon: { - Image(braveSystemName: "leo.microphone") - .foregroundStyle(Color(braveSystemName: .iconDefault)) - .padding([.leading, .trailing, .bottom]) - } - .labelStyle(.iconOnly) + Button { + Task { @MainActor in + await activateSpeechRecognition() } - .opacity(speechRecognizer.isVoiceSearchAvailable ? 1.0 : 0.0) - .disabled(!speechRecognizer.isVoiceSearchAvailable) - .frame(width: speechRecognizer.isVoiceSearchAvailable ? nil : 0.0) - } else { - Button { - onSubmit(prompt) - prompt = "" - } label: { - Image(braveSystemName: "leo.send") + } label: { + Label { + Text(Strings.AIChat.voiceInputButtonTitle) + .foregroundStyle(Color(braveSystemName: .textPrimary)) + } icon: { + Image(braveSystemName: "leo.microphone") .foregroundStyle(Color(braveSystemName: .iconDefault)) - .padding([.leading, .trailing, .bottom]) + .padding(.horizontal, 8.0) + .padding(.vertical, 4.0) + .padding(.bottom, 16.0) } + .labelStyle(.iconOnly) + } + .opacity(speechRecognizer.isVoiceSearchAvailable ? 1.0 : 0.0) + .disabled(!speechRecognizer.isVoiceSearchAvailable) + .frame(width: speechRecognizer.isVoiceSearchAvailable ? nil : 0.0) + + Spacer() + + Button { + onSubmit(prompt) + prompt = "" + } label: { + Image(braveSystemName: prompt.isEmpty ? "leo.send" : "leo.send.filled") + .foregroundStyle( + Color(braveSystemName: prompt.isEmpty ? .iconDisabled : .iconInteractive) + ) + .padding(.horizontal, 8.0) + .padding(.vertical, 4.0) + .padding(.bottom, 16.0) } } + .padding(.horizontal, 8.0) } .background( ContainerRelativeShape() .fill(Color(braveSystemName: .containerBackground)) - .shadow(color: .black.opacity(0.10), radius: 4.0, x: 0.0, y: 1.0) ) .overlay( ContainerRelativeShape() - .strokeBorder(Color(braveSystemName: .dividerStrong), lineWidth: 1.0) + .inset(by: -0.5) + .stroke( + LinearGradient( + stops: [ + .init(color: Color(braveSystemName: .dividerStrong), location: 0), + .init(color: Color(braveSystemName: .dividerStrong), location: 0.5), + // avoid stroke at bottom of shape + .init(color: Color(braveSystemName: .containerBackground), location: 1), + ], + startPoint: .top, + endPoint: .bottom + ), + lineWidth: 1.0 + ) + ) + .containerShape( + UnevenRoundedRectangle( + topLeadingRadius: 8.0, + bottomLeadingRadius: 0, + bottomTrailingRadius: 0, + topTrailingRadius: 8.0, + style: .continuous + ) ) - .containerShape(RoundedRectangle(cornerRadius: 8.0, style: .continuous)) .background { AIChatSpeechRecognitionView( speechRecognizer: speechRecognizer, diff --git a/ios/brave-ios/Sources/DesignSystem/Icons/Symbols.xcassets/leo.send.filled.symbolset/Contents.json b/ios/brave-ios/Sources/DesignSystem/Icons/Symbols.xcassets/leo.send.filled.symbolset/Contents.json new file mode 100644 index 000000000000..2f415ce6e4c0 --- /dev/null +++ b/ios/brave-ios/Sources/DesignSystem/Icons/Symbols.xcassets/leo.send.filled.symbolset/Contents.json @@ -0,0 +1,11 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "idiom" : "universal" + } + ] +} diff --git a/package-lock.json b/package-lock.json index ebaa01c143fa..71f4e206317a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@brave/brave-ui": "0.40.6", "@brave/leo": "github:brave/leo#4fe9d53ce3c23c91bd9952aa16822c5f1f2f3081", - "@brave/leo-sf-symbols": "github:brave/leo-sf-symbols#573b375ed2997dda47244410034b8420d9181590", + "@brave/leo-sf-symbols": "github:brave/leo-sf-symbols#f66f5701f8330253c1c113228c08f129178941c2", "@brave/wallet-standard-brave": "0.0.13", "@dnd-kit/core": "6.0.5", "@dnd-kit/sortable": "7.0.1", @@ -2188,9 +2188,9 @@ }, "node_modules/@brave/leo-sf-symbols": { "name": "leo-sf-symbols", - "version": "1.0.51", - "resolved": "git+ssh://git@github.com/brave/leo-sf-symbols.git#573b375ed2997dda47244410034b8420d9181590", - "integrity": "sha512-9/BtJUXo2fFxnVHUXFiYUhxzoHpwLVFXYHNpt+OZqu5rgnTxB9K63xAhQYwXNhqpr7ir/0OWBGJDBP4a49rt1A==", + "version": "1.0.58", + "resolved": "git+ssh://git@github.com/brave/leo-sf-symbols.git#f66f5701f8330253c1c113228c08f129178941c2", + "integrity": "sha512-siyUfMhRcepr26MKegYqtH2UsHUq4qM1q/ZJaMCh0t8ztP5ujJRV/fCM0DlRtr2awKPIEqw+X3bHd/08xAqI7A==", "license": "MPL-2.0" }, "node_modules/@brave/leo/node_modules/debug": { @@ -30424,9 +30424,9 @@ } }, "@brave/leo-sf-symbols": { - "version": "git+ssh://git@github.com/brave/leo-sf-symbols.git#573b375ed2997dda47244410034b8420d9181590", - "integrity": "sha512-9/BtJUXo2fFxnVHUXFiYUhxzoHpwLVFXYHNpt+OZqu5rgnTxB9K63xAhQYwXNhqpr7ir/0OWBGJDBP4a49rt1A==", - "from": "@brave/leo-sf-symbols@github:brave/leo-sf-symbols#573b375ed2997dda47244410034b8420d9181590" + "version": "git+ssh://git@github.com/brave/leo-sf-symbols.git#f66f5701f8330253c1c113228c08f129178941c2", + "integrity": "sha512-siyUfMhRcepr26MKegYqtH2UsHUq4qM1q/ZJaMCh0t8ztP5ujJRV/fCM0DlRtr2awKPIEqw+X3bHd/08xAqI7A==", + "from": "@brave/leo-sf-symbols@github:brave/leo-sf-symbols#f66f5701f8330253c1c113228c08f129178941c2" }, "@brave/wallet-standard-brave": { "version": "0.0.13", diff --git a/package.json b/package.json index d4d4a0d4efab..cdf21b711db4 100644 --- a/package.json +++ b/package.json @@ -170,7 +170,7 @@ "dependencies": { "@brave/brave-ui": "0.40.6", "@brave/leo": "github:brave/leo#4fe9d53ce3c23c91bd9952aa16822c5f1f2f3081", - "@brave/leo-sf-symbols": "github:brave/leo-sf-symbols#573b375ed2997dda47244410034b8420d9181590", + "@brave/leo-sf-symbols": "github:brave/leo-sf-symbols#f66f5701f8330253c1c113228c08f129178941c2", "@brave/wallet-standard-brave": "0.0.13", "@dnd-kit/core": "6.0.5", "@dnd-kit/sortable": "7.0.1", From 23f60aeb2820c4d12fd2606ea5e0cb1be8061f13 Mon Sep 17 00:00:00 2001 From: Stephen Heaps Date: Thu, 4 Jul 2024 11:33:43 -0400 Subject: [PATCH 2/3] Update response messaged view searched icon, adjust icon alignment to top of text. --- .../Messages/AIChatResponseMessageView.swift | 4 ++-- .../brave-icon-search.imageset/Contents.json | 22 ++++++++++++++++++ .../brave-icon-search-color@2x.png | Bin 0 -> 1745 bytes .../brave-icon-search-color@3x.png | Bin 0 -> 2827 bytes 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/Contents.json create mode 100644 ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/brave-icon-search-color@2x.png create mode 100644 ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/brave-icon-search-color@3x.png diff --git a/ios/brave-ios/Sources/AIChat/Components/Messages/AIChatResponseMessageView.swift b/ios/brave-ios/Sources/AIChat/Components/Messages/AIChatResponseMessageView.swift index 4ca2f0e6e87e..dabfa7d589b5 100644 --- a/ios/brave-ios/Sources/AIChat/Components/Messages/AIChatResponseMessageView.swift +++ b/ios/brave-ios/Sources/AIChat/Components/Messages/AIChatResponseMessageView.swift @@ -97,8 +97,8 @@ struct AIChatResponseMessageView: View { } if let searchQueriesEvent = searchQueriesEvent, !isEntryInProgress { - HStack { - Image(braveSystemName: "leo.search") + HStack(alignment: .top) { + Image("brave-icon-search", bundle: .module) generateSearchQueriesView(queries: searchQueriesEvent.searchQueries) .tint(Color(braveSystemName: .textPrimary)) diff --git a/ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/Contents.json b/ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/Contents.json new file mode 100644 index 000000000000..75d7139df1ad --- /dev/null +++ b/ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "brave-icon-search-color@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "brave-icon-search-color@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/brave-icon-search-color@2x.png b/ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/brave-icon-search-color@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7f4421569317dddf9c7cfda3243615066870156c GIT binary patch literal 1745 zcmV;?1}^!DP)e&1E-psDO>-^Z|R;e#q@9gZ%d*6Kf z-kUcex-a*bD7s5YBoe(VE42tSAH-!tMVN?tU3C?usDws|*;$yMpUKf(O2>c%$nD$J zQA`WoKt|owkf|-a?YA-W| z{lM^?I(s&sX=ke~pn-w?$6;#B2PC7Eg%zJEZZ@yKKMr6rPYpNcs>!*zZ^!BX0va5Q zPhn*v?j!tyl31nq2yu*Ta^$j@Y7U{T&?c&)&6HCYv@cOC77H_51&=X+$^caIt^oy^ z;cQRO17o>d&U~5#l;2U8s7}4O0EUU`P*syVo@=y-`yN%&KIG}kVCFEjVQO7KpnC+L zX37JDXc^HU$V#{XMsW{=6-HZWFm<%+XxEehwaR7OCv}@?T3w-X5EPHk&CN`<1r&=V z!j4ldpcxj&otw+|X)u;5K>1D$z!6ZcVF9vzr=q1LqNR$kW0;bAy)mXt7DuCxBr2iM zDs*!My_KGxP@l)TC*7@p07h02Hmh)=W|aCGAi^5{jy|GyP7~dPp1;dP+rx@>*=F+Z zaGT$7JrNOBh?4t=7Aw-0PdrsD=AvLfiG^OmTS+705)+#;G%ygq=CT9l%WLQ3!=Rqk zsAlHli$r}9>PRjWiC*7l*m6`#U3DgmjTbU*^sQmZ3W9kt;jz=zMd`*1OYIU|^ztzS z<{b1L1$l4oCi>Lpo2OC$u!ras^#4>OdfFy>ZPYBAd2d6V)s=CZI_uL$0y-zb5F^~L zd42GoUOu9j58-N+Ib?-b!=`;>k@;{R^UsCgm?iW-4$tdT{{|NyzvkKsICg*`%P=8Q z^!ikegwC>lIG+u!U|@u3mvJ+C2ub|8gG77m;FvGcI?mC$9(=(IZe#C;fRMag`uK8S zuA`>){RCXx>#&JPh;#SDR*UD^s7X+FS$0u8v^q7D#uZkV7DWa zS^s?opSfBx{kJge5469}nd`6XN=KPU0nhIyxe+!NO$XNKuxBH%QLhR6b;Y3^6i#X7 zx4^>5aYY{>oeUvrpG6#uM@?QjdWvYbZRUKF)yqe8vcA`-)QPDUh72>76)Z2bA1R;0 zXA;eqJHpuXMu=W|s|iNrDO)?GOvm4XDpP=Uyz*>pni$Kt;71MTZi=H8+zhMepK`PR zG@LdIKdEarh>nb!{$ESNjM6mmy6k8h@b}V&fDoh$hzC@I*u`6=%PC-=8r24JX+?jQ ziEiNYNv1xDWceT#{5gOPJxcUggy~$)^&V*K=IK^-rrOl4KmY|Ybu4zkb{t3cF;Hqn z{WXu|BMe_Ody}jhhCVz`^rRiMv;b#*d&u4WNnh#;2ki9sCr~R@FX?r5@zBgnv(ydv z(8@}8$@3$uU^swW{D={{+ADNkK@E5aq3=rrU*hw>)T~W4SNPcC5{U~XC=mgS18c}y+i8b*Cw2aI6RY)}jgLFg+8W)5CpfnohMf?n@UxKBDl*H61Z74N6J6mqGzhMb0 z8!aZe-+FBwjG8(OhXq)b&}E5NlsR$|;iUSpS-uL(%gfc{UVRR|X_Pi&>)GA3$oH3= z5KtV7ww|x}d4P7*gbOOAexS*gg+<(Q*xM(wN_8Q^99vvt+qNy^{(7kGG04x9S)Ixt zRMYu3P5 literal 0 HcmV?d00001 diff --git a/ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/brave-icon-search-color@3x.png b/ios/brave-ios/Sources/AIChat/Images.xcassets/brave-icon-search.imageset/brave-icon-search-color@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..1e48053881196ec2a6c1d71532f91373a11b8e55 GIT binary patch literal 2827 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 Date: Thu, 4 Jul 2024 15:36:53 -0400 Subject: [PATCH 3/3] Disable send when input is empty. --- .../Sources/AIChat/Components/Input/AIChatPromptInputView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/brave-ios/Sources/AIChat/Components/Input/AIChatPromptInputView.swift b/ios/brave-ios/Sources/AIChat/Components/Input/AIChatPromptInputView.swift index 3731e9615e8a..fe4cecc23618 100644 --- a/ios/brave-ios/Sources/AIChat/Components/Input/AIChatPromptInputView.swift +++ b/ios/brave-ios/Sources/AIChat/Components/Input/AIChatPromptInputView.swift @@ -150,6 +150,7 @@ struct AIChatPromptInputView: View { .padding(.vertical, 4.0) .padding(.bottom, 16.0) } + .disabled(prompt.isEmpty) } .padding(.horizontal, 8.0) }