@@ -44,64 +44,70 @@ struct MessageListView: View {
4444 }
4545 Spacer ( )
4646 }
47- }
48- ScrollViewReader { proxy in
49-
50- ChatScrollView {
51- VStack ( spacing: 0 ) {
52- if room. hasMoreMessages {
53- Button ( " Load more... " ) {
54- guard let oldestMessage = room. firstMessage? . ts
55- else { return }
56-
57- messagesLoader. loadMore ( from: oldestMessage)
47+ } else {
48+ ScrollViewReader { proxy in
49+ ChatScrollView {
50+ VStack ( spacing: 0 ) {
51+ if room. hasMoreMessages {
52+ Button ( " Load more... " ) {
53+ guard
54+ let oldestMessage = room. firstMessage?
55+ . ts
56+ else { return }
57+
58+ messagesLoader. loadMore ( from: oldestMessage)
59+ }
60+ . padding ( . bottom, 8 )
5861 }
59- . padding ( . bottom, 8 )
60- }
61-
62- ForEach ( messages. indices, id: \. self) { index in
63- let message = messages [ index]
64- let previousMessage =
65- messages. indices. contains ( index - 1 )
66- ? messages [ index - 1 ] : nil
67-
68- MessageView (
69- viewModel: . init(
70- message: message,
71- previousMessage: previousMessage,
72- server: server,
73- lastOpen: lastOpen
74- )
75- ) { action in
76- switch action {
77- case . resend( let message) :
78- messageSender. resendMessage (
62+
63+ ForEach ( messages. indices, id: \. self) { index in
64+ let message = messages [ index]
65+ let previousMessage =
66+ messages. indices. contains ( index - 1 )
67+ ? messages [ index - 1 ] : nil
68+
69+ MessageView (
70+ viewModel: . init(
7971 message: message,
80- in: room
72+ previousMessage: previousMessage,
73+ server: server,
74+ lastOpen: lastOpen
8175 )
82-
83- lastOpen = nil
84- case . delete( let message) :
85- database. remove ( message)
76+ ) { action in
77+ switch action {
78+ case . resend( let message) :
79+ messageSender. resendMessage (
80+ message: message,
81+ in: room
82+ )
83+
84+ lastOpen = nil
85+ case . delete( let message) :
86+ database. remove ( message)
87+ }
8688 }
8789 }
90+
91+ MessageComposerView (
92+ room: room,
93+ server: server,
94+ anchorID: bottomAnchor
95+ ) {
96+ messageSender. sendMessage ( $0, in: room)
97+
98+ lastOpen = nil
99+ }
100+ . id ( messageComposer)
101+ . padding ( . top, 8 )
88102 }
89-
90- MessageComposerView ( room: room, server: server, anchorID: bottomAnchor) {
91- messageSender. sendMessage ( $0, in: room)
92-
93- lastOpen = nil
103+ . onAppear {
104+ scrollToBottom ( proxy: proxy)
94105 }
95- . id ( messageComposer)
96- . padding ( . top, 8 )
97- }
98- . onAppear {
99- scrollToBottom ( proxy: proxy)
100- }
101- . onChange ( of: messages. last? . ts) { _ in
102- // Also scroll to bottom when new messages arrive
103- withAnimation ( . easeOut( duration: 0.3 ) ) {
104- proxy. scrollTo ( bottomAnchor, anchor: . center)
106+ . onChange ( of: messages. last? . ts) { _ in
107+ // Also scroll to bottom when new messages arrive
108+ withAnimation ( . easeOut( duration: 0.3 ) ) {
109+ proxy. scrollTo ( bottomAnchor, anchor: . center)
110+ }
105111 }
106112 }
107113 }
@@ -144,10 +150,11 @@ struct MessageListView: View {
144150 }
145151 }
146152 }
153+
147154 private func scrollToBottom( proxy: ScrollViewProxy ) {
148- // Small delay ensures layout is complete before scrolling
149- DispatchQueue . main. asyncAfter ( deadline: . now( ) + 0.05 ) {
150- proxy. scrollTo ( bottomAnchor, anchor: . bottom)
151- }
155+ // Small delay ensures layout is complete before scrolling
156+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + 0.1 ) {
157+ proxy. scrollTo ( bottomAnchor, anchor: . bottom)
152158 }
159+ }
153160}
0 commit comments