Skip to content
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

### ✅ Added
- Add the `makeAttachmentTextView` method to ViewFactory [#1013](https://github.com/GetStream/stream-chat-swiftui/pull/1013)

- Allow dismissing commands overlay when tapping the message list [#1024](https://github.com/GetStream/stream-chat-swiftui/pull/1024)
- Allows dismissing the keyboard attachments picker when tapping the message list [#1024](https://github.com/GetStream/stream-chat-swiftui/pull/1024)
### 🐞 Fixed
- Fix composer not being locked after the channel was frozen [#1015](https://github.com/GetStream/stream-chat-swiftui/pull/1015)

### 🔄 Changed

# [4.90.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.90.0)
_October 08, 2025_

Expand Down
16 changes: 15 additions & 1 deletion Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ public struct ChatChannelView<Factory: ViewFactory>: View, KeyboardReadable {
},
onJumpToMessage: viewModel.jumpToMessage(messageId:)
)
.dismissKeyboardOnTap(enabled: true) {
hideComposerCommandsAndAttachmentsPicker()
}
.overlay(
viewModel.currentDateString != nil ?
factory.makeDateIndicatorView(dateString: viewModel.currentDateString!)
Expand All @@ -81,7 +84,9 @@ public struct ChatChannelView<Factory: ViewFactory>: View, KeyboardReadable {
} else {
ZStack {
factory.makeEmptyMessagesView(for: channel, colors: colors)
.dismissKeyboardOnTap(enabled: keyboardShown)
.dismissKeyboardOnTap(enabled: keyboardShown) {
hideComposerCommandsAndAttachmentsPicker()
}
if viewModel.shouldShowTypingIndicator {
factory.makeTypingIndicatorBottomView(
channel: channel,
Expand Down Expand Up @@ -213,4 +218,13 @@ public struct ChatChannelView<Factory: ViewFactory>: View, KeyboardReadable {
let bottomPadding = topVC()?.view.safeAreaInsets.bottom ?? 0
return bottomPadding
}

private func hideComposerCommandsAndAttachmentsPicker() {
NotificationCenter.default.post(
name: .attachmentPickerHiddenNotification, object: nil
)
NotificationCenter.default.post(
name: .commandsOverlayHiddenNotification, object: nil
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import SwiftUI
public struct MessageComposerView<Factory: ViewFactory>: View, KeyboardReadable {
@Injected(\.colors) private var colors
@Injected(\.fonts) private var fonts
@Injected(\.utils) private var utils

// Initial popup size, before the keyboard is shown.
@State private var popupSize: CGFloat = 350
Expand Down Expand Up @@ -228,6 +229,18 @@ public struct MessageComposerView<Factory: ViewFactory>: View, KeyboardReadable
viewModel.updateDraftMessage(quotedMessage: quotedMessage)
}
})
.onReceive(NotificationCenter.default.publisher(for: .commandsOverlayHiddenNotification)) { _ in
guard utils.messageListConfig.hidesCommandsOverlayOnMessageListTap else {
return
}
viewModel.composerCommand = nil
}
.onReceive(NotificationCenter.default.publisher(for: .attachmentPickerHiddenNotification)) { _ in
guard utils.messageListConfig.hidesAttachmentsPickersOnMessageListTap else {
return
}
viewModel.pickerTypeState = .expanded(.none)
}
.accessibilityElement(children: .contain)
}
}
Expand Down Expand Up @@ -444,3 +457,13 @@ public struct ComposerInputView<Factory: ViewFactory>: View, KeyboardReadable {
isInCooldown || isChannelFrozen
}
}

// MARK: - Notification Names

extension Notification.Name {
/// Notification sent when the attachments picker should be hidden.
static let attachmentPickerHiddenNotification = Notification.Name("attachmentPickerHiddenNotification")

/// Notification sent when the commands overlay should be hidden.
static let commandsOverlayHiddenNotification = Notification.Name("commandsOverlayHiddenNotification")
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public struct MessageListConfig {
bouncedMessagesAlertActionsEnabled: Bool = true,
skipEditedMessageLabel: @escaping (ChatMessage) -> Bool = { _ in false },
draftMessagesEnabled: Bool = false,
downloadFileAttachmentsEnabled: Bool = false
downloadFileAttachmentsEnabled: Bool = false,
hidesCommandsOverlayOnMessageListTap: Bool = true,
hidesAttachmentsPickersOnMessageListTap: Bool = true
) {
self.messageListType = messageListType
self.typingIndicatorPlacement = typingIndicatorPlacement
Expand Down Expand Up @@ -66,6 +68,8 @@ public struct MessageListConfig {
self.skipEditedMessageLabel = skipEditedMessageLabel
self.draftMessagesEnabled = draftMessagesEnabled
self.downloadFileAttachmentsEnabled = downloadFileAttachmentsEnabled
self.hidesCommandsOverlayOnMessageListTap = hidesCommandsOverlayOnMessageListTap
self.hidesAttachmentsPickersOnMessageListTap = hidesAttachmentsPickersOnMessageListTap
}

public let messageListType: MessageListType
Expand Down Expand Up @@ -93,6 +97,16 @@ public struct MessageListConfig {
public let markdownSupportEnabled: Bool
public let userBlockingEnabled: Bool

/// A boolean to enable hiding the commands overlay when tapping the message list.
///
/// It is enabled by default.
public let hidesCommandsOverlayOnMessageListTap: Bool

/// A boolean to enable hiding the attachments keyboard picker when tapping the message list.
///
/// It is enabled by default.
public let hidesAttachmentsPickersOnMessageListTap: Bool

/// A boolean to enable the alert actions for bounced messages.
///
/// By default it is true and the bounced actions are displayed as an alert instead of a context menu.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,6 @@ public struct MessageListView<Factory: ViewFactory>: View, KeyboardReadable {
) : nil
)
.modifier(factory.makeMessageListContainerModifier())
.dismissKeyboardOnTap(enabled: keyboardShown)
.onDisappear {
messageRenderingUtil.update(previousTopMessage: nil)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/StreamChatSwiftUI/Utils/KeyboardHandling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ extension View {
/// - enabled: If true, tapping on the view dismisses the view, otherwise keyboard stays visible.
/// - onTapped: A closure which is triggered when keyboard is dismissed after tapping the view.
func dismissKeyboardOnTap(enabled: Bool, onKeyboardDismissed: (() -> Void)? = nil) -> some View {
modifier(HideKeyboardOnTapGesture(shouldAdd: enabled))
modifier(HideKeyboardOnTapGesture(shouldAdd: enabled, onTapped: onKeyboardDismissed))
}
}

Expand Down
Loading