public open class AttachmentFactory constructor(
public val canHandle: (attachments: List<Attachment>) -> Boolean,
public val previewContent: (
@Composable (
modifier: Modifier,
attachments: List<Attachment>,
onAttachmentRemoved: (Attachment) -> Unit,
) -> Unit
)? = null,
public val content: @Composable (
modifier: Modifier,
attachmentState: AttachmentState,
) -> Unit,
public val textFormatter: (attachments: Attachment) -> String = Attachment::previewText,
)
Custom Attachments
The AttachmentFactory
class allows you to build your own attachments to display in the Message List and in the MessageComposer before sending the attachment. It exposes the following properties and behavior:
canHandle
: Lambda function that accepts aList
of attachments in a message and returnstrue
if a given factory can consume the attachments and show some UI.previewContent
: Lambda function that accepts aModifier
,List
ofAttachment
s and anonAttachmentRemoved
handler. It’s used to render selected attachments in theMessageComposer
or theMessageInput
before sending the message.content
: Defines the composable function that accepts aModifier
and anAttachmentState
and shows a given attachment component in the message list.textFormatter
: Lambda function that accepts an attachment and returns a string representation for it.
There are a few examples of default attachment factory implementations, in the StreamAttachmentFactories.kt file:
public fun defaultFactories(
linkDescriptionMaxLines: Int = DEFAULT_LINK_DESCRIPTION_MAX_LINES,
): List<AttachmentFactory> = listOf(
UploadAttachmentFactory(),
LinkAttachmentFactory(linkDescriptionMaxLines),
GiphyAttachmentFactory(),
ImageAttachmentFactory(),
FileAttachmentFactory(),
)
These factories perform specific checks that you can explore by opening each specific factory.
Each of these factories supplies a predicate, as well as two content composable lambda functions that provide the appropriate content in the message input or the message list.
To customize the factories your code uses, you can always override the attachmentFactories
parameter of the ChatTheme
wrapper:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val defaultFactories = StreamAttachmentFactories.defaultFactories()
setContent {
// override the default factories by adding your own
ChatTheme(attachmentFactories = myAttachmentFactories + defaultFactories) {
// Chat components
}
}
}
That way, you can build any type of factory you want, to show things like the user location within a Google Maps component, audio files, videos and more.
Because we pick the first factory that can handle the attachments, the order of the factories matters when rendering the UI.
Make sure to always put the higher priority Attachment factories first.
Quoted Attachments
You can also customize the way attachments are displayed inside quoted messages. The approach used is nearly identical to the one shown in the previous example, with only the last step of the process being different.
After creating new attachment factories which display custom attachments inside quoted messages, you override ChatTheme.quotedAttachmentFactories
like so:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val myQuotedAttachmentFactories = listOf<AttachmentFactory>()
val defaultFactories = StreamAttachmentFactories.defaultQuotedFactories()
setContent {
// override the default factories by adding your own
ChatTheme(quotedAttachmentFactories = myQuotedAttachmentFactories + defaultFactories) {
// Chat components
}
}
}
In-Depth Guide
If you want to see a real world example of creating custom attachments, check out our detailed guide on creating custom attachments.