From 3e34dcf675ad2e6feb7dfb5aa61649500f51fad3 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Tue, 24 Feb 2026 12:41:32 +0100 Subject: [PATCH 01/22] feat(compose): add swipe-to-reveal actions on channel list items Add Pin/Unpin, Mute/Unmute, and Delete swipe actions behind channel list items using AnchoredDraggable from Compose Foundation 1.9.0. - SwipeableChannelItem wrapper with RTL support - SwipeRevealCoordinator for single-open-at-a-time behavior - DefaultChannelSwipeActions respecting channel capabilities - Overridable via ChatComponentFactory.ChannelSwipeActions() - Configurable via ChannelListConfig.swipeActionsEnabled - isPinned added to ChannelItemState --- .../api/stream-chat-android-compose.api | 57 ++++++-- .../compose/state/channels/list/ItemState.kt | 2 + .../compose/ui/channels/list/ChannelList.kt | 66 ++++++--- .../list/DefaultChannelSwipeActions.kt | 105 ++++++++++++++ .../ui/channels/list/SwipeActionItem.kt | 77 ++++++++++ .../channels/list/SwipeRevealCoordinator.kt | 82 +++++++++++ .../ui/channels/list/SwipeRevealValue.kt | 28 ++++ .../ui/channels/list/SwipeableChannelItem.kt | 134 ++++++++++++++++++ .../channels/UnreadCountIndicator.kt | 1 + .../compose/ui/theme/ChatComponentFactory.kt | 48 ++++++- .../android/compose/ui/theme/ChatConfig.kt | 2 + .../channels/ChannelListViewModel.kt | 2 + .../src/main/res/values/strings.xml | 7 + 13 files changed, 575 insertions(+), 36 deletions(-) create mode 100644 stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt create mode 100644 stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt create mode 100644 stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt create mode 100644 stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue.kt create mode 100644 stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt 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 1ec19c29604..a924aaa3486 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -89,15 +89,16 @@ public abstract class io/getstream/chat/android/compose/state/channels/list/Item public final class io/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState : io/getstream/chat/android/compose/state/channels/list/ItemState { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;ZLjava/util/List;Lio/getstream/chat/android/models/DraftMessage;Z)V - public synthetic fun (Lio/getstream/chat/android/models/Channel;ZLjava/util/List;Lio/getstream/chat/android/models/DraftMessage;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/getstream/chat/android/models/Channel;ZZLjava/util/List;Lio/getstream/chat/android/models/DraftMessage;Z)V + public synthetic fun (Lio/getstream/chat/android/models/Channel;ZZLjava/util/List;Lio/getstream/chat/android/models/DraftMessage;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lio/getstream/chat/android/models/Channel; public final fun component2 ()Z - public final fun component3 ()Ljava/util/List; - public final fun component4 ()Lio/getstream/chat/android/models/DraftMessage; - public final fun component5 ()Z - public final fun copy (Lio/getstream/chat/android/models/Channel;ZLjava/util/List;Lio/getstream/chat/android/models/DraftMessage;Z)Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState; - public static synthetic fun copy$default (Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState;Lio/getstream/chat/android/models/Channel;ZLjava/util/List;Lio/getstream/chat/android/models/DraftMessage;ZILjava/lang/Object;)Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState; + public final fun component3 ()Z + public final fun component4 ()Ljava/util/List; + public final fun component5 ()Lio/getstream/chat/android/models/DraftMessage; + public final fun component6 ()Z + public final fun copy (Lio/getstream/chat/android/models/Channel;ZZLjava/util/List;Lio/getstream/chat/android/models/DraftMessage;Z)Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState; + public static synthetic fun copy$default (Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState;Lio/getstream/chat/android/models/Channel;ZZLjava/util/List;Lio/getstream/chat/android/models/DraftMessage;ZILjava/lang/Object;)Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState; public fun equals (Ljava/lang/Object;)Z public final fun getChannel ()Lio/getstream/chat/android/models/Channel; public final fun getDraftMessage ()Lio/getstream/chat/android/models/DraftMessage; @@ -105,6 +106,7 @@ public final class io/getstream/chat/android/compose/state/channels/list/ItemSta public final fun getTypingUsers ()Ljava/util/List; public fun hashCode ()I public final fun isMuted ()Z + public final fun isPinned ()Z public final fun isSelected ()Z public fun toString ()Ljava/lang/String; } @@ -1309,10 +1311,39 @@ public final class io/getstream/chat/android/compose/ui/channels/list/Composable public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function4; } +public final class io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActionsKt { + public static final fun DefaultChannelSwipeActions (Landroidx/compose/foundation/layout/RowScope;Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState;Landroidx/compose/runtime/Composer;I)V +} + public final class io/getstream/chat/android/compose/ui/channels/list/SearchResultItemKt { public static final fun SearchResultItem (Lio/getstream/chat/android/compose/state/channels/list/ItemState$SearchResultItemState;Lio/getstream/chat/android/models/User;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;II)V } +public final class io/getstream/chat/android/compose/ui/channels/list/SwipeActionItemKt { + public static final fun SwipeActionItem-jB83MbM (Landroidx/compose/ui/graphics/painter/Painter;Ljava/lang/String;Lkotlin/jvm/functions/Function0;JJLandroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V +} + +public final class io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator { + public static final field $stable I + public fun ()V + public final fun closeAll (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun onItemOpened (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun register (Ljava/lang/String;Landroidx/compose/foundation/gestures/AnchoredDraggableState;)V + public final fun unregister (Ljava/lang/String;)V +} + +public final class io/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue : java/lang/Enum { + public static final field Closed Lio/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue; + public static final field Open Lio/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public static fun valueOf (Ljava/lang/String;)Lio/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue; + public static fun values ()[Lio/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue; +} + +public final class io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItemKt { + public static final fun SwipeableChannelItem (Ljava/lang/String;Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V +} + public final class io/getstream/chat/android/compose/ui/chats/ChatListContentMode : java/lang/Enum { public static final field Channels Lio/getstream/chat/android/compose/ui/chats/ChatListContentMode; public static final field Mentions Lio/getstream/chat/android/compose/ui/chats/ChatListContentMode; @@ -2772,13 +2803,15 @@ public final class io/getstream/chat/android/compose/ui/theme/AttachmentPickerTh public final class io/getstream/chat/android/compose/ui/theme/ChannelListConfig { public static final field $stable I public fun ()V - public fun (Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition;)V - public synthetic fun (Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition;Z)V + public synthetic fun (Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition; - public final fun copy (Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition;)Lio/getstream/chat/android/compose/ui/theme/ChannelListConfig; - public static synthetic fun copy$default (Lio/getstream/chat/android/compose/ui/theme/ChannelListConfig;Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition;ILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/ChannelListConfig; + public final fun component2 ()Z + public final fun copy (Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition;Z)Lio/getstream/chat/android/compose/ui/theme/ChannelListConfig; + public static synthetic fun copy$default (Lio/getstream/chat/android/compose/ui/theme/ChannelListConfig;Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition;ZILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/ChannelListConfig; public fun equals (Ljava/lang/Object;)Z public final fun getMuteIndicatorPosition ()Lio/getstream/chat/android/compose/ui/theme/MuteIndicatorPosition; + public final fun getSwipeActionsEnabled ()Z public fun hashCode ()I public fun toString ()Ljava/lang/String; } @@ -2880,6 +2913,7 @@ public abstract interface class io/getstream/chat/android/compose/ui/theme/ChatC public abstract fun ChannelMenuOptions (Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Ljava/util/List;Landroidx/compose/runtime/Composer;I)V public abstract fun ChannelOptionsItem (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/compose/state/channels/list/ChannelOptionState;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V public abstract fun ChannelOptionsItemLeadingIcon (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/compose/state/channels/list/ChannelOptionState;Landroidx/compose/runtime/Composer;I)V + public abstract fun ChannelSwipeActions (Landroidx/compose/foundation/layout/RowScope;Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState;Landroidx/compose/runtime/Composer;I)V public abstract fun CustomAttachmentContent (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)V public abstract fun DirectChannelInfoAvatarContainer (Lio/getstream/chat/android/models/User;Landroidx/compose/runtime/Composer;I)V public abstract fun DirectChannelInfoTopBar (Lio/getstream/chat/android/ui/common/state/messages/list/ChannelHeaderViewState;Landroidx/compose/foundation/lazy/LazyListState;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V @@ -3075,6 +3109,7 @@ public final class io/getstream/chat/android/compose/ui/theme/ChatComponentFacto public static fun ChannelMenuOptions (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Ljava/util/List;Landroidx/compose/runtime/Composer;I)V public static fun ChannelOptionsItem (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/compose/state/channels/list/ChannelOptionState;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V public static fun ChannelOptionsItemLeadingIcon (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/compose/state/channels/list/ChannelOptionState;Landroidx/compose/runtime/Composer;I)V + public static fun ChannelSwipeActions (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/foundation/layout/RowScope;Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState;Landroidx/compose/runtime/Composer;I)V public static fun CustomAttachmentContent (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)V public static fun DirectChannelInfoAvatarContainer (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Lio/getstream/chat/android/models/User;Landroidx/compose/runtime/Composer;I)V public static fun DirectChannelInfoTopBar (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Lio/getstream/chat/android/ui/common/state/messages/list/ChannelHeaderViewState;Landroidx/compose/foundation/lazy/LazyListState;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/state/channels/list/ItemState.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/state/channels/list/ItemState.kt index f3006cd7335..f313aa401f2 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/state/channels/list/ItemState.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/state/channels/list/ItemState.kt @@ -32,6 +32,7 @@ public sealed class ItemState { * * @param channel The channel to show. * @param isMuted If the channel is muted for the current user. + * @param isPinned If the channel is pinned for the current user. * @param typingUsers The list of users currently typing in the channel. * @param draftMessage The draft message for the current user in the channel. * @param isSelected Whether this channel is currently selected (e.g. via long-press context menu). @@ -39,6 +40,7 @@ public sealed class ItemState { public data class ChannelItemState( val channel: Channel, val isMuted: Boolean = false, + val isPinned: Boolean = false, val typingUsers: List = emptyList(), val draftMessage: DraftMessage? = null, val isSelected: Boolean = false, diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt index 175ba2c64a6..7cba4a11960 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt @@ -23,9 +23,11 @@ import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -50,6 +52,13 @@ import io.getstream.chat.android.models.querysort.QuerySortByField import io.getstream.chat.android.previewdata.PreviewChannelData import io.getstream.chat.android.previewdata.PreviewMessageData import io.getstream.chat.android.previewdata.PreviewUserData +import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction +import io.getstream.chat.android.ui.common.state.channels.actions.DeleteConversation +import io.getstream.chat.android.ui.common.state.channels.actions.MuteChannel +import io.getstream.chat.android.ui.common.state.channels.actions.PinChannel +import io.getstream.chat.android.ui.common.state.channels.actions.UnmuteChannel +import io.getstream.chat.android.ui.common.state.channels.actions.UnpinChannel +import kotlinx.coroutines.launch /** * Default ChannelList component, that relies on the [ChannelListViewModel] to load the data and @@ -150,25 +159,46 @@ public fun ChannelList( }, ) { val user by viewModel.user.collectAsState() + val scope = rememberCoroutineScope() + val swipeCoordinator = remember { SwipeRevealCoordinator() } + val swipeActionHandler: (ChannelAction) -> Unit = remember(viewModel) { + { + action -> + scope.launch { swipeCoordinator.closeAll() } + when (action) { + is PinChannel -> viewModel.pinChannel(action.channel) + is UnpinChannel -> viewModel.unpinChannel(action.channel) + is MuteChannel -> viewModel.muteChannel(action.channel) + is UnmuteChannel -> viewModel.unmuteChannel(action.channel) + is DeleteConversation -> viewModel.performChannelAction(action) + else -> {} + } + } + } - ChannelList( - modifier = modifier, - contentPadding = contentPadding, - channelsState = viewModel.channelsState, - currentUser = user, - lazyListState = lazyListState, - onLastItemReached = onLastItemReached, - onChannelClick = onChannelClick, - onChannelLongClick = onChannelLongClick, - loadingContent = loadingContent, - emptyContent = emptyContent, - emptySearchContent = emptySearchContent, - helperContent = helperContent, - loadingMoreContent = loadingMoreContent, - channelContent = channelContent, - searchResultContent = searchResultContent, - divider = divider, - ) + CompositionLocalProvider( + LocalSwipeRevealCoordinator provides swipeCoordinator, + LocalSwipeActionHandler provides swipeActionHandler, + ) { + ChannelList( + modifier = modifier, + contentPadding = contentPadding, + channelsState = viewModel.channelsState, + currentUser = user, + lazyListState = lazyListState, + onLastItemReached = onLastItemReached, + onChannelClick = onChannelClick, + onChannelLongClick = onChannelLongClick, + loadingContent = loadingContent, + emptyContent = emptyContent, + emptySearchContent = emptySearchContent, + helperContent = helperContent, + loadingMoreContent = loadingMoreContent, + channelContent = channelContent, + searchResultContent = searchResultContent, + divider = divider, + ) + } } /** diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt new file mode 100644 index 00000000000..b552b178b78 --- /dev/null +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014-2026 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.channels.list + +import androidx.compose.foundation.layout.RowScope +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import io.getstream.chat.android.compose.R +import io.getstream.chat.android.compose.state.channels.list.ItemState +import io.getstream.chat.android.compose.ui.theme.ChatTheme +import io.getstream.chat.android.models.ChannelCapabilities +import io.getstream.chat.android.ui.common.state.channels.actions.DeleteConversation +import io.getstream.chat.android.ui.common.state.channels.actions.MuteChannel +import io.getstream.chat.android.ui.common.state.channels.actions.PinChannel +import io.getstream.chat.android.ui.common.state.channels.actions.UnmuteChannel +import io.getstream.chat.android.ui.common.state.channels.actions.UnpinChannel +import kotlinx.coroutines.launch + +/** + * Default swipe actions for a channel list item: Pin/Unpin, Mute/Unmute, Delete. + * Respects channel capabilities to show/hide individual actions. + * + * @param channelItem The channel item state to build actions for. + */ +@Composable +public fun RowScope.DefaultChannelSwipeActions(channelItem: ItemState.ChannelItemState) { + val handler = LocalSwipeActionHandler.current ?: return + val coordinator = LocalSwipeRevealCoordinator.current + val scope = rememberCoroutineScope() + val channel = channelItem.channel + val capabilities = channel.ownCapabilities + + fun onAction(block: () -> Unit) { + block() + scope.launch { coordinator?.closeAll() } + } + + // Pin / Unpin + if (channelItem.isPinned) { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_unpin), + label = stringResource(R.string.stream_compose_swipe_action_unpin), + onClick = { onAction { handler(UnpinChannel(channel)) } }, + backgroundColor = ChatTheme.colors.accentPrimary, + contentColor = Color.White, + ) + } else { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_pin), + label = stringResource(R.string.stream_compose_swipe_action_pin), + onClick = { onAction { handler(PinChannel(channel)) } }, + backgroundColor = ChatTheme.colors.accentPrimary, + contentColor = Color.White, + ) + } + + // Mute / Unmute + if (capabilities.contains(ChannelCapabilities.MUTE_CHANNEL)) { + if (channelItem.isMuted) { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_unmute), + label = stringResource(R.string.stream_compose_swipe_action_unmute), + onClick = { onAction { handler(UnmuteChannel(channel)) } }, + backgroundColor = ChatTheme.colors.accentNeutral, + contentColor = Color.White, + ) + } else { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_mute), + label = stringResource(R.string.stream_compose_swipe_action_mute), + onClick = { onAction { handler(MuteChannel(channel)) } }, + backgroundColor = ChatTheme.colors.accentNeutral, + contentColor = Color.White, + ) + } + } + + // Delete + if (capabilities.contains(ChannelCapabilities.DELETE_CHANNEL)) { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_delete), + label = stringResource(R.string.stream_compose_swipe_action_delete), + onClick = { onAction { handler(DeleteConversation(channel)) } }, + backgroundColor = ChatTheme.colors.accentError, + contentColor = Color.White, + ) + } +} diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt new file mode 100644 index 00000000000..439afe3d2d4 --- /dev/null +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014-2026 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.channels.list + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import io.getstream.chat.android.compose.ui.theme.ChatTheme + +/** + * A single swipe action button displayed behind a channel list item. + * + * @param icon The icon to display. + * @param label The label text below the icon. + * @param onClick Called when this action is tapped. + * @param backgroundColor The background color of this action. + * @param contentColor The color for the icon and label. + * @param modifier Modifier for styling. + */ +@Composable +public fun SwipeActionItem( + icon: Painter, + label: String, + onClick: () -> Unit, + backgroundColor: Color, + contentColor: Color, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .width(80.dp) + .fillMaxHeight() + .clickable(onClick = onClick), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Icon( + painter = icon, + contentDescription = label, + tint = contentColor, + modifier = Modifier.size(24.dp), + ) + Text( + text = label, + style = ChatTheme.typography.footnoteBold, + color = contentColor, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } +} diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt new file mode 100644 index 00000000000..7ee41f4c252 --- /dev/null +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014-2026 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.channels.list + +import androidx.compose.foundation.gestures.AnchoredDraggableState +import androidx.compose.foundation.gestures.animateTo +import androidx.compose.runtime.compositionLocalOf +import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction + +/** + * Coordinates swipe-to-reveal state across multiple channel list items, + * ensuring only one item is open at a time. + */ +public class SwipeRevealCoordinator { + + private val registry = mutableMapOf>() + + /** + * Registers a swipe state for the given channel CID. + * Called from [SwipeableChannelItem]'s DisposableEffect. + */ + public fun register(cid: String, state: AnchoredDraggableState) { + registry[cid] = state + } + + /** + * Unregisters the swipe state for the given channel CID. + * Called when [SwipeableChannelItem] leaves composition. + */ + public fun unregister(cid: String) { + registry.remove(cid) + } + + /** + * Notifies the coordinator that an item has been opened. + * All other open items will be animated to [SwipeRevealValue.Closed]. + */ + public suspend fun onItemOpened(cid: String) { + registry.forEach { (key, state) -> + if (key != cid && state.currentValue == SwipeRevealValue.Open) { + state.animateTo(SwipeRevealValue.Closed) + } + } + } + + /** + * Closes all currently open items. + */ + public suspend fun closeAll() { + registry.forEach { (_, state) -> + if (state.currentValue == SwipeRevealValue.Open) { + state.animateTo(SwipeRevealValue.Closed) + } + } + } +} + +/** + * Provides the [SwipeRevealCoordinator] to child composables. + * `null` means swipe actions are not available in the current composition tree. + */ +internal val LocalSwipeRevealCoordinator = compositionLocalOf { null } + +/** + * Provides a handler for swipe channel actions (pin, mute, delete, etc.). + * `null` means no handler is available. + */ +internal val LocalSwipeActionHandler = compositionLocalOf<((ChannelAction) -> Unit)?> { null } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue.kt new file mode 100644 index 00000000000..3cd4bcfeca2 --- /dev/null +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014-2026 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.channels.list + +/** + * Represents the state of a swipe-to-reveal action on a channel list item. + */ +public enum class SwipeRevealValue { + /** The swipe actions are hidden. */ + Closed, + + /** The swipe actions are fully revealed. */ + Open, +} diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt new file mode 100644 index 00000000000..d6252c17e9d --- /dev/null +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2014-2026 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.channels.list + +import androidx.compose.foundation.gestures.AnchoredDraggableState +import androidx.compose.foundation.gestures.DraggableAnchors +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.gestures.anchoredDraggable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.offset +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.LayoutDirection +import kotlinx.coroutines.flow.filter +import kotlin.math.roundToInt + +/** + * A wrapper that adds swipe-to-reveal actions behind channel list item content. + * + * Uses [AnchoredDraggableState] to provide smooth swipe interaction with snap-to anchors. + * Supports RTL layouts and coordinates with [SwipeRevealCoordinator] for single-open behavior. + * + * @param channelCid The channel CID used for coordinator registration. + * @param modifier Modifier for styling. + * @param enabled Whether swiping is enabled. + * @param swipeActions Composable content for the action buttons revealed by swiping. + * @param content The channel item content displayed on top. + */ +@Composable +public fun SwipeableChannelItem( + channelCid: String, + modifier: Modifier = Modifier, + enabled: Boolean = true, + swipeActions: @Composable () -> Unit, + content: @Composable () -> Unit, +) { + val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl + val coordinator = LocalSwipeRevealCoordinator.current + + val anchoredDraggableState = remember { + AnchoredDraggableState(initialValue = SwipeRevealValue.Closed) + } + + var actionsWidthPx by remember { mutableIntStateOf(0) } + + // Update anchors when actions width changes + SideEffect { + if (actionsWidthPx > 0) { + val newAnchors = DraggableAnchors { + SwipeRevealValue.Closed at 0f + SwipeRevealValue.Open at -actionsWidthPx.toFloat() + } + anchoredDraggableState.updateAnchors(newAnchors, anchoredDraggableState.currentValue) + } + } + + // Register/unregister with coordinator + DisposableEffect(channelCid, coordinator) { + coordinator?.register(channelCid, anchoredDraggableState) + onDispose { + coordinator?.unregister(channelCid) + } + } + + // Notify coordinator when this item opens + LaunchedEffect(anchoredDraggableState) { + snapshotFlow { anchoredDraggableState.currentValue } + .filter { it == SwipeRevealValue.Open } + .collect { coordinator?.onItemOpened(channelCid) } + } + + Box( + modifier = modifier.clipToBounds(), + ) { + // Background: action buttons + Row( + modifier = Modifier + .fillMaxHeight() + .align(if (isRtl) Alignment.CenterStart else Alignment.CenterEnd) + .onSizeChanged { size -> actionsWidthPx = size.width }, + ) { + swipeActions() + } + + // Foreground: channel item content + Box( + modifier = Modifier + .offset { + val offset = anchoredDraggableState.offset + if (isRtl) { + IntOffset(x = -offset.roundToInt(), y = 0) + } else { + IntOffset(x = offset.roundToInt(), y = 0) + } + } + .anchoredDraggable( + state = anchoredDraggableState, + orientation = Orientation.Horizontal, + enabled = enabled, + ), + ) { + content() + } + } +} diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/UnreadCountIndicator.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/UnreadCountIndicator.kt index ccd5f567e4e..fb09fa1a7b5 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/UnreadCountIndicator.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/UnreadCountIndicator.kt @@ -47,6 +47,7 @@ public fun UnreadCountIndicator( color: Color = ChatTheme.colors.accentPrimary, // was errorAccent (red #FF3742) → accentPrimary (blue #005FFF) ) { val displayText = if (unreadCount > LimitTooManyUnreadCount) UnreadCountMany else unreadCount.toString() + @Suppress("MagicNumber") val shape = RoundedCornerShape(50) // pill shape diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt index 6d96bd0d002..b60860b8924 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt @@ -101,11 +101,14 @@ import io.getstream.chat.android.compose.ui.channels.list.DefaultChannelItemTrai import io.getstream.chat.android.compose.ui.channels.list.DefaultChannelListEmptyContent import io.getstream.chat.android.compose.ui.channels.list.DefaultChannelListLoadingIndicator import io.getstream.chat.android.compose.ui.channels.list.DefaultChannelSearchEmptyContent +import io.getstream.chat.android.compose.ui.channels.list.DefaultChannelSwipeActions import io.getstream.chat.android.compose.ui.channels.list.DefaultChannelsLoadingMoreIndicator import io.getstream.chat.android.compose.ui.channels.list.DefaultSearchResultItemCenterContent import io.getstream.chat.android.compose.ui.channels.list.DefaultSearchResultItemLeadingContent import io.getstream.chat.android.compose.ui.channels.list.DefaultSearchResultItemTrailingContent +import io.getstream.chat.android.compose.ui.channels.list.LocalSwipeRevealCoordinator import io.getstream.chat.android.compose.ui.channels.list.SearchResultItem +import io.getstream.chat.android.compose.ui.channels.list.SwipeableChannelItem import io.getstream.chat.android.compose.ui.components.DefaultSearchClearButton import io.getstream.chat.android.compose.ui.components.DefaultSearchLabel import io.getstream.chat.android.compose.ui.components.DefaultSearchLeadingIcon @@ -401,6 +404,8 @@ public interface ChatComponentFactory { /** * The default channel list item content. + * When swipe actions are enabled and a [SwipeRevealCoordinator][LocalSwipeRevealCoordinator] + * is provided, wraps the item in [SwipeableChannelItem]. */ @Composable public fun LazyItemScope.ChannelListItemContent( @@ -409,13 +414,42 @@ public interface ChatComponentFactory { onChannelClick: (Channel) -> Unit, onChannelLongClick: (Channel) -> Unit, ) { - ChannelItem( - modifier = Modifier.animateItem(), - channelItem = channelItem, - currentUser = currentUser, - onChannelClick = onChannelClick, - onChannelLongClick = onChannelLongClick, - ) + val coordinator = LocalSwipeRevealCoordinator.current + val swipeEnabled = ChatTheme.config.channelList.swipeActionsEnabled && coordinator != null + + if (swipeEnabled) { + SwipeableChannelItem( + channelCid = channelItem.channel.cid, + swipeActions = { Row { ChannelSwipeActions(channelItem) } }, + ) { + ChannelItem( + modifier = Modifier.animateItem(), + channelItem = channelItem, + currentUser = currentUser, + onChannelClick = onChannelClick, + onChannelLongClick = onChannelLongClick, + ) + } + } else { + ChannelItem( + modifier = Modifier.animateItem(), + channelItem = channelItem, + currentUser = currentUser, + onChannelClick = onChannelClick, + onChannelLongClick = onChannelLongClick, + ) + } + } + + /** + * The swipe actions revealed when swiping a channel list item. + * Override this to provide custom swipe actions. + * + * @param channelItem The channel item to build actions for. + */ + @Composable + public fun RowScope.ChannelSwipeActions(channelItem: ItemState.ChannelItemState) { + DefaultChannelSwipeActions(channelItem) } /** diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatConfig.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatConfig.kt index 4f410b64805..b2bef106e1e 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatConfig.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatConfig.kt @@ -31,9 +31,11 @@ public enum class MuteIndicatorPosition { * Behavioral configuration for the channel list. * * @param muteIndicatorPosition Where the mute icon is placed in the channel list item. + * @param swipeActionsEnabled Whether swipe-to-reveal actions are enabled on channel list items. */ public data class ChannelListConfig( val muteIndicatorPosition: MuteIndicatorPosition = MuteIndicatorPosition.INLINE_TITLE, + val swipeActionsEnabled: Boolean = true, ) /** diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel.kt index 85737f71d69..2e7565db871 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel.kt @@ -31,6 +31,7 @@ import io.getstream.chat.android.client.api.state.GlobalState import io.getstream.chat.android.client.api.state.QueryChannelsState import io.getstream.chat.android.client.api.state.globalStateFlow import io.getstream.chat.android.client.api.state.queryChannelsAsState +import io.getstream.chat.android.client.extensions.isPinned import io.getstream.chat.android.compose.state.QueryConfig import io.getstream.chat.android.compose.state.channels.list.ChannelsState import io.getstream.chat.android.compose.state.channels.list.ItemState @@ -747,6 +748,7 @@ public class ChannelListViewModel( ItemState.ChannelItemState( channel = it, isMuted = it.cid in mutedChannelIds, + isPinned = it.isPinned(), typingUsers = typingEvents[it.cid]?.users ?: emptyList(), draftMessage = draftMessages[it.cid], ) diff --git a/stream-chat-android-compose/src/main/res/values/strings.xml b/stream-chat-android-compose/src/main/res/values/strings.xml index 45627755bbe..87a39e2eaee 100644 --- a/stream-chat-android-compose/src/main/res/values/strings.xml +++ b/stream-chat-android-compose/src/main/res/values/strings.xml @@ -33,6 +33,13 @@ %d people are typing No channels available + + + Pin + Unpin + Mute + Unmute + Delete No results for \"%1$s\" From a0eeacd89dfe4a6c61994ffe8ec182d7a2faa2eb Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Tue, 24 Feb 2026 15:58:38 +0100 Subject: [PATCH 02/22] refactor(compose): rework swipe actions to match Figma spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DM channels show Archive + More, group channels show Mute + More. Primary action resolved via fallback priority (DM: Archive→Mute→Pin, Group: Mute→Archive→Pin). "More" opens the channel options bottom sheet via selectChannel. Add SwipeActionStyle enum (Primary/Secondary/Destructive) for slot-based coloring. Fix missing background() on SwipeActionItem. --- .../api/stream-chat-android-compose.api | 10 + .../compose/ui/channels/list/ChannelList.kt | 12 ++ .../list/DefaultChannelSwipeActions.kt | 195 +++++++++++++----- .../ui/channels/list/SwipeActionItem.kt | 35 ++++ .../ui/channels/list/SwipeActionStyle.kt | 36 ++++ .../channels/list/SwipeRevealCoordinator.kt | 10 +- .../stream_compose_ic_more_options.xml | 27 +++ .../src/main/res/values/strings.xml | 3 + 8 files changed, 280 insertions(+), 48 deletions(-) create mode 100644 stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle.kt create mode 100644 stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_options.xml 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 a924aaa3486..8e1ebf559f0 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -1320,9 +1320,19 @@ public final class io/getstream/chat/android/compose/ui/channels/list/SearchResu } public final class io/getstream/chat/android/compose/ui/channels/list/SwipeActionItemKt { + public static final fun SwipeActionItem (Landroidx/compose/ui/graphics/painter/Painter;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Lio/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V public static final fun SwipeActionItem-jB83MbM (Landroidx/compose/ui/graphics/painter/Painter;Ljava/lang/String;Lkotlin/jvm/functions/Function0;JJLandroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V } +public final class io/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle : java/lang/Enum { + public static final field Destructive Lio/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle; + public static final field Primary Lio/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle; + public static final field Secondary Lio/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle; + public static fun getEntries ()Lkotlin/enums/EnumEntries; + public static fun valueOf (Ljava/lang/String;)Lio/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle; + public static fun values ()[Lio/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle; +} + public final class io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator { public static final field $stable I public fun ()V diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt index 7cba4a11960..9c856e90387 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt @@ -52,10 +52,12 @@ import io.getstream.chat.android.models.querysort.QuerySortByField import io.getstream.chat.android.previewdata.PreviewChannelData import io.getstream.chat.android.previewdata.PreviewMessageData import io.getstream.chat.android.previewdata.PreviewUserData +import io.getstream.chat.android.ui.common.state.channels.actions.ArchiveChannel import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction import io.getstream.chat.android.ui.common.state.channels.actions.DeleteConversation import io.getstream.chat.android.ui.common.state.channels.actions.MuteChannel import io.getstream.chat.android.ui.common.state.channels.actions.PinChannel +import io.getstream.chat.android.ui.common.state.channels.actions.UnarchiveChannel import io.getstream.chat.android.ui.common.state.channels.actions.UnmuteChannel import io.getstream.chat.android.ui.common.state.channels.actions.UnpinChannel import kotlinx.coroutines.launch @@ -170,15 +172,25 @@ public fun ChannelList( is UnpinChannel -> viewModel.unpinChannel(action.channel) is MuteChannel -> viewModel.muteChannel(action.channel) is UnmuteChannel -> viewModel.unmuteChannel(action.channel) + is ArchiveChannel -> viewModel.archiveChannel(action.channel) + is UnarchiveChannel -> viewModel.unarchiveChannel(action.channel) is DeleteConversation -> viewModel.performChannelAction(action) else -> {} } } } + val moreClickHandler: (Channel) -> Unit = remember(viewModel) { + { + channel -> + scope.launch { swipeCoordinator.closeAll() } + viewModel.selectChannel(channel) + } + } CompositionLocalProvider( LocalSwipeRevealCoordinator provides swipeCoordinator, LocalSwipeActionHandler provides swipeActionHandler, + LocalChannelMoreClickHandler provides moreClickHandler, ) { ChannelList( modifier = modifier, diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt index b552b178b78..5a9b7f9a959 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt @@ -19,23 +19,33 @@ package io.getstream.chat.android.compose.ui.channels.list import androidx.compose.foundation.layout.RowScope import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import io.getstream.chat.android.client.extensions.isArchive import io.getstream.chat.android.compose.R import io.getstream.chat.android.compose.state.channels.list.ItemState -import io.getstream.chat.android.compose.ui.theme.ChatTheme +import io.getstream.chat.android.compose.ui.util.isDistinct +import io.getstream.chat.android.models.Channel import io.getstream.chat.android.models.ChannelCapabilities -import io.getstream.chat.android.ui.common.state.channels.actions.DeleteConversation +import io.getstream.chat.android.ui.common.state.channels.actions.ArchiveChannel +import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction import io.getstream.chat.android.ui.common.state.channels.actions.MuteChannel import io.getstream.chat.android.ui.common.state.channels.actions.PinChannel +import io.getstream.chat.android.ui.common.state.channels.actions.UnarchiveChannel import io.getstream.chat.android.ui.common.state.channels.actions.UnmuteChannel import io.getstream.chat.android.ui.common.state.channels.actions.UnpinChannel import kotlinx.coroutines.launch /** - * Default swipe actions for a channel list item: Pin/Unpin, Mute/Unmute, Delete. - * Respects channel capabilities to show/hide individual actions. + * Default swipe actions for a channel list item. + * + * Shows two actions: + * - **Primary action** (blue): Archive for DMs, Mute for groups — with fallback priority. + * - **More** (gray): Opens the channel options bottom sheet. + * + * The primary action is resolved via a priority list: + * - DM: Archive → Mute → Pin + * - Group: Mute → Archive → Pin * * @param channelItem The channel item state to build actions for. */ @@ -43,63 +53,154 @@ import kotlinx.coroutines.launch public fun RowScope.DefaultChannelSwipeActions(channelItem: ItemState.ChannelItemState) { val handler = LocalSwipeActionHandler.current ?: return val coordinator = LocalSwipeRevealCoordinator.current + val moreHandler = LocalChannelMoreClickHandler.current val scope = rememberCoroutineScope() val channel = channelItem.channel - val capabilities = channel.ownCapabilities fun onAction(block: () -> Unit) { block() scope.launch { coordinator?.closeAll() } } - // Pin / Unpin - if (channelItem.isPinned) { + // Resolve and render the primary action + val primaryAction = resolvePrimaryAction( + channel = channel, + isMuted = channelItem.isMuted, + isPinned = channelItem.isPinned, + ) + if (primaryAction != null) { + RenderSwipeAction( + action = primaryAction, + channel = channel, + style = SwipeActionStyle.Primary, + onAction = { onAction { handler(it) } }, + ) + } + + // "More" action — opens the channel options sheet + if (moreHandler != null) { SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_unpin), - label = stringResource(R.string.stream_compose_swipe_action_unpin), - onClick = { onAction { handler(UnpinChannel(channel)) } }, - backgroundColor = ChatTheme.colors.accentPrimary, - contentColor = Color.White, + icon = painterResource(R.drawable.stream_compose_ic_more_options), + label = stringResource(R.string.stream_compose_swipe_action_more), + onClick = { onAction { moreHandler(channel) } }, + style = SwipeActionStyle.Secondary, + ) + } +} + +/** + * Resolves the primary swipe action based on channel type and capabilities. + * + * DM priority: Archive → Mute → Pin. + * Group priority: Mute → Archive → Pin. + * + * Archive and Pin are always available (membership operations, no capability gate). + * Mute requires [ChannelCapabilities.MUTE_CHANNEL]. + */ +private fun resolvePrimaryAction( + channel: Channel, + isMuted: Boolean, + isPinned: Boolean, +): ResolvedSwipeAction? { + val capabilities = channel.ownCapabilities + val isArchived = channel.isArchive() + val canMute = capabilities.contains(ChannelCapabilities.MUTE_CHANNEL) + val isDM = channel.isDistinct() && channel.members.size == 2 + + val candidates: List = if (isDM) { + listOf( + ResolvedSwipeAction.Archive(isArchived), + ResolvedSwipeAction.Mute(isMuted).takeIf { canMute }, + ResolvedSwipeAction.Pin(isPinned), ) } else { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_pin), - label = stringResource(R.string.stream_compose_swipe_action_pin), - onClick = { onAction { handler(PinChannel(channel)) } }, - backgroundColor = ChatTheme.colors.accentPrimary, - contentColor = Color.White, + listOf( + ResolvedSwipeAction.Mute(isMuted).takeIf { canMute }, + ResolvedSwipeAction.Archive(isArchived), + ResolvedSwipeAction.Pin(isPinned), ) } - // Mute / Unmute - if (capabilities.contains(ChannelCapabilities.MUTE_CHANNEL)) { - if (channelItem.isMuted) { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_unmute), - label = stringResource(R.string.stream_compose_swipe_action_unmute), - onClick = { onAction { handler(UnmuteChannel(channel)) } }, - backgroundColor = ChatTheme.colors.accentNeutral, - contentColor = Color.White, - ) - } else { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_mute), - label = stringResource(R.string.stream_compose_swipe_action_mute), - onClick = { onAction { handler(MuteChannel(channel)) } }, - backgroundColor = ChatTheme.colors.accentNeutral, - contentColor = Color.White, - ) + return candidates.firstOrNull { it != null } +} + +/** + * Renders a resolved swipe action as a [SwipeActionItem]. + */ +@Composable +private fun RenderSwipeAction( + action: ResolvedSwipeAction, + channel: Channel, + style: SwipeActionStyle, + onAction: (ChannelAction) -> Unit, +) { + when (action) { + is ResolvedSwipeAction.Archive -> { + if (action.isArchived) { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_unarchive), + label = stringResource(R.string.stream_compose_swipe_action_unarchive), + onClick = { onAction(UnarchiveChannel(channel)) }, + style = style, + ) + } else { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_archive), + label = stringResource(R.string.stream_compose_swipe_action_archive), + onClick = { onAction(ArchiveChannel(channel)) }, + style = style, + ) + } + } + is ResolvedSwipeAction.Mute -> { + if (action.isMuted) { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_unmute), + label = stringResource(R.string.stream_compose_swipe_action_unmute), + onClick = { onAction(UnmuteChannel(channel)) }, + style = style, + ) + } else { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_mute), + label = stringResource(R.string.stream_compose_swipe_action_mute), + onClick = { onAction(MuteChannel(channel)) }, + style = style, + ) + } + } + is ResolvedSwipeAction.Pin -> { + if (action.isPinned) { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_unpin), + label = stringResource(R.string.stream_compose_swipe_action_unpin), + onClick = { onAction(UnpinChannel(channel)) }, + style = style, + ) + } else { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_pin), + label = stringResource(R.string.stream_compose_swipe_action_pin), + onClick = { onAction(PinChannel(channel)) }, + style = style, + ) + } } } +} - // Delete - if (capabilities.contains(ChannelCapabilities.DELETE_CHANNEL)) { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_delete), - label = stringResource(R.string.stream_compose_swipe_action_delete), - onClick = { onAction { handler(DeleteConversation(channel)) } }, - backgroundColor = ChatTheme.colors.accentError, - contentColor = Color.White, - ) - } +/** + * Internal representation of a resolved swipe action, used by [resolvePrimaryAction] + * to select the best action based on channel type and capabilities. + * + * This only carries the toggle state needed for icon/label selection. + * The actual [Channel] is passed separately when constructing [ChannelAction]s. + */ +private sealed interface ResolvedSwipeAction { + + data class Archive(val isArchived: Boolean) : ResolvedSwipeAction + + data class Mute(val isMuted: Boolean) : ResolvedSwipeAction + + data class Pin(val isPinned: Boolean) : ResolvedSwipeAction } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt index 439afe3d2d4..e207fdd30ab 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt @@ -16,6 +16,7 @@ package io.getstream.chat.android.compose.ui.channels.list +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -56,6 +57,7 @@ public fun SwipeActionItem( modifier = modifier .width(80.dp) .fillMaxHeight() + .background(backgroundColor) .clickable(onClick = onClick), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, @@ -75,3 +77,36 @@ public fun SwipeActionItem( ) } } + +/** + * A single swipe action button using [SwipeActionStyle] for slot-based coloring. + * + * @param icon The icon to display. + * @param label The label text below the icon. + * @param onClick Called when this action is tapped. + * @param style The visual style determining background and content colors. + * @param modifier Modifier for styling. + */ +@Composable +public fun SwipeActionItem( + icon: Painter, + label: String, + onClick: () -> Unit, + style: SwipeActionStyle, + modifier: Modifier = Modifier, +) { + val colors = ChatTheme.colors + val (bg, content) = when (style) { + SwipeActionStyle.Primary -> colors.accentPrimary to Color.White + SwipeActionStyle.Secondary -> colors.accentNeutral to Color.White + SwipeActionStyle.Destructive -> colors.accentError to Color.White + } + SwipeActionItem( + icon = icon, + label = label, + onClick = onClick, + backgroundColor = bg, + contentColor = content, + modifier = modifier, + ) +} diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle.kt new file mode 100644 index 00000000000..fa2a5184c01 --- /dev/null +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionStyle.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014-2026 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.channels.list + +import io.getstream.chat.android.compose.ui.theme.ChatTheme + +/** + * Visual style for a swipe action slot. + * + * The style determines the background and content colors of the action button. + * It is slot-based: the same action can be styled differently depending on its position. + */ +public enum class SwipeActionStyle { + /** Blue background ([ChatTheme.colors.accentPrimary]), white content. */ + Primary, + + /** Gray background ([ChatTheme.colors.accentNeutral]), white content. */ + Secondary, + + /** Red background ([ChatTheme.colors.accentError]), white content. */ + Destructive, +} diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt index 7ee41f4c252..87476c3f456 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt @@ -19,6 +19,7 @@ package io.getstream.chat.android.compose.ui.channels.list import androidx.compose.foundation.gestures.AnchoredDraggableState import androidx.compose.foundation.gestures.animateTo import androidx.compose.runtime.compositionLocalOf +import io.getstream.chat.android.models.Channel import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction /** @@ -76,7 +77,14 @@ public class SwipeRevealCoordinator { internal val LocalSwipeRevealCoordinator = compositionLocalOf { null } /** - * Provides a handler for swipe channel actions (pin, mute, delete, etc.). + * Provides a handler for swipe channel actions (pin, mute, archive, etc.). * `null` means no handler is available. */ internal val LocalSwipeActionHandler = compositionLocalOf<((ChannelAction) -> Unit)?> { null } + +/** + * Provides a handler for the "More" swipe action that opens the channel options sheet. + * Maps to the same flow as long-press: selecting the channel to show [SelectedChannelMenu]. + * `null` means no handler is available. + */ +internal val LocalChannelMoreClickHandler = compositionLocalOf<((Channel) -> Unit)?> { null } diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_options.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_options.xml new file mode 100644 index 00000000000..eb37dd78b04 --- /dev/null +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_options.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/stream-chat-android-compose/src/main/res/values/strings.xml b/stream-chat-android-compose/src/main/res/values/strings.xml index 87a39e2eaee..015f220ca19 100644 --- a/stream-chat-android-compose/src/main/res/values/strings.xml +++ b/stream-chat-android-compose/src/main/res/values/strings.xml @@ -40,6 +40,9 @@ Mute Unmute Delete + More + Archive + Unarchive No results for \"%1$s\" From 7d54d2d38c3740401160afcdd28c5bf09550b839 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Tue, 24 Feb 2026 16:38:55 +0100 Subject: [PATCH 03/22] fix(compose): fix swipe-to-reveal not responding to gestures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SideEffect does not track state reads for recomposition, so when onSizeChanged updated actionsWidthPx during layout, the anchor setup block never re-ran — leaving AnchoredDraggableState with no anchors and making the swipe gesture a no-op. Switch to LaunchedEffect(actionsWidthPx) so the key is tracked during composition and anchors are set after layout measurement. Also add height(IntrinsicSize.Min) to the outer Box so the background action Row can fillMaxHeight() properly inside LazyColumn's unbounded height context. --- .../ui/channels/list/SwipeableChannelItem.kt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt index d6252c17e9d..cb530a9a9f6 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt @@ -21,13 +21,14 @@ import androidx.compose.foundation.gestures.DraggableAnchors import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.anchoredDraggable import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember @@ -72,8 +73,8 @@ public fun SwipeableChannelItem( var actionsWidthPx by remember { mutableIntStateOf(0) } - // Update anchors when actions width changes - SideEffect { + // LaunchedEffect (not SideEffect) so the key triggers recomposition after onSizeChanged. + LaunchedEffect(actionsWidthPx) { if (actionsWidthPx > 0) { val newAnchors = DraggableAnchors { SwipeRevealValue.Closed at 0f @@ -99,7 +100,9 @@ public fun SwipeableChannelItem( } Box( - modifier = modifier.clipToBounds(), + modifier = modifier + .height(IntrinsicSize.Min) + .clipToBounds(), ) { // Background: action buttons Row( @@ -115,12 +118,8 @@ public fun SwipeableChannelItem( Box( modifier = Modifier .offset { - val offset = anchoredDraggableState.offset - if (isRtl) { - IntOffset(x = -offset.roundToInt(), y = 0) - } else { - IntOffset(x = offset.roundToInt(), y = 0) - } + val x = anchoredDraggableState.offset.roundToInt() + IntOffset(x = if (isRtl) -x else x, y = 0) } .anchoredDraggable( state = anchoredDraggableState, From 95bfb0da1219102a2e62ab45f4dad38dea41bad2 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Tue, 24 Feb 2026 17:17:26 +0100 Subject: [PATCH 04/22] fix(compose): wire swipe actions in sample's custom factory CustomChatComponentFactory overrode ChannelListItemContent without the SwipeableChannelItem wrapper, making swipe a no-op in the sample. - Add SwipeableChannelItem wrapper to the sample's override - Make LocalSwipeRevealCoordinator public so consumers who override ChannelListItemContent can check swipe availability --- .../component/CustomChatComponentFactory.kt | 53 +++++++++++++------ .../api/stream-chat-android-compose.api | 4 ++ .../channels/list/SwipeRevealCoordinator.kt | 4 +- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt index 429040f2f35..0ca216aec45 100644 --- a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt +++ b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt @@ -17,6 +17,7 @@ package io.getstream.chat.android.compose.sample.ui.component import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -25,6 +26,8 @@ import io.getstream.chat.android.compose.sample.ui.location.LocationComponentFac import io.getstream.chat.android.compose.sample.vm.SharedLocationViewModelFactory import io.getstream.chat.android.compose.state.channels.list.ItemState import io.getstream.chat.android.compose.ui.channels.list.ChannelItem +import io.getstream.chat.android.compose.ui.channels.list.LocalSwipeRevealCoordinator +import io.getstream.chat.android.compose.ui.channels.list.SwipeableChannelItem import io.getstream.chat.android.compose.ui.theme.ChatComponentFactory import io.getstream.chat.android.compose.ui.theme.ChatTheme import io.getstream.chat.android.models.Channel @@ -42,21 +45,39 @@ class CustomChatComponentFactory( onChannelClick: (Channel) -> Unit, onChannelLongClick: (Channel) -> Unit, ) { - ChannelItem( - modifier = Modifier - .animateItem() - .run { - // Highlight the item background color if it is pinned - if (channelItem.channel.isPinned()) { - background(color = ChatTheme.colors.highlight) - } else { - this - } - }, - channelItem = channelItem, - currentUser = currentUser, - onChannelClick = onChannelClick, - onChannelLongClick = onChannelLongClick, - ) + val coordinator = LocalSwipeRevealCoordinator.current + val swipeEnabled = ChatTheme.config.channelList.swipeActionsEnabled && coordinator != null + val itemModifier = Modifier + .animateItem() + .run { + if (channelItem.channel.isPinned()) { + background(color = ChatTheme.colors.highlight) + } else { + this + } + } + + if (swipeEnabled) { + SwipeableChannelItem( + channelCid = channelItem.channel.cid, + swipeActions = { Row { ChannelSwipeActions(channelItem) } }, + ) { + ChannelItem( + modifier = itemModifier, + channelItem = channelItem, + currentUser = currentUser, + onChannelClick = onChannelClick, + onChannelLongClick = onChannelLongClick, + ) + } + } else { + ChannelItem( + modifier = itemModifier, + channelItem = channelItem, + currentUser = currentUser, + onChannelClick = onChannelClick, + onChannelLongClick = onChannelLongClick, + ) + } } } 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 8e1ebf559f0..ad6c9cd9a0a 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -1342,6 +1342,10 @@ public final class io/getstream/chat/android/compose/ui/channels/list/SwipeRevea public final fun unregister (Ljava/lang/String;)V } +public final class io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinatorKt { + public static final fun getLocalSwipeRevealCoordinator ()Landroidx/compose/runtime/ProvidableCompositionLocal; +} + public final class io/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue : java/lang/Enum { public static final field Closed Lio/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue; public static final field Open Lio/getstream/chat/android/compose/ui/channels/list/SwipeRevealValue; diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt index 87476c3f456..95ec4e23521 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeRevealCoordinator.kt @@ -18,6 +18,7 @@ package io.getstream.chat.android.compose.ui.channels.list import androidx.compose.foundation.gestures.AnchoredDraggableState import androidx.compose.foundation.gestures.animateTo +import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.compositionLocalOf import io.getstream.chat.android.models.Channel import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction @@ -74,7 +75,8 @@ public class SwipeRevealCoordinator { * Provides the [SwipeRevealCoordinator] to child composables. * `null` means swipe actions are not available in the current composition tree. */ -internal val LocalSwipeRevealCoordinator = compositionLocalOf { null } +public val LocalSwipeRevealCoordinator: ProvidableCompositionLocal = + compositionLocalOf { null } /** * Provides a handler for swipe channel actions (pin, mute, archive, etc.). From ff1ec5e36d8c9aaae529dc21b534cd86856aebb6 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Tue, 24 Feb 2026 17:29:00 +0100 Subject: [PATCH 05/22] fix(compose): guard against NaN offset before anchors are set AnchoredDraggableState.offset returns Float.NaN when no anchors exist yet. roundToInt() throws on NaN in Kotlin. Guard with isNaN check, defaulting to 0 offset. --- .../android/compose/ui/channels/list/SwipeableChannelItem.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt index cb530a9a9f6..d2fff42bec4 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt @@ -118,7 +118,8 @@ public fun SwipeableChannelItem( Box( modifier = Modifier .offset { - val x = anchoredDraggableState.offset.roundToInt() + val raw = anchoredDraggableState.offset + val x = if (raw.isNaN()) 0 else raw.roundToInt() IntOffset(x = if (isRtl) -x else x, y = 0) } .anchoredDraggable( From b52729b62d5ee785de255d020ef953374db9f71a Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Tue, 24 Feb 2026 17:38:39 +0100 Subject: [PATCH 06/22] fix(compose): hide swipe actions behind opaque foreground The ChannelItem's 4dp card inset left the action Row visible through the transparent margins. Add a backgroundColor param to SwipeableChannelItem that paints the foreground layer opaque, covering the actions when the item is in the closed position. --- .../sample/ui/component/CustomChatComponentFactory.kt | 1 + .../api/stream-chat-android-compose.api | 2 +- .../compose/ui/channels/list/SwipeableChannelItem.kt | 7 ++++++- .../chat/android/compose/ui/theme/ChatComponentFactory.kt | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt index 0ca216aec45..6a2d7e9cba0 100644 --- a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt +++ b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt @@ -60,6 +60,7 @@ class CustomChatComponentFactory( if (swipeEnabled) { SwipeableChannelItem( channelCid = channelItem.channel.cid, + backgroundColor = ChatTheme.colors.appBackground, swipeActions = { Row { ChannelSwipeActions(channelItem) } }, ) { ChannelItem( 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 ad6c9cd9a0a..087acb6d8c5 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -1355,7 +1355,7 @@ public final class io/getstream/chat/android/compose/ui/channels/list/SwipeRevea } public final class io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItemKt { - public static final fun SwipeableChannelItem (Ljava/lang/String;Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V + public static final fun SwipeableChannelItem-fWhpE4E (Ljava/lang/String;Landroidx/compose/ui/Modifier;ZJLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V } public final class io/getstream/chat/android/compose/ui/chats/ChatListContentMode : java/lang/Enum { diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt index d2fff42bec4..9e97099ae5d 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt @@ -16,6 +16,7 @@ package io.getstream.chat.android.compose.ui.channels.list +import androidx.compose.foundation.background import androidx.compose.foundation.gestures.AnchoredDraggableState import androidx.compose.foundation.gestures.DraggableAnchors import androidx.compose.foundation.gestures.Orientation @@ -37,6 +38,7 @@ import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.IntOffset @@ -53,6 +55,7 @@ import kotlin.math.roundToInt * @param channelCid The channel CID used for coordinator registration. * @param modifier Modifier for styling. * @param enabled Whether swiping is enabled. + * @param backgroundColor Opaque background for the foreground layer, hiding actions when closed. * @param swipeActions Composable content for the action buttons revealed by swiping. * @param content The channel item content displayed on top. */ @@ -61,6 +64,7 @@ public fun SwipeableChannelItem( channelCid: String, modifier: Modifier = Modifier, enabled: Boolean = true, + backgroundColor: Color = Color.Unspecified, swipeActions: @Composable () -> Unit, content: @Composable () -> Unit, ) { @@ -114,9 +118,10 @@ public fun SwipeableChannelItem( swipeActions() } - // Foreground: channel item content + // Foreground: channel item content (opaque bg hides actions when closed) Box( modifier = Modifier + .background(backgroundColor) .offset { val raw = anchoredDraggableState.offset val x = if (raw.isNaN()) 0 else raw.roundToInt() diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt index b60860b8924..3e9717e7b37 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt @@ -420,6 +420,7 @@ public interface ChatComponentFactory { if (swipeEnabled) { SwipeableChannelItem( channelCid = channelItem.channel.cid, + backgroundColor = ChatTheme.colors.appBackground, swipeActions = { Row { ChannelSwipeActions(channelItem) } }, ) { ChannelItem( From 938c9c48f3440de8505361f43f7e9d116034ef78 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Tue, 24 Feb 2026 17:48:48 +0100 Subject: [PATCH 07/22] fix(compose): correct modifier order so background slides with content background() must be after offset() so the opaque layer moves with the channel item, covering actions when closed but revealing them when swiped open. --- .../android/compose/ui/channels/list/SwipeableChannelItem.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt index 9e97099ae5d..f682d0dcff2 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeableChannelItem.kt @@ -121,12 +121,12 @@ public fun SwipeableChannelItem( // Foreground: channel item content (opaque bg hides actions when closed) Box( modifier = Modifier - .background(backgroundColor) .offset { val raw = anchoredDraggableState.offset val x = if (raw.isNaN()) 0 else raw.roundToInt() IntOffset(x = if (isRtl) -x else x, y = 0) } + .background(backgroundColor) .anchoredDraggable( state = anchoredDraggableState, orientation = Orientation.Horizontal, From ac1fa4d1df1a16d6072b10bf4a4536ae618c1e7f Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Tue, 24 Feb 2026 18:00:14 +0100 Subject: [PATCH 08/22] =?UTF-8?q?fix(compose):=20swap=20swipe=20action=20o?= =?UTF-8?q?rder=20=E2=80=94=20More=20left,=20primary=20right?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Place the secondary More action first (leftmost) and the primary action (Archive/Mute) second (rightmost) to match the Figma spec. --- .../list/DefaultChannelSwipeActions.kt | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt index 5a9b7f9a959..a95dafded6a 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt @@ -62,7 +62,17 @@ public fun RowScope.DefaultChannelSwipeActions(channelItem: ItemState.ChannelIte scope.launch { coordinator?.closeAll() } } - // Resolve and render the primary action + // "More" action — opens the channel options sheet + if (moreHandler != null) { + SwipeActionItem( + icon = painterResource(R.drawable.stream_compose_ic_more_options), + label = stringResource(R.string.stream_compose_swipe_action_more), + onClick = { onAction { moreHandler(channel) } }, + style = SwipeActionStyle.Secondary, + ) + } + + // Primary action (rightmost) — resolved by channel type and capabilities val primaryAction = resolvePrimaryAction( channel = channel, isMuted = channelItem.isMuted, @@ -76,16 +86,6 @@ public fun RowScope.DefaultChannelSwipeActions(channelItem: ItemState.ChannelIte onAction = { onAction { handler(it) } }, ) } - - // "More" action — opens the channel options sheet - if (moreHandler != null) { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_more_options), - label = stringResource(R.string.stream_compose_swipe_action_more), - onClick = { onAction { moreHandler(channel) } }, - style = SwipeActionStyle.Secondary, - ) - } } /** From 7e2dd8791e5c6bca370b0fcbebbd1b9526b5a275 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 10:57:32 +0100 Subject: [PATCH 09/22] refactor(actions): unify ChannelAction into self-describing interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite ChannelAction from sealed class to interface carrying icon, label, capability, confirmation popup, and execution handler. This eliminates scattered when-switches, removes ChannelOptionState, and enables custom channel actions across Compose and XML surfaces. - ChannelAction: sealed class → interface with icon/label/onAction - Add ConfirmationPopup data class for deferred destructive actions - Copy 10 icon drawables to ui-common for cross-module access - Remove Cancel object (dismissal via onDismiss callbacks) - ViewModel: performChannelAction → executeOrConfirm/confirmPendingAction - Compose: delete ChannelOptionState, buildDefaultChannelActions returns List with ViewModel handlers bound - ChannelsScreen: generic confirmation dialog from action.confirmationPopup - ChatComponentFactory: ChannelOptionState refs → ChannelAction - Swipe actions: build ChannelAction objects directly - XML: factory returns List, delete ChannelOptionItem - Update tests, sample app, docs snippets, API dump --- .../feature/channel/list/ChannelsActivity.kt | 12 +- .../api/stream-chat-android-compose.api | 29 +-- .../state/channels/list/ChannelOptionState.kt | 38 --- .../compose/ui/channels/ChannelsScreen.kt | 66 ++--- .../ui/channels/info/SelectedChannelMenu.kt | 30 +-- .../compose/ui/channels/list/ChannelList.kt | 8 +- .../list/DefaultChannelSwipeActions.kt | 161 +++++------- .../ui/components/channels/ChannelOptions.kt | 236 ++++++++++-------- .../compose/ui/theme/ChatComponentFactory.kt | 59 +++-- .../channels/ChannelListViewModel.kt | 31 +-- .../ui/channels/SelectedChannelMenuTest.kt | 23 +- .../channels/ChannelListViewModelTest.kt | 9 +- .../compose/channels/SelectedChannelMenu.kt | 44 ++-- .../api/stream-chat-android-ui-common.api | 162 ++++++------ .../state/channels/actions/ChannelAction.kt | 136 +++++++--- .../channels/actions/ConfirmationPopup.kt | 30 +++ .../res/drawable/stream_ic_action_archive.xml | 26 ++ .../res/drawable/stream_ic_action_delete.xml | 26 ++ .../res/drawable/stream_ic_action_leave.xml | 35 +++ .../res/drawable/stream_ic_action_more.xml | 27 ++ .../res/drawable/stream_ic_action_mute.xml | 27 ++ .../res/drawable/stream_ic_action_pin.xml | 25 ++ .../drawable/stream_ic_action_unarchive.xml | 23 ++ .../res/drawable/stream_ic_action_unmute.xml | 27 ++ .../res/drawable/stream_ic_action_unpin.xml | 32 +++ .../drawable/stream_ic_action_view_info.xml | 27 ++ .../internal/ChannelActionsDialogFragment.kt | 13 +- .../actions/internal/ChannelOptionItem.kt | 35 --- .../internal/ChannelOptionItemsFactory.kt | 55 ++-- 29 files changed, 888 insertions(+), 564 deletions(-) delete mode 100644 stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/state/channels/list/ChannelOptionState.kt create mode 100644 stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup.kt create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_archive.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_delete.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_leave.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_more.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_pin.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unarchive.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unpin.xml create mode 100644 stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_view_info.xml delete mode 100644 stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelOptionItem.kt diff --git a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt index 4776479ed6a..7ece3e516e7 100644 --- a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt +++ b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt @@ -84,6 +84,7 @@ import io.getstream.chat.android.compose.ui.channels.list.ChannelItem import io.getstream.chat.android.compose.ui.channels.list.ChannelList import io.getstream.chat.android.compose.ui.components.SearchInput import io.getstream.chat.android.compose.ui.components.channels.ChannelOptionItemVisibility +import io.getstream.chat.android.compose.ui.components.channels.buildDefaultChannelActions import io.getstream.chat.android.compose.ui.mentions.MentionList import io.getstream.chat.android.compose.ui.theme.ChannelOptionsTheme import io.getstream.chat.android.compose.ui.theme.ChatTheme @@ -377,6 +378,13 @@ class ChannelsActivity : ComponentActivity() { val selectedChannel = delegatedSelectedChannel if (selectedChannel != null) { + val channelActions = buildDefaultChannelActions( + selectedChannel = selectedChannel, + isMuted = channelsViewModel.isChannelMuted(selectedChannel.cid), + ownCapabilities = selectedChannel.ownCapabilities, + viewModel = channelsViewModel, + onViewInfoAction = ::viewChannelInfo, + ) SelectedChannelMenu( modifier = Modifier .padding(16.dp) @@ -384,10 +392,10 @@ class ChannelsActivity : ComponentActivity() { .wrapContentHeight() .align(Alignment.Center), shape = RoundedCornerShape(16.dp), - isMuted = channelsViewModel.isChannelMuted(selectedChannel.cid), selectedChannel = selectedChannel, currentUser = user, - onChannelOptionClick = { action -> channelsViewModel.performChannelAction(action) }, + channelActions = channelActions, + onChannelOptionClick = { action -> channelsViewModel.executeOrConfirm(action) }, onDismiss = { channelsViewModel.dismissChannelAction() }, ) } 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 087acb6d8c5..91dd6d7804e 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -50,16 +50,6 @@ public final class io/getstream/chat/android/compose/state/QueryConfig { public fun toString ()Ljava/lang/String; } -public final class io/getstream/chat/android/compose/state/channels/list/ChannelOptionState { - public static final field $stable I - public synthetic fun (Ljava/lang/String;JLandroidx/compose/ui/graphics/painter/Painter;JLio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun getAction ()Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction; - public final fun getIconColor-0d7_KjU ()J - public final fun getIconPainter ()Landroidx/compose/ui/graphics/painter/Painter; - public final fun getTitle ()Ljava/lang/String; - public final fun getTitleColor-0d7_KjU ()J -} - public final class io/getstream/chat/android/compose/state/channels/list/ChannelsState { public static final field $stable I public fun ()V @@ -1234,7 +1224,7 @@ public final class io/getstream/chat/android/compose/ui/channels/info/Composable } public final class io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenuKt { - public static final fun SelectedChannelMenu-pX9LQoI (Lio/getstream/chat/android/models/Channel;ZLio/getstream/chat/android/models/User;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;Ljava/util/List;Landroidx/compose/ui/graphics/Shape;JLkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;III)V + public static final fun SelectedChannelMenu-Ic2awPA (Lio/getstream/chat/android/models/Channel;Lio/getstream/chat/android/models/User;Ljava/util/List;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;JLkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V } public final class io/getstream/chat/android/compose/ui/channels/list/ChannelItemKt { @@ -1609,7 +1599,7 @@ public final class io/getstream/chat/android/compose/ui/components/channels/Chan public final class io/getstream/chat/android/compose/ui/components/channels/ChannelOptionsKt { public static final fun ChannelOptions (Ljava/util/List;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V - public static final fun buildDefaultChannelOptionsState (Lio/getstream/chat/android/models/Channel;ZLjava/util/Set;Landroidx/compose/runtime/Composer;I)Ljava/util/List; + public static final fun buildDefaultChannelActions (Lio/getstream/chat/android/models/Channel;ZLjava/util/Set;Lio/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)Ljava/util/List; } public final class io/getstream/chat/android/compose/ui/components/channels/ComposableSingletons$ChannelMembersItemKt { @@ -2921,12 +2911,12 @@ public abstract interface class io/getstream/chat/android/compose/ui/theme/ChatC public abstract fun ChannelMediaAttachmentsPreviewTopBar (Lio/getstream/chat/android/ui/common/state/channel/attachments/ChannelAttachmentsViewState$Content$Item;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V public abstract fun ChannelMediaAttachmentsPreviewTopBarTitle (Lio/getstream/chat/android/ui/common/state/channel/attachments/ChannelAttachmentsViewState$Content$Item;Landroidx/compose/runtime/Composer;I)V public abstract fun ChannelMediaAttachmentsTopBar (Landroidx/compose/foundation/lazy/grid/LazyGridState;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V - public abstract fun ChannelMenu (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/models/Channel;ZLio/getstream/chat/android/models/User;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V + public abstract fun ChannelMenu (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/models/Channel;Lio/getstream/chat/android/models/User;Ljava/util/List;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V public abstract fun ChannelMenuCenterContent (Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Ljava/util/List;Landroidx/compose/runtime/Composer;I)V public abstract fun ChannelMenuHeaderContent (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/models/Channel;Lio/getstream/chat/android/models/User;Landroidx/compose/runtime/Composer;I)V public abstract fun ChannelMenuOptions (Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Ljava/util/List;Landroidx/compose/runtime/Composer;I)V - public abstract fun ChannelOptionsItem (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/compose/state/channels/list/ChannelOptionState;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V - public abstract fun ChannelOptionsItemLeadingIcon (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/compose/state/channels/list/ChannelOptionState;Landroidx/compose/runtime/Composer;I)V + public abstract fun ChannelOptionsItem (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V + public abstract fun ChannelOptionsItemLeadingIcon (Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;Landroidx/compose/runtime/Composer;I)V public abstract fun ChannelSwipeActions (Landroidx/compose/foundation/layout/RowScope;Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState;Landroidx/compose/runtime/Composer;I)V public abstract fun CustomAttachmentContent (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)V public abstract fun DirectChannelInfoAvatarContainer (Lio/getstream/chat/android/models/User;Landroidx/compose/runtime/Composer;I)V @@ -3117,12 +3107,12 @@ public final class io/getstream/chat/android/compose/ui/theme/ChatComponentFacto public static fun ChannelMediaAttachmentsPreviewTopBar (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Lio/getstream/chat/android/ui/common/state/channel/attachments/ChannelAttachmentsViewState$Content$Item;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V public static fun ChannelMediaAttachmentsPreviewTopBarTitle (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Lio/getstream/chat/android/ui/common/state/channel/attachments/ChannelAttachmentsViewState$Content$Item;Landroidx/compose/runtime/Composer;I)V public static fun ChannelMediaAttachmentsTopBar (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/foundation/lazy/grid/LazyGridState;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V - public static fun ChannelMenu (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/models/Channel;ZLio/getstream/chat/android/models/User;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V + public static fun ChannelMenu (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/models/Channel;Lio/getstream/chat/android/models/User;Ljava/util/List;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V public static fun ChannelMenuCenterContent (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Ljava/util/List;Landroidx/compose/runtime/Composer;I)V public static fun ChannelMenuHeaderContent (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/models/Channel;Lio/getstream/chat/android/models/User;Landroidx/compose/runtime/Composer;I)V public static fun ChannelMenuOptions (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Ljava/util/List;Landroidx/compose/runtime/Composer;I)V - public static fun ChannelOptionsItem (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/compose/state/channels/list/ChannelOptionState;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V - public static fun ChannelOptionsItemLeadingIcon (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/compose/state/channels/list/ChannelOptionState;Landroidx/compose/runtime/Composer;I)V + public static fun ChannelOptionsItem (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V + public static fun ChannelOptionsItemLeadingIcon (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;Landroidx/compose/runtime/Composer;I)V public static fun ChannelSwipeActions (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Landroidx/compose/foundation/layout/RowScope;Lio/getstream/chat/android/compose/state/channels/list/ItemState$ChannelItemState;Landroidx/compose/runtime/Composer;I)V public static fun CustomAttachmentContent (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)V public static fun DirectChannelInfoAvatarContainer (Lio/getstream/chat/android/compose/ui/theme/ChatComponentFactory;Lio/getstream/chat/android/models/User;Landroidx/compose/runtime/Composer;I)V @@ -4638,8 +4628,10 @@ public final class io/getstream/chat/android/compose/viewmodel/channels/ChannelL public fun (Lio/getstream/chat/android/client/ChatClient;Lio/getstream/chat/android/models/querysort/QuerySorter;Lio/getstream/chat/android/models/FilterObject;ILjava/lang/Integer;Ljava/lang/Integer;Lio/getstream/chat/android/client/api/event/ChatEventHandlerFactory;JZLkotlinx/coroutines/flow/Flow;)V public synthetic fun (Lio/getstream/chat/android/client/ChatClient;Lio/getstream/chat/android/models/querysort/QuerySorter;Lio/getstream/chat/android/models/FilterObject;ILjava/lang/Integer;Ljava/lang/Integer;Lio/getstream/chat/android/client/api/event/ChatEventHandlerFactory;JZLkotlinx/coroutines/flow/Flow;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun archiveChannel (Lio/getstream/chat/android/models/Channel;)V + public final fun confirmPendingAction ()V public final fun deleteConversation (Lio/getstream/chat/android/models/Channel;)V public final fun dismissChannelAction ()V + public final fun executeOrConfirm (Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;)V public final fun getActiveChannelAction ()Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction; public final fun getChannelMutes ()Lkotlinx/coroutines/flow/StateFlow; public final fun getChannelsState ()Lio/getstream/chat/android/compose/state/channels/list/ChannelsState; @@ -4652,7 +4644,6 @@ public final class io/getstream/chat/android/compose/viewmodel/channels/ChannelL public final fun leaveGroup (Lio/getstream/chat/android/models/Channel;)V public final fun loadMore ()V public final fun muteChannel (Lio/getstream/chat/android/models/Channel;)V - public final fun performChannelAction (Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;)V public final fun pinChannel (Lio/getstream/chat/android/models/Channel;)V public final fun refresh ()V public final fun selectChannel (Lio/getstream/chat/android/models/Channel;)V diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/state/channels/list/ChannelOptionState.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/state/channels/list/ChannelOptionState.kt deleted file mode 100644 index dc0865b8134..00000000000 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/state/channels/list/ChannelOptionState.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2014-2026 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.state.channels.list - -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.painter.Painter -import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction - -/** - * UI representation of a Channel option, when the user selects a channel in the list. - * - * @param title The title to represent the action. - * @param titleColor The color of the title text. - * @param iconPainter The icon to represent the action. - * @param iconColor The color of the icon. - * @param action The [ChannelAction] the option represents. - */ -public class ChannelOptionState( - public val title: String, - public val titleColor: Color, - public val iconPainter: Painter, - public val iconColor: Color, - public val action: ChannelAction, -) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/ChannelsScreen.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/ChannelsScreen.kt index bb2d8704c64..dad91a6f414 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/ChannelsScreen.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/ChannelsScreen.kt @@ -41,27 +41,18 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel -import io.getstream.chat.android.compose.R import io.getstream.chat.android.compose.state.channels.list.SearchQuery import io.getstream.chat.android.compose.ui.channels.list.ChannelList import io.getstream.chat.android.compose.ui.components.SimpleDialog +import io.getstream.chat.android.compose.ui.components.channels.buildDefaultChannelActions import io.getstream.chat.android.compose.ui.theme.ChatTheme import io.getstream.chat.android.compose.ui.theme.StreamTokens import io.getstream.chat.android.compose.viewmodel.channels.ChannelListViewModel import io.getstream.chat.android.compose.viewmodel.channels.ChannelViewModelFactory import io.getstream.chat.android.models.Channel import io.getstream.chat.android.models.Message -import io.getstream.chat.android.ui.common.state.channels.actions.ArchiveChannel -import io.getstream.chat.android.ui.common.state.channels.actions.DeleteConversation -import io.getstream.chat.android.ui.common.state.channels.actions.LeaveGroup -import io.getstream.chat.android.ui.common.state.channels.actions.MuteChannel -import io.getstream.chat.android.ui.common.state.channels.actions.PinChannel -import io.getstream.chat.android.ui.common.state.channels.actions.UnarchiveChannel -import io.getstream.chat.android.ui.common.state.channels.actions.UnmuteChannel -import io.getstream.chat.android.ui.common.state.channels.actions.UnpinChannel import io.getstream.chat.android.ui.common.state.channels.actions.ViewInfo /** @@ -191,6 +182,17 @@ public fun ChannelsScreen( enter = fadeIn(), exit = fadeOut(animationSpec = tween(durationMillis = AnimationConstants.DefaultDurationMillis / 2)), ) { + val channelActions = buildDefaultChannelActions( + selectedChannel = channel, + isMuted = listViewModel.isChannelMuted(channel.cid), + ownCapabilities = channel.ownCapabilities, + viewModel = listViewModel, + onViewInfoAction = { ch -> + listViewModel.dismissChannelAction() + onViewChannelInfoAction(ch) + }, + ) + ChatTheme.componentFactory.ChannelMenu( modifier = Modifier .align(Alignment.BottomCenter) @@ -206,23 +208,11 @@ public fun ChannelsScreen( ), selectedChannel = channel, currentUser = user, - isMuted = listViewModel.isChannelMuted(channel.cid), + channelActions = channelActions, onChannelOptionClick = remember(listViewModel) { { action -> - when (action) { - is ViewInfo -> { - listViewModel.dismissChannelAction() - onViewChannelInfoAction(action.channel) - } - is MuteChannel -> listViewModel.muteChannel(action.channel) - is UnmuteChannel -> listViewModel.unmuteChannel(action.channel) - is PinChannel -> listViewModel.pinChannel(action.channel) - is UnpinChannel -> listViewModel.unpinChannel(action.channel) - is ArchiveChannel -> listViewModel.archiveChannel(action.channel) - is UnarchiveChannel -> listViewModel.unarchiveChannel(action.channel) - else -> listViewModel.performChannelAction(action) - } + listViewModel.executeOrConfirm(action) } }, onDismiss = remember(listViewModel) { { listViewModel.dismissChannelAction() } }, @@ -230,32 +220,14 @@ public fun ChannelsScreen( } val activeAction = listViewModel.activeChannelAction + val popup = activeAction?.confirmationPopup - if (activeAction is LeaveGroup) { - SimpleDialog( - modifier = Modifier.padding(16.dp), - title = stringResource( - id = R.string.stream_compose_selected_channel_menu_leave_group_confirmation_title, - ), - message = stringResource( - id = R.string.stream_compose_selected_channel_menu_leave_group_confirmation_message, - ChatTheme.channelNameFormatter.formatChannelName(activeAction.channel, user), - ), - onPositiveAction = remember(listViewModel) { { listViewModel.leaveGroup(activeAction.channel) } }, - onDismiss = remember(listViewModel) { { listViewModel.dismissChannelAction() } }, - ) - } else if (activeAction is DeleteConversation) { + if (popup != null) { SimpleDialog( modifier = Modifier.padding(16.dp), - title = stringResource( - id = R.string.stream_compose_selected_channel_menu_delete_conversation_confirmation_title, - ), - message = stringResource( - id = R.string.stream_compose_selected_channel_menu_delete_conversation_confirmation_message, - ChatTheme.channelNameFormatter.formatChannelName(activeAction.channel, user), - ), - onPositiveAction = - remember(listViewModel) { { listViewModel.deleteConversation(activeAction.channel) } }, + title = popup.title, + message = popup.message, + onPositiveAction = remember(listViewModel) { { listViewModel.confirmPendingAction() } }, onDismiss = remember(listViewModel) { { listViewModel.dismissChannelAction() } }, ) } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt index 36f8e853bdf..5a74775553d 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt @@ -34,10 +34,8 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import io.getstream.chat.android.compose.state.channels.list.ChannelOptionState import io.getstream.chat.android.compose.ui.components.SimpleMenu import io.getstream.chat.android.compose.ui.components.channels.ChannelMembers -import io.getstream.chat.android.compose.ui.components.channels.buildDefaultChannelOptionsState import io.getstream.chat.android.compose.ui.theme.ChatTheme import io.getstream.chat.android.compose.ui.theme.StreamTokens import io.getstream.chat.android.compose.ui.util.getMembersStatusText @@ -47,17 +45,18 @@ import io.getstream.chat.android.models.User import io.getstream.chat.android.previewdata.PreviewChannelData import io.getstream.chat.android.previewdata.PreviewUserData import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction +import io.getstream.chat.android.ui.common.state.channels.actions.ViewInfo /** * Shows special UI when an item is selected. * It also prepares the available options for the channel, based on if we're an admin or not. * * @param selectedChannel The channel the user selected. - * @param isMuted If the channel is muted for the current user. + * @param currentUser The currently logged-in user data. + * @param channelActions The list of actions to show in the menu. * @param onChannelOptionClick Handler for when the user selects a channel option. * @param onDismiss Handler called when the dialog is dismissed. * @param modifier Modifier for styling. - * @param channelOptions The list of options to show in the UI, according to user permissions. * @param shape The shape of the component. * @param overlayColor The color applied to the overlay. * @param headerContent The content shown at the top of the dialog. @@ -66,16 +65,11 @@ import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction @Composable public fun SelectedChannelMenu( selectedChannel: Channel, - isMuted: Boolean, currentUser: User?, + channelActions: List, onChannelOptionClick: (ChannelAction) -> Unit, onDismiss: () -> Unit, modifier: Modifier = Modifier, - channelOptions: List = buildDefaultChannelOptionsState( - selectedChannel = selectedChannel, - isMuted = isMuted, - ownCapabilities = selectedChannel.ownCapabilities, - ), shape: Shape = ChatTheme.shapes.bottomSheet, overlayColor: Color = ChatTheme.colors.overlay, headerContent: @Composable ColumnScope.() -> Unit = { @@ -92,7 +86,7 @@ public fun SelectedChannelMenu( ChannelMenuCenterContent( modifier = Modifier, onChannelOptionClick = onChannelOptionClick, - channelOptions = channelOptions, + channelActions = channelActions, ) } }, @@ -168,6 +162,7 @@ internal fun DefaultSelectedChannelMenuHeaderContent( private fun SelectedChannelMenuCenteredDialogPreview() { ChatTheme { Box(modifier = Modifier.fillMaxSize()) { + val channel = PreviewChannelData.channelWithManyMembers SelectedChannelMenu( modifier = Modifier .padding(16.dp) @@ -175,9 +170,11 @@ private fun SelectedChannelMenuCenteredDialogPreview() { .wrapContentHeight() .align(Alignment.Center), shape = RoundedCornerShape(16.dp), - selectedChannel = PreviewChannelData.channelWithManyMembers, - isMuted = false, + selectedChannel = channel, currentUser = PreviewUserData.user1, + channelActions = listOf( + ViewInfo(channel = channel, label = "Channel Info", onAction = {}), + ), onChannelOptionClick = {}, onDismiss = {}, ) @@ -195,15 +192,18 @@ private fun SelectedChannelMenuCenteredDialogPreview() { private fun SelectedChannelMenuBottomSheetDialogPreview() { ChatTheme { Box(modifier = Modifier.fillMaxSize()) { + val channel = PreviewChannelData.channelWithManyMembers SelectedChannelMenu( modifier = Modifier .fillMaxWidth() .wrapContentHeight() .align(Alignment.BottomCenter), shape = ChatTheme.shapes.bottomSheet, - selectedChannel = PreviewChannelData.channelWithManyMembers, - isMuted = false, + selectedChannel = channel, currentUser = PreviewUserData.user1, + channelActions = listOf( + ViewInfo(channel = channel, label = "Channel Info", onAction = {}), + ), onChannelOptionClick = {}, onDismiss = {}, ) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt index 9c856e90387..d8b9624f23b 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelList.kt @@ -54,7 +54,6 @@ import io.getstream.chat.android.previewdata.PreviewMessageData import io.getstream.chat.android.previewdata.PreviewUserData import io.getstream.chat.android.ui.common.state.channels.actions.ArchiveChannel import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction -import io.getstream.chat.android.ui.common.state.channels.actions.DeleteConversation import io.getstream.chat.android.ui.common.state.channels.actions.MuteChannel import io.getstream.chat.android.ui.common.state.channels.actions.PinChannel import io.getstream.chat.android.ui.common.state.channels.actions.UnarchiveChannel @@ -168,14 +167,13 @@ public fun ChannelList( action -> scope.launch { swipeCoordinator.closeAll() } when (action) { - is PinChannel -> viewModel.pinChannel(action.channel) - is UnpinChannel -> viewModel.unpinChannel(action.channel) is MuteChannel -> viewModel.muteChannel(action.channel) is UnmuteChannel -> viewModel.unmuteChannel(action.channel) + is PinChannel -> viewModel.pinChannel(action.channel) + is UnpinChannel -> viewModel.unpinChannel(action.channel) is ArchiveChannel -> viewModel.archiveChannel(action.channel) is UnarchiveChannel -> viewModel.unarchiveChannel(action.channel) - is DeleteConversation -> viewModel.performChannelAction(action) - else -> {} + else -> viewModel.executeOrConfirm(action) } } } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt index a95dafded6a..cd4f409a337 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/DefaultChannelSwipeActions.kt @@ -40,13 +40,16 @@ import kotlinx.coroutines.launch * Default swipe actions for a channel list item. * * Shows two actions: - * - **Primary action** (blue): Archive for DMs, Mute for groups — with fallback priority. - * - **More** (gray): Opens the channel options bottom sheet. + * - **More** (gray, left): Opens the channel options bottom sheet. + * - **Primary action** (blue, right): Archive for DMs, Mute for groups — with fallback priority. * * The primary action is resolved via a priority list: * - DM: Archive → Mute → Pin * - Group: Mute → Archive → Pin * + * Each action is a self-executing [ChannelAction] that invokes its handler via + * [LocalSwipeActionHandler]. + * * @param channelItem The channel item state to build actions for. */ @Composable @@ -57,8 +60,8 @@ public fun RowScope.DefaultChannelSwipeActions(channelItem: ItemState.ChannelIte val scope = rememberCoroutineScope() val channel = channelItem.channel - fun onAction(block: () -> Unit) { - block() + fun onAction(action: ChannelAction) { + handler(action) scope.launch { coordinator?.closeAll() } } @@ -67,23 +70,26 @@ public fun RowScope.DefaultChannelSwipeActions(channelItem: ItemState.ChannelIte SwipeActionItem( icon = painterResource(R.drawable.stream_compose_ic_more_options), label = stringResource(R.string.stream_compose_swipe_action_more), - onClick = { onAction { moreHandler(channel) } }, + onClick = { + scope.launch { coordinator?.closeAll() } + moreHandler(channel) + }, style = SwipeActionStyle.Secondary, ) } // Primary action (rightmost) — resolved by channel type and capabilities - val primaryAction = resolvePrimaryAction( + val primaryAction = resolvePrimarySwipeAction( channel = channel, isMuted = channelItem.isMuted, isPinned = channelItem.isPinned, ) if (primaryAction != null) { - RenderSwipeAction( - action = primaryAction, - channel = channel, + SwipeActionItem( + icon = painterResource(primaryAction.icon), + label = primaryAction.label, + onClick = { onAction(primaryAction) }, style = SwipeActionStyle.Primary, - onAction = { onAction { handler(it) } }, ) } } @@ -97,110 +103,69 @@ public fun RowScope.DefaultChannelSwipeActions(channelItem: ItemState.ChannelIte * Archive and Pin are always available (membership operations, no capability gate). * Mute requires [ChannelCapabilities.MUTE_CHANNEL]. */ -private fun resolvePrimaryAction( +@Composable +private fun resolvePrimarySwipeAction( channel: Channel, isMuted: Boolean, isPinned: Boolean, -): ResolvedSwipeAction? { +): ChannelAction? { val capabilities = channel.ownCapabilities val isArchived = channel.isArchive() val canMute = capabilities.contains(ChannelCapabilities.MUTE_CHANNEL) val isDM = channel.isDistinct() && channel.members.size == 2 - val candidates: List = if (isDM) { - listOf( - ResolvedSwipeAction.Archive(isArchived), - ResolvedSwipeAction.Mute(isMuted).takeIf { canMute }, - ResolvedSwipeAction.Pin(isPinned), + // Build candidate actions with resolved labels + val archiveAction: ChannelAction = if (isArchived) { + UnarchiveChannel( + channel = channel, + label = stringResource(R.string.stream_compose_swipe_action_unarchive), + onAction = {}, ) } else { - listOf( - ResolvedSwipeAction.Mute(isMuted).takeIf { canMute }, - ResolvedSwipeAction.Archive(isArchived), - ResolvedSwipeAction.Pin(isPinned), + ArchiveChannel( + channel = channel, + label = stringResource(R.string.stream_compose_swipe_action_archive), + onAction = {}, ) } - return candidates.firstOrNull { it != null } -} - -/** - * Renders a resolved swipe action as a [SwipeActionItem]. - */ -@Composable -private fun RenderSwipeAction( - action: ResolvedSwipeAction, - channel: Channel, - style: SwipeActionStyle, - onAction: (ChannelAction) -> Unit, -) { - when (action) { - is ResolvedSwipeAction.Archive -> { - if (action.isArchived) { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_unarchive), - label = stringResource(R.string.stream_compose_swipe_action_unarchive), - onClick = { onAction(UnarchiveChannel(channel)) }, - style = style, - ) - } else { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_archive), - label = stringResource(R.string.stream_compose_swipe_action_archive), - onClick = { onAction(ArchiveChannel(channel)) }, - style = style, - ) - } - } - is ResolvedSwipeAction.Mute -> { - if (action.isMuted) { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_unmute), - label = stringResource(R.string.stream_compose_swipe_action_unmute), - onClick = { onAction(UnmuteChannel(channel)) }, - style = style, - ) - } else { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_mute), - label = stringResource(R.string.stream_compose_swipe_action_mute), - onClick = { onAction(MuteChannel(channel)) }, - style = style, - ) - } - } - is ResolvedSwipeAction.Pin -> { - if (action.isPinned) { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_unpin), - label = stringResource(R.string.stream_compose_swipe_action_unpin), - onClick = { onAction(UnpinChannel(channel)) }, - style = style, - ) - } else { - SwipeActionItem( - icon = painterResource(R.drawable.stream_compose_ic_pin), - label = stringResource(R.string.stream_compose_swipe_action_pin), - onClick = { onAction(PinChannel(channel)) }, - style = style, - ) - } + val muteAction: ChannelAction? = if (canMute) { + if (isMuted) { + UnmuteChannel( + channel = channel, + label = stringResource(R.string.stream_compose_swipe_action_unmute), + onAction = {}, + ) + } else { + MuteChannel( + channel = channel, + label = stringResource(R.string.stream_compose_swipe_action_mute), + onAction = {}, + ) } + } else { + null } -} - -/** - * Internal representation of a resolved swipe action, used by [resolvePrimaryAction] - * to select the best action based on channel type and capabilities. - * - * This only carries the toggle state needed for icon/label selection. - * The actual [Channel] is passed separately when constructing [ChannelAction]s. - */ -private sealed interface ResolvedSwipeAction { - data class Archive(val isArchived: Boolean) : ResolvedSwipeAction + val pinAction: ChannelAction = if (isPinned) { + UnpinChannel( + channel = channel, + label = stringResource(R.string.stream_compose_swipe_action_unpin), + onAction = {}, + ) + } else { + PinChannel( + channel = channel, + label = stringResource(R.string.stream_compose_swipe_action_pin), + onAction = {}, + ) + } - data class Mute(val isMuted: Boolean) : ResolvedSwipeAction + val candidates: List = if (isDM) { + listOf(archiveAction, muteAction, pinAction) + } else { + listOf(muteAction, archiveAction, pinAction) + } - data class Pin(val isPinned: Boolean) : ResolvedSwipeAction + return candidates.firstOrNull { it != null } } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt index aeed90ba55e..c4ccde5cf8b 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt @@ -22,22 +22,20 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import io.getstream.chat.android.client.extensions.isArchive import io.getstream.chat.android.client.extensions.isPinned import io.getstream.chat.android.compose.R -import io.getstream.chat.android.compose.state.channels.list.ChannelOptionState import io.getstream.chat.android.compose.ui.components.StreamHorizontalDivider import io.getstream.chat.android.compose.ui.theme.ChatTheme -import io.getstream.chat.android.compose.util.extensions.toSet +import io.getstream.chat.android.compose.viewmodel.channels.ChannelListViewModel import io.getstream.chat.android.models.Channel import io.getstream.chat.android.models.ChannelCapabilities import io.getstream.chat.android.previewdata.PreviewChannelData import io.getstream.chat.android.ui.common.state.channels.actions.ArchiveChannel -import io.getstream.chat.android.ui.common.state.channels.actions.Cancel import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction +import io.getstream.chat.android.ui.common.state.channels.actions.ConfirmationPopup import io.getstream.chat.android.ui.common.state.channels.actions.DeleteConversation import io.getstream.chat.android.ui.common.state.channels.actions.LeaveGroup import io.getstream.chat.android.ui.common.state.channels.actions.MuteChannel @@ -52,13 +50,13 @@ import io.getstream.chat.android.ui.common.state.channels.actions.ViewInfo * * It sets up different actions that we provide, based on user permissions. * - * @param options The list of options to show in the UI, according to user permissions. + * @param actions The list of channel actions to show in the UI. * @param onChannelOptionClick Handler for when the user selects a channel action. * @param modifier Modifier for styling. */ @Composable public fun ChannelOptions( - options: List, + actions: List, onChannelOptionClick: (ChannelAction) -> Unit, modifier: Modifier = Modifier, ) { @@ -67,14 +65,14 @@ public fun ChannelOptions( .fillMaxWidth() .wrapContentHeight(), ) { - items(options) { option -> + items(actions) { action -> StreamHorizontalDivider() with(ChatTheme.componentFactory) { ChannelOptionsItem( modifier = Modifier, - option = option, - onClick = { onChannelOptionClick(option.action) }, + action = action, + onClick = { onChannelOptionClick(action) }, ) } } @@ -82,181 +80,188 @@ public fun ChannelOptions( } /** - * Builds the default list of channel options, based on the current user and the state of the channel. + * Builds the default list of channel actions, based on the current user permissions and channel state. + * Each action is self-describing and carries its icon, label, and execution handler. * * @param selectedChannel The currently selected channel. * @param isMuted If the channel is muted or not. * @param ownCapabilities Set of capabilities the user is given for the current channel. - * @return The list of channel option items to display. + * @param viewModel The [ChannelListViewModel] to bind action handlers to. + * @param onViewInfoAction Handler invoked when the user selects the "View Info" action. + * @return The list of channel actions to display. */ -@Suppress("LongMethod") +@Suppress("LongMethod", "LongParameterList") @Composable -public fun buildDefaultChannelOptionsState( +public fun buildDefaultChannelActions( selectedChannel: Channel, isMuted: Boolean, ownCapabilities: Set, -): List { + viewModel: ChannelListViewModel, + onViewInfoAction: (Channel) -> Unit, +): List { val canLeaveChannel = ownCapabilities.contains(ChannelCapabilities.LEAVE_CHANNEL) val canDeleteChannel = ownCapabilities.contains(ChannelCapabilities.DELETE_CHANNEL) val canMuteChannel = ownCapabilities.contains(ChannelCapabilities.MUTE_CHANNEL) val optionVisibility = ChatTheme.channelOptionsTheme.optionVisibility + val channelName = ChatTheme.channelNameFormatter.formatChannelName( + selectedChannel, + viewModel.user.value, + ) return listOfNotNull( if (optionVisibility.isViewInfoVisible) { - ChannelOptionState( - title = stringResource(id = R.string.stream_compose_selected_channel_menu_view_info), - titleColor = ChatTheme.colors.textPrimary, // was textHighEmphasis - iconPainter = painterResource(id = R.drawable.stream_compose_ic_person), - iconColor = ChatTheme.colors.textSecondary, // was textLowEmphasis - action = ViewInfo(selectedChannel), + ViewInfo( + channel = selectedChannel, + label = stringResource(id = R.string.stream_compose_selected_channel_menu_view_info), + onAction = { onViewInfoAction(selectedChannel) }, ) } else { null }, if (optionVisibility.isLeaveChannelVisible && canLeaveChannel) { - ChannelOptionState( - title = stringResource(id = R.string.stream_compose_selected_channel_menu_leave_group), - titleColor = ChatTheme.colors.textPrimary, // was textHighEmphasis - iconPainter = painterResource(id = R.drawable.stream_compose_ic_person_remove), - iconColor = ChatTheme.colors.textSecondary, // was textLowEmphasis - action = LeaveGroup(selectedChannel), + LeaveGroup( + channel = selectedChannel, + label = stringResource(id = R.string.stream_compose_selected_channel_menu_leave_group), + onAction = { viewModel.leaveGroup(selectedChannel) }, + confirmationPopup = ConfirmationPopup( + title = stringResource( + id = R.string.stream_compose_selected_channel_menu_leave_group_confirmation_title, + ), + message = stringResource( + id = R.string.stream_compose_selected_channel_menu_leave_group_confirmation_message, + channelName, + ), + confirmButtonText = stringResource( + id = R.string.stream_compose_selected_channel_menu_leave_group, + ), + ), ) } else { null }, - buildMuteOption( + buildMuteAction( canMuteChannel = optionVisibility.isMuteChannelVisible && canMuteChannel, isMuted = isMuted, selectedChannel = selectedChannel, + viewModel = viewModel, ), - buildPinOption( + buildPinAction( canPinChannel = optionVisibility.isPinChannelVisible, selectedChannel = selectedChannel, + viewModel = viewModel, ), - buildArchiveOption( + buildArchiveAction( canArchiveChannel = optionVisibility.isArchiveChannelVisible, selectedChannel = selectedChannel, + viewModel = viewModel, ), if (optionVisibility.isDeleteChannelVisible && canDeleteChannel) { - ChannelOptionState( - title = stringResource(id = R.string.stream_compose_selected_channel_menu_delete_conversation), - titleColor = ChatTheme.colors.errorAccent, - iconPainter = painterResource(id = R.drawable.stream_compose_ic_delete), - iconColor = ChatTheme.colors.errorAccent, - action = DeleteConversation(selectedChannel), + DeleteConversation( + channel = selectedChannel, + label = stringResource( + id = R.string.stream_compose_selected_channel_menu_delete_conversation, + ), + onAction = { viewModel.deleteConversation(selectedChannel) }, + confirmationPopup = ConfirmationPopup( + title = stringResource( + id = R.string + .stream_compose_selected_channel_menu_delete_conversation_confirmation_title, + ), + message = stringResource( + id = R.string + .stream_compose_selected_channel_menu_delete_conversation_confirmation_message, + channelName, + ), + confirmButtonText = stringResource( + id = R.string.stream_compose_selected_channel_menu_delete_conversation, + ), + ), ) } else { null }, - ChannelOptionState( - title = stringResource(id = R.string.stream_compose_selected_channel_menu_dismiss), - titleColor = ChatTheme.colors.textPrimary, // was textHighEmphasis - iconPainter = painterResource(id = R.drawable.stream_compose_ic_clear), - iconColor = ChatTheme.colors.textSecondary, // was textLowEmphasis - action = Cancel, - ), ) } /** - * Builds the pin option for the channel, based on the current state. - * - * @param canPinChannel If the user can pin the channel. - * @param selectedChannel The currently selected channel. + * Builds the pin action for the channel, based on the current state. */ @Composable -private fun buildPinOption( +private fun buildPinAction( canPinChannel: Boolean, selectedChannel: Channel, -) = when (selectedChannel.isPinned().takeIf { canPinChannel }) { - false -> Triple( - R.string.stream_compose_selected_channel_menu_pin_channel, - R.drawable.stream_compose_ic_pin, - PinChannel(selectedChannel), + viewModel: ChannelListViewModel, +): ChannelAction? = when (selectedChannel.isPinned().takeIf { canPinChannel }) { + false -> PinChannel( + channel = selectedChannel, + label = stringResource(id = R.string.stream_compose_selected_channel_menu_pin_channel), + onAction = { viewModel.pinChannel(selectedChannel) }, ) - true -> Triple( - R.string.stream_compose_selected_channel_menu_unpin_channel, - R.drawable.stream_compose_ic_unpin, - UnpinChannel(selectedChannel), + true -> UnpinChannel( + channel = selectedChannel, + label = stringResource(id = R.string.stream_compose_selected_channel_menu_unpin_channel), + onAction = { viewModel.unpinChannel(selectedChannel) }, ) null -> null -}?.let { - ChannelOptionState( - title = stringResource(id = it.first), - titleColor = ChatTheme.colors.textPrimary, // was textHighEmphasis - iconPainter = painterResource(id = it.second), - iconColor = ChatTheme.colors.textSecondary, // was textLowEmphasis - action = it.third, - ) } /** - * Builds the archive option for the channel, based on the current state. - * - * @param canArchiveChannel If the user can archive the channel. - * @param selectedChannel The currently selected channel. + * Builds the archive action for the channel, based on the current state. */ @Composable -private fun buildArchiveOption( +private fun buildArchiveAction( canArchiveChannel: Boolean, selectedChannel: Channel, -) = when (selectedChannel.isArchive().takeIf { canArchiveChannel }) { - false -> Triple( - R.string.stream_compose_selected_channel_menu_archive_channel, - R.drawable.stream_compose_ic_archive, - ArchiveChannel(selectedChannel), + viewModel: ChannelListViewModel, +): ChannelAction? = when (selectedChannel.isArchive().takeIf { canArchiveChannel }) { + false -> ArchiveChannel( + channel = selectedChannel, + label = stringResource(id = R.string.stream_compose_selected_channel_menu_archive_channel), + onAction = { viewModel.archiveChannel(selectedChannel) }, ) - true -> Triple( - R.string.stream_compose_selected_channel_menu_unarchive_channel, - R.drawable.stream_compose_ic_unarchive, - UnarchiveChannel(selectedChannel), + true -> UnarchiveChannel( + channel = selectedChannel, + label = stringResource(id = R.string.stream_compose_selected_channel_menu_unarchive_channel), + onAction = { viewModel.unarchiveChannel(selectedChannel) }, ) null -> null -}?.let { - ChannelOptionState( - title = stringResource(id = it.first), - titleColor = ChatTheme.colors.textPrimary, // was textHighEmphasis - iconPainter = painterResource(id = it.second), - iconColor = ChatTheme.colors.textSecondary, // was textLowEmphasis - action = it.third, - ) } @Composable -private fun buildMuteOption( +private fun buildMuteAction( canMuteChannel: Boolean, isMuted: Boolean, selectedChannel: Channel, -) = if (canMuteChannel) { - val uiData = when (isMuted) { - true -> Triple( - R.string.stream_compose_selected_channel_menu_unmute_channel, - R.drawable.stream_compose_ic_unmute, - UnmuteChannel(selectedChannel), + viewModel: ChannelListViewModel, +): ChannelAction? = if (canMuteChannel) { + when (isMuted) { + true -> UnmuteChannel( + channel = selectedChannel, + label = stringResource(id = R.string.stream_compose_selected_channel_menu_unmute_channel), + onAction = { viewModel.unmuteChannel(selectedChannel) }, ) - false -> Triple( - R.string.stream_compose_selected_channel_menu_mute_channel, - R.drawable.stream_compose_ic_mute, - MuteChannel(selectedChannel), + false -> MuteChannel( + channel = selectedChannel, + label = stringResource(id = R.string.stream_compose_selected_channel_menu_mute_channel), + onAction = { viewModel.muteChannel(selectedChannel) }, ) } - - ChannelOptionState( - title = stringResource(id = uiData.first), - titleColor = ChatTheme.colors.textPrimary, // was textHighEmphasis - iconPainter = painterResource(id = uiData.second), - iconColor = ChatTheme.colors.textSecondary, // was textLowEmphasis - action = uiData.third, - ) } else { null } +/** + * Checks if the given channel is a 1-on-1 conversation. + */ +private fun Channel.isOneToOne(currentUser: io.getstream.chat.android.models.User?): Boolean { + return members.size == 2 && members.any { it.user.id == currentUser?.id } +} + /** * Preview of [ChannelOptions]. * @@ -266,11 +271,24 @@ private fun buildMuteOption( @Composable private fun ChannelOptionsPreview() { ChatTheme { + val channel = PreviewChannelData.channelWithMessages ChannelOptions( - options = buildDefaultChannelOptionsState( - selectedChannel = PreviewChannelData.channelWithMessages, - isMuted = false, - ownCapabilities = ChannelCapabilities.toSet(), + actions = listOf( + ViewInfo( + channel = channel, + label = "Channel Info", + onAction = {}, + ), + MuteChannel( + channel = channel, + label = "Mute Channel", + onAction = {}, + ), + DeleteConversation( + channel = channel, + label = "Delete Conversation", + onAction = {}, + ), ), onChannelOptionClick = {}, ) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt index 3e9717e7b37..91fdabb0bbf 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt @@ -72,7 +72,6 @@ import androidx.core.net.toUri import io.getstream.chat.android.client.ChatClient import io.getstream.chat.android.client.extensions.getCreatedAtOrThrow import io.getstream.chat.android.compose.R -import io.getstream.chat.android.compose.state.channels.list.ChannelOptionState import io.getstream.chat.android.compose.state.channels.list.ItemState import io.getstream.chat.android.compose.state.mediagallerypreview.MediaGalleryPreviewResult import io.getstream.chat.android.compose.state.messageoptions.MessageOptionItemState @@ -2098,25 +2097,25 @@ public interface ChatComponentFactory { * * @param modifier The modifier for the menu. * @param selectedChannel The selected channel. - * @param isMuted Whether the channel is muted. * @param currentUser The current user. - * @param onChannelOptionClick Callback for when a channel option is clicked. + * @param channelActions The list of channel actions to show in the menu. + * @param onChannelOptionClick Callback for when a channel action is clicked. * @param onDismiss Callback for when the menu is dismissed. */ @Composable public fun ChannelMenu( modifier: Modifier, selectedChannel: Channel, - isMuted: Boolean, currentUser: User?, + channelActions: List, onChannelOptionClick: (ChannelAction) -> Unit, onDismiss: () -> Unit, ) { SelectedChannelMenu( modifier = modifier, selectedChannel = selectedChannel, - isMuted = isMuted, currentUser = currentUser, + channelActions = channelActions, onChannelOptionClick = onChannelOptionClick, onDismiss = onDismiss, ) @@ -2143,17 +2142,17 @@ public interface ChatComponentFactory { /** * Factory method for creating the center content of the SelectedChannelMenu. * - * @param onChannelOptionClick Callback for when a channel option is clicked. - * @param channelOptions List of channel options. + * @param onChannelOptionClick Callback for when a channel action is clicked. + * @param channelActions List of channel actions. */ @Composable public fun ChannelMenuCenterContent( modifier: Modifier, onChannelOptionClick: (ChannelAction) -> Unit, - channelOptions: List, + channelActions: List, ) { ChannelMenuOptions( - channelOptions = channelOptions, + channelActions = channelActions, onChannelOptionClick = onChannelOptionClick, modifier = modifier, ) @@ -2162,42 +2161,49 @@ public interface ChatComponentFactory { /** * Factory method for creating the options content of the SelectedChannelMenu. * - * @param onChannelOptionClick Callback for when a channel option is clicked. - * @param channelOptions List of channel options. + * @param onChannelOptionClick Callback for when a channel action is clicked. + * @param channelActions List of channel actions. */ @Composable public fun ChannelMenuOptions( modifier: Modifier, onChannelOptionClick: (ChannelAction) -> Unit, - channelOptions: List, + channelActions: List, ) { ChannelOptions( - options = channelOptions, + actions = channelActions, onChannelOptionClick = onChannelOptionClick, modifier = modifier, ) } /** - * Factory method for creating the footer content of the SelectedChannelMenu. + * Factory method for creating a single channel option item. * - * @param modifier The modifier for the footer. + * @param modifier The modifier for the item. + * @param action The channel action to render. + * @param onClick Callback for when the item is clicked. */ @Composable public fun ChannelOptionsItem( modifier: Modifier, - option: ChannelOptionState, + action: ChannelAction, onClick: () -> Unit, ) { + val titleColor = if (action.isDestructive) { + ChatTheme.colors.errorAccent + } else { + ChatTheme.colors.textPrimary + } MenuOptionItem( modifier = modifier, - title = option.title, - titleColor = option.titleColor, + title = action.label, + titleColor = titleColor, leadingIcon = { - ChannelOptionsItemLeadingIcon(Modifier, option) + ChannelOptionsItemLeadingIcon(Modifier, action) }, onClick = onClick, - style = ChatTheme.typography.bodyDefault, // was bodyBold (14sp/W500); Figma: body/default (16sp/Regular) + style = ChatTheme.typography.bodyDefault, itemHeight = 56.dp, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start, @@ -2207,16 +2213,21 @@ public interface ChatComponentFactory { /** * Factory method for creating the leading icon of the Channel options menu item. * - * @param option The channel option state. + * @param action The channel action. */ @Composable - public fun ChannelOptionsItemLeadingIcon(modifier: Modifier, option: ChannelOptionState) { + public fun ChannelOptionsItemLeadingIcon(modifier: Modifier, action: ChannelAction) { + val iconColor = if (action.isDestructive) { + ChatTheme.colors.errorAccent + } else { + ChatTheme.colors.textSecondary + } Icon( modifier = modifier .size(56.dp) .padding(16.dp), - painter = option.iconPainter, - tint = option.iconColor, + painter = painterResource(id = action.icon), + tint = iconColor, contentDescription = null, ) } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel.kt index 2e7565db871..bd856c58c0d 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModel.kt @@ -50,7 +50,6 @@ import io.getstream.chat.android.models.TypingEvent import io.getstream.chat.android.models.User import io.getstream.chat.android.models.querysort.QuerySortByField import io.getstream.chat.android.models.querysort.QuerySorter -import io.getstream.chat.android.ui.common.state.channels.actions.Cancel import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction import io.getstream.chat.android.ui.common.utils.extensions.defaultChannelListFilter import io.getstream.log.taggedLogger @@ -619,25 +618,29 @@ public class ChannelListViewModel( } /** - * Clears the active action if we've chosen [Cancel], otherwise, stores the selected action as - * the currently active action, in [activeChannelAction]. + * Executes the given [ChannelAction] immediately if it doesn't require confirmation, + * or stores it as [activeChannelAction] to show a confirmation dialog. * - * It also removes the [selectedChannel] if the action is [Cancel]. - * - * @param channelAction The selected action. + * @param action The action to execute or confirm. */ - public fun performChannelAction(channelAction: ChannelAction) { - if (channelAction is Cancel) { - selectedChannel.value = null - } - - activeChannelAction = if (channelAction == Cancel) { - null + public fun executeOrConfirm(action: ChannelAction) { + if (action.confirmationPopup != null) { + activeChannelAction = action } else { - channelAction + action.onAction() + dismissChannelAction() } } + /** + * Executes the currently pending [activeChannelAction] after user confirmation + * and dismisses it from the UI. + */ + public fun confirmPendingAction() { + activeChannelAction?.onAction?.invoke() + dismissChannelAction() + } + /** * Mutes a channel. * diff --git a/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/channels/SelectedChannelMenuTest.kt b/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/channels/SelectedChannelMenuTest.kt index 9d7a2bb067f..4bc7a3b2dd9 100644 --- a/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/channels/SelectedChannelMenuTest.kt +++ b/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/channels/SelectedChannelMenuTest.kt @@ -28,6 +28,7 @@ import io.getstream.chat.android.compose.util.extensions.toSet import io.getstream.chat.android.models.ChannelCapabilities import io.getstream.chat.android.previewdata.PreviewChannelData import io.getstream.chat.android.previewdata.PreviewUserData +import io.getstream.chat.android.ui.common.state.channels.actions.ViewInfo import org.junit.Rule import org.junit.Test @@ -39,14 +40,17 @@ internal class SelectedChannelMenuTest : PaparazziComposeTest { @Test fun `selected channel`() { snapshot { + val channel = PreviewChannelData.channelWithManyMembers.copy( + ownCapabilities = ChannelCapabilities.toSet(), + ) Box(modifier = Modifier.fillMaxSize()) { SelectedChannelMenu( modifier = Modifier.align(Alignment.BottomCenter), - selectedChannel = PreviewChannelData.channelWithManyMembers.copy( - ownCapabilities = ChannelCapabilities.toSet(), - ), - isMuted = false, + selectedChannel = channel, currentUser = PreviewUserData.user1, + channelActions = listOf( + ViewInfo(channel = channel, label = "Channel Info", onAction = {}), + ), onChannelOptionClick = {}, onDismiss = {}, ) @@ -57,14 +61,17 @@ internal class SelectedChannelMenuTest : PaparazziComposeTest { @Test fun `selected channel in dark mode`() { snapshot(isInDarkMode = true) { + val channel = PreviewChannelData.channelWithManyMembers.copy( + ownCapabilities = ChannelCapabilities.toSet(), + ) Box(modifier = Modifier.fillMaxSize()) { SelectedChannelMenu( modifier = Modifier.align(Alignment.BottomCenter), - selectedChannel = PreviewChannelData.channelWithManyMembers.copy( - ownCapabilities = ChannelCapabilities.toSet(), - ), - isMuted = false, + selectedChannel = channel, currentUser = PreviewUserData.user1, + channelActions = listOf( + ViewInfo(channel = channel, label = "Channel Info", onAction = {}), + ), onChannelOptionClick = {}, onDismiss = {}, ) diff --git a/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModelTest.kt b/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModelTest.kt index faf5b675528..cb9e9161359 100644 --- a/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModelTest.kt +++ b/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channels/ChannelListViewModelTest.kt @@ -115,8 +115,13 @@ internal class ChannelListViewModelTest { .get(this) viewModel.selectChannel(channel1) - viewModel.performChannelAction(DeleteConversation(channel1)) - viewModel.deleteConversation(channel1) + viewModel.executeOrConfirm( + DeleteConversation( + channel = channel1, + label = "Delete", + onAction = { viewModel.deleteConversation(channel1) }, + ), + ) viewModel.activeChannelAction `should be equal to` null viewModel.selectedChannel.value `should be equal to` null diff --git a/stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/channels/SelectedChannelMenu.kt b/stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/channels/SelectedChannelMenu.kt index a21525bb861..76569a505aa 100644 --- a/stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/channels/SelectedChannelMenu.kt +++ b/stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/channels/SelectedChannelMenu.kt @@ -18,10 +18,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import io.getstream.chat.android.compose.ui.channels.info.SelectedChannelMenu +import io.getstream.chat.android.compose.ui.components.channels.buildDefaultChannelActions import io.getstream.chat.android.compose.ui.theme.ChatTheme import io.getstream.chat.android.compose.viewmodel.channels.ChannelListViewModel import io.getstream.chat.android.compose.viewmodel.channels.ChannelViewModelFactory -import io.getstream.chat.android.ui.common.state.channels.actions.ViewInfo /** * [Usage](https://getstream.io/chat/docs/sdk/android/compose/channel-components/selected-channel-menu/#usage) @@ -44,7 +44,13 @@ private object SelectedChannelMenuUsageSnippet { // The rest of your UI if (currentlySelectedChannel != null) { - val isMuted = listViewModel.isChannelMuted(currentlySelectedChannel.cid) + val channelActions = buildDefaultChannelActions( + selectedChannel = currentlySelectedChannel, + isMuted = listViewModel.isChannelMuted(currentlySelectedChannel.cid), + ownCapabilities = currentlySelectedChannel.ownCapabilities, + viewModel = listViewModel, + onViewInfoAction = {}, + ) SelectedChannelMenu( modifier = Modifier @@ -52,9 +58,9 @@ private object SelectedChannelMenuUsageSnippet { .wrapContentHeight() // Wrap height .align(Alignment.BottomCenter), // Aligning the content to the bottom selectedChannel = currentlySelectedChannel, - isMuted = isMuted, currentUser = user, - onChannelOptionClick = { listViewModel.performChannelAction(it) }, + channelActions = channelActions, + onChannelOptionClick = { listViewModel.executeOrConfirm(it) }, onDismiss = { listViewModel.dismissChannelAction() } ) } @@ -86,7 +92,15 @@ private object SelectedChannelMenuHandlingActionsSnippet { // The rest of your UI if (currentlySelectedChannel != null) { - val isMuted = listViewModel.isChannelMuted(currentlySelectedChannel.cid) + val channelActions = buildDefaultChannelActions( + selectedChannel = currentlySelectedChannel, + isMuted = listViewModel.isChannelMuted(currentlySelectedChannel.cid), + ownCapabilities = currentlySelectedChannel.ownCapabilities, + viewModel = listViewModel, + onViewInfoAction = { channel -> + // Start the channel info screen + }, + ) SelectedChannelMenu( modifier = Modifier @@ -94,14 +108,10 @@ private object SelectedChannelMenuHandlingActionsSnippet { .wrapContentHeight() // Wrap height .align(Alignment.BottomCenter), // Aligning the content to the bottom selectedChannel = currentlySelectedChannel, - isMuted = isMuted, currentUser = user, + channelActions = channelActions, onChannelOptionClick = { action -> - if (action is ViewInfo) { - // Start the channel info screen - } else { - listViewModel.performChannelAction(action) - } + listViewModel.executeOrConfirm(action) }, onDismiss = { listViewModel.dismissChannelAction() } ) @@ -134,7 +144,13 @@ private object SelectedChannelMenuCustomizationSnippet { // The rest of your UI if (currentlySelectedChannel != null) { - val isMuted = listViewModel.isChannelMuted(currentlySelectedChannel.cid) + val channelActions = buildDefaultChannelActions( + selectedChannel = currentlySelectedChannel, + isMuted = listViewModel.isChannelMuted(currentlySelectedChannel.cid), + ownCapabilities = currentlySelectedChannel.ownCapabilities, + viewModel = listViewModel, + onViewInfoAction = {}, + ) SelectedChannelMenu( modifier = Modifier @@ -144,9 +160,9 @@ private object SelectedChannelMenuCustomizationSnippet { .align(Alignment.Center), // Centering the component shape = RoundedCornerShape(16.dp), // Rounded corners for all sides selectedChannel = currentlySelectedChannel, - isMuted = isMuted, currentUser = user, - onChannelOptionClick = { listViewModel.performChannelAction(it) }, + channelActions = channelActions, + onChannelOptionClick = { listViewModel.executeOrConfirm(it) }, onDismiss = { listViewModel.dismissChannelAction() } ) } diff --git a/stream-chat-android-ui-common/api/stream-chat-android-ui-common.api b/stream-chat-android-ui-common/api/stream-chat-android-ui-common.api index f8508c9c22e..798837ef3d6 100644 --- a/stream-chat-android-ui-common/api/stream-chat-android-ui-common.api +++ b/stream-chat-android-ui-common/api/stream-chat-android-ui-common.api @@ -1630,122 +1630,144 @@ public final class io/getstream/chat/android/ui/common/state/channel/info/Channe public final class io/getstream/chat/android/ui/common/state/channels/actions/ArchiveChannel : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/ArchiveChannel; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/ArchiveChannel;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/ArchiveChannel; - public fun equals (Ljava/lang/Object;)Z + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z } -public final class io/getstream/chat/android/ui/common/state/channels/actions/Cancel : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { - public static final field $stable I - public static final field INSTANCE Lio/getstream/chat/android/ui/common/state/channels/actions/Cancel; - public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun toString ()Ljava/lang/String; +public abstract interface class io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { + public abstract fun getChannel ()Lio/getstream/chat/android/models/Channel; + public abstract fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public abstract fun getIcon ()I + public abstract fun getLabel ()Ljava/lang/String; + public abstract fun getOnAction ()Lkotlin/jvm/functions/Function0; + public abstract fun getRequiredCapability ()Ljava/lang/String; + public abstract fun isDestructive ()Z } -public abstract class io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { - public static final field $stable I - public abstract fun getChannel ()Lio/getstream/chat/android/models/Channel; +public final class io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction$DefaultImpls { + public static fun getConfirmationPopup (Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;)Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public static fun getRequiredCapability (Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;)Ljava/lang/String; + public static fun isDestructive (Lio/getstream/chat/android/ui/common/state/channels/actions/ChannelAction;)Z } -public final class io/getstream/chat/android/ui/common/state/channels/actions/DeleteConversation : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { +public final class io/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/DeleteConversation; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/DeleteConversation;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/DeleteConversation; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; public fun equals (Ljava/lang/Object;)Z - public fun getChannel ()Lio/getstream/chat/android/models/Channel; + public final fun getConfirmButtonText ()Ljava/lang/String; + public final fun getMessage ()Ljava/lang/String; + public final fun getTitle ()Ljava/lang/String; public fun hashCode ()I public fun toString ()Ljava/lang/String; } +public final class io/getstream/chat/android/ui/common/state/channels/actions/DeleteConversation : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { + public static final field $stable I + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup;)V + public synthetic fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getChannel ()Lio/getstream/chat/android/models/Channel; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z +} + public final class io/getstream/chat/android/ui/common/state/channels/actions/LeaveGroup : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/LeaveGroup; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/LeaveGroup;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/LeaveGroup; - public fun equals (Ljava/lang/Object;)Z + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup;)V + public synthetic fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z } public final class io/getstream/chat/android/ui/common/state/channels/actions/MuteChannel : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/MuteChannel; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/MuteChannel;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/MuteChannel; - public fun equals (Ljava/lang/Object;)Z + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z } public final class io/getstream/chat/android/ui/common/state/channels/actions/PinChannel : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/PinChannel; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/PinChannel;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/PinChannel; - public fun equals (Ljava/lang/Object;)Z + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z } public final class io/getstream/chat/android/ui/common/state/channels/actions/UnarchiveChannel : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/UnarchiveChannel; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/UnarchiveChannel;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/UnarchiveChannel; - public fun equals (Ljava/lang/Object;)Z + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z } public final class io/getstream/chat/android/ui/common/state/channels/actions/UnmuteChannel : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/UnmuteChannel; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/UnmuteChannel;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/UnmuteChannel; - public fun equals (Ljava/lang/Object;)Z + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z } public final class io/getstream/chat/android/ui/common/state/channels/actions/UnpinChannel : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/UnpinChannel; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/UnpinChannel;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/UnpinChannel; - public fun equals (Ljava/lang/Object;)Z + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z } public final class io/getstream/chat/android/ui/common/state/channels/actions/ViewInfo : io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction { public static final field $stable I - public fun (Lio/getstream/chat/android/models/Channel;)V - public final fun component1 ()Lio/getstream/chat/android/models/Channel; - public final fun copy (Lio/getstream/chat/android/models/Channel;)Lio/getstream/chat/android/ui/common/state/channels/actions/ViewInfo; - public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/channels/actions/ViewInfo;Lio/getstream/chat/android/models/Channel;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/channels/actions/ViewInfo; - public fun equals (Ljava/lang/Object;)Z + public fun (Lio/getstream/chat/android/models/Channel;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V public fun getChannel ()Lio/getstream/chat/android/models/Channel; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; + public fun getConfirmationPopup ()Lio/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup; + public fun getIcon ()I + public fun getLabel ()Ljava/lang/String; + public fun getOnAction ()Lkotlin/jvm/functions/Function0; + public fun getRequiredCapability ()Ljava/lang/String; + public fun isDestructive ()Z } public abstract interface class io/getstream/chat/android/ui/common/state/mentions/MentionListEvent { diff --git a/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction.kt b/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction.kt index 57dec15ace8..476e9efd4a4 100644 --- a/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction.kt +++ b/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction.kt @@ -16,66 +16,146 @@ package io.getstream.chat.android.ui.common.state.channels.actions +import androidx.annotation.DrawableRes import io.getstream.chat.android.models.Channel +import io.getstream.chat.android.models.ChannelCapabilities +import io.getstream.chat.android.ui.common.R /** - * Represents the list of actions users can take with selected channels. + * A self-describing channel action that carries display info, capability requirements, and an + * execution handler. Works for swipe actions, options menus, and any future action surface. * - * @property channel The selected channel. + * @property channel The channel this action targets. + * @property icon Drawable resource for the action icon. + * @property label Human-readable label for the action. + * @property requiredCapability Optional channel capability required to show this action. + * @property confirmationPopup Optional confirmation dialog to show before executing. + * @property isDestructive Whether this action is destructive (e.g. delete). + * @property onAction The handler to execute when the action is confirmed. */ -public sealed class ChannelAction { - public abstract val channel: Channel +public interface ChannelAction { + public val channel: Channel + + @get:DrawableRes + public val icon: Int + public val label: String + public val requiredCapability: String? get() = null + public val confirmationPopup: ConfirmationPopup? get() = null + public val isDestructive: Boolean get() = false + public val onAction: () -> Unit } /** * Show more info about the channel. */ -public data class ViewInfo(override val channel: Channel) : ChannelAction() - -/** - * Shows a dialog to leave the group. - */ -public data class LeaveGroup(override val channel: Channel) : ChannelAction() +public class ViewInfo( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_view_info +} /** - * Mutes the channel. + * Leave the group channel. */ -public data class MuteChannel(override val channel: Channel) : ChannelAction() +public class LeaveGroup( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, + override val confirmationPopup: ConfirmationPopup? = null, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_leave + override val requiredCapability: String = ChannelCapabilities.LEAVE_CHANNEL +} /** - * Unmutes the channel. + * Mute the channel. */ -public data class UnmuteChannel(override val channel: Channel) : ChannelAction() +public class MuteChannel( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_mute + override val requiredCapability: String = ChannelCapabilities.MUTE_CHANNEL +} /** - * Shows a dialog to delete the conversation, if we have the permission. + * Unmute the channel. */ -public data class DeleteConversation(override val channel: Channel) : ChannelAction() +public class UnmuteChannel( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_unmute + override val requiredCapability: String = ChannelCapabilities.MUTE_CHANNEL +} /** - * Shows a dialog to pin the channel. + * Delete the conversation. */ -public data class PinChannel(override val channel: Channel) : ChannelAction() +public class DeleteConversation( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, + override val confirmationPopup: ConfirmationPopup? = null, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_delete + override val requiredCapability: String = ChannelCapabilities.DELETE_CHANNEL + override val isDestructive: Boolean = true +} /** - * Shows a dialog to unpin the channel. + * Pin the channel. */ -public data class UnpinChannel(override val channel: Channel) : ChannelAction() +public class PinChannel( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_pin +} /** - * Shows a dialog to archive the channel. + * Unpin the channel. */ -public data class ArchiveChannel(override val channel: Channel) : ChannelAction() +public class UnpinChannel( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_unpin +} /** - * Shows a dialog to unarchive the channel. + * Archive the channel. */ -public data class UnarchiveChannel(override val channel: Channel) : ChannelAction() +public class ArchiveChannel( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_archive +} /** - * Dismisses the actions. + * Unarchive the channel. */ -public object Cancel : ChannelAction() { - override val channel: Channel = Channel() - override fun toString(): String = "Cancel" +public class UnarchiveChannel( + override val channel: Channel, + override val label: String, + override val onAction: () -> Unit, +) : ChannelAction { + @DrawableRes + override val icon: Int = R.drawable.stream_ic_action_unarchive } diff --git a/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup.kt b/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup.kt new file mode 100644 index 00000000000..2a827eedd7a --- /dev/null +++ b/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ConfirmationPopup.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014-2026 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.ui.common.state.channels.actions + +/** + * Represents a confirmation popup that should be shown before executing a [ChannelAction]. + * + * @property title The title of the confirmation dialog. + * @property message The message body of the confirmation dialog. + * @property confirmButtonText The text for the positive/confirm button. + */ +public data class ConfirmationPopup( + val title: String, + val message: String, + val confirmButtonText: String, +) diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_archive.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_archive.xml new file mode 100644 index 00000000000..cec4155be38 --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_archive.xml @@ -0,0 +1,26 @@ + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_delete.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_delete.xml new file mode 100644 index 00000000000..8206790e59f --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_delete.xml @@ -0,0 +1,26 @@ + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_leave.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_leave.xml new file mode 100644 index 00000000000..6da43ae63fc --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_leave.xml @@ -0,0 +1,35 @@ + + + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_more.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_more.xml new file mode 100644 index 00000000000..eb37dd78b04 --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_more.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml new file mode 100644 index 00000000000..ccb20f4a864 --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_pin.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_pin.xml new file mode 100644 index 00000000000..52d2e19fd43 --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_pin.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unarchive.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unarchive.xml new file mode 100644 index 00000000000..6fc54afb332 --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unarchive.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml new file mode 100644 index 00000000000..d90f8a706ee --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unpin.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unpin.xml new file mode 100644 index 00000000000..4b0b05d6be0 --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unpin.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_view_info.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_view_info.xml new file mode 100644 index 00000000000..8f5c15502d5 --- /dev/null +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_view_info.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelActionsDialogFragment.kt b/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelActionsDialogFragment.kt index 5e228599df4..b4a66ace000 100644 --- a/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelActionsDialogFragment.kt +++ b/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelActionsDialogFragment.kt @@ -34,6 +34,7 @@ import io.getstream.chat.android.ui.common.utils.extensions.isDirectMessaging import io.getstream.chat.android.ui.databinding.StreamUiFragmentChannelActionsBinding import io.getstream.chat.android.ui.feature.channels.actions.ChannelActionsDialogViewStyle import io.getstream.chat.android.ui.font.setTextStyle +import io.getstream.chat.android.ui.utils.extensions.getDrawableCompat import io.getstream.chat.android.ui.utils.extensions.getMembersStatusText import io.getstream.chat.android.ui.utils.extensions.isCurrentUser import io.getstream.chat.android.ui.utils.extensions.setStartDrawable @@ -155,20 +156,22 @@ internal class ChannelActionsDialogFragment : BottomSheetDialogFragment() { selectedChannel = channel, ownCapabilities = channel.ownCapabilities, style = style, - ).forEach { option -> + ).forEach { action -> val channelOptionTextView = requireContext().streamThemeInflater.inflate( R.layout.stream_ui_channel_option_item, binding.optionsContainer, false, ) as TextView - channelOptionTextView.text = option.optionText - channelOptionTextView.setStartDrawable(option.optionIcon) + channelOptionTextView.text = action.label + channelOptionTextView.setStartDrawable( + requireContext().getDrawableCompat(action.icon)!!, + ) channelOptionTextView.setOnClickListener { - channelOptionClickListener?.onChannelOptionClick(option.channelAction) + channelOptionClickListener?.onChannelOptionClick(action) dismiss() } channelOptionTextView.setTextStyle( - if (option.isWarningItem) { + if (action.isDestructive) { style.warningItemTextStyle } else { style.itemTextStyle diff --git a/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelOptionItem.kt b/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelOptionItem.kt deleted file mode 100644 index efff4edddea..00000000000 --- a/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelOptionItem.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2014-2026 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.ui.feature.channels.actions.internal - -import android.graphics.drawable.Drawable -import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction - -/** - * UI representation of a Channel option, when the user selects a channel in the list. - * - * @param optionText The text of the option item. - * @param optionIcon The icon of the option item. - * @param channelAction The [ChannelAction] the option represents. - * @param isWarningItem If the option item is dangerous. - */ -internal data class ChannelOptionItem( - val optionIcon: Drawable, - val optionText: String, - val channelAction: ChannelAction, - val isWarningItem: Boolean = false, -) diff --git a/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelOptionItemsFactory.kt b/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelOptionItemsFactory.kt index 639f28156e1..f92f2b84f00 100644 --- a/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelOptionItemsFactory.kt +++ b/stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/channels/actions/internal/ChannelOptionItemsFactory.kt @@ -20,31 +20,30 @@ import android.content.Context import io.getstream.chat.android.models.Channel import io.getstream.chat.android.models.ChannelCapabilities import io.getstream.chat.android.ui.R -import io.getstream.chat.android.ui.common.state.channels.actions.Cancel +import io.getstream.chat.android.ui.common.state.channels.actions.ChannelAction import io.getstream.chat.android.ui.common.state.channels.actions.DeleteConversation import io.getstream.chat.android.ui.common.state.channels.actions.LeaveGroup import io.getstream.chat.android.ui.common.state.channels.actions.ViewInfo import io.getstream.chat.android.ui.feature.channels.actions.ChannelActionsDialogViewStyle -import io.getstream.chat.android.ui.utils.extensions.getDrawableCompat /** - * An interface that allows the creation of channel option items. + * An interface that allows the creation of channel action items. */ internal interface ChannelOptionItemsFactory { /** - * Creates [ChannelOptionItem]s for the selected channel. + * Creates [ChannelAction]s for the selected channel. * * @param selectedChannel The currently selected channel. * @param ownCapabilities Set of capabilities the user is given for the current channel. * @param style The style of the dialog. - * @return The list of channel option items to display. + * @return The list of channel actions to display. */ fun createChannelOptionItems( selectedChannel: Channel, ownCapabilities: Set, style: ChannelActionsDialogViewStyle, - ): List + ): List companion object { /** @@ -68,55 +67,49 @@ internal open class DefaultChannelOptionItemsFactory( ) : ChannelOptionItemsFactory { /** - * Creates [ChannelOptionItem]s for the selected channel. + * Creates [ChannelAction]s for the selected channel. + * + * [ChannelAction.onAction] is left empty because the XML module dispatches + * actions through [ChannelActionsDialogFragment.ChannelOptionClickListener], + * not through the action's own handler. * * @param selectedChannel The currently selected channel. * @param ownCapabilities Set of capabilities the user is given for the current channel. * @param style The style of the dialog. - * @return The list of channel option items to display. + * @return The list of channel actions to display. */ override fun createChannelOptionItems( selectedChannel: Channel, ownCapabilities: Set, style: ChannelActionsDialogViewStyle, - ): List { + ): List { val canLeaveChannel = ownCapabilities.contains(ChannelCapabilities.LEAVE_CHANNEL) val canDeleteChannel = ownCapabilities.contains(ChannelCapabilities.DELETE_CHANNEL) return listOfNotNull( if (style.viewInfoEnabled) { - ChannelOptionItem( - optionText = context.getString(R.string.stream_ui_channel_list_view_info), - optionIcon = context.getDrawableCompat(R.drawable.stream_ui_ic_single_user)!!, - channelAction = ViewInfo(selectedChannel), + ViewInfo( + channel = selectedChannel, + label = context.getString(R.string.stream_ui_channel_list_view_info), + onAction = {}, ) } else { null }, if (style.leaveGroupEnabled && canLeaveChannel) { - ChannelOptionItem( - optionText = context.getString(R.string.stream_ui_channel_list_leave_channel), - optionIcon = context.getDrawableCompat(R.drawable.stream_ui_ic_leave_group)!!, - channelAction = LeaveGroup(selectedChannel), + LeaveGroup( + channel = selectedChannel, + label = context.getString(R.string.stream_ui_channel_list_leave_channel), + onAction = {}, ) } else { null }, if (style.deleteConversationEnabled && canDeleteChannel) { - ChannelOptionItem( - optionText = context.getString(R.string.stream_ui_channel_list_delete_channel), - optionIcon = context.getDrawableCompat(R.drawable.stream_ui_ic_delete)!!, - channelAction = DeleteConversation(selectedChannel), - isWarningItem = true, - ) - } else { - null - }, - if (style.cancelEnabled) { - ChannelOptionItem( - optionText = context.getString(R.string.stream_ui_channel_list_dismiss_dialog), - optionIcon = context.getDrawableCompat(R.drawable.stream_ui_ic_clear)!!, - channelAction = Cancel, + DeleteConversation( + channel = selectedChannel, + label = context.getString(R.string.stream_ui_channel_list_delete_channel), + onAction = {}, ) } else { null From 06537cad4de7c12047b7890e1cb8ff52a35ea2a6 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 11:13:59 +0100 Subject: [PATCH 10/22] fix(compose): remove unused isOneToOne and re-record snapshots Remove dead `isOneToOne` extension (Detekt UnusedPrivateMember) and re-record ChannelItemTest Paparazzi snapshots. --- .../ui/components/channels/ChannelOptions.kt | 7 ------- ...channels_ChannelItemTest_draft_message.png | Bin 19080 -> 18982 bytes ...ItemTest_last_message_delivered_status.png | Bin 23996 -> 23330 bytes ...elItemTest_last_message_pending_status.png | Bin 24371 -> 23642 bytes ...annelItemTest_last_message_seen_status.png | Bin 24082 -> 23391 bytes ...annelItemTest_last_message_sent_status.png | Bin 23800 -> 23040 bytes ...channels_ChannelItemTest_muted_channel.png | Bin 24653 -> 22514 bytes ...ItemTest_muted_channel_trailing_bottom.png | Bin 13496 -> 12709 bytes ...i.channels_ChannelItemTest_no_messages.png | Bin 18388 -> 18279 bytes ...annels_ChannelItemTest_unread_messages.png | Bin 25318 -> 23130 bytes 10 files changed, 7 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt index c4ccde5cf8b..0e6ca3d55c5 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt @@ -255,13 +255,6 @@ private fun buildMuteAction( null } -/** - * Checks if the given channel is a 1-on-1 conversation. - */ -private fun Channel.isOneToOne(currentUser: io.getstream.chat.android.models.User?): Boolean { - return members.size == 2 && members.any { it.user.id == currentUser?.id } -} - /** * Preview of [ChannelOptions]. * diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_draft_message.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_draft_message.png index 5555c3dc6f4a8a15ce3c914baeca0b6a7f2da5a8..ef695edada2e2369063f793006031341e0dfcf49 100644 GIT binary patch literal 18982 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 literal 19080 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 zÐ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%0A&1i z!En(szj2y+o5EQ+pNK00>W?lYVaf3fBh z$8ZC5Ng&$pW8sjUh3fX{T#aTQhi@unMh9+Ql6_{T%BlRv98d*Ggg2LsryB6l7Gr|de;knkmI+r_h$nNZ?2oKo_KR_Okx)mSi^k^P z@9N;lK4JX#g8jLCrnWO!r(d1LIYr-zG0n4av|hREDk*cH?Y`qlM9%G;Z{YEPI!-F_ zN_fb34@ZspW7;1QOUYrE`47>vh>l59B$y}jstW)m3+a- z0)@rW*M~-j;)83;xn(%=71ju5UqUHj2lgIs>2)p;@jH=eH^?QgF)KMeLEt{m*x0GB z(~r^gBfua0cQ$a3W89+`|0hJ@-{{AGCNudLsrkS2gZ~y4`j3nMNAC5v#s4GsdaX71 z=->0LzfrOOw=MYpAKCm*u`uABznS#+E&Z+OpKtAdq|^VCKlrz>`&*R!_QBs5|CcJ@ z-w5WtuD@#u{vCh*f7|<;wg374^q;-GEe1fi{PvOGl_URq{P_#3#uonvFcY@tyQPQG zHJAT51$g4CeQY|1*scKrm4EpM_~AeJJJ9WaI?g};_xnejy4wyCzaO>QTaNxsW1X@a H_n-YYv@l^X diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_last_message_delivered_status.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_last_message_delivered_status.png index 8a1d374d09d7fac23359f522ec716fffb5f65e99..c22933e67a489670c0e35220a2f9ba2505736de3 100644 GIT binary patch literal 23330 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 literal 23996 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 PbY~*IKpicy@rwH^A2X?@ diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_last_message_pending_status.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_last_message_pending_status.png index 5f9f6884abf84b0882f5d3b27d7034e3768d2bea..44633ecf8cb7a6dafb50589815ef3c001a5cb734 100644 GIT binary patch literal 23642 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 E0#sjtJpcdz literal 24371 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 literal 24082 zcmeFZXIRrq*DtKwZ37jzNC_yY5u`{9Rivm$P&(2iG=WeQNQY3O z^xh#rC<0PLQK}F^&Yyjs5BGKU^PKm&uJhr2-*e6fK~`omGi%nAwbt)9!J6tym+9E( zPMtb+`T4V_FHW8M19IxrndJ-T07)~)_3TrpjK`lpeXR3lVlCx-^>xLG048M5tZ9=V z9}k`RtqY5FSX;%%T%R6%$h@m~m-Vl+r@8Xed9L-0i!X_vzj|izKF%f=hUiYr-zkbcQ-Zqo$Fpk{l-GX$Klr>y;!t@UPc_K;1hw zr5e|JA@?KvkD7302a8Fy$WenJc0h4&(Y&0a#vaB_CU8yo%dN+)R-powuMxO<2}zcd zZfi@Nv+5G4Qmw3x{?o2x+`gUBb|yu1DPs^ASJ$}~Jmt$N_^>XBKn3Oh$Krb>O2O*uYJ&0Tf? zGxR0Out+Q7PKkO`uOI0T?I`>Vfkxdd?*(eSf`{~Zkuh#{hW(`TYW_G)&+!v^t*(dQgxfKt%h zXZhlHC$5z#rht_vzdjuhY5Wb!d3?Hc(g*kyrK-*&rw9&id^JrNL1?dXxBfPy(oedR zh(=Q}y7kf`qJK9uIc8Ucc>y!;9BgJKbA^L)AAf6w1D^o(GZcyy&XkM`s&!5_vnGwo z%5e!K{uQr!wGXYtVZi-uK-_Nlb=yskWD=5ST(fcNlx7JE6=)FTEMmA`?q8F@YSER# zpdK8j#l}D1L;2OlIn@|IZ#>@`rc%fLGcV20r7KpzRn~j&e#M&tl4EU;T9QPMfH8iU zQ>8mqmLz-dBg*gnQx5f0ZzsEkQ`{$b5yo|!4HP`LT4FVIkJJ~z(d+Rwd`}B!Qa?7M zo5$hWEwV8~JFZGAASknfd<9?aUL{ZDK%{xo22^MJ*C2IcT%A8UqI?$!L=*3r-wi>R z*%z6GOxCVE`0@GL%zhxdPJ1SdHmrV*T4*fT~T&A_+ILA6=AEBf5_zRL-)1i zb60M}%d`qqP0p#y9sKBYfM;e!OJGRllWN_og1L+@V3vIIN01y__*2`kHT(vi?1Rr! zPg%7aDU8`l;uiE-Eyz3C)R3o&on<=p=+b#kpD(qmg++B{%QFN5O|rK=KRha<-|6sc zsa$)p|3l>J566ZBD|rG8+ot2`0OhiSPgFXPyc~F)Z|1MUY8Y|RetgZKe9-*0SXnk6Y~54b!Uj$bhWCt_u=N+-k1eL)wgr(&F-@6 zWqopf6g>>AW}*VIa8*4AFdl&j!_s z_DX>TYz*Hm2pCqnGLrv6o&}Vx`3wR=sSe?0X2OPSvEBF4b-Ky6%#R`^LW#P^wG4DO9I{4X>8Fb_dVz zr9^LsI#fAM84id@LPknNf?wfDEzvCr`amr8A+`pbapM9T3BpfdQ zlNlAgJ|df4&1^Z*816r27IffneJ0AGp5#QB!g&DOLhcR2u2j!O(0(UB?rwztu$B^+ z;i=vJ`!B!T;&QNPMLBQQ@0+Yu40>wB3*TPwX$JI4mY8xIibl4D-z59j9&L3+VW5HL zF*|#Iu?Sjp*!@#H{*7A-GmPDE`06NzZ2C2`{z~C~dC$0YTFPV^ zK3}JyrKRtN_gabL*SDvSbA;{SYrnm|g*o2K%GOJ+j+>)%g1c!oKCmcUAJ1tH>pnk2 zo0UtNGm3aP(}SScU9Qbmjn*IMi_K(9*qExNgc!f8b7@~n^KYnKO7%X1wB&wNLpejO zfFZcMF7+a}m-_Za#PU+T3TuBh(oZRI`u-sLZudyiuV)T@NJm=Im16Qn=`ndP6Z6p` z^S8=GymoAeU(6I}6w5f{MSpEJ%a75Oa=wSv4_p`TR?*{Prr|qDsJ@@GO;mREBngK} z!1BKn0h931=CBckNbgC`_{`%n=)&7LyzkfeSDYI^q-+uhNs>;f1QR;@(Oo+tHihzg zK7xwJ5ssy;&YcQTlK@9uY-zJ$N9^i_hIXnT6%9b4M+yF=JO6(NX(&f#U} z;gRea_etlrPHTAMZ6ayd&WLYHp+y{GPKJ47IG9tPx$25Tq$Ndf4`6RunyfE1P&T^k z;KQXEqaUa1z4PpG*x2e2neZS^KdHO{O&1zW10xTps!w)b)xZ>UPt>aW=ag1YlB5Qi z7<2H+guh~M+2=a^23Ba>oJ?K^+rfcNE;>?Q=hRsJm(kk~_1ERSu&X9z+uys^PHE~v zt*WNnx3j|3rDp$}QNHG&I2vj*+?-$ZY)Ts<$VZ+-p+?cC?WXX^2@zdxJKu^+y3*jR zMrqrts~q}fVcogNB;ARPoJ>}bVmV^!wnAVwH5Y}M@dFm=liFCwS)^f0@pw`hhSEqc z^m})>MR$z!ew4D+C1eq%>PBT2fc;+BB+&dya4{Up333?DUIz;(^z0)y_OQA^C%OiH zdm2R9og)OCb?e;QQent!evY6q{)bpk%U?=2X1iqg>E}@>&8mjjAmm$G8wA#38GR!C2faF>0aLdvgHsR-6I zpFfMx(TU)YJt}>{p{XtXP%jO(<@)C?DK->cF!~cB|HHeM?P0dB^Fx;5&AbkOzQO|D z5Oe~>QW^FLalIuJE()=GuDKr-Ta=mhz%@4lQ&MBWP$-jU z6=8vD)-WYwfIw5slK433$jKD$sR7Of>)i1kazP<~*?d-Ujs z^yP=K1!x2BKCB~fsJD03HD`EQxq#5x=&)`f!qFU2_p75IB^>B>iLh(Q0F*sPYR4!H zg*?ssNQ&g;#acdnhC$|Y6ncR4&TokQ5tgWo(T44<&HfC9R;pdQ+x7J} z7<|X0QhERiwdKGl+rpom(S)UOT?p&;+9lOEAl8ztj5n%B(rgP9s0a>whq7cYM zHuqwrC3Y^56Y+wJDhR&X@EowE5Ctud&+pylq3Q`D7jYw1Gk)Z_6$*IZ)nw!+bcx=V zWy$B)b;8l7PnIhmX*X%^c9ZbM`Xj|9zk%q#POfEa>S$glxAd5jwpzZSvNkOG@f+xh zhX96@?p7N+Vd5N0!nTIAvW7eKLP7wqwu~D^7Xs25C@*LMMUapaZSG_j>hc1bJODqPyC8K2o7hoF!~9 z{Q%*2e6aN6FykU`A-d!*SYiZpMN@nIEQ`_SYd9SP!uHuyG54UYs-ZCJ;gKvCW&ffg zc`QHggcq=9p#Lg;Yns5yPwM*47XA2(Q@w;|QjBjO$Lz$ee@jLE%0l^!+>u!gg4EzW z=iq}B-n=4S<(i^C-99yh#F!_=e}1=4Laf@ThD2-RFNif5t6_`EtsrFk!hWs!=A#VwrJkJdnQAhsOcJky!t7N|JDV zSR{F6wkqjk1KMq)X6bNOd^Ro7w1PqQr?lSh5>dcY+qv3SAG};;BbkOri#2`O!(>dc zRbmkstQ;n-OGXxOQG)L^7m<$ioZ!t}Y4=|Xc+1SHZyaQkeMWBSXSJ@TPk&%@T0iIU zGH+N_^;w%9J0&(v_(Cu_!mL1OlUwmix zr}L=?U)QTGFh7nN)Z^o8g-mNzRZ-3(2IRc*Zk^T$bvLS2suaDX^XS=tmo;zl=p3eM49VF+8|4Ymk1cL$S8;Grq1 zMVnWL@5r=mZSuWpeg{XJD6iB+(*V?2K=&PCs^z-5UOjlvs?K6kx)92P^xzQn|m8HJI>fR^f;Ut6-miA^fr_%eIL(iVY6h%y9AQll>WeFgBS|7Qc3BGt%F_`}aL{SI2Kjsc{<4<~D!z0)Hp1t7oG^#poc>qcXbC(yWG45d_QAQ&|Y~bh04J8+b&UWts)2XS5LiO9E z3WsN>Cly#`K&?WhmAI>HU4G7lT1qGnwSR&=-oIAX4osEKZ7^73?A3=)3FFi3G4@#r zm6Hcwf8bffNaau16JD!>0?kfZ7Xe!ch?+@8(ewtwFHZ(~C;x@8sVo=~t}%%amB{ah z=5F+ouKlFfJh!Yee;8725*~ubG`vdPtONoh&s)2f6+#C_6EFyI7xoQ5ug`77)svmZ$9nmw?{p32(-b=<2 zrm198TIP#C^6x`iHE&-R7iE?&8&Rj=!`u<;G^egmN(^~W0^+^)0txtPOAb|2i~Mg- zA~){6>E4_5M4BJq|HdLC)T0Gzz^b`IZ zD-DyFXistNeX#M7Q9VC;UkNN3b9{312$49ylOkn|^ReLHCppOzd_5Z;VN0N`d|zL` zahKS6@HWIA?vAOSXxC}6A}d^Z(5!!oL3ZaeX9Cl)`?TlM!ORA5Q|bx9icPz83B+t2FC(^<2{0uQzJQ@3eIft)EsSLG(G(CY5{4`Un_E|o zTP2nMPWT*-kthVFO#LcY`>&K=he`J9drsS#Bsdvgv~*BV8BSXH+>1SaUbRrpz*Ow@ z3R}B@zb;xBds;w#qk4W2=Ay$xZqUP-$nHHJ+PrfpVcyk*C=l#u#5!o9P<#yH>xPGO zcw0A_9EAWBY@*z;{Erb&%ZZ>~6;e^@;I8mI_QAJLX)bMvjN1#BNmMK9cvPEDE)ZJqeH;@w&LmdaT8p z`#JuA_q4OJIb5LKS+fwbmq%Te;}No)kTcR)!XmC(?_qo{ZYxcS(`_fohK|FCNYm07 zhk%q&*(P7g-Y!vv+$`&q5N^?D9CYR8(VjSBRMm5F$8gfM9+;MvUJvGJf2!eg=!{w6hvTU28lv9S<$bAU=o z-W$r-0@J?c^BOUHh)wa?>gceXRVWN9_Sl?0mYkmr;&jhTafd0N&eXd>&24-r6YG!_ zdy5KOBhS$Gne>gc?m(gY%bB5q%DF1bw1J(1alI~5xoy;%T-k;=CeLd2wf8`=LD>(v z;urX}(ymG1ZmEq8LSR<)$^w1MUtnl< zwrzj<?kdFJ!>h?=Z0)$?*kdhb;{c_SDw`_ zo_O33Dy8N=fd>cQjOgm;q=a@}#}F}wRpkgI5Ln1#4gEPiAq|8s%4zG_QR>PhlLP+y z^iDwRxg1fg7Vw4Z7+2*OkFE!*Yd^Ao&&>Yx{#lzbsiTk z*kQD|u)FJKbw46ifbB>p-Od;k6banOn~SgNd+9FkZ_dmJX=^(Sx4(Sn3xtwteD}uN zXzoAIO5C`BN|rO{EWKJ2DIQ7Y=64qLSB{$geE!M}R?>Tx9Hj^j zKiRWQs}t=z2GR;(?JVeJS{0vGnDSt0YZ&`I`X66}0oTu})$((9wcGl{h>*4=qd4S= z)g#Ye@fP91YPEds3;LkclOV2ukU^0lFanR-93_8iM7`Zad4Z|^6r*x2HfqnZD-&1; z&z6dOS1m=v)I0e*>7{cME`r{Wf?%TM^}WxDjo~;;yilxP3a)Y_^oiL@L=n6KV=h;G z<%?LL<EFeE#YG)aKj^k+<%4Vj)w^UsD0M@nh9&Q;6DsQ^-@O}c$Ev>>n z&e;9=#?YmYsv(s_a+a)(R3>*pHn9xv9CFqX28hWv;+r-wsW%0P&TBWsUHU4C^q*o^ z*gj%D*RX-6Tt$CgW|!FMx+3@c742wwq3FHFPuQ<8l%vrW<5}@a4=_Hq`yL(L8*o^h z(v5gxgOF{5GbF`MuJ{>I6WWp#Z}q{4AI16JYw~S#DWUG$0jX6nl&SxW!#PC(hQ;qq zRr21Unu^R40i(cCVh|7We~pEyArBjALoVoKU$6jXbsA)yjMg(< zK4389>TYkZ3tF;ni>xUT}~?AERqJGWXlhuZnWSdbIew4hjeE>_1RxmUlGb1&TGyiS0|6hVW4wuG zv}VQ7KY_CcXE@9Uas`P%3g1S@=4*+;`H zgP2hD28KB>BOvNYJ}kxF7KM0qF%U(;d9gvuaykV`yuzY?#c_Ad>&*f-uvSwHWH;7a z3t}~mB@qHIRG&?RlKAE`#XkBQPDf00u6OnJ;TP=<`8VAN#W_uv3cGc7#=Q2{xO!4+ z8hg2-&>~P#$6t*^Z2@Kr18@1Fh5tDVz7KS0Au;50=oYLeG zed8xe?zC^>>ja3Io*s)Z*L(wgD9NF2q1Tg>NN1X{ zIJQhG5ce;<8tjNL=F@AB2|{b>>;JA~6Sw2LTf9|Dr`yvp>$RFU>Y~e9cwb>HdDs{p z;4{|E$p)%7Zpje>yyV4=WjvqQE-533Bk@vuxp($_QOi@2I|J(>cJRhU53)&!H@`TT zaXpWrWRdcvg0HvzrAhRIP*MbpzmW=TDLJx&={lZ|nUat~323xd50_9OxqGh7O~7(F zb6Ys(BU;NuhyLAG=2q$gK?>}8^s6n;zKDF47|8;J9`#CHgMl{uwCEiGB_a2jnb#bR zzdBoDkfMptC4tFntw!t4Zf8>X%W{`Y4@`{Z25$dgR$p-Y7v2Sa_+rITxkf*09;a;i}DVdWv%WTy;H2zwwiu-U+_@wNa`^II zill&diaWv3f5;ziflXMYF{?SgTvk)5XAHcn+O6#LT4LNQ&Kyv*^6m#E|1K-|eXFcH ztO=^%^f{EOn>s^L_OK3))|TOxd8mlK+uX~-7^jH~1 z>$)c7-0vN%=er~-ST^-kX(WOwDwk)@^#s*O(>69N%o6iMJCfqZ9itrF1<)3W1E2Vd zOOXNwr*c8pW$m5Sz5wYuF$k|VF%l_0_AEdZnhPWWLA7#oiBnyj?afHmIwL*z~1cAp5f(w_vD82rKeveCVGtckZ%HZQkIKUGE~`fdkK-MKZwdjbzx9f# z)a+HduDTfw%hzjzcq}EIErvq1I6mdSE88ydRGMv#9oUdC%!XI%H~H=g{46OBQx$tT z0MlDb7PB`Y%1bMh(TUYAj>2&vIx81~zONeTX2evYOPJqQZ~;quOXOfHoSMFBxLk*EApYxEZ=hMA6-ogY`RS6pukd?8Un`NYiRsophg>l6aaRz z`+F+;vVt25#=?4k!S=%gf3qx%SHyj=@dIL=q3>Ylk(Uxa^&5RWP4?oLfA32#3hAtM zHg;lGfGbo8Trd{!9oQk`^XUbX1@BA&uJlxJphen$wfh^t-T>6wL1DkR{>fSg4AWg+H}#j?$F^LeYi8 zI>9`Bs~DK=3zJea!rtBuYq-uYp7qt$p$DYTTT)`f)2Y0a_}t59nI(Rw-$kKNnU{Hq z$-Iz|Rd-Dj2BolqCwj-4lF@uhqVaf-2{{sdTE!l({Axhc9;d_O5z#!0!U|RL%E6G& zLzq>G^ht}~WA0h{h!>k+oF`fr-(CFR*ptnNf!xOvC!j)_W=A@cHDi;oS=kCl9$)z$ zRoAh>Oz-0IWhu4|oKJ@3fF93fMTRPdAb&*7rSzM?#6`0p(~#@%AJO_q6A7NL_*gd~ zrg@tojrQRVn{kzV)d;_cb9xr=JEHo5t+SEL>~TrKHS?u**kdeBHCIuxJW`@72G|Jo z#B?)9n;k@02Rcf0J{Nv1N0vA633`(yz*$dJ8DcIyGXnzX&vicaP;Qsyl#{O7u)i-1 zlJhy!VFkDEy^`eL7?@e~Q}lz@C={wjvy;AZ@3u}0yM$p;rd9xl3I9zECeN20%WNxB zvv8BuM)WrxdT>_k*&N>FOR7xqy7n252auHqwwH|Q!|K{CpU5B)W6#q1Uj{jqDTbl7 z-ft#f8TkE!DQ z$L+fYns21+bdh?KHBW0*b|+tUm3Kz|l=3PF;ZRzz`#o1I^J*a{oQcgm^j@ih<=&2} zQkrZ^?UvS?4agLvcp%oD{hO`8ngsDPGEY&d)eL^;DIw9f=K(pcizg?G;TiS&LgHah zQZl|yVzQqQHkSQr9QtHMP0BIx*Xt+PNXNzDr1)t!i0{Zl{hiT*(XdSQHj}}bs*?8x zXQQSYOV!S&zgJ(vQlcCr?ABGBJ}>P0-bwk;%N55emZOy`IaAJ;R#+<7F%ZO86`h-3 zz;`JHH;pQjWgPI<(VHQmgNJ2x z&!>^O-yvsqb^VVkME)R1ri&g5|Jv%7`=r@J;%4J+=Wuhf%g!PbR^{R?Qa;z)tyWlB zqk+fi(U)Lw&<(#212O2L@juKhOec$`SRtn0B|e2Z}^5}+_kT4w(#Nt z!9(O)S@=|U*nLcVyh>4xtb0MKOI^qw?;kJAw8|n`7S}mGMTF&9PQHskU@@3^(ySYmMwK*^zG7EiQJcrg8GqeaeY|~S z%9B(co3{MY7YMh0ZNH8P2PrBmT~-2OrL|tjBFY2nKsO$rKV*AUTy4o=lMRP7JF;!|R1$9V#1~YvguOK{KM#ER55(KQfz|#6g!>1E?LQF< z18_c|wf_u{-^jKAi#f>{)hM(0{9}E6pXVyQ& z|L^IwN%6lnlK*Qs|5|z9@0{rCALr>mPKy6zo&JAkL4saixc%|!lNcRV5b*1Q865a= z`=c=AZ|Q$7yN$Z^k8=ML*;VMdlUDxqegD1O|3r2H{Nbb<|7zpEm&>PPOR(%pNvi0t z>2OV^IOn>~sJd=!&(QVL{NoLNlDeCvRpMMl|2nCsdRACSd+EXch|ZE+(hISMWZ0K= zi0b8&9;10xFu#XtW)_*I>flc(u;Y7@tU%Wq+oMZkk7g&A2(ih*BHUbiH9tHYA^)nt z)nlNub&fkE{N3N3QVm|g{W;Uej{qiixy(4Asn@s1BMNpV*MT zriK#nm6Md!r$Q`4C`FeNOJW6$SN(qfx>xn;+Y>?QCl@k89N^6N`Q;fcx(#9Cj?-v0 z_1Co$lO*aP*@>%R6CCcaYBxIGB)hxgniJ^`%GR>jL{d0>s!3*XUdJ!Z`+OPPr*QaQ zDgfG-Nx5)4I_ub|W{~=O8)x88`K#QR=2O+<`dEurOwBv+!VqmEJpe6&pFRe<0Tx!<|rH@cEv@c zS5EsqRWmV1XZDxUuxhp8a_bK_8}is)C^t6}mQ0@Aa78`*`7?{UHLor`E?`jlaq!~p zkEP2bPVQRLhSyhP_Yncd{*?U|?Di4=X0^KP`RY*oWc*Wq!pG? zj?;C+>?J^+(?hWjakLrdzW$gu;OY|*ulcEn$r0Z`&!+wiZ+V(iGFpp1_)^Q~+5K8j z*vqZkcx?`!fqpiQTKXBIM8UFJ9CQZ*Q=;pfE zy^Fc$oG6WinNu!qWJSn3(=-2=_Nlh{Wj-^g?HwUIb#(B{(dGHv?f#mP0^*ojk{mdP zOUV{iSDl`-Na6I~S^5IEwKJU^{0K_?-I2G^bdizj2|xf+BEq-d^;*x}3qCI_XB?`( zZgH^nz94It#?Y$qnvs$CJz`-zFY0)=sz45-9G3%3$JR*v`84;YHkn1agCllH>y0B6 z)at8)#gS9lVz-LH@ko{Y;X=gmeoS(Bm3d1VcE87?mfaEb7XmKrzPWksO0DF=*_XKm zl-(*kf-+?wj_Ss3D^H{9q?}W|{Thw-_lPRn6MmhO;(hH$`{PSfkBjh5DCWH6l?KXj zQ1q_g##jq&Z+yu#*XkHYaK`jW-Ls^?Y9(G9dmE(;-2HgCQ}*0139$TFWc~4(px?WW z>=H6>*nf`;)t1ckV5vFAQ6=J0ax`;Y`bbxcP4BNGBm@mU;a+Swv%5i>!QlY1#cW&j z{BoVfL(2Q;?E$|LwjIi5K^ZTfyApx0vx?Z*+R#7rB}we=Nq?>1?X9(465(~G!cx8T zI*&ajFd1Y|q>!@tN6qO$`ju6d<{VI1xBkrWk9mXRBUj7LEnb4!J_*IT|J235YKodp ze)tA%e}pneNV}1j{1PAnJ?-~RkVg#n{8B5Yz#8>ywMnr8{Pp9uUCr(7X}-StiQcXNd7=(uD4xL9HJpdEhg~-Zo2&9oBgi}5qQaIA5zl$6h@|^_l`}m zVNzgG&rX~itH(Z+Qgix)Ba$MpPh_7*ZrOFLw&r$5-gRQ(Jx-cqtUhxDh=p8W{DC zA;zK10_s@WwosJu2j43@t#;or3R6LhaxOykTd>Bl0O+|`c9S3XrDJ!O_A$LVg*qCswlPugR-Rq%QU}V4inBM-iSKddR|A4 z{%kA|&$@R(ImrQf?6B0~}Dl$?@j$K8uUtEKrK2bgX)>*cllJ$9vDry3HiA8foX%XYAV zjSiAA6I>leL|effK`yoOX&FtM>IS9)DiaZ-X|mSpiD=u=x#(sE!eN-A)em{KB+3k6 znY+8I?hE36GzOU?o6chvZY(-QseI)8?T^Y`?fI5atNCBnCfk_1;7xBn%o>FnG3@9P z<3x30PZ1XMcvHq`4KMF)0sY~f=DpxRI3~_ejcUSFZF|_YuR(Jm=c&vs?J~zdhWw^# zH$W+SNplK2Br_%P4m&ucvYHE0qT3z9-jU0XBd-&^H>nI|*t~%kFkDA4W)OwKyJaT+ z9B4bP(*D4ltm)19=A}LH1vhVan<hX`j*)B~-?_DI3nyE^J`Ru_oR_s*8|u3j?RW2x$93$4bw0d_e|-Qx;=c)N4OZ{ZvJq*A=RjsAl)Q;^h0I( zQcP}Vb9=sc_WdvvcU=;peARjyV4R$-vzu}vP~`G_+dv7VP1cRL6wl)Tzu0HmW4bTm z(Vpa#{Ua}H)7M&~yTj5iUcs_p_0BI zSQ}P$01X2e0|`~xpK(Ss^lM#}hS!eYNEa!;%Uwk|)$MmmUFq*hRo&O>pw;9n0}QB( z3h78wpOuliFw}b^-y7YNHR$tqJiwwBt*V4+NAHa!WW8t~f=nEGmT83QCOg%|l#qC% z&<{LEY>EuZhVFgjy9nM+vl2KeUC#FZmz5+4>ND&R0LtTi%Y*j;X9f5r8Ez&y6WAa( z6{DtXYl{vq3B26%UhL}_Yv=L3b{ZV@0exVFPqyyqxCPBB@AQi9=Fq_kMP%%jbo0ret>)yo`PQ zz8)lM&7A0{`@>sox)0~yTH`PoAx~Y~=VEkgQaj@VTfK{F&K7!cCaequDwrw!oid+P z<*uE_63^H(=>38`6tzMh)-6t)iC=>yiX$pDn%dHQR(n!0IGoE80xr1vy1>+3J;~j1 zqt3J8)SG=O!{q6pn=zBLCsqfF7h*EeXy_!RxzI8Fom{2jcFVF;3oc%a9*1NR2ri%g zVF#a16Yl7f%$l(@H+i#bEDx_O*PZ>~oA$;UPZoEnt2OIZvL!fpy%zFV%Hph+S76yD zDlaV(VuWv7ggTi&v64-!9vb4yMt8Kf56r)SsS8%;QwzTXN%i9(4z%#~vjR-_()`qw zbJ&119Ej8R=y^xF8KOe!I6KNXiV?ZLM^SVmAGMzk9)YTjxIJS>0#9y_Twtp!=qTQPqaSD}zye^&8VZPUfA$ zwnHp4N8h=9wk$`PuTyg^T6*Y#jrI@8m9EXB3%Oh>u`%NZalz<=8rCKpWr|kdge<7k z*Vu1m361JXyD8rm_U6vk?ZOxpM*XevNO56ajOazz@*iDvQJ&(~!F>JpPd|9aT->ea zynMQ$K|@~hccq!%1^1opKVZ4*OTB7TxuAw;)NWUy!{GJ9DVeeQ!$WpI!^?4_hl*5K zCG3&dT?1QC^s`WNV`l5$s}FL-3&c7f?7WwXAB2e9rn`>)S|W-lgb#{+a83pg*7)JS-E9{=XL+sH)clKB z*nH}91=pXRO;cN6X4JT?TB}P%L|P|VI%JttJtA(*3);^-;1Ybc2%Rx}K^!nxGHtH{ zZc`V)QE4HRfp%-T_yzU)Rl>&1dMjQ&_B{7uUrTR~&lh_&)l$nvSr^T-gZU-{<5d;*u|gN~J16UQ}TBZ5U@{gea?A04hH zIZZxrARP$#@W&gxt38z7-Sj{D*7Eqo*FHY<4RDPLu{9S{cpb7>uh+ocdj3>|3M(Jq zb3jG;%Iu((D$f>CNLQn0FPy^)CEyPRFUlyWpE%crc(j&{N(1*IdHK4aYic1YcdKY? zO-y;`EugCIMEf(>xF6PVKl(gTgPP($65@5cecnz2A6?Kzg24-nzmv9Za{2xc(P;WL z&%QoMB|5Gp?5
Uf3Ohe=@bgYA>bo(PiwYR8vA`fK1sHU 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 oe}03%x*Wfw4&NAu@1*1NBU`OWM|6TfqV# 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 z

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 diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_muted_channel.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_muted_channel.png index 8cb7d166d95a83ff41d2525e7d2b36c34d3f9ba8..72d49304d635798a8a4266226f252439f700a120 100644 GIT binary patch literal 22514 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 Qwy@)N?byA&J|KqvA8=MGzyJUM literal 24653 zcmeFZcT`hb`!0&xZKH^a2%(6If`GKp1OyZ`N)zcF1VZn<2e*hQ1Tpl`dnbSpN+?lE z2)%bgr1vHzK!Duk{(g6iZ`?i3Io}`m-f_lnoPUxrW@gr!bFO#3>wTa3Jn!c>uV2zp zvrtn}QPC;Bdagl5^#_=W>iqKMi$F`u?VH(DRBvx8K7Xd=GqIj>DdFaevyTzpR$D?q2m2e)oSAN#DE5O$~#5v&eJ0AF;dJFyi$@%-& z|DYN2d&K|j{f}li?eBj7*8GMW-epQT)+Gf|NI_2f!@Ay-lO;JqqCIM5#K4}v`e4GI z9JEhju`ixE+ldT14Ae34wXB|xQvUT67^@H%-K?R^zt9~{8%C>a`L+CLl6baw%QV3C zw!rWEr*D6i#u)gMmxMB~s=f!SoIyzM>5DZez0An{qsg{Y3xn1@l6|T1mCZ^f#X* z$0}FyW?ku|*Q8_MwEFlJX{k1=B*(bJx{jfSgNe>lGLdq?w?9h5nbmvYM6%WI)DD@V zg&bFz8Cqw7uSbE+TP~X(I@d15J&^MzHU<*lAd#sa=`EvQ?t*pe-!}J0O-W|)pFu)z z-$|3#D+qKFQ$Hgjs)7LfJPWxK+@ae1k;zbI@Q-|Ru+7VQ0GnZ4avY-iib5!|G31l9*I4i4X@z+zLf0#Wo@`f_n2kWG^j!P z7oKyi3h~*Rr(|sYoq>dKke4ufOh2zC(`bCbYfjEWd#h1KU89+18M~o}qxtGtaAKv) z%v_}0W>C=VXKsAHTl%ep+cJLHBD8SY@0qQyr8njUYUgiI&J0byLZMo?_BYECfp7IW zpd;9&RDV?6CT8vA*e=9G^9T)!9m7{T5hk2<7rc)a;z<$A+{rHQiB+8fbwkFS3{|)j z_ml|2Y`1hw1VUZ!thR^C6QiB`4Fci6#}e(fUfy;bf7dn*7r|PmDnS_Hujm4QHdZrq zZa~YOed7G$vQ~t`aLd*>0xye#!2sg(>h%@f_J{Tb+*HeCg`bCERv6(fpCsDS=rahasgIr|tNy zo$HL*Soz{3Q{9wAH%8M53DaHYyUUF+$i4OPLH5ACerC|S7uObK@{--c>?bM9H#_TF64c=&sSI@1@G_YsQM(_qI1lV+jp-~<1y z2GWW1q%$^9NBMgjM^LhBJtkBX_2P3?=Gqo!4RyvGvDIEpQVY=AVe2 z!qbwSzK}h#-BXw#-Nd~PO`<8_*8$+Id7;AED#)Kb^yl+PzInmSHYx^e{W zA&8_{U6b~tMNuKa^+9out0EEQ2=&g{g?Q7=YId(NGmsdMqh@j$^Zlo%_tFsUA-J|> zX8V1e#`F^n!W-8dtu++Smd*u5UmXYN5HHHHLvwB|zeo{V0&GpsUi=45l&e4V*E_0UaFViO-vcZ=UXb2Tw!_3a=R22m;L_9=S#PJ z($mM^xKSq5O5_wFkPALFSOYcO7xuNftgAA6eZ??iWaMMi&_ouw|IVBb*Vm2GiI)!0 zkMta=2%VU7V-;m1ck6UhFM&9CEH|P+{pQN_(^q!w2ja#Sf zlMBL&GAG_2kY~dMZ$zlnW2qe+gO*af3)yu2cr1@AgKDZGKp;!19pOaZ9HQtU>MPHn z7YCR<2e6BE2T1fAq8Pt0Rd^NRilNseU=V#^rn;@hy58MKf+}Ee6R(;XC_OBl?m238 z?7M+5cr{ljxU4Ied*~ZtW%=)yyVsz_sd+$2)6V_66THkYpIp{lq3UDUNBgx#o+tvU~|i`i&xo}>%6JOz%0sHr+YURCetm%7UUJb2>3pRn+`H^R`>(xkaaq@%O|jxWKcc3Ywz;y z;xbpOt|tgIT<8D^P6<|Xqv}Ivhvof>C_-U6)PD3x^uJ(ugaWomT2P3uK@*>mO-TYyD& zgTXA}3|plmmrlKa_azgXE+*~lluX`Ojbf351sua15RHY*pd5C()ov!!VKbq}vg zsa5{#9s_E*Yqih{ce^3{qsABh)k0G+#nEI zFQHb?sdfR(=9dAO^E=U}kBKlpP$jW}G;R15q5h+UsCE9KC~8P5$1yG7mm;n+ziIm7 zW!+Z14OMwn!w!xWG}zdTs*#7Qz;oS}z+gMo$~b1U#<+*Sh)9SB;~!5?g~1)pQCwyZ z(=ak&j49&IVo3`N0vR`rT{z+|UD*AZ*xNw(F=;FI$ODI%y&rt8EQjui> zWeIXi(bdeg@VIS{=qDa^JWm2K>NKv#Ag<6o^$d)=BMMfQaGV=)=zH85;1CDqvSzQU zuPfh(LIsgq3E!`VYvW6n1ZOa5<(1Md@f3GDRx8#-H~lB2%$yd%*25);y$lt)#9nRG=g;%2P4IVw6UF+KZtz}fI#Nn46$cF!zha6btQao-S3tl z9y;0`eY!LkXAXy>-?tL)_ox4ohr=!JcRZ#A-4Gk(b$`!d-aQt~?B zKI7YdFt}rKKMAMsF_u;PY!+=gbQroIS=^l(v|Cu>*C@j z>iz2C3`{*542ynXKvr2R5c?Wb2}R?pYrDOjfL>Ed4N(bY7K{e>lwQ)FoTKZ)Km1`6 zJ9)oJUxEX6Xoj(WRWx8QlbeX4-qbY>6e~rP|AmnV5K_ ziK%%4*U@kr+Aq1X_7mT9IKD8=by`AOfEWppx&jr<+cY(PsknxxWtS3_X*IO(e@JV9 zT?F2cN?RO>U(F-n-F*XoqST>@cEeFOzUUUhd35USN8-T@YhZIrQ!2O$N*HWqFeH_Q zy1k$|W1#7(t1;!LnU6qR|Mo(47 zhO!UzYSVH&>HSf^CTi4~;y>@U*>e!CJ>K$RPs*RCdN;1fG66)ea70D1uzWJI`BCT6 zf6s762lA{U#(~kuv*H7XE#Pw#mGXEdW~kBPj*|u)=DP@*63eU?3$yN@g)MN0o>ylr z0QU*Lz!GWBcU(yBxG2nx#xKK~g>1f;o}B_AI^b*qmnfw#)_Lurl`vJCu=U%+FRXiC zTUC7PCE6MM4*Xb=7qkU-`K9u}%KSBUuH&w4>@S9 z5;AG|ai}nzrzKITSm@!8!l$n>CNI_j_XB%}YRW7aOk89NlIBs-#C(*!o92v3?+R_= zn#&jt9}e8@6vX<>U4zvrF0(3frv-c?n$nyV9BD80(UjVUa7YhQ(5iy28miB+t%QJ8 z$bcP2syf%pegZRVU>rDsEev)Z-p@gC0V(*SrWn$DAJwZ3?W~}krZ!E&Ov-J~mtL^0 z6mLc6(exi_!G7Kj<%x9}8&Shn=JGv~=Dx&V3|IfKGO+g@QgVwpSAGj=#8Ft>xoq4? z>Q|xy%;^FC8eaQ0YT+yMjBN1N0QFcuO$TBP;Hxx*h`*c}00N?6dIIv4t&=Rc;lo^Lv_wlS#nN3rdJH zl8Np)Y##A4!Hf2HntXeI((oLm*He6-_@prGb3Z9cez5N>!P0)X<+7)333fUWlqPmZ z9k|!fdCshY_KY1pvn++8w@@ieP;s69vC&#-wayQkDQyYe>W+G~lHF%be*lon9E8g$ zRzJ%uTB*9@5!!c>wxX|Of56hryyac^E%!BvOl<&DNuLHGyPjd~>nMgnqe>toqqx-l zz%N{Dr7IU>K7STIPOg5A3*_Q&0MdRc&o2CBx=LDWA%5)6b-?nsrIk`5O>+l6T8t^Y ztf`$#-Ff1_rt`otw*RLEjfEtPpY?CN;Yy`mGRAPAXa+^-;~%b6&B4U7WG|1Repy&d z`|mL?H1c5S8aoY+}$M`u7)!s*V{G;l2;gvZSalOfE zSWFgTW!$O&uEtb0AxK5_R7MyqU*X&2dY=Y^yjt3aKXD9}8E9Lt8zdG%#R~`VpCHdj zH;VAUq6~3za>nUfA@N({~%TY%ihoMj%{9njdY)fHCiP;q^LI#=7UR z+LfD&PUEVP%A%r05_WOZrGu`WF=&MCfRF0M6ZweDQr9*6i5;dc8Z*FOlom#t*3?kOGtkQT3K3z5d|N~`AmK`cqizu=oVnAN!qB2^5e!44&I zKL^$12r0gcNSJHWaq?HnZW^VA4^`82y5SsTIBzoR-YYXIbNDm3(e2H8`S1K$&MQJ} z7Lsle9n((8x(c^?VN0SP|=K!jF_Nb}xmASEBEKKbT#zN~|{ z2#N%;%2llTP1Y=kJFQThCyS0_*H*>BNltnukVPPM|MeNm)}%oQISM2Zmc*xhEZ{2a z;^1SqBfyKSNqMfuOy|PM+0n1v+St8~QUYXwac0s}O#C-qWEfEa@J4uKX@^%g0Lct- zn5G%DM8j18DC4AVApKczX0P|O@6s?ZmV@&dx!+v;ykz$z-?;&6Q9{W>^!wa_t8|w? zoU#a%0E>SSNZzRiHXK>#D!WwWYgrET6TTBW+ot@Rsj2%@eC{WAL)m5{OVv2SRKZ}s zmxbmdtNJi~*}o9yO#}CbD{#FZlHFU}EFGcZmvMM4Z|^U&h4(77iV?qIx_}d!Q@Jx^ zk@CIqD-i{K%GrOsnYm0-znHxt^)eZ`95S?HcXc?tX0@>BxL{Q(bpO<@Ze*t4EAUyv z*Rr)lsnU{shtYm7!?ssTgV@^R1V)`YZ?Rh3;L^VT!0}Tr$4S$jOl)jw>_x4wD-#p9 zaKW4UEBEV3@`l3AkAb)BUXrnb*{i~tMG^3f`%qxpj+txmtxGvHGDTsuh=We1T%o{a zXPHaGj~O93mIQwdj7mo~<1PQi9i>SO3YA4_YswCcz1{43B~I48)%5UD^g#TqD%vE( zRBU;BIt;{-;nU~dC$k{c`1LgAHsi%pd&XCFTiFZuD!T`gQk`YpGu9S5rFp5de%%Zy zQ3$;%+vrx(#+ci=E#>7LmphDMYK+G?Y3PPEU29BI>^1F`fSnyoPr8r57}57uZu1+j zPSxtXqaVzkm1_sG#pWlyzpQdjw+U)~Rjx2luB9@A-?V4GcF~jbR-lL*MfZlgo^?`+ zjYc53u33pl7y-!k)A9weC%>YYK@WZc7}N9?`TKc#pFN6BiGd}wE6L&8XW}%af`cu?iIl z{COJK_v}*bU*|97_Hy?~F0lng0%5E_B;h7bJ{2*`FS`k(g*{+!*d=4b$t^79%;O2F zqDSfi2pM=V&K;N>g0*P-0$MZzrMBi7E0Y(gv8gkF!GoK!gPL<)?Hk@qt!+tf)^N_j zUQ{~~e%(5*+o&>>dgPVT7)Z9dnP})#n?r=H7UW@Ir^lAbSo=}bnXISjjF(KsSV9q% zX5!^7#om^K3NoD}$ogJ^Ky73#RQv^codrI4J zNBH~tGpwv2R{*Fzrd3&dfpx6t7Khb=JAYv6O&`OC4ldq6&6oC^e! z(G-b`Yfp8>fmZge1A`8bdHO_oQ(O$fWQ*wz>x|B5#lje2mJ z;+)aGQ8n4KRV0rGJAssBXmWzb@SikaOSYzIGUoL?F8HcWXEIs|r(}i;bUbwNFd+o< z-inLUy8LkS(TSfxTq7@akjC923(r6iCJACd1u@qjeOk<@VEcSYccSL(c&%bUTW_p0 z!A_2lwW&Q>1z@3jjaKsxKhdcX@OM>?<*m0?PS5sBgN_{itoH=?;9>TTnltRg@M-Nj zrXuJv#*fG-XEn7q)%;|r2~{sYGqQ6an^Zoy6UqUrA?7ZDbe@L^gTd*3RhZl}r~b?k z3I2}I^`mzDm_JI$-XU_}x%Pl1^HySZhCPp3-ENOGjW}56ufYbs)Z@LC=<8bmigWaJ zS}=#O*quanj9`^`t*fJ*Y6dO*bld2d;R4-=*Xd;ZBEtn5AF*(zVf77f#2%3D9|5+atYb7-gWOs+fE?<(`H)Mam*JwGj4BTJX_8VMN(0p_- z?eB~wTx7>Va>sRBsC?gjvtiDsXKc>HIXt`&!(I6&1_VzrM z7{X+du*s{=w%kBJnA4QMUGVcN&3Mgl+vbDf{QD7zau1{jJA2VcP8bdkq~t>ej7jM2 zhLNod1fspb0aF>rKvSfBan7T_M_>s5u=k5$a94Vg>*ok~jykA$dkjbk`<-=_nIXA< zUhsPSdNFP{?qLR^9YE;0*p`zzk@0hHO@}klktUgk5@LJ?5{fp^*+o}A8+z&WvKF47 z9UrvnBsjCW_@>n^guue90q-Z}9REU=GmGU#eJSlnnC9I=>~KRm*09O}Ib3<$E9a&? zR7;bNq{&oJ6^cYW@m9UZ7JrG zJZJRYBX>F=P-UjMiv4wW58#plqCZyB7lbSq)(scOH|VoY;TUp#44 z;x8p&3yCu*^{Ahwv0o5zk6$x!1A%gSjaE#35hx2X0Ol;8#q>m7WHt1w-gAcJ@*Y*7 z6ZJ8b^{?y|v_;1x;sJzERbh}lH)jm5cgCNUUoQfi_I$gMh!N(MOdcL`i;Pv4t;#9P zkA1kV!yB(1NFxj$DT%3!yz$L$XXKGBBv&;_97J|R59_QnL6H8h#&XOcTm?n1PMciQ zYCs_!EFiJwC9t)X5wxsWTVYg}U&F#`)>^L^Q7%wDhQDtq3clU(+>MadlVjoeB>;k> zz7LAa-nB8Pp!)!1&4s=zTP}U}3Adn8#Uoarx>Uovw(9(nBNWsKH=345<^d=bz}FZ@ z;^Ls9N3+%9tpdE8*wnMoa4$czN={C*DI{&z4>&JP!i z9B}(dp3jmH<3MW75TSC|_>e=B%^+a8*8W-5_Ty7W#*dG0$E5Nb8$2_>tMuIG%yLQ! zLs{^D)dqG@8Gp&LB$te?eSZu>-9TW^cTqV$&RL&i_(TuG4D`eqeH_7XM&t1KdA&p( zWdx?A#6D3NJiKii{E=?Nt=hQkxjqOfa@FK+)^NU&EVDiw(Jm%0(~fTu(`VhzbuSo+ z`C#%`1gv<$Q566`y=HGQTfVgu*QH>Fr(C$+QB7%zxehE!?+ z@S<|OpGhssVhI(7P*;vd(x43<7`Jsj6^7spvS&SP=TZtM@yjVicp!g)8*Ig-C4Sb{ z4Y15>vVh(&!S_8(t|W$8T9_ZB4W}Xrib2waa2@4GEqFctC#IuOVlM!=F;3r*Nvn}( zPRte>MSXwG;9HjwQg_Ou@V$v^-nO0y#=ueZtwe!s9VP-UHuF0QV)WwY(d-#TX9qf7 zbLPRsQ3LSgr#bzAV?zrukE=yT+Qaz#9JLT_Bg8{ALftG=z6)2N)g}c#Fu_@fb-m&_ z^GvhT9)OAed|bfgwDfQYzg+JpYxZOnWbl`R1=L|Z8VEP$3LRsbf0bHv;0t$e9QoBFCCxOtfl7o){D4BFc@QPNyU3Ow{>76 zlx-kw*Nkro_6f<|T9qJF)9I`OC$1xsj_;B!ZFoP$xQ3t~SPF@2mrF&!;h|q*5n&>1 zYu4328dncA6U3)nnv0i;t+U6?k1mo|o#{Nj*dO{W9;=?G3Ks)|YbJD!zbaY;6~9vg z9($kgiastsmRsCaJOL8}>`9|m_klev8Go9hoTIQfCA^pbZ#z}NQytw>rIv z+;JaE(3x*IEqd>M;m{s%_^9!?N`B?R>v$z+afP0X0-@)-qcdUJHY^nmW?84wc?HMJohFLOj zE<@`)#qK1s3AGUdKai)F6{QV5S))w73%46>nd%d-$jSfOic$K@PMAg1Z#g6M78E+4 zuiYG8-qd6F2a9njmn-PjaGW+iRD=z1loKLd8K6^K^xH z@Y_zHnz${}{rl05>BkrMLLlguN5Aws{Dgq8qGjF7TnGGer-+B{mcE#S{2o7gF==i?QMxAw|5d=>Z z2ZPn)gvXR`2id63i9ko1Y6f6nVYA(Dv(G}*d<1~qGnfvz6TA01%pbz5^=EDfeB!n+ zKc7Hnne57^in_3~$JUJIgUWlPl!+UzGlMJ(cjQfZr<%u&6(P8bu?F>_BKA=Rj$(^k z0bl&4Z@m`)pOJ7cc3EJJgxYF`e2L)xR@PeKJ(RTr<+}P z&(Kr_{3t#Ap1q-XGb)E#?eRshEga7Kcm%^b?Vd1lQ?T&9K2u7Q`C6}@Nx@Q9*~m8c zwbjLHWqA?zamApLSbZgbr?jIVorxwr`hv~{#--HCwXTdl+WLKJb39N#J9`$tCu6$E zU^{I^<&lWTRGSCLghf)6z-Ks@`E5f+)aQ?%>v@DA|S>??!L(zy=`$@eQtJKj zQd1nLTzfF62KK;2Xlsfy&K)?a2#-sU8nM$&;n@6>>P~MnK4yI;#KP)i70WYNZm~N& zm7;z4J=?~6$PJ}9CsttqqXxNL1`tPP!eQoyVQ{! zN$i4~Q&P9CH*0acg-9}Z(a-Eew2oK5aC_CxB2z|A1JsOlb@RR1Z0mcA${ZT!OD17LYc^W63s zH(eM1P>oH97Lo~h*WfMiixAjyP$Mgj(NnHH+on|k$!7TZjYxXJ0)VFef63eX*R}sa z=ldTtGlPJUQvIX%KbnOA`XjK~|Ign4X#N*D@qgX??^MQr>-~@Bf3DQuz5m(#AM+tU zzWUE*{4dVr|9Zy%;!OVA9R9VM|NAe*e@G0ybL01V{bPCmjVb!?591%r|1hop?uPj3 z_j3LJV8{RAHl^hh~I|ufBf@*YG6?xvAmn-!)^>69QjrytI98sx6T&gSQTkKXdF z2}IRvvs1k%Q0m*`MrQQSvGD|!-xK82j7}ugxno}oOxMrLFC~(t>6w9{HQ}`?ta@C5 z>nT~A!)FTIdrl%k;eRhkp&~82)l9QvrrDgP{H6Q51`|M zBQ&=MCBtB$lBz9td-^u{_Pn@VRV*2x*DAv{2_(tyVpDH5Nrwz-y2@jgUoT#*?R2ad zbaG0elh_@-Vdzj1z2?)-=+u)eS)X#jW^>ASb9Iee$8<)ziukMVUNLd0*IVvnPkEY1 zJpCy`n%^z0HRGW5c3O)ge1=riP{#m_n@fh9-dZUiRy2)k*r^yDA~pX0V1LZNeal=f1yW(ExN7JtL>$feBzRNyJu+4or#LY?L_ZEM8ormIDp znuq&h*FMF>yYrg&!HZFhum$(c09Ev1@_3_tCSt{Z={$@~nf4)eCrEaxrh>Z(zM~ef zNj~R#T{(DHvM6R@sSosT22n2Mh9Ocd1UW@uZ_+chi4!={hF^2`S~6nDp2+ z%2`Hn0FXUswqdtq50@<@Jnd$>LkF$9w)th&oG~Fu;0NQXJt_@piyxjiBi4Q9ID7h5MVN|>qp77g!` zWcRNz3Eb+)r|J~-tY78w_9acOh9ZtE-B!Bs?i{bZdh6xd8+L|^mDuIn1~RRoXXGIf zr?wD+1kUUw`&Q%WCK-O(^CT~YvN71(h*vo=4csue?X7{^i4dQdLT`E4zK*`O8m$&e zw(ue@eXj?OMm@8LTZ@gS?131gdMhb1+--9JZFX4&C%6i*0sQ?dIWCP6Roe}7z=2hA@QxFQ?vF4TR|r; zJ|aM3R`sPRGTUP``pB<#Z{u^pX~e~CI{FW*7_Gaf74IMOPeWxBWr^M1Q%e|v&>hzkIBukJqmOX<#LXiPfh^xX-hv(KkGRsyp1m*i=}t8c zEE*j7gh0rVPeun=k+I$@v$yQ0+tC~QN;zLBC!?5@uK?;BDYFw}C}=6=HEAE@y>&`o zt841tob(=7@LoIEsW~p&46nOd(Vknt5XDk>dsO~$j*h+cymq+{%L`Tdti z0FY?={@s_O?P$TlSoVkt$%?>gkF%&AKJ8~p0CO)=J(Zaixx>Ik23XT)sw18zuu~bz zWF%){>GzWBoLOquv|f_l04FX9>Y;LG0I9tH)oyOVA9^9%H9K=6usZj?z6<>9qbBjA zc%$i@BEz6){;Bi~q+mG4?d%bLS1>DJ!?WQO1_mANtyrg#Pp`_(COqd9vD-^nK3l|W zc#SugU~S!rgxH;^ysp-ZNn*WV@F>wI9GfP4x``h%djEteWgYUQu$Ao@)`d1z_mv~R`T zj<-n@ai?7mJZ_aZIWr9;YZAo4!)PZJ9=M9}?L9*{!gs!$`=qg&DEV+rB7(l(x$exG zSP$W{4maezZuq0vmGj7Bhtc>1=8WBSnm!dZR3dNqZ(r93lmk-w7mhD+91*`88!OjlyFQV1dU+OQ3B`D9AkdWWcfHBP)PTj>%vt3*CnZN{cEO-k%|Sfrb@l8+ z&P0jGIOY$xECHq0y4RY_9c}fZ8Y->M2$fzYQ$f5maPC!FW9*wnJX>3KU2#m*w>^&t zIxP57jX!zZco5MQpQVA2`cYfXqbX*)_+BRylUmAT0ln(zn@rRlEF}8*>s>5u*vX|h z7O|gc0}Okyz1CY&sut4jvb~ zR~%Fe@I{33jNnz0Mce6H*xg8hXRzbk&6k5sXv(KQ0lwvI`DW1ab;@LOq-^T`PfPk1vEFuf|D&cCX~e=-%oU2x7L8~Kgl1Y5 zsZC*U2E;h$P0(8sM3`=0E%2fOG`PEyU*z^Zuu9oH>%0YceEr$tBn-=-Ce678vt!qP zYak$q$LDvdUF)DQH`#oX4xKK z*93Yf@&@;d4}Zu8P7m|!l}fRvcWY(k!vPzazSXN|@ReSYXnDUGkuB-I^k7j=ctfB; z)_E+3W534s4M76fK#9%{&`R;Hc_d@Ng5T>7?e3GQ+5+e7^*M%~2>&~teKb9){>0kx z0{Ju2%KiY}Lk0B526<{%Pj5B2D^)JO0}AKH(`jg(WI# zeM0yy43D~dNiTrGF9nhv#bELW@819?PyQS}3B+51$GZ6l&{?auqzFB~>;w0ktRPkN z5YgD5u(Ehb@V%Y-h;E6&O?jJsA@GL4#zK&02-nb%EscQ=YE9(+lCPMh6eOImQlpGH z&@bDlo=S@@N2(v+{{xas#ksrBEZO@ZyfZ;1(EcwoP?FzUi;LP_WB$oW+cv8_cD`pv z`%QQ_v*dtx{CYikdgTH^{`86Y^ALztX^4nB?n`I#es-knEjws7jkNJBX~RSRmjSPu z966c32>x`8F$xG^t)g&f8$X|cS&ynJ6&vVPsS_Klqlf5u-ej~EBWD)cEealWtA(!x ze^_Ij;K~fXzr=53X9W7J(?tsqY?NtCAC#0wO47Ci7K`@{BE+j@IF;LJ{jaK?Q-fGjd zGB<`4uZLfQaE&q}&%9+YWvuz}9Fv**=6lt+((K(>N%ukiMv<(MB>9Lg=`DKFTKBRy zGQrx^uLxqL9C!Mb_>#yrhhp1Kt@GQyq>nAB8I0Ym3jJ71RAAa|3s}m{2JZ_i6grv9 z+Pd3(dYn zXIRvF24o)xGRxZ+$n=!r^s>%MHrKAtD=y;G+4{#6FyvV4X)z$bNqlXHwoOXSBsi?G zpHix)Z6&I0cO5I>T`>ikfnysm(L1`7QQcO0sgs0C#o}TFVtkO4ee1(g@1fK@-eR!C zkQhh_%t^z7uQZ}RTpPF-p9VXNAj|fSmZGCd8-w@821{#3r_Y2e5-V4BOR*%v@R7lr zy(Cm@r9c-DOB1#Q8}~&LfGo+_f@I1GSB<4|&e@PZgE8f0 z7QK3RT5MQ*o|64ruz|J4qRk?cWwa04>N9m;KufTH?B)Fi4%Kswh4$Xw&E0{gH`i&B;Zu;a8!Y&R`BYsNA$uhvrl6eZEHxnr8ia@gT`Y zzmnDij|kFqugqI*n&Hze^r&&9iA0T)j9)FcMy`Tb1b?-ukiBw=9B9${z=71|E_gVS zZ0~x-9Ea(u+L=H*EQH1T0sF5L9iWW2H)A1g96m6MjldQjKi0%tc6;ld^Cu@&TXd9=Ozu?a++oy<)4-Ltm%3)YrDXsTJWGyV+> zyw*OonU8M9)ny4Dm6E-a?mG2MeQ!CDZLW1C4Hth_tnR8;rRL?NV{?m7tIdvln(A%# z(t9OVHxK()_PHv?K-qHuZUEuRgCVsNkxGM2I|@PBwA~-t?AltGD;gg##v&R|j_tiQ z*2K?fh%8;jf7KmJ?K`_KUX%QL2KBI{rKxS+MCOuf$rF(SRVBip>XP5)6PX!oQ z0?0;&9}poaitt%OVRZ2#NVz(=N|!v2pltUW&seQPAb3T#CFZ1+j`0=`=-TK@t6WJ& zjrG}8Q%cbs`~&?B4Ehc7ur&aVIcTjfJ$WJp|gx>N4XU~sTikm-X8^%4l= zL^x6_1Q;kkH3WA*E6OCd!4BWi$o+UI}-#vwFEB_6FWb_Me7mTY$ zAmx&@LhQ6m19n3E7h-j%*2i1(8UT(^<3QWJ4|b4aNbQ` z09mcm`dIl34rzcP9<*NLI@d940&L0~YjC3t3nIJ^J=dYyH!uwy6nH`H~bx}nG{4!^pWwrvn%n%3H*HE|^_(*R}E^Vd;+y859hpq5mc|6>m*H*tKJ zC{gM*M+Z>cm4i-_{q_RU_c;e^-L1X1e_X0F4LU_H?-E>^>144dn{``2jgibNYJK;D z5sE|3*wd<4Rwux{#@w|uF^aajW>413npfv{kwRwg=_wE5jovHslzr6>(5|Z6#Zpd7 zduUjOIGpEx=_3&i$c@(bI_)&hx0F?!?D5yR8yCF{4h{NCho zirNzT%%bi~QzjGa_Y~#QIv@sU*pmeU7zHs^vr3?d*_Wdu z;?W1gGLsEVgIhALv(JNM!z+v+kflodsSOwU;lnY)YtZU{Z92E)AU>2rPEKyeVL;JMRZM z+I+Dzg2s5REzT)pxf`4TUfmV}ko;{#j_zJ2DyQ(RH0V6B#b%dH?2hh6q+uIKUQWiP znL62F1C}SL%M*S?Aa&U^CfP6b2_GAdULJ%Fc+Q@H>#cLHuuE8VB}fexYLnnyUA-Lv zBO2ZC7e_03X#ts=13Ah7nf=DzZ*2{U06g#~$CTeX0a_eD-JYu^tqykrdiDVd*n><@w(en!#hTGG7ytf5Z6EHCg{{d9U zm?sS@3-Sc_6J`ANTz;1c!FdYQZ#TgwOi=z9ns6X(8!+*UTMm~3m?I%TM z_7i8oMQtFI1*&?Sx>EmE)o+njrW^brbZ=Z8cYLQ@+j8av<8L-*MaoKXsvPSgJp*3n z2(H9vzHYBEbp@(WEb;G|`fs2;^wy=q^2**)_6F5X4}Jt+BHMrHeZ|j>={?w(w9Z!8 zU}AM=e5=H8Oqf;d9XJ@=jchKhG|1Nynhx0Q*0Aw&m$Z{3lyMluqirf%*-LC3tDc?zlh8W?p6P=|x)RuZ+6C zr3N@plc3Xm4@~78hwuFLpn6z%G_Pd32EAYE2osyOfPpcMZm&>H#pOpAy>w~O@Wisq8Q6xa(c4cd$t9LS-MmFRtrEo z>DH``b*o{c2W4(KyJP-rjcKce0AIvlmn*gl4?jw;NRnIac{G*qS1k5p5%T&%p0LqA|o#v+a~!4>NV_R83 zj{e6hd8bEO{-PFUA=pjhhtd62{#)IY1_2OXxT$52(s{Fs))3sLv4yH=mZFAf4Q)nM zDDG}MUhkv-Z!ON2Vld8v!7R7gK>22*bNvp)e2kHVX*?KI;ZdaU!lkC|I?53U-{^DY z_RCvFXgx(+b#mb~FhildVXyqk9dYmkY}D90$B-H*bdbF#lLAO8WZg%_$beqpb%mL# zN!!|Ot@5v;jS3gis58sZxLH)@cH1gI&BVBXMbewpCf6IHfeHl^m5KvLvEmbG`=x5z zH#QE?uKBfwKAGQ=b=c(ZiYe2i`rV%0$y7jiw^t#2-f5+SS1{w87IQ2F%`YnBmpd_1 zYKq-!c=!daI-^m;DCgB1Ml5Unc}gOZCdI^`14@WEXPXlQducsxK+7jU7_x}xjNI$h znTe7GiZxJ@Ev?p%kUIk~C5{ORUGEX;t@`L#fi(Zk+F}nL9_KQj0rbr+?o=Q19}vhx zndNClwOeg*9|2$9lpR(ufRZs>_z`w#BTwf(TtzWf>A6K{Obh!TyX1b=w?{PE!+Cch z1p!QPV$g05Mt@-i{Q#1T}x11ofMp>f7KHp%ahghy@ zXVCN>-FX{ScUGa0e9`~?1!y9}nJIaipEIyc`?~C7C1n^-`Z9<*Sk%U$ zpk|swwwc$t;h8%9YelGzXd4}uJby}Xjli%WgvoFY!#r*ATaMO+R(S`wst$K!)o$pd zZw7uH0rV@j4V%KAxp7c=%{WtTb|X<>&8DmCCN+q2cWER+i~|Wf0^GzS<+7#ne+y@^ zoT$4++6|(XdZW=UXDc^xIbg&f2TEGbG^Lvx39bTZnfkeEvW5IUDZ&TvAb!-}=8%GS zpZ+j<_a4SC1C56A+(vrVwOR#GxDwp(u1zVFrqZYF1?)7m_ux?WmY=bJ%kIXKk zk9==t#gOgAoNAqWAWZP#)t)t5EX>T;?xCN$08yp+8N#nqRwi8(p6ZjY05?4bUWuh5 zm(1dnj?}8qQ<58F0ISZGzX*g2r2Z?ZtfEvQpruxv{gBV^c`Fj;>jHtHdVIIF-H!zp zqX#YlJiiY8)Q~69$svK*Z{5m}6WL+;m*1D>$)D<^rcfO}>Czd_DVH%t>DfqcDAq)} zdw9DslB2yK0iy8)86%0`sUrU;G>x8 zN$HbXJM54K`|I&8?NPZq+j5fiV6<77o%>!RaYc1`ww{9zef4I*Z;QI7Biq3UDYa3ID^~>iALRAQ#PV}su?d>Ed6?mY z`9`(vqi08Q7~|azVJRsL*5rP7p$iC^XQiM_kdyqH)V&fx#xXrRt#>=%aGaAqT8K1& zayaa+j-}K_skswaeJr$ge0;(l+tkA)mp^94gx zKOCTeHo5|g`;{(2H-j@gY9X;c?6vza9DWb9lQ~^eK>p>b>oU)vIz1C3v8{gNfrqk z#A0!h!d8cr5g}Nz-jud3oCjKn2vxeAHAfCF;=M_leXA1MCeF2=@SI_SE8?kr?r5AE z@I!@)Yk4%gsld;~2g79uQ>r%?MwZcJ>sWPflmt?A zuOqT(cC292LDexLL^g>;cCc$N(%(oUZWoHRPCqVMBmY{Oqz@-S;F*t@&!aKd1@G+r zC~{4RC)eTw3y$z=Pw1&PC@~m6vib6Hc9+wDh}b?5SBJu2KM4KJVqO(Ge8urE+B6-8jB&8gh~#(M0egF1aYiQ zJji9m;~%BvSzT9)YYKhmq9HG{hTFj&r%f(z9@VpVds+Pze<#kxj=#}?c}>#yp{(fL z{*g+mit^16zJDzRl+Rk zydWU-24o|>W_8Y(v!5=o6R?qvjFQWuuu%C`jGAYXrxMmV|5=^;i*0gP`OT$F$ zqq}dkuQ)TQ%#a^W#wXM#>UG~TX0see?44~?F{4PLKp{b;Hf*~zJ4YIQG?g#YpQh$w zHnJ0Z(N`h8s2VNF2~K9ralV=LOiVG&vb?uT-hz;3&Rl7^_jYx4e$QW( zclqi?2#Vh>p)qjF@iQ61@7y0u@CCbQ!O=&-wb{p2W$u^B_ETBGoqoLFpKFcZZ=jD7 zUl<`v3Q;OaFDLpswuYJX@2iYM%VLINhZH5Kql0a&g(oZ5^LdH>j;V(JjK{$w&2K_72ligSuk#S4H@d8BTi?? zKs`PbvVR132j0yAnC~;>GYStC6D#Pw#3$TnJEE%zCJpgT;4^N++@*vIJwKVQ86~&O ztLt4LTwpjq&k5Us398)^u>QE)8`_$zqvMw4Q~q`kpNB6GP`vvho%y&;ccf?6H@&#- z2Wj_e37xQrJC=*zsvNnY7+u$_71(jSIg&em0D_w%NtSYk0%ad}K0C;pbjhKCad~}; zsSiEkkn-Hkth#iP2UrlU;YIjruv{=UOpVaZdRef<7>p7;voj8*(b_(-aN3<`TOH}B?MkU zZ4`^=a%|(;NlBgl#^l$uyR|Rdh#6HDz1aQ}1t;gPrd|^e<@hs@hX!1KPor}LZkzcn zB|q&H1YwYE04)_KL$*ocWoP!rm}jPb=t-AoK;IX?O->-P!^WFl{_*p<;kk}DzBTAjN1oQ4?e1eLxrR!k$nH^R?>7Cv?ujr zB5vLQd1h|xDF|3fpVTXkIn5w?x$3e0UZB@#HfT0E)8d7TdO377Q918lChS0Rvwd*5aeE-a5C!j(n!} zUBEyfxGHWhyO@2@AgFe_yidP+I=up7u>BlvaKLqF(9ssg?6p+`A;b0PoEuRM zWl2^n77~HGk+!R`-{^j}q(2a!`|ML8Q=*Ay4!ym2xCz|m;Hp4#+!+%`=Pc-AdHbeY3|Ly7c=h@-E cI~}9d;G)>T?0l*9!eY0x*}u2I`q0_G1Jff4;Q#;t diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_muted_channel_trailing_bottom.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_muted_channel_trailing_bottom.png index 72c061f99ba0bcb246de536d1834d235f57ccace..592c5e38869bef3f1f90351aa4df58d5292a65ca 100644 GIT binary patch delta 9556 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

&(Gr$#}6L#1NrvU6)w+*H1 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 EA6>i4s{jB1 diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_unread_messages.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelItemTest_unread_messages.png index 2c6f6bbabdea5838f0abd02c5bb851cc912bbf26..d454526cf62b896bda940d6dcacbb34e39ee5389 100644 GIT binary patch literal 23130 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 Fe*wkOyg>i} literal 25318 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 E2YAB7D*ylh From e7ed1814cd0537d0a768bafb08aade61d9c9d867 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:22:40 +0100 Subject: [PATCH 11/22] feat(icons): update channel action and list icons to Figma design system Replace legacy Material-style icons with filled variants from Stream Foundations. All icons now use 16x16 viewport with filled paths for consistent rendering. Mute/unmute switched from speaker to bell icons. --- .../res/drawable/stream_compose_ic_add.xml | 25 ++++++++----------- .../res/drawable/stream_compose_ic_clock.xml | 8 +++--- .../res/drawable/stream_compose_ic_error.xml | 11 ++++---- .../stream_compose_ic_more_options.xml | 10 +++----- .../res/drawable/stream_compose_ic_muted.xml | 7 +++--- .../drawable/stream_compose_message_seen.xml | 7 ++---- .../drawable/stream_compose_message_sent.xml | 7 ++---- .../res/drawable/stream_ic_action_archive.xml | 11 ++++---- .../res/drawable/stream_ic_action_delete.xml | 11 ++++---- .../res/drawable/stream_ic_action_leave.xml | 18 +++---------- .../res/drawable/stream_ic_action_more.xml | 10 +++----- .../res/drawable/stream_ic_action_mute.xml | 10 +++----- .../res/drawable/stream_ic_action_pin.xml | 10 ++++---- .../res/drawable/stream_ic_action_unmute.xml | 10 +++----- .../res/drawable/stream_ic_action_unpin.xml | 15 +++-------- .../drawable/stream_ic_action_view_info.xml | 10 +++----- 16 files changed, 68 insertions(+), 112 deletions(-) diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_add.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_add.xml index ab429e4e5b5..cce7cbe49a2 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_add.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_add.xml @@ -15,20 +15,15 @@ limitations under the License. --> - + android:width="24dp" + android:height="24dp" + android:viewportWidth="16" + android:viewportHeight="16"> - + android:fillColor="#FF000000" + android:fillType="evenOdd" + android:pathData="M4.61305,2.00002H7.5C7.77613,2.00002 8,2.22388 8,2.50002C8,2.77616 7.77613,3.00002 7.5,3.00002H4.63333C4.25171,3.00002 3.99557,3.00041 3.79832,3.01653C3.60691,3.03217 3.51538,3.06009 3.45501,3.09085C3.29821,3.17074 3.17072,3.29823 3.09083,3.45503C3.06007,3.5154 3.03215,3.60692 3.01651,3.79834C3.00039,3.99559 3,4.25173 3,4.63335V11.3667C3,11.7483 3.00039,12.0044 3.01651,12.2017C3.03215,12.3931 3.06007,12.4846 3.09083,12.545C3.17072,12.7018 3.29821,12.8293 3.45501,12.9092C3.51538,12.94 3.60691,12.9679 3.79832,12.9835C3.99557,12.9996 4.25171,13 4.63333,13H11.3667C11.7483,13 12.0044,12.9996 12.2017,12.9835C12.3931,12.9679 12.4846,12.94 12.545,12.9092C12.7018,12.8293 12.8293,12.7018 12.9092,12.545C12.9399,12.4846 12.9679,12.3931 12.9835,12.2017C12.9996,12.0044 13,11.7483 13,11.3667V8.50002C13,8.22389 13.2239,8.00002 13.5,8.00002C13.7761,8.00002 14,8.22389 14,8.50002V11.387C14,11.7431 14,12.0403 13.9802,12.2832C13.9595,12.5364 13.9147,12.7742 13.8002,12.999C13.6244,13.344 13.3439,13.6244 12.999,13.8002C12.7741,13.9148 12.5364,13.9595 12.2831,13.9802C12.0403,14 11.7431,14 11.387,14H4.61303C4.25693,14 3.95971,14 3.71689,13.9802C3.46363,13.9595 3.22586,13.9148 3.00102,13.8002C2.65605,13.6244 2.37559,13.344 2.19982,12.999C2.08526,12.7742 2.04052,12.5364 2.01983,12.2832C1.99999,12.0403 1.99999,11.7431 2,11.387V4.61306C1.99999,4.25696 1.99999,3.95973 2.01983,3.71691C2.04052,3.46365 2.08526,3.22588 2.19982,3.00104C2.37559,2.65607 2.65605,2.37561 3.00102,2.19984C3.22586,2.08528 3.46363,2.04054 3.71689,2.01985C3.95971,2.00001 4.25694,2.00001 4.61305,2.00002Z" /> + diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_clock.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_clock.xml index 74c38c6fdc2..37cf3f14177 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_clock.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_clock.xml @@ -20,9 +20,7 @@ android:viewportWidth="16" android:viewportHeight="16"> + android:fillColor="#FF000000" + android:fillType="evenOdd" + android:pathData="M8.00004,14.6666C11.6819,14.6666 14.6667,11.6818 14.6667,7.99998C14.6667,4.31808 11.6819,1.33331 8.00004,1.33331C4.31814,1.33331 1.33337,4.31808 1.33337,7.99998C1.33337,11.6818 4.31814,14.6666 8.00004,14.6666ZM8.50004,5.16665C8.50004,4.89051 8.27617,4.66665 8.00004,4.66665C7.72391,4.66665 7.50004,4.89051 7.50004,5.16665V7.99998C7.50004,8.13258 7.55271,8.25978 7.64651,8.35351L9.47984,10.1868C9.67511,10.3821 9.99164,10.3821 10.1869,10.1868C10.3822,9.99158 10.3822,9.67505 10.1869,9.47978L8.50004,7.79285V5.16665Z" /> diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_error.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_error.xml index 6d6fd934674..66d4c1cbd2f 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_error.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_error.xml @@ -17,11 +17,10 @@ + android:viewportWidth="16" + android:viewportHeight="16"> + android:fillColor="#FF000000" + android:fillType="evenOdd" + android:pathData="M8.00004,1.33331C11.6819,1.33331 14.6667,4.31808 14.6667,7.99998C14.6667,11.6818 11.6819,14.6666 8.00004,14.6666C4.31814,14.6666 1.33337,11.6818 1.33337,7.99998C1.33337,4.31808 4.31814,1.33331 8.00004,1.33331ZM8.00004,9.66665C7.63184,9.66665 7.33337,9.96511 7.33337,10.3333C7.33345,10.7014 7.63189,11 8.00004,11C8.3682,11 8.66663,10.7014 8.66671,10.3333C8.66671,9.96511 8.36824,9.66665 8.00004,9.66665ZM8.00004,5.33331C7.72391,5.33331 7.50004,5.55717 7.50004,5.83331V8.49998C7.50011,8.77605 7.72395,8.99998 8.00004,8.99998C8.27613,8.99998 8.49997,8.77605 8.50004,8.49998V5.83331C8.50004,5.55717 8.27617,5.33331 8.00004,5.33331Z" /> diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_options.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_options.xml index eb37dd78b04..f54561e9b7a 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_options.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_options.xml @@ -17,11 +17,9 @@ + android:viewportWidth="16" + android:viewportHeight="16"> + android:fillColor="#FF000000" + android:pathData="M3.91635,8.00037C3.91618,8.78253 3.28247,9.41621 2.50034,9.41638C1.76683,9.41638 1.16271,8.85929 1.09018,8.1449L1.08334,8.00037L1.09018,7.85486C1.16286,7.14062 1.76694,6.58337 2.50034,6.58337L2.64487,6.59021C3.35924,6.66274 3.91635,7.26683 3.91635,8.00037ZM9.41635,8.00037C9.41618,8.78252 8.78249,9.41621 8.00034,9.41638C7.26681,9.41638 6.66271,8.85929 6.59018,8.1449L6.58334,8.00037L6.59018,7.85486C6.66286,7.14062 7.26692,6.58337 8.00034,6.58337L8.14487,6.59021C8.85926,6.66274 9.41635,7.26684 9.41635,8.00037ZM14.9164,8.00037C14.9162,8.78252 14.2825,9.41621 13.5003,9.41638C12.7668,9.41638 12.1627,8.85929 12.0902,8.1449L12.0833,8.00037L12.0902,7.85486C12.1629,7.14062 12.7669,6.58337 13.5003,6.58337L13.6449,6.59021C14.3593,6.66274 14.9164,7.26684 14.9164,8.00037Z" /> diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_muted.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_muted.xml index e891c5f4f9a..cb12bf0f1d2 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_muted.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_muted.xml @@ -19,8 +19,7 @@ android:height="16dp" android:viewportWidth="16" android:viewportHeight="16"> - + diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_message_seen.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_message_seen.xml index dffb9f8cd18..4f6d76d71a9 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_message_seen.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_message_seen.xml @@ -20,9 +20,6 @@ android:viewportWidth="16" android:viewportHeight="16"> + android:fillColor="#FF000000" + android:pathData="M9.74121,3.43164C9.9169,3.15085 10.2874,3.06564 10.5684,3.24121C10.8492,3.41691 10.9344,3.78745 10.7588,4.06836L5.44629,12.5684C5.34945,12.7231 5.18722,12.8249 5.00586,12.8457C4.82419,12.8664 4.64297,12.8031 4.51367,12.6738L1.32617,9.48633C1.09186,9.25202 1.09186,8.87299 1.32617,8.63868C1.56049,8.40436 1.93951,8.40436 2.17383,8.63868L4.82715,11.292L9.74121,3.43164ZM13.7412,3.43164C13.9169,3.15085 14.2874,3.06564 14.5684,3.24121C14.8492,3.41691 14.9344,3.78745 14.7588,4.06836L9.44629,12.5684C9.2706,12.8492 8.90006,12.9344 8.61914,12.7588C8.33835,12.5831 8.25314,12.2126 8.42871,11.9316L13.7412,3.43164Z" /> diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_message_sent.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_message_sent.xml index c721d5edb3c..4c300f2cc6e 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_message_sent.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_message_sent.xml @@ -20,9 +20,6 @@ android:viewportWidth="16" android:viewportHeight="16"> + android:fillColor="#FF000000" + android:pathData="M11.7412,3.43164C11.9169,3.15085 12.2874,3.06564 12.5684,3.24121C12.8492,3.41691 12.9344,3.78745 12.7588,4.06836L7.44629,12.5684C7.34945,12.7231 7.18722,12.8249 7.00586,12.8457C6.82419,12.8664 6.64297,12.8031 6.51367,12.6738L3.32617,9.48633C3.09186,9.25202 3.09186,8.87299 3.32617,8.63867C3.56049,8.40436 3.93951,8.40436 4.17383,8.63867L6.82715,11.292L11.7412,3.43164Z" /> diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_archive.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_archive.xml index cec4155be38..cbbd91b57c5 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_archive.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_archive.xml @@ -17,10 +17,9 @@ - + android:viewportWidth="16" + android:viewportHeight="16"> + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_delete.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_delete.xml index 8206790e59f..0d3c615ae87 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_delete.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_delete.xml @@ -17,10 +17,9 @@ - + android:viewportWidth="16" + android:viewportHeight="16"> + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_leave.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_leave.xml index 6da43ae63fc..c687cead6fa 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_leave.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_leave.xml @@ -17,19 +17,9 @@ + android:viewportWidth="16" + android:viewportHeight="16"> - - + android:fillColor="#FF000000" + android:pathData="M1.90039,12.167V3.83301C1.90057,2.76552 2.76552,1.90057 3.83301,1.90039H7.5C7.83137,1.90039 8.09961,2.16863 8.09961,2.5C8.09961,2.83137 7.83137,3.09961 7.5,3.09961H3.83301C3.42826,3.09979 3.09979,3.42826 3.09961,3.83301V12.167C3.09978,12.5718 3.42825,12.9002 3.83301,12.9004H7.5C7.83137,12.9004 8.09961,13.1686 8.09961,13.5C8.09961,13.8314 7.83137,14.0996 7.5,14.0996H3.83301C2.76552,14.0994 1.90057,13.2345 1.90039,12.167ZM10.0762,4.57617C10.3105,4.34186 10.6895,4.34186 10.9238,4.57617L13.9238,7.57617C14.1581,7.81049 14.1581,8.18951 13.9238,8.42383L10.9238,11.4238C10.6895,11.6581 10.3105,11.6581 10.0762,11.4238C9.84186,11.1895 9.84186,10.8105 10.0762,10.5762L12.0527,8.59961H6C5.66863,8.59961 5.40039,8.33137 5.40039,8C5.40039,7.66863 5.66863,7.40039 6,7.40039H12.0527L10.0762,5.42383C9.84186,5.18951 9.84186,4.81049 10.0762,4.57617Z" /> diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_more.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_more.xml index eb37dd78b04..f54561e9b7a 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_more.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_more.xml @@ -17,11 +17,9 @@ + android:viewportWidth="16" + android:viewportHeight="16"> + android:fillColor="#FF000000" + android:pathData="M3.91635,8.00037C3.91618,8.78253 3.28247,9.41621 2.50034,9.41638C1.76683,9.41638 1.16271,8.85929 1.09018,8.1449L1.08334,8.00037L1.09018,7.85486C1.16286,7.14062 1.76694,6.58337 2.50034,6.58337L2.64487,6.59021C3.35924,6.66274 3.91635,7.26683 3.91635,8.00037ZM9.41635,8.00037C9.41618,8.78252 8.78249,9.41621 8.00034,9.41638C7.26681,9.41638 6.66271,8.85929 6.59018,8.1449L6.58334,8.00037L6.59018,7.85486C6.66286,7.14062 7.26692,6.58337 8.00034,6.58337L8.14487,6.59021C8.85926,6.66274 9.41635,7.26684 9.41635,8.00037ZM14.9164,8.00037C14.9162,8.78252 14.2825,9.41621 13.5003,9.41638C12.7668,9.41638 12.1627,8.85929 12.0902,8.1449L12.0833,8.00037L12.0902,7.85486C12.1629,7.14062 12.7669,6.58337 13.5003,6.58337L13.6449,6.59021C14.3593,6.66274 14.9164,7.26684 14.9164,8.00037Z" /> diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml index ccb20f4a864..ebdacf7af00 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml @@ -17,11 +17,9 @@ + android:viewportWidth="16" + android:viewportHeight="16"> + android:fillColor="#FF000000" + android:pathData="M1.4095,1.40955C1.64382,1.17523 2.02284,1.17523 2.25716,1.40955L14.5911,13.7426C14.8253,13.9769 14.8254,14.3569 14.5911,14.5912C14.3569,14.8254 13.9768,14.8253 13.7425,14.5912L11.2161,12.0648C10.9485,13.5995 9.61156,14.7668 8.00032,14.767C6.40119,14.767 5.07116,13.6174 4.78938,12.1H3.86458C2.69143,12.1 1.78874,11.0638 1.94954,9.90173L2.46321,6.1947C2.54989,5.40694 2.79885,4.67213 3.17415,4.02185L1.4095,2.2572C1.17519,2.02289 1.17519,1.64386 1.4095,1.40955ZM6.02278,12.1C6.27995,12.9486 7.06769,13.5668 8.00032,13.5668C8.93286,13.5666 9.72077,12.9486 9.97786,12.1H6.02278ZM8.00032,1.23376C10.8481,1.23393 13.2373,3.38151 13.5394,6.21326L14.0081,10.6029C14.0433,10.9323 13.8043,11.2278 13.4749,11.2631C13.1456,11.2982 12.8502,11.0601 12.8148,10.7308L12.346,6.34021C12.1088,4.11863 10.2345,2.43315 8.00032,2.43298C7.14091,2.43298 6.3354,2.682 5.65559,3.11462C5.37609,3.29252 5.00543,3.21047 4.82747,2.93103C4.64957,2.65154 4.73165,2.28088 5.01106,2.10291C5.87798,1.55112 6.9061,1.23376 8.00032,1.23376ZM4.06184,4.90955C3.8504,5.34884 3.70814,5.82975 3.65364,6.34021C3.65297,6.34646 3.65255,6.35351 3.65169,6.35974L3.13802,10.0658C3.07692,10.5067 3.41955,10.8998 3.86458,10.8998H10.0511L4.06184,4.90955Z" /> diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_pin.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_pin.xml index 52d2e19fd43..05f29cc7239 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_pin.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_pin.xml @@ -17,9 +17,9 @@ - + android:viewportWidth="16" + android:viewportHeight="16"> + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml index d90f8a706ee..6d35f3b5e32 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml @@ -17,11 +17,9 @@ + android:viewportWidth="16" + android:viewportHeight="16"> + android:fillColor="#FF000000" + android:pathData="M12.8926,10.7972L12.0674,9.19757C11.9412,8.95287 11.8684,8.68417 11.8545,8.40948L11.7314,5.97003C11.632,3.99113 9.99271,2.43292 8,2.43292C6.00726,2.43292 4.368,3.99015 4.26855,5.96906L4.14453,8.40948C4.13061,8.68431 4.0587,8.95302 3.93262,9.19757L3.10742,10.7972C3.1024,10.807 3.09961,10.8182 3.09961,10.8294C3.09962,10.8684 3.1319,10.8997 3.1709,10.8997H12.8291C12.8681,10.8997 12.9004,10.8684 12.9004,10.8294C12.9004,10.8183 12.8977,10.8071 12.8926,10.7972ZM6.02246,12.0999C6.2796,12.9486 7.06733,13.5667 8,13.5667C8.93265,13.5667 9.72039,12.9486 9.97754,12.0999H6.02246ZM14.0996,10.8294C14.0996,11.5311 13.5308,12.0999 12.8291,12.0999H11.2109C10.9292,13.6174 9.59912,14.7669 8,14.7669C6.40085,14.7669 5.07082,13.6174 4.78906,12.0999H3.1709C2.46916,12.0999 1.90041,11.5311 1.90039,10.8294C1.90039,10.627 1.94825,10.4274 2.04102,10.2474L2.86621,8.64777C2.91399,8.5551 2.94099,8.45314 2.94629,8.34894L3.06934,5.90948C3.20084,3.28834 5.37132,1.2337 8,1.2337C10.6286,1.2337 12.7992,3.28834 12.9307,5.90948L13.0537,8.34894C13.059,8.45327 13.0861,8.55526 13.1338,8.64777L13.959,10.2474C14.0517,10.4273 14.0996,10.6269 14.0996,10.8294Z" /> diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unpin.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unpin.xml index 4b0b05d6be0..ad378670cff 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unpin.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unpin.xml @@ -17,16 +17,9 @@ + android:viewportWidth="16" + android:viewportHeight="16"> - + android:fillColor="#FF000000" + android:pathData="M1.4095,1.40883C1.64373,1.17494 2.02292,1.17494 2.25716,1.40883L5.70833,4.86C5.76709,4.90037 5.81732,4.95143 5.85872,5.01039L10.9886,10.1403C11.0477,10.1815 11.0985,10.232 11.139,10.2907L14.5911,13.7428C14.825,13.977 14.825,14.3562 14.5911,14.5905C14.3568,14.8248 13.9768,14.8248 13.7425,14.5905L11.057,11.9049L10.9935,12.3239C10.7527,13.889 8.83493,14.5168 7.71516,13.3971L5.58235,11.2643L2.92415,13.9244C2.68982,14.1586 2.30978,14.1587 2.07552,13.9244C1.84126,13.6902 1.84136,13.3101 2.07552,13.0758L4.7347,10.4166L2.60286,8.2848C1.48313,7.16502 2.11092,5.24728 3.6761,5.00648L4.09407,4.94203L1.4095,2.25746C1.17519,2.02314 1.17519,1.64314 1.4095,1.40883ZM3.85872,6.193C3.26504,6.28434 3.02678,7.01141 3.45149,7.43617L5.9554,9.94105C5.974,9.9556 5.99389,9.96892 6.01106,9.98597C6.0297,10.0045 6.04517,10.0253 6.06087,10.0455L8.5638,12.5485C8.98857,12.9732 9.71563,12.7349 9.80696,12.1412L10.0052,10.8532L5.14583,5.99379L3.85872,6.193ZM8.31184,2.27015C8.88859,1.06869 10.4788,0.797511 11.4212,1.73988L14.2601,4.57875C15.2024,5.52112 14.9312,7.11137 13.7298,7.68812L13.7288,7.6891L11.5911,8.70863C11.2921,8.85086 10.9339,8.72337 10.7913,8.42445C10.6491,8.12546 10.7766,7.7672 11.0755,7.62465L13.2122,6.60609C13.6666,6.38673 13.7685,5.78445 13.4115,5.42738L10.5726,2.58851C10.2151,2.23106 9.61164,2.33396 9.3929,2.78968L8.37532,4.92445C8.23277,5.22337 7.87451,5.35086 7.57552,5.20863C7.27659,5.06608 7.1491,4.70782 7.29134,4.40882L8.31087,2.27113L8.31184,2.27015Z" /> diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_view_info.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_view_info.xml index 8f5c15502d5..fd381147c4e 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_view_info.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_view_info.xml @@ -17,11 +17,9 @@ + android:viewportWidth="16" + android:viewportHeight="16"> + android:fillColor="#FF000000" + android:pathData="M13.5667,8.00031C13.5667,4.92603 11.0745,2.4331 8.00033,2.43292C4.92595,2.43292 2.43295,4.92592 2.43295,8.00031C2.43312,11.0745 4.92606,13.5667 8.00033,13.5667C11.0744,13.5665 13.5666,11.0744 13.5667,8.00031ZM7.39974,10.8333V7.93292H7.16634C6.83512,7.93275 6.56673,7.66458 6.56673,7.33331C6.56673,7.00205 6.83512,6.73388 7.16634,6.7337H8.00033C8.33155,6.73388 8.59994,7.00205 8.59994,7.33331V10.8333C8.59994,11.1646 8.33155,11.4327 8.00033,11.4329C7.66896,11.4329 7.39974,11.1647 7.39974,10.8333ZM7.91634,5.14972C7.81524,5.14989 7.73373,5.23219 7.73373,5.33331L7.7474,5.4046C7.77515,5.47041 7.84047,5.51678 7.91634,5.51691C8.01759,5.51691 8.09994,5.43455 8.09994,5.33331C8.09993,5.23208 8.01759,5.14972 7.91634,5.14972ZM14.7669,8.00031C14.7668,11.7372 11.7372,14.7667 8.00033,14.7669C4.26331,14.7669 1.2339,11.7373 1.23373,8.00031C1.23373,4.26318 4.2632,1.2337 8.00033,1.2337C11.7373,1.23388 14.7669,4.26329 14.7669,8.00031ZM8.93295,5.33331C8.93295,5.89479 8.47786,6.34991 7.91634,6.34991C7.35498,6.34974 6.89974,5.89468 6.89974,5.33331C6.89974,4.77194 7.35498,4.31689 7.91634,4.31671L8.02084,4.32159C8.53343,4.37374 8.93294,4.80699 8.93295,5.33331Z" /> From 7133df2c6f8e79d93a7a87afba0561bf9ea42302 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:27:20 +0100 Subject: [PATCH 12/22] fix(icons): correct mute/unmute and add icon mappings Mute/unmute: use IconMute (speaker) and IconVolumeFull instead of bell icons. Add: use IconPlusLarge (plus) instead of IconEditBigSolid (pen). --- .../src/main/res/drawable/stream_compose_ic_add.xml | 6 +----- .../src/main/res/drawable/stream_compose_ic_muted.xml | 6 +++++- .../src/main/res/drawable/stream_ic_action_mute.xml | 6 +++++- .../src/main/res/drawable/stream_ic_action_unmute.xml | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_add.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_add.xml index cce7cbe49a2..e36ba0fb939 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_add.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_add.xml @@ -21,9 +21,5 @@ android:viewportHeight="16"> - + android:pathData="M7.40039,13.5V8.59961H2.5C2.16863,8.59961 1.90039,8.33137 1.90039,8C1.90039,7.66863 2.16863,7.40039 2.5,7.40039H7.40039V2.5C7.40039,2.16863 7.66863,1.90039 8,1.90039C8.33137,1.90039 8.59961,2.16863 8.59961,2.5V7.40039H13.5C13.8314,7.40039 14.0996,7.66863 14.0996,8C14.0996,8.33137 13.8314,8.59961 13.5,8.59961H8.59961V13.5C8.59961,13.8314 8.33137,14.0996 8,14.0996C7.66863,14.0996 7.40039,13.8314 7.40039,13.5Z" /> diff --git a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_muted.xml b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_muted.xml index cb12bf0f1d2..15a6526a235 100644 --- a/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_muted.xml +++ b/stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_muted.xml @@ -21,5 +21,9 @@ android:viewportHeight="16"> + android:fillType="evenOdd" + android:pathData="M11.3333,3.95956V2.81723C11.3333,2.13798 10.5643,1.74407 10.0131,2.14095L6.72353,4.50943C6.5817,4.61155 6.41136,4.66649 6.2366,4.66649H5.16666C4.15414,4.66649 3.33333,5.4873 3.33333,6.49982V9.4998C3.33333,10.1667 3.68936,10.7503 4.22171,11.0712L2.14645,13.1465C1.95119,13.3417 1.95119,13.6583 2.14645,13.8535C2.34171,14.0488 2.65829,14.0488 2.85355,13.8535L13.8535,2.85355C14.0488,2.65829 14.0488,2.34171 13.8535,2.14645C13.6583,1.95119 13.3417,1.95119 13.1465,2.14645L11.3333,3.95956ZM4.98059,10.3123C4.60992,10.2277 4.33333,9.89607 4.33333,9.4998V6.49982C4.33333,6.03959 4.70642,5.66649 5.16666,5.66649H6.2366C6.62107,5.66649 6.9958,5.54561 7.3078,5.32097L10.3333,3.14261V4.95956L4.98059,10.3123Z" /> + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml index ebdacf7af00..980937e003f 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_mute.xml @@ -21,5 +21,9 @@ android:viewportHeight="16"> + android:fillType="evenOdd" + android:pathData="M11.3333,3.95956V2.81723C11.3333,2.13798 10.5643,1.74407 10.0131,2.14095L6.72353,4.50943C6.5817,4.61155 6.41136,4.66649 6.2366,4.66649H5.16666C4.15414,4.66649 3.33333,5.4873 3.33333,6.49982V9.4998C3.33333,10.1667 3.68936,10.7503 4.22171,11.0712L2.14645,13.1465C1.95119,13.3417 1.95119,13.6583 2.14645,13.8535C2.34171,14.0488 2.65829,14.0488 2.85355,13.8535L13.8535,2.85355C14.0488,2.65829 14.0488,2.34171 13.8535,2.14645C13.6583,1.95119 13.3417,1.95119 13.1465,2.14645L11.3333,3.95956ZM4.98059,10.3123C4.60992,10.2277 4.33333,9.89607 4.33333,9.4998V6.49982C4.33333,6.03959 4.70642,5.66649 5.16666,5.66649H6.2366C6.62107,5.66649 6.9958,5.54561 7.3078,5.32097L10.3333,3.14261V4.95956L4.98059,10.3123Z" /> + diff --git a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml index 6d35f3b5e32..afbafe0dc56 100644 --- a/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml +++ b/stream-chat-android-ui-common/src/main/res/drawable/stream_ic_action_unmute.xml @@ -21,5 +21,5 @@ android:viewportHeight="16"> + android:pathData="M14.2331,8.00005C14.2331,6.2786 13.5365,4.72053 12.4079,3.59185C12.1736,3.35753 12.1736,2.97752 12.4079,2.74322C12.6422,2.50928 13.0223,2.50906 13.2565,2.74322C14.601,4.08773 15.4333,5.94755 15.4333,8.00005C15.4332,10.0523 14.6008,11.9115 13.2565,13.2559C13.0222,13.4902 12.6422,13.4901 12.4079,13.2559C12.1736,13.0216 12.1736,12.6416 12.4079,12.4073C13.5364,11.2787 14.233,9.72126 14.2331,8.00005ZM11.067,8.00005C11.067,7.15323 10.724,6.38764 10.1686,5.83209C9.9343,5.59778 9.93432,5.21777 10.1686,4.98345C10.4029,4.74914 10.7829,4.74914 11.0172,4.98345C11.7885,5.75485 12.2662,6.82219 12.2663,8.00005C12.2663,9.1781 11.7887,10.2462 11.0172,11.0176C10.783,11.2518 10.4029,11.2516 10.1686,11.0176C9.93432,10.7833 9.93437,10.4033 10.1686,10.169C10.7242,9.61339 11.067,8.84707 11.067,8.00005ZM8.76627,13.1827C8.76619,13.9433 7.90514,14.3841 7.28775,13.9395L3.99869,11.5713C3.87395,11.4815 3.7238,11.4337 3.56998,11.4336H2.49966C1.4321,11.4335 0.567092,10.5677 0.567047,9.50005V6.50005C0.567047,5.43241 1.43206,4.56664 2.49966,4.56646H3.56998C3.72375,4.56645 3.87389,4.51862 3.99869,4.42877L7.28775,2.05962L7.40591,1.98638C8.00924,1.6713 8.76627,2.1041 8.76627,2.81744V13.1827ZM1.76627,9.50005C1.76631,9.90493 2.09483,10.2333 2.49966,10.2335H3.56998C3.97535,10.2335 4.37078,10.3607 4.69986,10.5977L7.56705,12.6612V3.33795L4.69986,5.4024C4.37084,5.63929 3.9754,5.76665 3.56998,5.76666H2.49966C2.0948,5.76683 1.76627,6.09515 1.76627,6.50005V9.50005Z" /> From c4e96f1d25cc758eb6af1c19a1e0b67508e6b45d Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:29:18 +0100 Subject: [PATCH 13/22] fix(channels): move Leave to end as destructive action Reorder channel actions: ViewInfo, Mute, Pin, Archive, Leave, Delete. Destructive actions (Leave, Delete) are now grouped last. Mark LeaveGroup as isDestructive = true. --- .../ui/components/channels/ChannelOptions.kt | 32 +++++++++---------- .../state/channels/actions/ChannelAction.kt | 1 + 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt index 0e6ca3d55c5..f1ed5a8fcd7 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt @@ -118,6 +118,22 @@ public fun buildDefaultChannelActions( } else { null }, + buildMuteAction( + canMuteChannel = optionVisibility.isMuteChannelVisible && canMuteChannel, + isMuted = isMuted, + selectedChannel = selectedChannel, + viewModel = viewModel, + ), + buildPinAction( + canPinChannel = optionVisibility.isPinChannelVisible, + selectedChannel = selectedChannel, + viewModel = viewModel, + ), + buildArchiveAction( + canArchiveChannel = optionVisibility.isArchiveChannelVisible, + selectedChannel = selectedChannel, + viewModel = viewModel, + ), if (optionVisibility.isLeaveChannelVisible && canLeaveChannel) { LeaveGroup( channel = selectedChannel, @@ -139,22 +155,6 @@ public fun buildDefaultChannelActions( } else { null }, - buildMuteAction( - canMuteChannel = optionVisibility.isMuteChannelVisible && canMuteChannel, - isMuted = isMuted, - selectedChannel = selectedChannel, - viewModel = viewModel, - ), - buildPinAction( - canPinChannel = optionVisibility.isPinChannelVisible, - selectedChannel = selectedChannel, - viewModel = viewModel, - ), - buildArchiveAction( - canArchiveChannel = optionVisibility.isArchiveChannelVisible, - selectedChannel = selectedChannel, - viewModel = viewModel, - ), if (optionVisibility.isDeleteChannelVisible && canDeleteChannel) { DeleteConversation( channel = selectedChannel, diff --git a/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction.kt b/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction.kt index 476e9efd4a4..9abe4b2a6a5 100644 --- a/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction.kt +++ b/stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channels/actions/ChannelAction.kt @@ -69,6 +69,7 @@ public class LeaveGroup( @DrawableRes override val icon: Int = R.drawable.stream_ic_action_leave override val requiredCapability: String = ChannelCapabilities.LEAVE_CHANNEL + override val isDestructive: Boolean = true } /** From d4500ddc5733783856ff75f7bd22393c84d97d54 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:35:27 +0100 Subject: [PATCH 14/22] feat(channels): redesign bottom sheet header with group avatar Replace horizontal member list with compact header: channel avatar (left) + channel name + member count/status (right). Matches Figma Channel Detail Sheet design. --- .../ui/channels/info/SelectedChannelMenu.kt | 79 +++++++++++-------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt index dbaafdad643..78373eb39ce 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/info/SelectedChannelMenu.kt @@ -17,10 +17,13 @@ package io.getstream.chat.android.compose.ui.channels.info import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text @@ -30,16 +33,14 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import io.getstream.chat.android.compose.ui.components.SimpleMenu -import io.getstream.chat.android.compose.ui.components.channels.ChannelMembers +import io.getstream.chat.android.compose.ui.components.avatar.AvatarSize import io.getstream.chat.android.compose.ui.theme.ChatTheme import io.getstream.chat.android.compose.ui.theme.StreamTokens import io.getstream.chat.android.compose.ui.util.getMembersStatusText -import io.getstream.chat.android.compose.ui.util.isOneToOne import io.getstream.chat.android.models.Channel import io.getstream.chat.android.models.User import io.getstream.chat.android.previewdata.PreviewChannelData @@ -112,44 +113,52 @@ internal fun DefaultSelectedChannelMenuHeaderContent( selectedChannel: Channel, currentUser: User?, ) { - val channelMembers = selectedChannel.members - val membersToDisplay = if (selectedChannel.isOneToOne(currentUser)) { - channelMembers.filter { it.user.id != currentUser?.id } - } else { - channelMembers - } - - Text( + Row( modifier = Modifier .fillMaxWidth() .padding( - start = StreamTokens.spacingMd, // 16dp (was 16.dp, now token-aligned) - end = StreamTokens.spacingMd, // 16dp (was 16.dp) - top = StreamTokens.spacingMd, // 16dp (was 16.dp) + start = StreamTokens.spacingMd, + end = StreamTokens.spacingMd, + top = StreamTokens.spacingMd, + bottom = StreamTokens.spacingSm, ), - textAlign = TextAlign.Center, - text = ChatTheme.channelNameFormatter.formatChannelName(selectedChannel, currentUser), - style = ChatTheme.typography.headingSmall, // was title3Bold (18sp/W500) - color = ChatTheme.colors.textPrimary, // was textHighEmphasis - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text( - modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Center, - text = selectedChannel.getMembersStatusText( - context = LocalContext.current, + verticalAlignment = Alignment.CenterVertically, + ) { + ChatTheme.componentFactory.ChannelAvatar( + modifier = Modifier.size(AvatarSize.ExtraLarge), + channel = selectedChannel, currentUser = currentUser, - userPresence = ChatTheme.userPresence, - ), - style = ChatTheme.typography.captionDefault, // was footnoteBold - color = ChatTheme.colors.textSecondary, // was textLowEmphasis - ) + showIndicator = true, + showBorder = false, + ) - ChannelMembers( - members = membersToDisplay, - currentUser = currentUser, - ) + Column( + modifier = Modifier + .padding(start = StreamTokens.spacingSm) + .weight(1f), + ) { + Text( + text = ChatTheme.channelNameFormatter.formatChannelName( + selectedChannel, + currentUser, + ), + style = ChatTheme.typography.headingSmall, + color = ChatTheme.colors.textPrimary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + Text( + text = selectedChannel.getMembersStatusText( + context = LocalContext.current, + currentUser = currentUser, + userPresence = ChatTheme.userPresence, + ), + style = ChatTheme.typography.captionDefault, + color = ChatTheme.colors.textSecondary, + maxLines = 1, + ) + } + } } /** From d329a4d11b1fc74131d5629c2158b89f516135a6 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:40:22 +0100 Subject: [PATCH 15/22] fix(channels): use headingSmall for channel name, icon-only swipe actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Channel list title: bodyDefault → headingSmall (semi-bold) to match Figma. Swipe actions: remove text label, show icon only in a centered Box. --- .../compose/ui/channels/list/ChannelItem.kt | 2 +- .../compose/ui/channels/list/SwipeActionItem.kt | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelItem.kt index 7371a21b418..cfee61943f5 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/ChannelItem.kt @@ -251,7 +251,7 @@ internal fun RowScope.DefaultChannelItemCenterContent( .testTag("Stream_ChannelName") .weight(1f, fill = false), text = ChatTheme.channelNameFormatter.formatChannelName(channel, currentUser), - style = ChatTheme.typography.bodyDefault, + style = ChatTheme.typography.headingSmall, maxLines = 1, overflow = TextOverflow.Ellipsis, color = ChatTheme.colors.textPrimary, diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt index 2e4eb47f45c..ae7e1409fb9 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt @@ -18,19 +18,16 @@ package io.getstream.chat.android.compose.ui.channels.list import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material3.Icon -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import io.getstream.chat.android.compose.ui.theme.ChatTheme @@ -53,14 +50,13 @@ public fun SwipeActionItem( contentColor: Color, modifier: Modifier = Modifier, ) { - Column( + Box( modifier = modifier .width(80.dp) .fillMaxHeight() .background(backgroundColor) .clickable(onClick = onClick), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, + contentAlignment = Alignment.Center, ) { Icon( painter = icon, @@ -68,13 +64,6 @@ public fun SwipeActionItem( tint = contentColor, modifier = Modifier.size(24.dp), ) - Text( - text = label, - style = ChatTheme.typography.captionEmphasis, - color = contentColor, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) } } From 6ebb8a0b6435f1870df40b360580a04e4c3c176c Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:42:36 +0100 Subject: [PATCH 16/22] fix(swipe): use backgroundCoreSurface for secondary action Light gray background with dark icon instead of dark slate500 with white icon. Matches Figma swipe action design. --- .../chat/android/compose/ui/channels/list/SwipeActionItem.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt index ae7e1409fb9..95b0264a5e2 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channels/list/SwipeActionItem.kt @@ -87,7 +87,7 @@ public fun SwipeActionItem( val colors = ChatTheme.colors val (bg, content) = when (style) { SwipeActionStyle.Primary -> colors.accentPrimary to Color.White - SwipeActionStyle.Secondary -> colors.accentNeutral to Color.White + SwipeActionStyle.Secondary -> colors.backgroundCoreSurface to colors.textPrimary SwipeActionStyle.Destructive -> colors.accentError to Color.White } SwipeActionItem( From 89829198eab50abfc9c456a0398d1b7b43f93bbc Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:43:59 +0100 Subject: [PATCH 17/22] fix(channels): reduce bottom sheet action item size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Item height 56dp → 48dp, icon container 56dp → 48dp with 12dp padding (24dp icon). More compact to match Figma design. --- .../chat/android/compose/ui/theme/ChatComponentFactory.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt index 2f428f3978d..083ae07c7b4 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt @@ -2204,7 +2204,7 @@ public interface ChatComponentFactory { }, onClick = onClick, style = ChatTheme.typography.bodyDefault, - itemHeight = 56.dp, + itemHeight = 48.dp, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start, ) @@ -2224,8 +2224,8 @@ public interface ChatComponentFactory { } Icon( modifier = modifier - .size(56.dp) - .padding(16.dp), + .size(48.dp) + .padding(12.dp), painter = painterResource(id = action.icon), tint = iconColor, contentDescription = null, From a82053e34fc2ba1127d933a04d8e6f5eb2b9fa47 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:46:25 +0100 Subject: [PATCH 18/22] fix(channels): use StreamTokens for bottom sheet action dimensions Icon: spacingXl (24dp) with spacingSm (12dp) horizontal padding. Replaces hardcoded 48dp/12dp values with design system tokens. --- .../chat/android/compose/ui/theme/ChatComponentFactory.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt index 083ae07c7b4..6dceab06b02 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt @@ -2224,8 +2224,8 @@ public interface ChatComponentFactory { } Icon( modifier = modifier - .size(48.dp) - .padding(12.dp), + .padding(horizontal = StreamTokens.spacingSm) // 12dp + .size(StreamTokens.spacingXl), // 24dp painter = painterResource(id = action.icon), tint = iconColor, contentDescription = null, From 18dd86e0a708ab0a3c20ec5417829d1b4255e28c Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:48:53 +0100 Subject: [PATCH 19/22] fix(channels): remove dividers between bottom sheet action items No dividers between channel options per Figma design. --- .../android/compose/ui/components/channels/ChannelOptions.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt index f1ed5a8fcd7..d9b0f136f8c 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt @@ -66,8 +66,6 @@ public fun ChannelOptions( .wrapContentHeight(), ) { items(actions) { action -> - StreamHorizontalDivider() - with(ChatTheme.componentFactory) { ChannelOptionsItem( modifier = Modifier, From 6b69f27e12c3c0c099f63eaf0749afdc1bed8c12 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:51:16 +0100 Subject: [PATCH 20/22] fix(channels): align bottom sheet items with Figma List Item spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Row height 48dp → 44dp, horizontal padding spacing2xs (4dp), icon 24dp with 8dp end gap. Matches Mobile / List Item Figma component. --- .../chat/android/compose/ui/theme/ChatComponentFactory.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt index 6dceab06b02..12ad28f28bc 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt @@ -2196,7 +2196,7 @@ public interface ChatComponentFactory { ChatTheme.colors.textPrimary } MenuOptionItem( - modifier = modifier, + modifier = modifier.padding(horizontal = StreamTokens.spacing2xs), title = action.label, titleColor = titleColor, leadingIcon = { @@ -2204,7 +2204,7 @@ public interface ChatComponentFactory { }, onClick = onClick, style = ChatTheme.typography.bodyDefault, - itemHeight = 48.dp, + itemHeight = 44.dp, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Start, ) @@ -2224,7 +2224,7 @@ public interface ChatComponentFactory { } Icon( modifier = modifier - .padding(horizontal = StreamTokens.spacingSm) // 12dp + .padding(end = StreamTokens.spacingXs) // 8dp gap to text .size(StreamTokens.spacingXl), // 24dp painter = painterResource(id = action.icon), tint = iconColor, From e042ebb4a51c40ce9063bc65b5e2cfc889113ba0 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:54:07 +0100 Subject: [PATCH 21/22] fix(channels): increase bottom sheet item horizontal padding to spacingMd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit spacing2xs (4dp) → spacingMd (16dp) to match visible Figma padding. --- .../chat/android/compose/ui/theme/ChatComponentFactory.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt index 12ad28f28bc..275ccf53ea8 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt @@ -2196,7 +2196,7 @@ public interface ChatComponentFactory { ChatTheme.colors.textPrimary } MenuOptionItem( - modifier = modifier.padding(horizontal = StreamTokens.spacing2xs), + modifier = modifier.padding(horizontal = StreamTokens.spacingMd), title = action.label, titleColor = titleColor, leadingIcon = { From aec1cb47f5a7f25e5063cc76be8420426c782091 Mon Sep 17 00:00:00 2001 From: Aleksandar Apostolov Date: Wed, 25 Feb 2026 14:56:01 +0100 Subject: [PATCH 22/22] fix(channels): add bottom padding to channel options list spacingXs (8dp) bottom content padding for breathing room below last action item. --- .../android/compose/ui/components/channels/ChannelOptions.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt index d9b0f136f8c..6823f4bd2a7 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/channels/ChannelOptions.kt @@ -16,6 +16,7 @@ package io.getstream.chat.android.compose.ui.components.channels +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.LazyColumn @@ -27,8 +28,8 @@ import androidx.compose.ui.tooling.preview.Preview import io.getstream.chat.android.client.extensions.isArchive import io.getstream.chat.android.client.extensions.isPinned import io.getstream.chat.android.compose.R -import io.getstream.chat.android.compose.ui.components.StreamHorizontalDivider import io.getstream.chat.android.compose.ui.theme.ChatTheme +import io.getstream.chat.android.compose.ui.theme.StreamTokens import io.getstream.chat.android.compose.viewmodel.channels.ChannelListViewModel import io.getstream.chat.android.models.Channel import io.getstream.chat.android.models.ChannelCapabilities @@ -64,6 +65,7 @@ public fun ChannelOptions( modifier = modifier .fillMaxWidth() .wrapContentHeight(), + contentPadding = PaddingValues(bottom = StreamTokens.spacingXs), ) { items(actions) { action -> with(ChatTheme.componentFactory) {