@@ -43,7 +43,6 @@ struct ChatPanelMessages: View {
4343 let chat : StoreOf < Chat >
4444 @State var cancellable = Set < AnyCancellable > ( )
4545 @State var isScrollToBottomButtonDisplayed = true
46- @State var isPinnedToBottom = true
4746 @Namespace var bottomID
4847 @Namespace var topID
4948 @Namespace var scrollSpace
@@ -128,11 +127,7 @@ struct ChatPanelMessages: View {
128127 scrollToBottomButton ( proxy: proxy)
129128 }
130129 . background {
131- PinToBottomHandler (
132- chat: chat,
133- isBottomHidden: isBottomHidden,
134- pinnedToBottom: $isPinnedToBottom
135- ) {
130+ PinToBottomHandler ( chat: chat, isBottomHidden: isBottomHidden) {
136131 proxy. scrollTo ( bottomID, anchor: . bottom)
137132 }
138133 }
@@ -151,22 +146,26 @@ struct ChatPanelMessages: View {
151146 cancellable. forEach { $0. cancel ( ) }
152147 cancellable = [ ]
153148 }
149+ . onChange ( of: isEnabled) { isEnabled in
150+ chat. send ( . setIsEnabled( isEnabled) )
151+ }
154152 }
155153 }
156154
157155 func trackScrollWheel( ) {
158156 NSApplication . shared. publisher ( for: \. currentEvent)
159- . filter {
160- if !isEnabled { return false }
157+ . receive ( on: DispatchQueue . main)
158+ . filter { [ chat] in
159+ guard chat. withState ( \. isEnabled) else { return false }
161160 return $0? . type == . scrollWheel
162161 }
163162 . compactMap { $0 }
164163 . sink { event in
165- guard isPinnedToBottom else { return }
164+ guard chat . withState ( \ . isPinnedToBottom) else { return }
166165 let delta = event. deltaY
167166 let scrollUp = delta > 0
168167 if scrollUp {
169- isPinnedToBottom = false
168+ chat . send ( . manuallyScrolledUp )
170169 }
171170 }
172171 . store ( in: & cancellable)
@@ -184,7 +183,7 @@ struct ChatPanelMessages: View {
184183 @ViewBuilder
185184 func scrollToBottomButton( proxy: ScrollViewProxy ) -> some View {
186185 Button ( action: {
187- isPinnedToBottom = true
186+ chat . send ( . scrollToBottomButtonTapped )
188187 withAnimation ( . easeInOut( duration: 0.1 ) ) {
189188 proxy. scrollTo ( bottomID, anchor: . bottom)
190189 }
@@ -222,18 +221,16 @@ struct ChatPanelMessages: View {
222221 struct PinToBottomHandler : View {
223222 let chat : StoreOf < Chat >
224223 let isBottomHidden : Bool
225- @Binding var pinnedToBottom : Bool
226224 let scrollToBottom : ( ) -> Void
227225
228226 @State var isInitialLoad = true
229-
227+
230228 var body : some View {
231229 WithPerceptionTracking {
232230 EmptyView ( )
233231 . onChange ( of: chat. isReceivingMessage) { isReceiving in
234232 if isReceiving {
235233 Task {
236- pinnedToBottom = true
237234 await Task . yield ( )
238235 withAnimation ( . easeInOut( duration: 0.1 ) ) {
239236 scrollToBottom ( )
@@ -242,7 +239,7 @@ struct ChatPanelMessages: View {
242239 }
243240 }
244241 . onChange ( of: chat. history. last) { _ in
245- if pinnedToBottom || isInitialLoad {
242+ if chat . withState ( \ . isPinnedToBottom ) || isInitialLoad {
246243 if isInitialLoad {
247244 isInitialLoad = false
248245 }
@@ -256,7 +253,7 @@ struct ChatPanelMessages: View {
256253 }
257254 . onChange ( of: isBottomHidden) { value in
258255 // This is important to prevent it from jumping to the top!
259- if value, pinnedToBottom {
256+ if value, chat . withState ( \ . isPinnedToBottom ) {
260257 scrollToBottom ( )
261258 }
262259 }
0 commit comments