Skip to content

Commit c59ea3f

Browse files
authored
6.24.0 release testing (#5939)
* Add local filtering for attachments in ChannelAttachmentsViewController and unify SDKs * Use imagePreviewUrl to consider thumbUrl or imageUrl
1 parent 846b3a7 commit c59ea3f

File tree

14 files changed

+59
-34
lines changed

14 files changed

+59
-34
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
## stream-chat-android-ui-components
6060
### 🐞 Fixed
61+
- Fix the inconsistency in the channel attachments items between XML and Compose SDKs. [#5939](https://github.com/GetStream/stream-chat-android/pull/5939)
6162

6263
### ⬆️ Improved
6364

@@ -71,6 +72,7 @@
7172

7273
## stream-chat-android-compose
7374
### 🐞 Fixed
75+
- Fix the inconsistency in the channel attachments items between XML and Compose SDKs. [#5939](https://github.com/GetStream/stream-chat-android/pull/5939)
7476

7577
### ⬆️ Improved
7678
- Remove the fixed height modifier in `FileUploadItem`. [#5932](https://github.com/GetStream/stream-chat-android/pull/5932)

stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/attachments/ChannelMediaAttachmentsActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import io.getstream.chat.android.compose.viewmodel.channel.ChannelAttachmentsVie
3434
import io.getstream.chat.android.compose.viewmodel.channel.ChannelAttachmentsViewModelFactory
3535
import io.getstream.chat.android.models.AttachmentType
3636
import io.getstream.chat.android.ui.common.feature.channel.attachments.ChannelAttachmentsViewEvent
37+
import io.getstream.chat.android.ui.common.utils.extensions.imagePreviewUrl
3738
import kotlinx.coroutines.flow.collectLatest
3839

3940
class ChannelMediaAttachmentsActivity : ComponentActivity() {
@@ -49,6 +50,7 @@ class ChannelMediaAttachmentsActivity : ComponentActivity() {
4950
ChannelAttachmentsViewModelFactory(
5051
cid = requireNotNull(intent.getStringExtra(KEY_CID)),
5152
attachmentTypes = listOf(AttachmentType.IMAGE, AttachmentType.VIDEO),
53+
localFilter = { !it.imagePreviewUrl.isNullOrEmpty() && it.titleLink.isNullOrEmpty() },
5254
)
5355
}
5456

stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/chats/ChatsActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ import io.getstream.chat.android.ui.common.feature.channel.info.ChannelInfoViewE
9797
import io.getstream.chat.android.ui.common.state.channel.info.ChannelInfoViewState
9898
import io.getstream.chat.android.ui.common.state.messages.list.ChannelHeaderViewState
9999
import io.getstream.chat.android.ui.common.state.messages.list.DeletedMessageVisibility
100+
import io.getstream.chat.android.ui.common.utils.extensions.imagePreviewUrl
100101
import kotlinx.coroutines.GlobalScope
101102
import kotlinx.coroutines.delay
102103
import kotlinx.coroutines.flow.collectLatest
@@ -576,6 +577,7 @@ class ChatsActivity : ComponentActivity() {
576577
val viewModelFactory = ChannelAttachmentsViewModelFactory(
577578
cid = cid,
578579
attachmentTypes = listOf(AttachmentType.IMAGE, AttachmentType.VIDEO),
580+
localFilter = { !it.imagePreviewUrl.isNullOrEmpty() && it.titleLink.isNullOrEmpty() },
579581
)
580582
val viewModel = viewModel<ChannelAttachmentsViewModel>(
581583
factory = viewModelFactory,

stream-chat-android-compose/api/stream-chat-android-compose.api

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4751,16 +4751,17 @@ public final class io/getstream/chat/android/compose/util/KeyValuePair {
47514751

47524752
public final class io/getstream/chat/android/compose/viewmodel/channel/ChannelAttachmentsViewModel : androidx/lifecycle/ViewModel {
47534753
public static final field $stable I
4754-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function1;)V
4755-
public synthetic fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
4754+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
4755+
public synthetic fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
47564756
public final fun getEvents ()Lkotlinx/coroutines/flow/SharedFlow;
47574757
public final fun getState ()Lkotlinx/coroutines/flow/StateFlow;
47584758
public final fun onViewAction (Lio/getstream/chat/android/ui/common/feature/channel/attachments/ChannelAttachmentsViewAction;)V
47594759
}
47604760

47614761
public final class io/getstream/chat/android/compose/viewmodel/channel/ChannelAttachmentsViewModelFactory : androidx/lifecycle/ViewModelProvider$Factory {
47624762
public static final field $stable I
4763-
public fun <init> (Ljava/lang/String;Ljava/util/List;)V
4763+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function1;)V
4764+
public synthetic fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
47644765
public fun create (Ljava/lang/Class;)Landroidx/lifecycle/ViewModel;
47654766
}
47664767

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/ChannelAttachmentsViewModel.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package io.getstream.chat.android.compose.viewmodel.channel
1818

1919
import androidx.lifecycle.ViewModel
2020
import androidx.lifecycle.viewModelScope
21+
import io.getstream.chat.android.models.Attachment
2122
import io.getstream.chat.android.ui.common.feature.channel.attachments.ChannelAttachmentsViewAction
2223
import io.getstream.chat.android.ui.common.feature.channel.attachments.ChannelAttachmentsViewController
2324
import io.getstream.chat.android.ui.common.feature.channel.attachments.ChannelAttachmentsViewEvent
@@ -30,15 +31,18 @@ import kotlinx.coroutines.flow.StateFlow
3031
*
3132
* @param cid The full channel identifier (e.g., "messaging:123").
3233
* @param attachmentTypes The list of attachment types (e.g., "image", "file").
34+
* @param localFilter A function to filter attachments locally after fetching.
3335
* @param controllerProvider The provider for [ChannelAttachmentsViewController].
3436
*/
3537
public class ChannelAttachmentsViewModel(
3638
private val cid: String,
3739
private val attachmentTypes: List<String>,
40+
private val localFilter: (attachment: Attachment) -> Boolean = { true },
3841
private val controllerProvider: ViewModel.() -> ChannelAttachmentsViewController = {
3942
ChannelAttachmentsViewController(
4043
cid = cid,
4144
attachmentTypes = attachmentTypes,
45+
localFilter = localFilter,
4246
scope = viewModelScope,
4347
)
4448
},

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/ChannelAttachmentsViewModelFactory.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,26 @@ package io.getstream.chat.android.compose.viewmodel.channel
1818

1919
import androidx.lifecycle.ViewModel
2020
import androidx.lifecycle.ViewModelProvider
21+
import io.getstream.chat.android.models.Attachment
2122

2223
/**
2324
* Factory for creating instances of [ChannelAttachmentsViewModel].
2425
*
2526
* @param cid The full channel identifier (e.g., "messaging:123").
2627
* @param attachmentTypes The list of attachment types (e.g., "image", "file").
28+
* @param localFilter A function to filter attachments locally after fetching.
2729
*/
2830
public class ChannelAttachmentsViewModelFactory(
2931
private val cid: String,
3032
private val attachmentTypes: List<String>,
33+
private val localFilter: (attachment: Attachment) -> Boolean = { true },
3134
) : ViewModelProvider.Factory {
3235

3336
override fun <T : ViewModel> create(modelClass: Class<T>): T {
3437
require(modelClass == ChannelAttachmentsViewModel::class.java) {
3538
"ChannelAttachmentsViewModelFactory can only create instances of ChannelAttachmentsViewModel"
3639
}
3740
@Suppress("UNCHECKED_CAST")
38-
return ChannelAttachmentsViewModel(cid, attachmentTypes) as T
41+
return ChannelAttachmentsViewModel(cid, attachmentTypes, localFilter) as T
3942
}
4043
}

stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/attachments/ChannelAttachmentsViewController.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package io.getstream.chat.android.ui.common.feature.channel.attachments
1919
import io.getstream.chat.android.client.ChatClient
2020
import io.getstream.chat.android.client.extensions.cidToTypeAndId
2121
import io.getstream.chat.android.core.internal.InternalStreamChatApi
22+
import io.getstream.chat.android.models.Attachment
2223
import io.getstream.chat.android.models.Filters
2324
import io.getstream.chat.android.models.SearchMessagesResult
2425
import io.getstream.chat.android.ui.common.state.channel.attachments.ChannelAttachmentsViewState
@@ -47,13 +48,15 @@ import kotlinx.coroutines.flow.update
4748
*
4849
* @param cid The full channel identifier (e.g., "messaging:123").
4950
* @param attachmentTypes The list of attachment types to filter by.
51+
* @param localFilter A function to filter attachments locally after fetching.
5052
* @param chatClient The [ChatClient] instance used for interacting with the chat API.
5153
* @param scope The [CoroutineScope] used for launching coroutines.
5254
*/
5355
@InternalStreamChatApi
5456
public class ChannelAttachmentsViewController(
5557
private val cid: String,
5658
private val attachmentTypes: List<String>,
59+
private val localFilter: (attachment: Attachment) -> Boolean = { true },
5760
private val chatClient: ChatClient = ChatClient.instance(),
5861
scope: CoroutineScope,
5962
) {
@@ -120,7 +123,7 @@ public class ChannelAttachmentsViewController(
120123
nextPage = result.next
121124
val items = result.messages.flatMap { message ->
122125
message.attachments
123-
.filter { it.type in attachmentTypes }
126+
.filter(localFilter)
124127
.map {
125128
ChannelAttachmentsViewState.Content.Item(
126129
message = message,

stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/utils/StreamFileUtil.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,7 @@ public object StreamFileUtil {
262262
Success(getUri(file))
263263
}
264264

265-
is Failure -> response.also {
266-
println()
267-
}
265+
is Failure -> response
268266
}
269267
}
270268
}

stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/channel/attachments/ChannelAttachmentsViewControllerTest.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package io.getstream.chat.android.ui.common.feature.channel.attachments
1919
import app.cash.turbine.test
2020
import io.getstream.chat.android.client.ChatClient
2121
import io.getstream.chat.android.client.extensions.cidToTypeAndId
22+
import io.getstream.chat.android.models.Attachment
2223
import io.getstream.chat.android.models.Filters
2324
import io.getstream.chat.android.models.SearchMessagesResult
2425
import io.getstream.chat.android.randomAttachment
@@ -52,8 +53,9 @@ internal class ChannelAttachmentsViewControllerTest {
5253

5354
@Test
5455
fun `when initial load succeeds, should update state with content`() = runTest {
55-
val attachment1 = randomAttachment(type = ATTACHMENT_TYPE)
56-
val attachment2 = randomAttachment(type = ATTACHMENT_TYPE)
56+
val attachmentType = randomString()
57+
val attachment1 = randomAttachment(type = attachmentType)
58+
val attachment2 = randomAttachment(type = attachmentType)
5759
val message1 = randomMessage(
5860
cid = CID,
5961
attachments = listOf(attachment1, randomAttachment()),
@@ -68,7 +70,7 @@ internal class ChannelAttachmentsViewControllerTest {
6870
)
6971
val sut = Fixture()
7072
.givenSearchMessagesResult(result = searchMessagesResult)
71-
.get(backgroundScope)
73+
.get(backgroundScope, localFilter = { it.type == attachmentType })
7274

7375
sut.state.test {
7476
skipItems(1) // Skip initial state
@@ -105,14 +107,14 @@ internal class ChannelAttachmentsViewControllerTest {
105107

106108
@Test
107109
fun `when load more succeeds, should append items to state`() = runTest {
108-
val attachment1 = randomAttachment(type = ATTACHMENT_TYPE)
110+
val attachment1 = randomAttachment()
109111
val message1 = randomMessage(cid = CID, attachments = listOf(attachment1))
110112
val nextPage = randomString()
111113
val firstSearchMessagesResult = SearchMessagesResult(
112114
messages = listOf(message1),
113115
next = nextPage,
114116
)
115-
val attachment2 = randomAttachment(type = ATTACHMENT_TYPE)
117+
val attachment2 = randomAttachment()
116118
val message2 = randomMessage(cid = CID, attachments = listOf(attachment2))
117119
val secondSearchMessagesResult = SearchMessagesResult(
118120
messages = listOf(message2),
@@ -151,7 +153,7 @@ internal class ChannelAttachmentsViewControllerTest {
151153

152154
@Test
153155
fun `when load more fails, should emit error event and retain state`() = runTest {
154-
val attachment1 = randomAttachment(type = ATTACHMENT_TYPE)
156+
val attachment1 = randomAttachment()
155157
val message1 = randomMessage(cid = CID, attachments = listOf(attachment1))
156158
val nextPage = randomString()
157159
val firstSearchMessagesResult = SearchMessagesResult(
@@ -271,9 +273,10 @@ private class Fixture {
271273
) doAnswer { result?.asCall() ?: error?.asCall() }
272274
}
273275

274-
fun get(scope: CoroutineScope) = ChannelAttachmentsViewController(
276+
fun get(scope: CoroutineScope, localFilter: (Attachment) -> Boolean = { true }) = ChannelAttachmentsViewController(
275277
cid = CID,
276278
attachmentTypes = listOf(ATTACHMENT_TYPE),
279+
localFilter = localFilter,
277280
chatClient = chatClient,
278281
scope = scope,
279282
)

stream-chat-android-ui-components-sample/src/main/kotlin/io/getstream/chat/ui/sample/feature/chat/info/shared/media/ChatInfoSharedMediaFragment.kt

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import io.getstream.chat.android.models.AttachmentType
3333
import io.getstream.chat.android.ui.ChatUI
3434
import io.getstream.chat.android.ui.common.feature.channel.attachments.ChannelAttachmentsViewAction
3535
import io.getstream.chat.android.ui.common.state.channel.attachments.ChannelAttachmentsViewState
36+
import io.getstream.chat.android.ui.common.utils.extensions.imagePreviewUrl
3637
import io.getstream.chat.android.ui.feature.gallery.AttachmentGalleryDestination
3738
import io.getstream.chat.android.ui.feature.gallery.AttachmentGalleryItem
3839
import io.getstream.chat.android.ui.viewmodel.channel.ChannelAttachmentsViewModel
@@ -46,8 +47,9 @@ class ChatInfoSharedMediaFragment : Fragment() {
4647
private val args: ChatInfoSharedMediaFragmentArgs by navArgs()
4748
private val viewModel: ChannelAttachmentsViewModel by viewModels {
4849
ChannelAttachmentsViewModelFactory(
49-
args.cid!!,
50+
cid = args.cid!!,
5051
attachmentTypes = listOf(AttachmentType.IMAGE, AttachmentType.VIDEO),
52+
localFilter = { !it.imagePreviewUrl.isNullOrEmpty() && it.titleLink.isNullOrEmpty() },
5153
)
5254
}
5355

@@ -122,19 +124,15 @@ class ChatInfoSharedMediaFragment : Fragment() {
122124
}
123125

124126
is ChannelAttachmentsViewState.Content -> {
125-
val results = state.items.mapNotNull {
126-
if (!it.attachment.imageUrl.isNullOrEmpty() && it.attachment.titleLink.isNullOrEmpty()) {
127-
AttachmentGalleryItem(
128-
attachment = it.attachment,
129-
user = it.message.user,
130-
createdAt = it.message.getCreatedAtOrThrow(),
131-
messageId = it.message.id,
132-
cid = it.message.cid,
133-
isMine = it.message.user.id == user?.id,
134-
)
135-
} else {
136-
null
137-
}
127+
val results = state.items.map {
128+
AttachmentGalleryItem(
129+
attachment = it.attachment,
130+
user = it.message.user,
131+
createdAt = it.message.getCreatedAtOrThrow(),
132+
messageId = it.message.id,
133+
cid = it.message.cid,
134+
isMine = it.message.user.id == user?.id,
135+
)
138136
}
139137
if (results.isEmpty()) {
140138
showEmptyState()

0 commit comments

Comments
 (0)