💄 Auto hide input on watchOS
This commit is contained in:
		| @@ -263,6 +263,8 @@ struct ChatRoomView: View { | |||||||
|     @State private var hasLoadedMessages = false // Track if messages have been loaded |     @State private var hasLoadedMessages = false // Track if messages have been loaded | ||||||
|     @State private var messageText = "" // Text input for sending messages |     @State private var messageText = "" // Text input for sending messages | ||||||
|     @State private var isSending = false // Track sending state |     @State private var isSending = false // Track sending state | ||||||
|  |     @State private var isInputHidden = false // Track if input should be hidden during scrolling | ||||||
|  |     @State private var scrollTimer: Timer? // Timer to show input after scrolling stops | ||||||
|  |  | ||||||
|     @State private var cancellables = Set<AnyCancellable>() // For managing subscriptions |     @State private var cancellables = Set<AnyCancellable>() // For managing subscriptions | ||||||
|  |  | ||||||
| @@ -311,6 +313,7 @@ struct ChatRoomView: View { | |||||||
|                         } |                         } | ||||||
|                         .padding(.horizontal) |                         .padding(.horizontal) | ||||||
|                         .padding(.vertical, 8) |                         .padding(.vertical, 8) | ||||||
|  |                         .padding(.bottom, 8) | ||||||
|                     } |                     } | ||||||
|                     .onAppear { |                     .onAppear { | ||||||
|                         // Scroll to bottom when messages load |                         // Scroll to bottom when messages load | ||||||
| @@ -326,37 +329,55 @@ struct ChatRoomView: View { | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                     .onScrollPhaseChange { _, phase  in | ||||||
|  |                         switch phase { | ||||||
|  |                         case .interacting: | ||||||
|  |                             if !isInputHidden { | ||||||
|  |                                 withAnimation(.easeOut(duration: 0.2)) { | ||||||
|  |                                     isInputHidden = true | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         case .idle: | ||||||
|  |                             withAnimation(.easeIn(duration: 0.3)) { | ||||||
|  |                                 isInputHidden = false | ||||||
|  |                             } | ||||||
|  |                         default: break | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // Message input area |             // Message input area | ||||||
|             HStack(spacing: 8) { |             if !isInputHidden { | ||||||
|                 TextField("Send message...", text: $messageText) |                 HStack(spacing: 8) { | ||||||
|                     .font(.system(size: 14)) |                     TextField("Send message...", text: $messageText) | ||||||
|                     .disabled(isSending) |                         .font(.system(size: 14)) | ||||||
|                     .frame(height: 40) |                         .disabled(isSending) | ||||||
|  |                         .frame(height: 40) | ||||||
|  |  | ||||||
|                 Button { |                     Button { | ||||||
|                     Task { |                         Task { | ||||||
|                         await sendMessage() |                             await sendMessage() | ||||||
|                     } |                         } | ||||||
|                 } label: { |                     } label: { | ||||||
|                     if isSending { |                         if isSending { | ||||||
|                         ProgressView() |                             ProgressView() | ||||||
|                             .frame(width: 20, height: 20) |                                 .frame(width: 20, height: 20) | ||||||
|                     } else { |                         } else { | ||||||
|                         Image(systemName: "arrow.up.circle.fill") |                             Image(systemName: "arrow.up.circle.fill") | ||||||
|                             .resizable() |                                 .resizable() | ||||||
|                             .frame(width: 20, height: 20) |                                 .frame(width: 20, height: 20) | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|  |                     .labelStyle(.iconOnly) | ||||||
|  |                     .buttonStyle(.glass) | ||||||
|  |                     .disabled(messageText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isSending) | ||||||
|  |                     .frame(width: 40, height: 40) | ||||||
|                 } |                 } | ||||||
|                 .labelStyle(.iconOnly) |                 .padding(.horizontal) | ||||||
|                 .buttonStyle(.glass) |                 .padding(.top, 8) | ||||||
|                 .disabled(messageText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isSending) |                 .transition(.move(edge: .bottom).combined(with: .opacity)) | ||||||
|                 .frame(width: 40, height: 40) |  | ||||||
|             } |             } | ||||||
|             .padding(.horizontal) |  | ||||||
|             .padding(.top, 8) |  | ||||||
|         } |         } | ||||||
|         .navigationTitle(room.name ?? "Chat") |         .navigationTitle(room.name ?? "Chat") | ||||||
|         .task { |         .task { | ||||||
| @@ -368,6 +389,8 @@ struct ChatRoomView: View { | |||||||
|         .onDisappear { |         .onDisappear { | ||||||
|             cancellables.forEach { $0.cancel() } |             cancellables.forEach { $0.cancel() } | ||||||
|             cancellables.removeAll() |             cancellables.removeAll() | ||||||
|  |             scrollTimer?.invalidate() | ||||||
|  |             scrollTimer = nil | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user