Skip to content

Commit

Permalink
Add ChatTheme property that controls message options visibility
Browse files Browse the repository at this point in the history
  • Loading branch information
liviu-timar committed Apr 3, 2024
1 parent ed304a3 commit f770fd4
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public fun defaultMessageOptionsState(
): List<MessageOptionItemState>
```

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:

Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -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.

Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
33 changes: 32 additions & 1 deletion stream-chat-android-compose/api/stream-chat-android-compose.api
Original file line number Diff line number Diff line change
Expand Up @@ -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 <init> ()V
public fun <init> (ZZZZZZZZZ)V
public synthetic fun <init> (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;
Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
)
Loading

0 comments on commit f770fd4

Please sign in to comment.