@@ -61,55 +61,79 @@ struct ChatPanelToolbar: View {
6161struct ChatPanelMessages : View {
6262 @ObservedObject var chat : ChatProvider
6363 @AppStorage ( \. disableLazyVStack) var disableLazyVStack
64-
65- @ViewBuilder
66- func vstack( @ViewBuilder content: ( ) -> some View ) -> some View {
67- if disableLazyVStack {
68- VStack ( spacing: 4 ) {
69- content ( )
70- }
71- } else {
72- LazyVStack ( spacing: 4 ) {
73- content ( )
74- }
64+ @State var height : Double = 0
65+
66+ struct HeightPreferenceKey : PreferenceKey {
67+ static var defaultValue : Double = 0
68+ static func reduce( value: inout Double , nextValue: ( ) -> Double ) {
69+ value = nextValue ( ) + value
7570 }
7671 }
77-
78- var body : some View {
79- CustomScrollView {
80- VStack ( spacing: 0 ) {
81- vstack {
82- Spacer ( )
83-
84- if chat. isReceivingMessage {
85- StopRespondingButton ( chat: chat)
72+
73+ struct UpdateHeightModifier : ViewModifier {
74+ func body( content: Content ) -> some View {
75+ content
76+ . background {
77+ GeometryReader { proxy in
78+ Color . clear
79+ . preference ( key: HeightPreferenceKey . self, value: proxy. size. height)
8680 }
81+ }
82+ }
83+ }
84+
85+ var body : some View {
86+ List {
87+ Group {
88+ Spacer ( )
89+ . modifier ( UpdateHeightModifier ( ) )
90+
91+ if chat. isReceivingMessage {
92+ StopRespondingButton ( chat: chat)
93+ . padding ( . vertical, 4 )
94+ . listRowInsets ( EdgeInsets ( top: 0 , leading: - 8 , bottom: 0 , trailing: - 8 ) )
95+ . modifier ( UpdateHeightModifier ( ) )
96+ }
8797
88- if chat. history. isEmpty {
89- Text ( " New Chat " )
90- . frame ( maxWidth: . infinity, alignment: . center)
91- . padding ( )
92- . scaleEffect ( x: - 1 , y: - 1 , anchor: . center)
93- . foregroundStyle ( . secondary)
94- }
98+ if chat. history. isEmpty {
99+ Text ( " New Chat " )
100+ . frame ( maxWidth: . infinity, alignment: . center)
101+ . padding ( . vertical)
102+ . scaleEffect ( x: - 1 , y: - 1 , anchor: . center)
103+ . foregroundStyle ( . secondary)
104+ . listRowInsets ( EdgeInsets ( top: 0 , leading: - 8 , bottom: 0 , trailing: - 8 ) )
105+ . modifier ( UpdateHeightModifier ( ) )
106+ }
95107
96- ForEach ( chat. history. reversed ( ) , id: \. id) { message in
97- let text = message. text. isEmpty && !message. isUser ? " ... " : message
98- . text
108+ ForEach ( chat. history. reversed ( ) , id: \. id) { message in
109+ let text = message. text. isEmpty && !message. isUser ? " ... " : message
110+ . text
99111
100- if message. isUser {
101- UserMessage ( text: text)
102- } else {
103- BotMessage ( text: text)
104- }
112+ if message. isUser {
113+ UserMessage ( text: text)
114+ . listRowInsets ( EdgeInsets ( top: 0 , leading: - 8 , bottom: 0 , trailing: - 8 ) )
115+ . padding ( . vertical, 4 )
116+ } else {
117+ BotMessage ( text: text)
118+ . listRowInsets ( EdgeInsets ( top: 0 , leading: - 8 , bottom: 0 , trailing: - 8 ) )
119+ . padding ( . vertical, 4 )
105120 }
106-
107- Spacer ( )
108121 }
122+ . listItemTint ( . clear)
123+ . modifier ( UpdateHeightModifier ( ) )
124+
125+ Spacer ( )
126+ . modifier ( UpdateHeightModifier ( ) )
109127 }
110128 . scaleEffect ( x: - 1 , y: 1 , anchor: . center)
111129 }
130+ . id ( " \( chat. history. count) , \( chat. isReceivingMessage) " )
131+ . listStyle ( . plain)
132+ . frame ( idealHeight: max ( 50 , height + 16 ) )
112133 . scaleEffect ( x: 1 , y: - 1 , anchor: . center)
134+ . onPreferenceChange ( HeightPreferenceKey . self) { newHeight in
135+ height = newHeight
136+ }
113137 }
114138}
115139
@@ -136,6 +160,7 @@ private struct StopRespondingButton: View {
136160 }
137161 . buttonStyle ( . borderless)
138162 . scaleEffect ( x: - 1 , y: - 1 , anchor: . center)
163+ . frame ( maxWidth: . infinity, alignment: . center)
139164 }
140165}
141166
@@ -170,6 +195,7 @@ private struct UserMessage: View {
170195 NSPasteboard . general. clearContents ( )
171196 NSPasteboard . general. setString ( text, forType: . string)
172197 }
198+ . buttonStyle ( . borderless)
173199 }
174200 }
175201}
@@ -210,6 +236,7 @@ private struct BotMessage: View {
210236 NSPasteboard . general. clearContents ( )
211237 NSPasteboard . general. setString ( text, forType: . string)
212238 }
239+ . buttonStyle ( . borderless)
213240 }
214241 }
215242 . frame ( maxWidth: . infinity, alignment: . trailing)
0 commit comments