diff --git a/docusaurus/docs/Android/compose/general-customization/chat-theme.mdx b/docusaurus/docs/Android/compose/general-customization/chat-theme.mdx index fa2978f3bfc..017437161c3 100644 --- a/docusaurus/docs/Android/compose/general-customization/chat-theme.mdx +++ b/docusaurus/docs/Android/compose/general-customization/chat-theme.mdx @@ -17,6 +17,7 @@ The `ChatTheme` component is a wrapper that **you should use as the root** of al * `messagePreviewFormatter`: Used to define the message preview formatting in the app. You can use the default implementation, or customize the display of message previews according to your needs. * `imageLoaderFactory`: Used to create Coil image loader instances. You can use the default image loader factory, or provide a custom one. * `messageAlignmentProvider`: Used to provide an alignment for a particular message. You can use the default implementation which aligns the messages of the current user to end, or customize it according to your needs. +* `messageOptionItemVisibility`: Used to control menu item visibility in the selected message options menu. All options are visible by default. * `messageOptionsUserReactionAlignment`: Used to define how message reactions are aligned when browsing all reactions for a given message. * `permissionHandlers`: Used to handle permissions inside the app. Default implementation of the download permission handler automatically downloads files after the permission has been granted. * `attachmentsPickerTabFactories`: Used to display different tabs in the attachments picker dialog. @@ -303,6 +304,12 @@ You can find out more about it by reading the [class documentation](https://gith As with all of the other `ChatTheme` properties, you can easily customize how the messages are aligned by overriding `ChatTheme.messageAlignmentProvider` with your own implementation of `MessageAlignmentProvider`. +### MessageOptionItemVisibility + +Controls menu item visibility in the selected message options menu. All options are visible by default. + +See the `MessageOptionItemVisibility` [class documentation](https://github.com/GetStream/stream-chat-android/blob/62c5243ecd4c51580c419c7c9a4d4af154d1cd89/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility.kt) for more details. + ### MessageOptionsUserReactionAlignment Determines the alignment of the reaction icon inside user reactions. By default, they are aligned to the end. diff --git a/docusaurus/docs/Android/compose/guides/implementing-own-capabilities.mdx b/docusaurus/docs/Android/compose/guides/implementing-own-capabilities.mdx index d51f5d1e59e..cb67a35de52 100644 --- a/docusaurus/docs/Android/compose/guides/implementing-own-capabilities.mdx +++ b/docusaurus/docs/Android/compose/guides/implementing-own-capabilities.mdx @@ -102,7 +102,7 @@ public fun defaultMessageOptionsState( ): List ``` -This function uses `ownCapabilities` to produce the correct list of `MessageOptionItemState`. +This function uses the [`ChatTheme.messageOptionItemVisibility`](../general-customization/chat-theme.mdx#messageoptionitemvisibility) property and `ownCapabilities` to produce the correct list of `MessageOptionItemState`. Read more about customizing what options `SelectedMessageMenu` shows [here](../message-components/selected-message-menu.mdx#customizing-the-menu-option-list). `defaultMessageOptionsState` regulates the following capabilities: @@ -182,7 +182,7 @@ Additionally, the capability '**send-typing-events ***' is implemented in our `M our `MessageComposerViewModel`. Please keep this in mind should you wish to not use our `ViewModel`s. -# How capabilities affect the UI +## How capabilities affect the UI Let's take `MessageComposer` into consideration. If we left it with the default, empty set of own capabilities we would get the following result: diff --git a/docusaurus/docs/Android/compose/message-components/selected-message-menu.mdx b/docusaurus/docs/Android/compose/message-components/selected-message-menu.mdx index 3944412a71c..23b5cf14368 100644 --- a/docusaurus/docs/Android/compose/message-components/selected-message-menu.mdx +++ b/docusaurus/docs/Android/compose/message-components/selected-message-menu.mdx @@ -1,4 +1,8 @@ -# Selecting Messages +--- +toc_max_heading_level: 4 +--- + +# Selected Message Menu The `SelectedMessageMenu` component allows you to show different message options to the user when they select a message in the `MessageList`. This is usually done by long tapping on a message item. @@ -99,7 +103,7 @@ Next, let's see how to customize the menu. ## Customization -You can customize the reactions you show, as well as the message options in this component: +You can customize the `SelectedMessageMenu` component by using the following parameters: ```kotlin @Composable @@ -114,15 +118,40 @@ fun SelectedMessageMenu( ) ``` -* `messageOptions`: Allows you to customize which message options are shown in the overlay. You can use `defaultMessageOptionsState()` to get the default actions that we expose in our SDK. +* `messageOptions`: Allows you to customize which message options are shown in the overlay. See [below](#customizing-the-menu-option-list). * `modifier`: Modifier for the dialog component. * `overlayColor`: Allows you to customize the color of the overlay. * `shape`: Allows you to customize the shape of the dialog. -* `reactionTypes`: Allows you to customize which reactions show in the overlay. By default it uses `ChatTheme.reactionIconFactory` which is exposed by the [`ChatTheme`](../general-customization/chat-theme.mdx) component. +* `reactionTypes`: Allows you to customize which reactions show in the overlay. See [below](#customizing-reactions). + +#### Customizing the Menu Option List + +You can pass `defaultMessageOptionsState()` to the `messageOptions` parameter to get the default actions that we expose in our SDK. This function uses the [`ChatTheme.messageOptionItemVisibility`](../general-customization/chat-theme.mdx#messageoptionitemvisibility) property and [own capabilities](../guides/implementing-own-capabilities.mdx) under the hood to control which action is visible to the user. + +The values that `defaultMessageOptionsState()` gets from `ChatTheme.messageOptionItemVisibility` take precedence over own capabilities, so you can pass your own implementation of [`MessageOptionItemVisibility`](https://github.com/GetStream/stream-chat-android/blob/62c5243ecd4c51580c419c7c9a4d4af154d1cd89/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility.kt) to `ChatTheme.messageOptionItemVisibility` to control which options to show. This is useful when you are using `MessagesScreen`, for example, which sets up `SelectedMessageMenu` automatically. + +```kotlin +ChatTheme( + // ... + messageOptionItemVisibility = MessageOptionItemVisibility( + isMarkAsUnreadVisible = false, + isCopyTextVisible = false, + ), + // ... +) { + // Rest of the UI +} +``` + +#### Customizing Reactions + +By default, the `reactionTypes` parameter uses [`ChatTheme.reactionIconFactory`](../general-customization/chat-theme.mdx#reactioniconfactory) as a value which is exposed by the [`ChatTheme`](../general-customization/chat-theme.mdx) component. The best way to customize reactions is by overriding `ChatTheme.reactionIconFactory` with your own implementation of `ReactionIconFactory` so that all of your components wrapped inside of `ChatTheme` draw from the same source. -By default `SelectedMessageMenu` looks like a bottom sheet, however you can customize it to look like a completely different component, such as a dialog, a drawer or whatever helps you retain the look and feel of your app. +#### Customizing the Appearance + +By default `SelectedMessageMenu` looks like a bottom sheet. However you can customize it to look like a completely different component, such as a dialog, a drawer or whatever helps you retain the look and feel of your app. ```kotlin if (selectedMessageState is SelectedMessageOptionsState) { @@ -154,7 +183,9 @@ The code above will produce the following UI: |---|---| | ![Stylised SelectedMessageMenu component](../../assets/compose_custom_selected_message_menu_shape_and_alignment.png) | ![Stylised SelectedMessageMenu component dark](../../assets/compose_custom_selected_message_menu_shape_and_alignment_dark.png) | -`SelectedMessageMenu` provides you with `Composable` slots that are ready for more extensive customizations. +#### Customizing by Using Slots + +`SelectedMessageMenu` provides you with `Composable` slots that are ready for more extensive customizations: ```kotlin @Composable diff --git a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt index f09393f9b08..71e87215d44 100644 --- a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt +++ b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt @@ -53,6 +53,7 @@ import io.getstream.chat.android.compose.sample.R import io.getstream.chat.android.compose.state.mediagallerypreview.MediaGalleryPreviewResultType import io.getstream.chat.android.compose.state.messages.attachments.StatefulStreamMediaRecorder import io.getstream.chat.android.compose.ui.components.composer.MessageInput +import io.getstream.chat.android.compose.ui.components.messageoptions.MessageOptionItemVisibility import io.getstream.chat.android.compose.ui.components.messageoptions.defaultMessageOptionsState import io.getstream.chat.android.compose.ui.components.reactionpicker.ReactionsPicker import io.getstream.chat.android.compose.ui.components.selectedmessage.SelectedMessageMenu @@ -114,6 +115,7 @@ class MessagesActivity : BaseConnectedActivity() { dateFormatter = ChatApp.dateFormatter, autoTranslationEnabled = ChatApp.autoTranslationEnabled, isComposerLinkPreviewEnabled = ChatApp.isComposerLinkPreviewEnabled, + messageOptionItemVisibility = MessageOptionItemVisibility(), allowUIAutomationTest = true, messageComposerTheme = MessageComposerTheme.defaultTheme(typography).let { messageComposerTheme -> messageComposerTheme.copy( diff --git a/stream-chat-android-compose/api/stream-chat-android-compose.api b/stream-chat-android-compose/api/stream-chat-android-compose.api index 773bb76631f..76045e8dab6 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -959,6 +959,36 @@ public final class io/getstream/chat/android/compose/ui/components/messageoption public static final fun MessageOptionItem (Lio/getstream/chat/android/compose/state/messageoptions/MessageOptionItemState;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment$Vertical;Landroidx/compose/foundation/layout/Arrangement$Horizontal;Landroidx/compose/runtime/Composer;II)V } +public final class io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility { + public static final field $stable I + public fun ()V + public fun (ZZZZZZZZZ)V + public synthetic fun (ZZZZZZZZZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Z + public final fun component2 ()Z + public final fun component3 ()Z + public final fun component4 ()Z + public final fun component5 ()Z + public final fun component6 ()Z + public final fun component7 ()Z + public final fun component8 ()Z + public final fun component9 ()Z + public final fun copy (ZZZZZZZZZ)Lio/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility; + public static synthetic fun copy$default (Lio/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility;ZZZZZZZZZILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I + public final fun isCopyTextVisible ()Z + public final fun isDeleteMessageVisible ()Z + public final fun isEditMessageVisible ()Z + public final fun isFlagMessageVisible ()Z + public final fun isMarkAsUnreadVisible ()Z + public final fun isPinMessageVisible ()Z + public final fun isReplyVisible ()Z + public final fun isRetryMessageVisible ()Z + public final fun isThreadReplyVisible ()Z + public fun toString ()Ljava/lang/String; +} + public final class io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionsKt { public static final fun MessageOptions (Ljava/util/List;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;II)V public static final fun defaultMessageOptionsState (Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/User;ZLjava/util/Set;Landroidx/compose/runtime/Composer;I)Ljava/util/List; @@ -1481,6 +1511,7 @@ public final class io/getstream/chat/android/compose/ui/theme/ChatTheme { public final fun getMessageAlignmentProvider (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/util/MessageAlignmentProvider; public final fun getMessageComposerTheme (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/theme/MessageComposerTheme; public final fun getMessageDateSeparatorTheme (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/theme/MessageDateSeparatorTheme; + public final fun getMessageOptionItemVisibility (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility; public final fun getMessageOptionsUserReactionAlignment (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/ui/common/state/messages/list/MessageOptionsUserReactionAlignment; public final fun getMessagePreviewFormatter (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/util/MessagePreviewFormatter; public final fun getMessageTextFormatter (Landroidx/compose/runtime/Composer;I)Lio/getstream/chat/android/compose/ui/util/MessageTextFormatter; @@ -1501,7 +1532,7 @@ public final class io/getstream/chat/android/compose/ui/theme/ChatTheme { } public final class io/getstream/chat/android/compose/ui/theme/ChatThemeKt { - public static final fun ChatTheme (ZZZLio/getstream/chat/android/compose/ui/theme/StreamColors;Lio/getstream/chat/android/compose/ui/theme/StreamDimens;Lio/getstream/chat/android/compose/ui/theme/StreamTypography;Lio/getstream/chat/android/compose/ui/theme/StreamShapes;Landroidx/compose/material/ripple/RippleTheme;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/compose/ui/util/ReactionIconFactory;ZLio/getstream/chat/android/ui/common/helper/DateFormatter;Lio/getstream/chat/android/ui/common/utils/ChannelNameFormatter;Lio/getstream/chat/android/compose/ui/util/MessagePreviewFormatter;Lio/getstream/chat/android/compose/ui/util/SearchResultNameFormatter;Lio/getstream/chat/android/compose/ui/util/StreamCoilImageLoaderFactory;Lio/getstream/chat/android/compose/ui/util/MessageAlignmentProvider;Lio/getstream/chat/android/ui/common/state/messages/list/MessageOptionsUserReactionAlignment;Ljava/util/List;ZLio/getstream/chat/android/ui/common/images/resizing/StreamCdnImageResizing;ZLio/getstream/chat/android/compose/ui/theme/MessageTheme;Lio/getstream/chat/android/compose/ui/theme/MessageTheme;Lio/getstream/chat/android/compose/ui/theme/MessageDateSeparatorTheme;Lio/getstream/chat/android/compose/ui/theme/MessageUnreadSeparatorTheme;Lio/getstream/chat/android/compose/ui/theme/MessageComposerTheme;Lio/getstream/chat/android/compose/ui/util/MessageTextFormatter;Lio/getstream/chat/android/compose/ui/util/QuotedMessageTextFormatter;Lio/getstream/sdk/chat/audio/recording/StreamMediaRecorder;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;IIIIII)V + public static final fun ChatTheme (ZZZLio/getstream/chat/android/compose/ui/theme/StreamColors;Lio/getstream/chat/android/compose/ui/theme/StreamDimens;Lio/getstream/chat/android/compose/ui/theme/StreamTypography;Lio/getstream/chat/android/compose/ui/theme/StreamShapes;Landroidx/compose/material/ripple/RippleTheme;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/compose/ui/util/ReactionIconFactory;ZLio/getstream/chat/android/ui/common/helper/DateFormatter;Lio/getstream/chat/android/ui/common/utils/ChannelNameFormatter;Lio/getstream/chat/android/compose/ui/util/MessagePreviewFormatter;Lio/getstream/chat/android/compose/ui/util/SearchResultNameFormatter;Lio/getstream/chat/android/compose/ui/util/StreamCoilImageLoaderFactory;Lio/getstream/chat/android/compose/ui/util/MessageAlignmentProvider;Lio/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility;Lio/getstream/chat/android/ui/common/state/messages/list/MessageOptionsUserReactionAlignment;Ljava/util/List;ZLio/getstream/chat/android/ui/common/images/resizing/StreamCdnImageResizing;ZLio/getstream/chat/android/compose/ui/theme/MessageTheme;Lio/getstream/chat/android/compose/ui/theme/MessageTheme;Lio/getstream/chat/android/compose/ui/theme/MessageDateSeparatorTheme;Lio/getstream/chat/android/compose/ui/theme/MessageUnreadSeparatorTheme;Lio/getstream/chat/android/compose/ui/theme/MessageComposerTheme;Lio/getstream/chat/android/compose/ui/util/MessageTextFormatter;Lio/getstream/chat/android/compose/ui/util/QuotedMessageTextFormatter;Lio/getstream/sdk/chat/audio/recording/StreamMediaRecorder;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;IIIIII)V } public final class io/getstream/chat/android/compose/ui/theme/ComponentSize { diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility.kt new file mode 100644 index 00000000000..2e9e1c7375a --- /dev/null +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptionItemVisibility.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014-2024 Stream.io Inc. All rights reserved. + * + * Licensed under the Stream License; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://github.com/GetStream/stream-chat-android/blob/main/LICENSE + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.getstream.chat.android.compose.ui.components.messageoptions + +import io.getstream.chat.android.compose.ui.components.selectedmessage.SelectedMessageMenu + +/** + * Controls menu item visibility in the selected message options menu. All options are visible by default. + * + * @param isRetryMessageVisible Visibility of the retry failed message option. + * @param isReplyVisible Visibility of the reply to message option (quote message). + * @param isThreadReplyVisible Visibility of the reply to message in thread option. + * @param isMarkAsUnreadVisible Visibility of the mark message as unread option. + * @param isCopyTextVisible Visibility of the copy message text option. + * @param isEditMessageVisible Visibility of the edit message option. + * @param isFlagMessageVisible Visibility of the flag message option. + * @param isPinMessageVisible Visibility of the pin message to chat option. + * @param isDeleteMessageVisible Visibility of the delete message option. + * + * @see [SelectedMessageMenu] + * @see [MessageOptions] + * @see [defaultMessageOptionsState] + */ +public data class MessageOptionItemVisibility( + val isRetryMessageVisible: Boolean = true, + val isReplyVisible: Boolean = true, + val isThreadReplyVisible: Boolean = true, + val isMarkAsUnreadVisible: Boolean = true, + val isCopyTextVisible: Boolean = true, + val isEditMessageVisible: Boolean = true, + val isFlagMessageVisible: Boolean = true, + val isPinMessageVisible: Boolean = true, + val isDeleteMessageVisible: Boolean = true, +) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptions.kt index a8c8f28b8a3..f5d04f5d056 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptions.kt @@ -146,8 +146,11 @@ public fun defaultMessageOptionsState( val canMarkAsUnread = ownCapabilities.contains(ChannelCapabilities.READ_EVENTS) val canFlagMessage = ownCapabilities.contains(ChannelCapabilities.FLAG_MESSAGE) + // options menu item visibility + val visibility = ChatTheme.messageOptionItemVisibility + return listOfNotNull( - if (isOwnMessage && isMessageFailed) { + if (visibility.isRetryMessageVisible && isOwnMessage && isMessageFailed) { MessageOptionItemState( title = R.string.stream_compose_resend_message, iconPainter = painterResource(R.drawable.stream_compose_ic_resend), @@ -158,7 +161,7 @@ public fun defaultMessageOptionsState( } else { null }, - if (isMessageSynced && canQuoteMessage) { + if (visibility.isReplyVisible && isMessageSynced && canQuoteMessage) { MessageOptionItemState( title = R.string.stream_compose_reply, iconPainter = painterResource(R.drawable.stream_compose_ic_reply), @@ -169,7 +172,7 @@ public fun defaultMessageOptionsState( } else { null }, - if (!isInThread && isMessageSynced && canThreadReply) { + if (visibility.isThreadReplyVisible && !isInThread && isMessageSynced && canThreadReply) { MessageOptionItemState( title = R.string.stream_compose_thread_reply, iconPainter = painterResource(R.drawable.stream_compose_ic_thread), @@ -180,7 +183,7 @@ public fun defaultMessageOptionsState( } else { null }, - if (canMarkAsUnread) { + if (visibility.isMarkAsUnreadVisible && canMarkAsUnread) { MessageOptionItemState( title = R.string.stream_compose_mark_as_unread, iconPainter = painterResource(R.drawable.stream_compose_ic_mark_as_unread), @@ -191,7 +194,7 @@ public fun defaultMessageOptionsState( } else { null }, - if (isTextOnlyMessage || hasLinks) { + if (visibility.isCopyTextVisible && (isTextOnlyMessage || hasLinks)) { MessageOptionItemState( title = R.string.stream_compose_copy_message, iconPainter = painterResource(R.drawable.stream_compose_ic_copy), @@ -202,7 +205,8 @@ public fun defaultMessageOptionsState( } else { null }, - if (((isOwnMessage && canEditOwnMessage) || canEditAnyMessage) && !selectedMessage.isGiphy()) { + if (visibility.isEditMessageVisible && + (((isOwnMessage && canEditOwnMessage) || canEditAnyMessage) && !selectedMessage.isGiphy())) { MessageOptionItemState( title = R.string.stream_compose_edit_message, iconPainter = painterResource(R.drawable.stream_compose_ic_edit), @@ -213,7 +217,7 @@ public fun defaultMessageOptionsState( } else { null }, - if (canFlagMessage && !isOwnMessage) { + if (visibility.isFlagMessageVisible && canFlagMessage && !isOwnMessage) { MessageOptionItemState( title = R.string.stream_compose_flag_message, iconPainter = painterResource(R.drawable.stream_compose_ic_flag), @@ -224,7 +228,7 @@ public fun defaultMessageOptionsState( } else { null }, - if (isMessageSynced && canPinMessage) { + if (visibility.isPinMessageVisible && isMessageSynced && canPinMessage) { MessageOptionItemState( title = if (selectedMessage.pinned) R.string.stream_compose_unpin_message else R.string.stream_compose_pin_message, action = Pin(selectedMessage), @@ -235,7 +239,7 @@ public fun defaultMessageOptionsState( } else { null }, - if (canDeleteAnyMessage || (isOwnMessage && canDeleteOwnMessage)) { + if (visibility.isDeleteMessageVisible && (canDeleteAnyMessage || (isOwnMessage && canDeleteOwnMessage))) { MessageOptionItemState( title = R.string.stream_compose_delete_message, iconPainter = painterResource(R.drawable.stream_compose_ic_delete), diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt index e266f29580f..027a10a856a 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt @@ -39,6 +39,7 @@ import io.getstream.chat.android.client.header.VersionPrefixHeader import io.getstream.chat.android.compose.ui.attachments.AttachmentFactory import io.getstream.chat.android.compose.ui.attachments.StreamAttachmentFactories import io.getstream.chat.android.compose.ui.attachments.preview.handler.AttachmentPreviewHandler +import io.getstream.chat.android.compose.ui.components.messageoptions.MessageOptionItemVisibility import io.getstream.chat.android.compose.ui.messages.attachments.factory.AttachmentsPickerTabFactories import io.getstream.chat.android.compose.ui.messages.attachments.factory.AttachmentsPickerTabFactory import io.getstream.chat.android.compose.ui.util.LocalStreamImageLoader @@ -104,6 +105,9 @@ private val LocalSearchResultNameFormatter = compositionLocalOf { error("No MessageAlignmentProvider provided! Make sure to wrap all usages of Stream components in a ChatTheme.") } +private val LocalMessageOptionItemVisibility = compositionLocalOf { + error("No MessageOptionItemVisibility provided! Make sure to wrap all usages of Stream components in a ChatTheme.") +} private val LocalMessageOptionsUserReactionAlignment = compositionLocalOf { error( "No LocalMessageOptionsUserReactionAlignment provided! Make sure to wrap all usages of Stream components " + @@ -181,11 +185,13 @@ private val LocalStreamMediaRecorder = compositionLocalOf { * @param quotedAttachmentFactories Quoted attachment factories that we provide. * @param reactionIconFactory Used to create an icon [Painter] for the given reaction type. * @param allowUIAutomationTest Allow to simulate ui automation with given test tags. - * @param dateFormatter [DateFormatter] used throughout the app for date and time information. - * @param channelNameFormatter [ChannelNameFormatter] used throughout the app for channel names. - * @param messagePreviewFormatter [MessagePreviewFormatter] used to generate a string preview for the given message. + * @param dateFormatter [DateFormatter] Used throughout the app for date and time information. + * @param channelNameFormatter [ChannelNameFormatter] Used throughout the app for channel names. + * @param messagePreviewFormatter [MessagePreviewFormatter] Used to generate a string preview for the given message. * @param imageLoaderFactory A factory that creates new Coil [ImageLoader] instances. - * @param messageAlignmentProvider [MessageAlignmentProvider] used to provide message alignment for the given message. + * @param messageAlignmentProvider [MessageAlignmentProvider] Used to provide message alignment for the given message. + * @param messageOptionItemVisibility [MessageOptionItemVisibility] Determines menu item visibility in the + * message options menu. All options are visible by default. * @param messageOptionsUserReactionAlignment Alignment of the user reaction inside the message options. * @param attachmentsPickerTabFactories Attachments picker tab factories that we provide. * @param videoThumbnailsEnabled Dictates whether video thumbnails will be displayed inside video previews. @@ -227,6 +233,7 @@ public fun ChatTheme( searchResultNameFormatter: SearchResultNameFormatter = SearchResultNameFormatter.defaultFormatter(), imageLoaderFactory: StreamCoilImageLoaderFactory = StreamCoilImageLoaderFactory.defaultFactory(), messageAlignmentProvider: MessageAlignmentProvider = MessageAlignmentProvider.defaultMessageAlignmentProvider(), + messageOptionItemVisibility: MessageOptionItemVisibility = MessageOptionItemVisibility(), messageOptionsUserReactionAlignment: MessageOptionsUserReactionAlignment = MessageOptionsUserReactionAlignment.END, attachmentsPickerTabFactories: List = AttachmentsPickerTabFactories.defaultFactories(), videoThumbnailsEnabled: Boolean = true, @@ -298,6 +305,7 @@ public fun ChatTheme( LocalMessageComposerTheme provides messageComposerTheme, LocalStreamImageLoader provides imageLoaderFactory.imageLoader(LocalContext.current.applicationContext), LocalMessageAlignmentProvider provides messageAlignmentProvider, + LocalMessageOptionItemVisibility provides messageOptionItemVisibility, LocalMessageOptionsUserReactionAlignment provides messageOptionsUserReactionAlignment, LocalAttachmentsPickerTabFactories provides attachmentsPickerTabFactories, LocalVideoThumbnailsEnabled provides videoThumbnailsEnabled, @@ -444,6 +452,11 @@ public object ChatTheme { @ReadOnlyComposable get() = LocalMessageAlignmentProvider.current + public val messageOptionItemVisibility: MessageOptionItemVisibility + @Composable + @ReadOnlyComposable + get() = LocalMessageOptionItemVisibility.current + /** * Retrieves the current [MessageOptionsUserReactionAlignment] at the call site's position in the hierarchy. */