Skip to content

Commit cf481f5

Browse files
Redesign channel list, swipe actions and actions bottom sheet (#6181)
* feat(compose): update ChannelsScreen and SearchInput to Figma tokens - ChannelsScreen: search section padding top 8dp→16dp, horizontal 12dp→16dp (spacingMd), bottom 8dp (spacingXs) - SearchInput DefaultSearchLeadingIcon: 16x16dp size, leading 16dp padding, tint textLowEmphasis→textTertiary - SearchInput DefaultSearchLabel: typography body→bodyDefault, color textLowEmphasis→textTertiary - SearchInput: add 48dp minHeight, innerPadding start=spacingXs/end=spacingMd/v=spacingSm - InputField: border color borders→borderCoreDefault * feat(compose): update ChannelListHeader to Figma spec - Container: padding 8dp→spacingSm (12dp), add spacedBy(spacingXs) gap between children - Add 1dp bottom border (borderCoreDefault) replacing drop shadow - Elevation default: headerElevation (4dp)→0.dp - Title typography: title3Bold→headingSmall, color: textHighEmphasis→textPrimary - Title padding: 16.dp→spacingMd (token-aligned) - Leading avatar: 40dp visual wrapped in 48dp hit target Box - Trailing button: accentPrimary bg, CircleShape, 0dp elevation, 48dp hit target * feat(compose): restructure ChannelItem layout per Figma - Leading: avatar 40dp→channelListItemAvatarSize (48dp), all padding spacingMd (16dp) - Center content major restructure: timestamp+badge moved from trailing→title row, delivery status moved→message row - Channel name: bodyBold+fontSize16→bodyDefault, textHighEmphasis→textPrimary - Mute icon: moved inline into title row, textLowEmphasis→textTertiary - Message preview: body→captionDefault, textLowEmphasis→textSecondary - Typing indicator: gap 6dp→spacing2xs, body→captionDefault, textLowEmphasis→textSecondary - Trailing content: replaced with empty Spacer stub (spacingMd=16dp) for API compatibility * feat(compose): update UnreadCountIndicator, Timestamp, and delivery status - UnreadCountIndicator: errorAccent (red)→accentPrimary (blue), add 2dp presenceBorder border, min 18dp→20dp, RoundedCornerShape(9)→pill (50), captionBold→numericExtraLarge, Color.White→badgeTextOnAccent - Timestamp: default style footnote→captionDefault (14sp), textLowEmphasis→textTertiary, add lineHeightNormal (20sp) - StreamDimens: add channelListItemAvatarSize=48.dp field (channelAvatarSize=40.dp retained for header) * feat(compose): update SearchResultItem and SelectedChannelMenu tokens - SearchResultItem leading: avatar 40dp→48dp, padding channelItemHorizontalPadding→spacingMd (16dp) - SearchResultItem center: bodyBold+fontSize16→bodyDefault, textHighEmphasis→textPrimary, body→captionDefault, textLowEmphasis→textSecondary, add 4dp gap - SearchResultItem trailing: padding updated to spacingMd, timestamp footnote→captionDefault+textTertiary+20sp lineHeight, alignment Bottom→CenterVertically - SearchResultItem container Row: add Arrangement.spacedBy(spacingMd) for 16dp avatar-content gap - SelectedChannelMenu header: title3Bold→headingSmall, textHighEmphasis→textPrimary, footnoteBold→captionDefault, textLowEmphasis→textSecondary - ChannelOptions: all non-destructive options textHighEmphasis→textPrimary, textLowEmphasis→textSecondary (delete option unchanged) - ChatComponentFactory ChannelOptionsItem: bodyBold→bodyDefault - StreamHorizontalDivider: borders→borderCoreSurfaceSubtle * fix(compose): swap header icon from pencil to plus per Figma spec The Figma design uses a plus icon for the new channel button, not the pencil/edit icon. Switched from stream_compose_ic_new_chat to stream_compose_ic_add with explicit 24dp sizing. * refactor(compose): decouple SearchInput from InputField Move SearchInput to use BasicTextField directly, matching the pattern used by the new message composer. This removes the dependency on InputField and its composer-specific theme (inputBackground), making the search bar transparent so it inherits the parent background color. Works correctly in both light and dark mode. * fix(compose): update SearchInput radius and fix icon clipping Use radius3xl (24dp) matching the composer's MessageInputShape instead of radiusLg (12dp). Move padding into decorationBox so the search icon isn't clipped by the border/clip modifiers. * fix(compose): reduce header plus icon from 24dp to 20dp Match the composer's icon size (icon/size/md = 20dp) for consistent icon sizing across the SDK. * fix: update search leading icon default paddings * fix(compose): replace search icon with Figma stroked variant Replace the filled 24dp search icon with the stroked 20dp variant from Figma (IconMagnifyingGlassSearch), matching the new design system's stroked icon style. * fix(compose): center plus icon in header button with 10dp padding Add Box with 10dp padding and center alignment inside the Surface, matching Figma button/padding-x/icon-only/md and button/padding-y/md tokens. The icon was not centered and appeared oversized. * feat(compose): add attachment type icons and message states to channel list preview Add inline preview icons for photo, video, file, link, and location attachment types in the channel list message preview. Handle deleted messages, error state indicator, and empty chat placeholder per Figma spec. Voice messages and location now include sender name prefix for group chats. * fix(compose): show deleted message preview in channel list The getPreviewMessage function filters out deleted messages, so the formatter's isDeleted check was never reached. Add getLastMessageIncludingDeleted to pass deleted messages to the formatter. Suppress delivery status icon for deleted messages. * fix(compose): ensure preview icons fill placeholder bounds Add Modifier.fillMaxSize() to all inline preview icons so they properly scale to the 16sp placeholder regardless of their intrinsic drawable size (some are 12dp, mic is 20dp, poll is 24dp). * fix(compose): use TextCenter alignment for preview icons instead of fillMaxSize Revert fillMaxSize() on icons — the real issue is PlaceholderVerticalAlign.Center centers in the line box (16sp) rather than the text glyphs (14sp). TextCenter fixes the vertical alignment against the caption text. * feat(compose): show sender name in group chat previews and fix icon alignment - getSenderDisplayName now returns the sender's name for group chats (was only returning "You" for current user, null for everyone else) - Add isDirectMessaging parameter to formatMessagePreview so the formatter knows when to suppress the sender name (DMs only) - ChannelItem passes isOneToOne to the formatter - Reduce icon placeholder from 16sp to 14sp (matching font size) with Modifier.size(14.dp) to prevent text baseline displacement * fix(compose): align channel list item with Figma spec - Configurable mute icon position (inline title / trailing bottom) - DM typing shows "Typing" without name; group shows proper name formats - Remove "You:" prefix from DM outgoing non-deleted messages - Replace hardcoded mute icon size with design token * fix(compose): use inline poll icon instead of emoji in channel list preview Replace hardcoded 📊 emoji with ic_poll drawable via appendInlineContent, matching the pattern used by all other attachment type previews. * fix(compose): resolve CI failures in channel list redesign Fix detekt MaxLineLength/LongMethod/MagicNumber violations, spotless formatting, and docs compile error from formatMessagePreview signature. * fix(compose): update delivery status icons to Figma stroked style, add poll sender prefix and chatTextRead token Replace filled delivery status icons (clock, single check, double check) with stroked outlines per Figma spec. Add sender name prefix for poll messages in group chats. Add chatTextRead semantic color token for read status icon tint. * fix(compose): reduce unread badge text from 14sp to 12sp Badge number felt oversized inside the 20dp pill with 2dp border. Switched from numericExtraLarge (14sp) to numericLarge (12sp) for better visual proportion. * feat(compose): add focus and selected interaction states to ChannelItem Add visual feedback for focus (blue rounded border) and selected (tinted background) states on channel list items, matching the Figma design system interaction states. * fix(compose): inset channel item card shape, fix badge proportions - Add 4dp horizontal padding before border/clip/background so the rounded selected/focused card has visible inset from list edges - Remove 2dp white border from UnreadCountIndicator (was for avatar overlap, not standalone badge in title row) - Switch badge text from numericLarge (12sp) to numericMedium (10sp) which is the style designed for unread count indicators * 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 * refactor(compose): rework swipe actions to match Figma spec 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. * fix(compose): fix swipe-to-reveal not responding to gestures 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. * 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 * 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. * 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. * 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. * fix(compose): swap swipe action order — More left, primary right Place the secondary More action first (leftmost) and the primary action (Archive/Mute) second (rightmost) to match the Figma spec. * refactor(actions): unify ChannelAction into self-describing interface 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<ChannelAction> 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<ChannelAction>, delete ChannelOptionItem - Update tests, sample app, docs snippets, API dump * fix(compose): remove unused isOneToOne and re-record snapshots Remove dead `isOneToOne` extension (Detekt UnusedPrivateMember) and re-record ChannelItemTest Paparazzi snapshots. * fix(compose): apply spotless formatting and re-record snapshots Fix spotless violation in UnreadCountIndicator and re-record ChannelItemTest + ChannelListTest Paparazzi snapshots. * fix(e2e): update channel preview assertion for sender name prefix Channel preview now shows sender name for non-DM participant messages. Update assertMessageInChannelPreview to expect "ParticipantName: text" when fromCurrentUser is false. * 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. * 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). * 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. * 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. * fix(channels): use headingSmall for channel name, icon-only swipe actions Channel list title: bodyDefault → headingSmall (semi-bold) to match Figma. Swipe actions: remove text label, show icon only in a centered Box. * 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. * fix(channels): reduce bottom sheet action item size Item height 56dp → 48dp, icon container 56dp → 48dp with 12dp padding (24dp icon). More compact to match Figma design. * 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. * fix(channels): remove dividers between bottom sheet action items No dividers between channel options per Figma design. * fix(channels): align bottom sheet items with Figma List Item spec Row height 48dp → 44dp, horizontal padding spacing2xs (4dp), icon 24dp with 8dp end gap. Matches Mobile / List Item Figma component. * fix(channels): increase bottom sheet item horizontal padding to spacingMd spacing2xs (4dp) → spacingMd (16dp) to match visible Figma padding. * fix(channels): add bottom padding to channel options list spacingXs (8dp) bottom content padding for breathing room below last action item. * fix(compose): re-record Paparazzi snapshots after v7 merge * fix(compose): use collectAsState instead of StateFlow.value in composition * feat(channels): skeleton loading, empty state redesign - Replace spinner with shimmer skeleton items (8 placeholder rows matching channel item layout: avatar + title/timestamp + message) - Redesign empty state: 32dp icon, "No conversations yet" copy, optional "Start a chat" CTA wired to header action - Update ChatComponentFactory.ChannelListEmptyContent with onStartChatClick callback - ChannelsScreen passes onHeaderActionClick as empty state CTA * fix(channels): address PR review feedback from Petar and CodeRabbit - Fix deleted messages filtered out in channel preview (missing isDeleted predicate) - Fix hardcoded icon color breaking XML SDK dark mode (tint with text style color) - Fix ConcurrentModificationException in SwipeRevealCoordinator (snapshot registry) - Add contentDescription to IsErrorIcon for accessibility - Remove isPinned from ChannelItemState (derive from Channel.isPinned extension) - Move animateItem from inner ChannelItem to outer SwipeableChannelItem - Simplify header trailing content nesting and use AvatarSize constants - Clip avatar clickable area to CircleShape for proper ripple shape - Add text overflow for members status in SelectedChannelMenu - Remove migration artifact comments from SearchResultItem - Fix SwipeActionItem label KDoc (contentDescription, not visible text) - Add @OptIn(ExperimentalFoundationApi) to SwipeableChannelItem - Remove .planning directory from git tracking * fix(channels): address PR review round 2 — API fixes and CodeRabbit feedback - Separate onStartChatClick from onHeaderActionClick in ChannelsScreen (P4+P5) - Rename onChannelOptionClick → onChannelOptionConfirm for semantic clarity (P3+P15) - Remove deprecated 2-param formatMessagePreview overload (v7 breaking change) - Move animateItem() to outer SwipeableChannelItem in sample CustomChatComponentFactory - Add dark mode snapshot for muted channel trailing bottom test - Make poll preview strings translatable * fix(channels): address PR review round 3 — Gian's feedback - Remove leftover comment and unnecessary Box wrapper in header - Use applyIf extension for focus/selected modifiers in ChannelItem - Use AvatarSize.ExtraLarge constant instead of raw 48.dp - Extract TitleRow and MessageRow composables from center content - Remove verbose section-divider comments - Delete accidentally committed GAPS.md - Replace raw dp values with StreamTokens in empty state - Replace OutlinedButton with StreamTextButton secondaryOutline - Remove RowScope extension from DefaultChannelSwipeActions - Wrap swipe action resolution in remember with resources - Make swipe actions self-executing via onAction + rememberUpdatedState - Replace hardcoded Color.White with theme tokens in SwipeActionItem - Replace RoundedCornerShape(50) with CircleShape in UnreadCountIndicator - Update public API dump * fix(channels): fix compose tests and re-record Paparazzi snapshots Loading state changed from CircularProgressIndicator to skeleton shimmer. Update ChannelsScreenTest and ChatsScreenTest to assert on testTag instead of ProgressBarRangeInfo. Re-record all affected snapshots. * fix(channels): resolve Detekt findings in channel list components Reduce parameter count in TitleRow/MessageRow by passing channelItemState directly. Extract swipe action builders to shorten rememberPrimarySwipeAction. Wrap long KDoc lines in ChatComponentFactory. * fix(channels): update E2E test for deleted message preview Channel preview now shows 'Message deleted' instead of falling back to the previous message, matching the redesigned behavior. * fix(compose-sample): revert deleted message E2E test assertion Mock server hard-deletes messages regardless of hard_delete=false param, so getLastMessageIncludingDeleted() cannot find the removed message. Revert to asserting the previous message ("Old") is shown instead. * fix(compose): address Andre's PR feedback - MuteIndicatorPosition: rename SCREAMING_SNAKE_CASE to PascalCase (InlineTitle, TrailingBottom) per new enum convention - Revert stream_compose_ic_add.xml to original (shared drawable) - Replace Surface with StreamButton in header trailing content - Update API dump for enum rename * fix(compose): add missing Color import in ChannelListHeader * fix(compose): fix import ordering and re-record snapshots - Fix Detekt import ordering violation in ChannelListHeader.kt - Re-record Paparazzi snapshots after v7 merge and StreamButton change
1 parent e322a2a commit cf481f5

135 files changed

Lines changed: 2659 additions & 884 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
*.iml
2+
.planning/
23
.composite
34
buildSrc/build
45
.gradle

stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotChannelListAsserts.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import io.getstream.chat.android.compose.pages.ChannelListPage.ChannelList.Chann
2020
import io.getstream.chat.android.compose.uiautomator.isDisplayed
2121
import io.getstream.chat.android.compose.uiautomator.waitToAppear
2222
import io.getstream.chat.android.compose.uiautomator.waitToDisappear
23+
import io.getstream.chat.android.e2e.test.robots.ParticipantRobot
2324
import org.junit.Assert.assertEquals
2425
import org.junit.Assert.assertFalse
2526
import org.junit.Assert.assertTrue
@@ -30,7 +31,11 @@ fun UserRobot.assertChannelAvatar(): UserRobot {
3031
}
3132

3233
fun UserRobot.assertMessageInChannelPreview(text: String, fromCurrentUser: Boolean? = null): UserRobot {
33-
val expectedPreview = if (fromCurrentUser == true) "You: $text" else text
34+
val expectedPreview = when (fromCurrentUser) {
35+
true -> "You: $text"
36+
false -> "${ParticipantRobot.name}: $text"
37+
null -> text
38+
}
3439
assertEquals(expectedPreview, Channel.messagePreview.waitToAppear().text.trimEnd())
3540
return this
3641
}

stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/ChannelListTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class ChannelListTests : StreamTestCase() {
190190
step("WHEN user goes back to the channel list") {
191191
userRobot.tapOnBackButton()
192192
}
193-
step("THEN the channel preview shows previous message") {
193+
step("THEN the channel preview shows the previous message") {
194194
userRobot.assertMessageInChannelPreview(oldMessage, fromCurrentUser = false)
195195
}
196196
step("AND the message timestamp is shown") {

stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import io.getstream.chat.android.compose.ui.channels.list.ChannelItem
8484
import io.getstream.chat.android.compose.ui.channels.list.ChannelList
8585
import io.getstream.chat.android.compose.ui.components.SearchInput
8686
import io.getstream.chat.android.compose.ui.components.channels.ChannelOptionItemVisibility
87+
import io.getstream.chat.android.compose.ui.components.channels.buildDefaultChannelActions
8788
import io.getstream.chat.android.compose.ui.mentions.MentionList
8889
import io.getstream.chat.android.compose.ui.theme.ChannelOptionsTheme
8990
import io.getstream.chat.android.compose.ui.theme.ChatConfig
@@ -381,17 +382,24 @@ class ChannelsActivity : ComponentActivity() {
381382

382383
val selectedChannel = delegatedSelectedChannel
383384
if (selectedChannel != null) {
385+
val channelActions = buildDefaultChannelActions(
386+
selectedChannel = selectedChannel,
387+
isMuted = channelsViewModel.isChannelMuted(selectedChannel.cid),
388+
ownCapabilities = selectedChannel.ownCapabilities,
389+
viewModel = channelsViewModel,
390+
onViewInfoAction = ::viewChannelInfo,
391+
)
384392
SelectedChannelMenu(
385393
modifier = Modifier
386394
.padding(16.dp)
387395
.fillMaxWidth()
388396
.wrapContentHeight()
389397
.align(Alignment.Center),
390398
shape = RoundedCornerShape(16.dp),
391-
isMuted = channelsViewModel.isChannelMuted(selectedChannel.cid),
392399
selectedChannel = selectedChannel,
393400
currentUser = user,
394-
onChannelOptionClick = { action -> channelsViewModel.performChannelAction(action) },
401+
channelActions = channelActions,
402+
onChannelOptionConfirm = { action -> channelsViewModel.executeOrConfirm(action) },
395403
onDismiss = { channelsViewModel.dismissChannelAction() },
396404
)
397405
}

stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/CustomChatComponentFactory.kt

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import io.getstream.chat.android.compose.sample.ui.location.LocationComponentFac
2525
import io.getstream.chat.android.compose.sample.vm.SharedLocationViewModelFactory
2626
import io.getstream.chat.android.compose.state.channels.list.ItemState
2727
import io.getstream.chat.android.compose.ui.channels.list.ChannelItem
28+
import io.getstream.chat.android.compose.ui.channels.list.LocalSwipeRevealCoordinator
29+
import io.getstream.chat.android.compose.ui.channels.list.SwipeableChannelItem
2830
import io.getstream.chat.android.compose.ui.theme.ChatComponentFactory
2931
import io.getstream.chat.android.compose.ui.theme.ChatTheme
3032
import io.getstream.chat.android.models.Channel
@@ -42,21 +44,37 @@ class CustomChatComponentFactory(
4244
onChannelClick: (Channel) -> Unit,
4345
onChannelLongClick: (Channel) -> Unit,
4446
) {
45-
ChannelItem(
46-
modifier = Modifier
47-
.animateItem()
48-
.run {
49-
// Highlight the item background color if it is pinned
50-
if (channelItem.channel.isPinned()) {
51-
background(color = ChatTheme.colors.backgroundCoreHighlight)
52-
} else {
53-
this
54-
}
55-
},
56-
channelItem = channelItem,
57-
currentUser = currentUser,
58-
onChannelClick = onChannelClick,
59-
onChannelLongClick = onChannelLongClick,
60-
)
47+
val coordinator = LocalSwipeRevealCoordinator.current
48+
val swipeEnabled = ChatTheme.config.channelList.swipeActionsEnabled && coordinator != null
49+
val pinnedModifier = if (channelItem.channel.isPinned()) {
50+
Modifier.background(color = ChatTheme.colors.backgroundCoreHighlight)
51+
} else {
52+
Modifier
53+
}
54+
55+
if (swipeEnabled) {
56+
SwipeableChannelItem(
57+
modifier = Modifier.animateItem(),
58+
channelCid = channelItem.channel.cid,
59+
backgroundColor = ChatTheme.colors.backgroundCoreApp,
60+
swipeActions = { ChannelSwipeActions(channelItem) },
61+
) {
62+
ChannelItem(
63+
modifier = pinnedModifier,
64+
channelItem = channelItem,
65+
currentUser = currentUser,
66+
onChannelClick = onChannelClick,
67+
onChannelLongClick = onChannelLongClick,
68+
)
69+
}
70+
} else {
71+
ChannelItem(
72+
modifier = Modifier.animateItem().then(pinnedModifier),
73+
channelItem = channelItem,
74+
currentUser = currentUser,
75+
onChannelClick = onChannelClick,
76+
onChannelLongClick = onChannelLongClick,
77+
)
78+
}
6179
}
6280
}

0 commit comments

Comments
 (0)