Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
948b979
feat(compose): update ChannelsScreen and SearchInput to Figma tokens
aleksandar-apostolov Feb 19, 2026
5f6cc82
feat(compose): update ChannelListHeader to Figma spec
aleksandar-apostolov Feb 19, 2026
10525ff
feat(compose): restructure ChannelItem layout per Figma
aleksandar-apostolov Feb 19, 2026
2a32f9f
feat(compose): update UnreadCountIndicator, Timestamp, and delivery s…
aleksandar-apostolov Feb 19, 2026
2fd84d0
feat(compose): update SearchResultItem and SelectedChannelMenu tokens
aleksandar-apostolov Feb 19, 2026
6907fca
fix(compose): swap header icon from pencil to plus per Figma spec
aleksandar-apostolov Feb 20, 2026
12a72c7
Merge remote-tracking branch 'origin/v7' into redesign/channel-list
aleksandar-apostolov Feb 20, 2026
0fd252b
refactor(compose): decouple SearchInput from InputField
aleksandar-apostolov Feb 20, 2026
74788ea
fix(compose): update SearchInput radius and fix icon clipping
aleksandar-apostolov Feb 20, 2026
a171ec0
fix(compose): reduce header plus icon from 24dp to 20dp
aleksandar-apostolov Feb 20, 2026
3cfd855
fix: update search leading icon default paddings
aleksandar-apostolov Feb 20, 2026
ba9152f
fix(compose): replace search icon with Figma stroked variant
aleksandar-apostolov Feb 20, 2026
a0a2f7d
fix(compose): center plus icon in header button with 10dp padding
aleksandar-apostolov Feb 20, 2026
68275bd
feat(compose): add attachment type icons and message states to channe…
aleksandar-apostolov Feb 23, 2026
1fc8abb
fix(compose): show deleted message preview in channel list
aleksandar-apostolov Feb 23, 2026
26dc024
fix(compose): ensure preview icons fill placeholder bounds
aleksandar-apostolov Feb 23, 2026
8e64370
fix(compose): use TextCenter alignment for preview icons instead of f…
aleksandar-apostolov Feb 23, 2026
77da710
feat(compose): show sender name in group chat previews and fix icon a…
aleksandar-apostolov Feb 23, 2026
a20a5e0
fix(compose): align channel list item with Figma spec
aleksandar-apostolov Feb 23, 2026
e0f83cd
Merge remote-tracking branch 'origin/v7' into redesign/channel-list
aleksandar-apostolov Feb 23, 2026
944d10a
fix(compose): use inline poll icon instead of emoji in channel list p…
aleksandar-apostolov Feb 23, 2026
adb75b4
fix(compose): resolve CI failures in channel list redesign
aleksandar-apostolov Feb 24, 2026
9862146
fix(compose): update delivery status icons to Figma stroked style, ad…
aleksandar-apostolov Feb 24, 2026
8c53c05
fix(compose): reduce unread badge text from 14sp to 12sp
aleksandar-apostolov Feb 24, 2026
d38cace
feat(compose): add focus and selected interaction states to ChannelItem
aleksandar-apostolov Feb 24, 2026
acf9683
fix(compose): inset channel item card shape, fix badge proportions
aleksandar-apostolov Feb 24, 2026
3e34dcf
feat(compose): add swipe-to-reveal actions on channel list items
aleksandar-apostolov Feb 24, 2026
a0eeacd
refactor(compose): rework swipe actions to match Figma spec
aleksandar-apostolov Feb 24, 2026
7d54d2d
fix(compose): fix swipe-to-reveal not responding to gestures
aleksandar-apostolov Feb 24, 2026
95bfb0d
fix(compose): wire swipe actions in sample's custom factory
aleksandar-apostolov Feb 24, 2026
ff1ec5e
fix(compose): guard against NaN offset before anchors are set
aleksandar-apostolov Feb 24, 2026
b52729b
fix(compose): hide swipe actions behind opaque foreground
aleksandar-apostolov Feb 24, 2026
938c9c4
fix(compose): correct modifier order so background slides with content
aleksandar-apostolov Feb 24, 2026
ac1fa4d
fix(compose): swap swipe action order — More left, primary right
aleksandar-apostolov Feb 24, 2026
7e2dd87
refactor(actions): unify ChannelAction into self-describing interface
aleksandar-apostolov Feb 25, 2026
06537ca
fix(compose): remove unused isOneToOne and re-record snapshots
aleksandar-apostolov Feb 25, 2026
1f00d78
fix(compose): apply spotless formatting and re-record snapshots
aleksandar-apostolov Feb 25, 2026
a1b494f
fix(e2e): update channel preview assertion for sender name prefix
aleksandar-apostolov Feb 25, 2026
6359d79
Merge branch 'redesign/channel-list' into redesign/channel-list-swipe…
aleksandar-apostolov Feb 25, 2026
8c19da8
Merge branch 'v7' into redesign/channel-list
aleksandar-apostolov Feb 25, 2026
4a52dcd
merge(channel-list): merge redesign/channel-list into swipe-actions
aleksandar-apostolov Feb 25, 2026
fff42ed
Merge branch 'redesign/channel-list-swipe-actions' of https://github.…
aleksandar-apostolov Feb 25, 2026
e7ed181
feat(icons): update channel action and list icons to Figma design system
aleksandar-apostolov Feb 25, 2026
7133df2
fix(icons): correct mute/unmute and add icon mappings
aleksandar-apostolov Feb 25, 2026
c4e96f1
fix(channels): move Leave to end as destructive action
aleksandar-apostolov Feb 25, 2026
d4500dd
feat(channels): redesign bottom sheet header with group avatar
aleksandar-apostolov Feb 25, 2026
d329a4d
fix(channels): use headingSmall for channel name, icon-only swipe act…
aleksandar-apostolov Feb 25, 2026
6ebb8a0
fix(swipe): use backgroundCoreSurface for secondary action
aleksandar-apostolov Feb 25, 2026
8982919
fix(channels): reduce bottom sheet action item size
aleksandar-apostolov Feb 25, 2026
a82053e
fix(channels): use StreamTokens for bottom sheet action dimensions
aleksandar-apostolov Feb 25, 2026
18dd86e
fix(channels): remove dividers between bottom sheet action items
aleksandar-apostolov Feb 25, 2026
6b69f27
fix(channels): align bottom sheet items with Figma List Item spec
aleksandar-apostolov Feb 25, 2026
e042ebb
fix(channels): increase bottom sheet item horizontal padding to spaci…
aleksandar-apostolov Feb 25, 2026
aec1cb4
fix(channels): add bottom padding to channel options list
aleksandar-apostolov Feb 25, 2026
926c04c
Merge remote-tracking branch 'origin/v7' into redesign/channel-list
aleksandar-apostolov Feb 25, 2026
252345a
fix(compose): re-record Paparazzi snapshots after v7 merge
aleksandar-apostolov Feb 25, 2026
aaa1bfa
fix(compose): use collectAsState instead of StateFlow.value in compos…
aleksandar-apostolov Feb 25, 2026
054f8ad
feat(channels): skeleton loading, empty state redesign
aleksandar-apostolov Feb 25, 2026
6885e8a
fix(channels): address PR review feedback from Petar and CodeRabbit
aleksandar-apostolov Feb 26, 2026
9872808
fix(channels): address PR review round 2 — API fixes and CodeRabbit f…
aleksandar-apostolov Feb 26, 2026
be008f3
fix(channels): address PR review round 3 — Gian's feedback
aleksandar-apostolov Feb 26, 2026
43c8c30
fix(channels): fix compose tests and re-record Paparazzi snapshots
aleksandar-apostolov Feb 26, 2026
7f8a797
Merge branch 'v7' into redesign/channel-list
aleksandar-apostolov Feb 26, 2026
a50041c
fix(channels): resolve Detekt findings in channel list components
aleksandar-apostolov Feb 26, 2026
507c98f
fix(channels): update E2E test for deleted message preview
aleksandar-apostolov Feb 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.iml
.planning/
.composite
buildSrc/build
.gradle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.getstream.chat.android.compose.pages.ChannelListPage.ChannelList.Chann
import io.getstream.chat.android.compose.uiautomator.isDisplayed
import io.getstream.chat.android.compose.uiautomator.waitToAppear
import io.getstream.chat.android.compose.uiautomator.waitToDisappear
import io.getstream.chat.android.e2e.test.robots.ParticipantRobot
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
Expand All @@ -30,7 +31,11 @@ fun UserRobot.assertChannelAvatar(): UserRobot {
}

fun UserRobot.assertMessageInChannelPreview(text: String, fromCurrentUser: Boolean? = null): UserRobot {
val expectedPreview = if (fromCurrentUser == true) "You: $text" else text
val expectedPreview = when (fromCurrentUser) {
true -> "You: $text"
false -> "${ParticipantRobot.name}: $text"
null -> text
}
assertEquals(expectedPreview, Channel.messagePreview.waitToAppear().text.trimEnd())
return this
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class ChannelListTests : StreamTestCase() {

@AllureId("5821")
@Test
fun test_channelPreviewShowsPreviousMessage_whenLastMessageIsDeleted() {
fun test_channelPreviewShowsDeletedMessage_whenLastMessageIsDeleted() {
val oldMessage = "Old"
val newMessage = "New"

Expand All @@ -190,8 +190,8 @@ class ChannelListTests : StreamTestCase() {
step("WHEN user goes back to the channel list") {
userRobot.tapOnBackButton()
}
step("THEN the channel preview shows previous message") {
userRobot.assertMessageInChannelPreview(oldMessage, fromCurrentUser = false)
step("THEN the channel preview shows 'Message deleted'") {
userRobot.assertMessageInChannelPreview("Message deleted", fromCurrentUser = false)
}
step("AND the message timestamp is shown") {
userRobot.assertMessagePreviewTimestamp(isDisplayed = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.ChatConfig
Expand Down Expand Up @@ -381,17 +382,24 @@ 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)
.fillMaxWidth()
.wrapContentHeight()
.align(Alignment.Center),
shape = RoundedCornerShape(16.dp),
isMuted = channelsViewModel.isChannelMuted(selectedChannel.cid),
selectedChannel = selectedChannel,
currentUser = user,
onChannelOptionClick = { action -> channelsViewModel.performChannelAction(action) },
channelActions = channelActions,
onChannelOptionConfirm = { action -> channelsViewModel.executeOrConfirm(action) },
onDismiss = { channelsViewModel.dismissChannelAction() },
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,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
Expand All @@ -42,21 +44,37 @@ 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.backgroundCoreHighlight)
} else {
this
}
},
channelItem = channelItem,
currentUser = currentUser,
onChannelClick = onChannelClick,
onChannelLongClick = onChannelLongClick,
)
val coordinator = LocalSwipeRevealCoordinator.current
val swipeEnabled = ChatTheme.config.channelList.swipeActionsEnabled && coordinator != null
val pinnedModifier = if (channelItem.channel.isPinned()) {
Modifier.background(color = ChatTheme.colors.backgroundCoreHighlight)
} else {
Modifier
}

if (swipeEnabled) {
SwipeableChannelItem(
modifier = Modifier.animateItem(),
channelCid = channelItem.channel.cid,
backgroundColor = ChatTheme.colors.backgroundCoreApp,
swipeActions = { ChannelSwipeActions(channelItem) },
) {
ChannelItem(
modifier = pinnedModifier,
channelItem = channelItem,
currentUser = currentUser,
onChannelClick = onChannelClick,
onChannelLongClick = onChannelLongClick,
)
}
} else {
ChannelItem(
modifier = Modifier.animateItem().then(pinnedModifier),
channelItem = channelItem,
currentUser = currentUser,
onChannelClick = onChannelClick,
onChannelLongClick = onChannelLongClick,
)
}
}
}
Loading
Loading