Skip to content

Commit 9e78a0a

Browse files
committed
Allow customizing the QuotedMessageContentView
1 parent 412b39f commit 9e78a0a

File tree

3 files changed

+66
-23
lines changed

3 files changed

+66
-23
lines changed

Sources/StreamChatSwiftUI/ChatChannel/MessageList/QuotedMessageView.swift

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,13 @@ public struct QuotedMessageView<Factory: ViewFactory>: View {
109109

110110
public var body: some View {
111111
HStack(alignment: .top) {
112-
QuotedMessageContentView(
113-
factory: factory,
112+
factory.makeQuotedMessageContentView(
114113
quotedMessage: quotedMessage,
115-
fillAvailableSpace: fillAvailableSpace,
116-
forceLeftToRight: forceLeftToRight,
117-
attachmentSize: attachmentSize
114+
options: QuotedMessageContentViewOptions(
115+
fillAvailableSpace: fillAvailableSpace,
116+
forceLeftToRight: forceLeftToRight,
117+
attachmentSize: attachmentSize
118+
)
118119
)
119120
}
120121
.id(quotedMessage.messageId)
@@ -151,7 +152,30 @@ public struct QuotedMessageView<Factory: ViewFactory>: View {
151152
}
152153
}
153154

154-
struct QuotedMessageContentView<Factory: ViewFactory>: View {
155+
/// Options for configuring the quoted message content view.
156+
public struct QuotedMessageContentViewOptions {
157+
/// Whether the quoted container should take all the available space.
158+
public let fillAvailableSpace: Bool
159+
/// Whether to force left to right layout.
160+
public let forceLeftToRight: Bool
161+
/// The size of the attachment preview.
162+
public let attachmentSize: CGSize
163+
164+
public init(
165+
fillAvailableSpace: Bool,
166+
forceLeftToRight: Bool,
167+
attachmentSize: CGSize = CGSize(width: 36, height: 36)
168+
) {
169+
self.fillAvailableSpace = fillAvailableSpace
170+
self.forceLeftToRight = forceLeftToRight
171+
self.attachmentSize = attachmentSize
172+
}
173+
}
174+
175+
/// The quoted message content view.
176+
///
177+
/// It is the view that is embedded in quoted message bubble view.
178+
public struct QuotedMessageContentView<Factory: ViewFactory>: View {
155179
@Environment(\.channelTranslationLanguage) var translationLanguage
156180

157181
@Injected(\.images) private var images
@@ -161,9 +185,7 @@ struct QuotedMessageContentView<Factory: ViewFactory>: View {
161185

162186
public var factory: Factory
163187
public var quotedMessage: ChatMessage
164-
public var fillAvailableSpace: Bool
165-
public var forceLeftToRight: Bool
166-
public let attachmentSize: CGSize
188+
public var options: QuotedMessageContentViewOptions
167189

168190
private var messageTypeResolver: MessageTypeResolving {
169191
utils.messageTypeResolver
@@ -172,18 +194,14 @@ struct QuotedMessageContentView<Factory: ViewFactory>: View {
172194
public init(
173195
factory: Factory,
174196
quotedMessage: ChatMessage,
175-
fillAvailableSpace: Bool,
176-
forceLeftToRight: Bool,
177-
attachmentSize: CGSize = CGSize(width: 36, height: 36)
197+
options: QuotedMessageContentViewOptions
178198
) {
179199
self.factory = factory
180200
self.quotedMessage = quotedMessage
181-
self.fillAvailableSpace = fillAvailableSpace
182-
self.forceLeftToRight = forceLeftToRight
183-
self.attachmentSize = attachmentSize
201+
self.options = options
184202
}
185203

186-
var body: some View {
204+
public var body: some View {
187205
if !quotedMessage.attachmentCounts.isEmpty {
188206
ZStack {
189207
if messageTypeResolver.hasCustomAttachment(message: quotedMessage) {
@@ -193,22 +211,22 @@ struct QuotedMessageContentView<Factory: ViewFactory>: View {
193211
} else if !quotedMessage.imageAttachments.isEmpty {
194212
LazyLoadingImage(
195213
source: MediaAttachment(url: quotedMessage.imageAttachments[0].imageURL, type: .image),
196-
width: attachmentSize.width,
197-
height: attachmentSize.height,
214+
width: options.attachmentSize.width,
215+
height: options.attachmentSize.height,
198216
resize: false
199217
)
200218
} else if !quotedMessage.giphyAttachments.isEmpty {
201219
LazyGiphyView(
202220
source: quotedMessage.giphyAttachments[0].previewURL,
203-
width: attachmentSize.width
221+
width: options.attachmentSize.width
204222
)
205223
} else if !quotedMessage.fileAttachments.isEmpty {
206224
Image(uiImage: filePreviewImage(for: quotedMessage.fileAttachments[0].assetURL))
207225
} else if !quotedMessage.videoAttachments.isEmpty {
208226
VideoAttachmentView(
209227
attachment: quotedMessage.videoAttachments[0],
210228
message: quotedMessage,
211-
width: attachmentSize.width,
229+
width: options.attachmentSize.width,
212230
ratio: 1.0,
213231
cornerRadius: 0
214232
)
@@ -218,11 +236,11 @@ struct QuotedMessageContentView<Factory: ViewFactory>: View {
218236
.originalURL
219237
)
220238
.onDisappear(.cancel)
221-
.processors([ImageProcessors.Resize(width: attachmentSize.width)])
239+
.processors([ImageProcessors.Resize(width: options.attachmentSize.width)])
222240
.priority(.high)
223241
}
224242
}
225-
.frame(width: hasVoiceAttachments ? nil : attachmentSize.width, height: attachmentSize.height)
243+
.frame(width: hasVoiceAttachments ? nil : options.attachmentSize.width, height: options.attachmentSize.height)
226244
.aspectRatio(1, contentMode: .fill)
227245
.clipShape(RoundedRectangle(cornerRadius: 8))
228246
.allowsHitTesting(false)
@@ -238,7 +256,7 @@ struct QuotedMessageContentView<Factory: ViewFactory>: View {
238256
.accessibility(identifier: "quotedMessageText")
239257
}
240258

241-
if fillAvailableSpace {
259+
if options.fillAvailableSpace {
242260
Spacer()
243261
}
244262
}

Sources/StreamChatSwiftUI/DefaultViewFactory.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,17 @@ extension ViewFactory {
998998
)
999999
}
10001000

1001+
public func makeQuotedMessageContentView(
1002+
quotedMessage: ChatMessage,
1003+
options: QuotedMessageContentViewOptions
1004+
) -> some View {
1005+
QuotedMessageContentView(
1006+
factory: self,
1007+
quotedMessage: quotedMessage,
1008+
options: options
1009+
)
1010+
}
1011+
10011012
public func makeCustomAttachmentQuotedView(for message: ChatMessage) -> some View {
10021013
EmptyView()
10031014
}

Sources/StreamChatSwiftUI/ViewFactory.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,20 @@ public protocol ViewFactory: AnyObject {
10151015
scrolledId: Binding<String?>
10161016
) -> QuotedMessageViewType
10171017

1018+
associatedtype QuotedMessageContentViewType: View
1019+
/// Creates the quoted message content view.
1020+
///
1021+
/// It is the view that is embedded in quoted message bubble view.
1022+
///
1023+
/// - Parameters:
1024+
/// - quotedMessage: the quoted message.
1025+
/// - options: configuration options for the quoted message content view.
1026+
/// - Returns: view displayed in the quoted message content slot.
1027+
func makeQuotedMessageContentView(
1028+
quotedMessage: ChatMessage,
1029+
options: QuotedMessageContentViewOptions
1030+
) -> QuotedMessageContentViewType
1031+
10181032
associatedtype CustomAttachmentQuotedViewType: View
10191033
/// Creates a quoted view for custom attachments. Returns `EmptyView` by default.
10201034
/// - Parameter message: the quoted message.

0 commit comments

Comments
 (0)