@@ -2,33 +2,90 @@ import MarkdownUI
22import SwiftUI
33
44struct ChatPanel : View {
5- @ ObservedObject var viewModel : SuggestionPanelViewModel
5+ var viewModel : SuggestionPanelViewModel
66 @ObservedObject var chat : ChatRoom
7+ @State var typedMessage = " "
8+ @Namespace var inputAreaNamespace
79
810 var body : some View {
911 ZStack ( alignment: . topTrailing) {
10- ScrollView {
11- LazyVStack {
12- ForEach ( chat. history. reversed ( ) , id: \. id) { message in
13- Markdown ( message. text)
14- . markdownTheme ( . gitHub. text {
15- BackgroundColor ( Color . clear)
16- } )
17- . frame ( maxWidth: . infinity, alignment: . leading)
18- . padding ( )
19- . background (
20- RoundedRectangle ( cornerRadius: 9 , style: . continuous)
21- . fill (
22- message. isUser
12+ VStack {
13+ ScrollView {
14+ LazyVStack ( ) {
15+ if chat. isReceivingMessage {
16+ Button ( action: {
17+ chat. stop ( )
18+ } ) {
19+ HStack ( spacing: 4 ) {
20+ Image ( systemName: " stop.fill " )
21+ Text ( " Stop Responding " )
22+ }
23+ . rotationEffect ( Angle ( degrees: 180 ) )
24+ . padding ( 8 )
25+ . background (
26+ . regularMaterial,
27+ in: RoundedRectangle ( cornerRadius: 8 , style: . continuous)
28+ )
29+ }
30+ . buttonStyle ( . plain)
31+ . xcodeStyleFrame ( )
32+ . matchedGeometryEffect ( id: " input " , in: inputAreaNamespace)
33+ }
34+
35+ ForEach ( chat. history. reversed ( ) , id: \. id) { message in
36+ let text = message. text. isEmpty && !message. isUser ? " ... " : message. text
37+
38+ Markdown ( text)
39+ . textSelection ( . enabled)
40+ . markdownTheme ( . gitHub. text {
41+ BackgroundColor ( Color . clear)
42+ } )
43+ . frame ( maxWidth: . infinity, alignment: . leading)
44+ . padding ( )
45+ . background (
46+ RoundedRectangle ( cornerRadius: 9 , style: . continuous)
47+ . fill (
48+ message. isUser
2349 ? Color . userChatContentBackground
2450 : Color . contentBackground
25- )
51+ )
52+ )
53+ . xcodeStyleFrame ( )
54+ . rotationEffect ( Angle ( degrees: 180 ) )
55+ }
56+ }
57+ }
58+ . rotationEffect ( Angle ( degrees: 180 ) )
59+
60+ if !chat. isReceivingMessage {
61+ HStack {
62+ TextField ( " Type a message " , text: $typedMessage)
63+ . textFieldStyle ( . plain)
64+ . padding ( 8 )
65+ . background (
66+ . regularMaterial,
67+ in: RoundedRectangle ( cornerRadius: 8 , style: . continuous)
2668 )
27- . rotationEffect ( Angle ( degrees: 180 ) )
69+ . xcodeStyleFrame ( )
70+
71+ Button ( action: {
72+ if typedMessage. isEmpty { return }
73+ chat. send ( typedMessage)
74+ typedMessage = " "
75+ } ) {
76+ Image ( systemName: " paperplane.fill " )
77+ . padding ( 8 )
78+ . background (
79+ . regularMaterial,
80+ in: RoundedRectangle ( cornerRadius: 8 , style: . continuous)
81+ )
82+ }
83+ . buttonStyle ( . plain)
84+ . xcodeStyleFrame ( )
2885 }
86+ . matchedGeometryEffect ( id: " input " , in: inputAreaNamespace)
2987 }
3088 }
31- . rotationEffect ( Angle ( degrees: 180 ) )
3289
3390 // close button
3491 Button ( action: {
@@ -39,11 +96,10 @@ struct ChatPanel: View {
3996 Image ( systemName: " xmark " )
4097 . padding ( [ . leading, . bottom] , 16 )
4198 . padding ( [ . top, . trailing] , 8 )
42- . foregroundColor ( . white )
99+ . foregroundStyle ( . secondary )
43100 }
44101 . buttonStyle ( . plain)
45102 }
46- . colorScheme ( viewModel. colorScheme)
47103 }
48104}
49105
@@ -76,9 +132,12 @@ struct ChatPanel_Preview: PreviewProvider {
76132 """#
77133 ) ,
78134 ] ,
79- isReceivingMessage: false
135+ isReceivingMessage: true
80136 ) )
137+ . padding ( 8 )
138+ . background ( Color . contentBackground)
81139 . frame ( width: 450 , height: 500 )
140+ . colorScheme ( . dark)
82141 }
83142}
84143
@@ -112,8 +171,11 @@ struct ChatPanel_Light_Preview: PreviewProvider {
112171 """#
113172 ) ,
114173 ] ,
115- isReceivingMessage: false
174+ isReceivingMessage: true
116175 ) )
176+ . padding ( 8 )
177+ . background ( Color . contentBackground)
117178 . frame ( width: 450 , height: 500 )
179+ . colorScheme ( . light)
118180 }
119181}
0 commit comments