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 a4995a4 commit 62c5243
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 14 deletions.
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,45 @@
/*
* 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

/**
* Controls the visibility of items in the 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 [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,
)
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -104,6 +105,9 @@ private val LocalSearchResultNameFormatter = compositionLocalOf<SearchResultName
private val LocalMessageAlignmentProvider = compositionLocalOf<MessageAlignmentProvider> {
error("No MessageAlignmentProvider provided! Make sure to wrap all usages of Stream components in a ChatTheme.")
}
private val LocalMessageOptionItemVisibility = compositionLocalOf<MessageOptionItemVisibility> {
error("No MessageOptionItemVisibility provided! Make sure to wrap all usages of Stream components in a ChatTheme.")
}
private val LocalMessageOptionsUserReactionAlignment = compositionLocalOf<MessageOptionsUserReactionAlignment> {
error(
"No LocalMessageOptionsUserReactionAlignment provided! Make sure to wrap all usages of Stream components " +
Expand Down Expand Up @@ -181,11 +185,13 @@ private val LocalStreamMediaRecorder = compositionLocalOf<StreamMediaRecorder> {
* @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.
Expand Down Expand Up @@ -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<AttachmentsPickerTabFactory> = AttachmentsPickerTabFactories.defaultFactories(),
videoThumbnailsEnabled: Boolean = true,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
*/
Expand Down

0 comments on commit 62c5243

Please sign in to comment.