Skip to content

Commit 2ad18d8

Browse files
authored
Merge branch 'v7' into rm-archive-primary
2 parents 061eb54 + 9ce7d4f commit 2ad18d8

File tree

16 files changed

+148
-59
lines changed

16 files changed

+148
-59
lines changed

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messageoptions/MessageOptions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public fun defaultMessageOptionsState(
138138
} else {
139139
null
140140
},
141-
if (visibility.canMarkAsUnread(ownCapabilities)) {
141+
if (visibility.canMarkAsUnread(currentUser, selectedMessage, ownCapabilities)) {
142142
MessageOptionItemState(
143143
title = R.string.stream_compose_mark_as_unread,
144144
iconPainter = painterResource(R.drawable.stream_compose_ic_mark_as_unread),

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/util/extensions/MessageOptionItemVisibility.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,13 @@ internal fun MessageOptionItemVisibility.canBlockUser(
122122
)
123123

124124
internal fun MessageOptionItemVisibility.canMarkAsUnread(
125+
currentUser: User?,
126+
message: Message,
125127
ownCapabilities: Set<String>,
126128
): Boolean = canMarkAsUnread(
127129
markAsUnreadEnabled = isMarkAsUnreadVisible,
130+
currentUser = currentUser,
131+
message = message,
128132
ownCapabilities = ownCapabilities,
129133
)
130134

stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/util/extensions/MessageOptionItemVisibilityTest.kt

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,12 @@ internal class MessageOptionItemVisibilityTest {
150150
@MethodSource("canMarkAsUnreadArguments")
151151
fun `Verify canMarkAsUnread() extension function return proper value`(
152152
messageOptionItemVisibility: MessageOptionItemVisibility,
153+
currentUser: User?,
154+
message: Message,
153155
ownCapabilities: Set<String>,
154156
expectedResult: Boolean,
155157
) {
156-
messageOptionItemVisibility.canMarkAsUnread(ownCapabilities) `should be` expectedResult
158+
messageOptionItemVisibility.canMarkAsUnread(currentUser, message, ownCapabilities) `should be` expectedResult
157159
}
158160

159161
@ParameterizedTest
@@ -212,18 +214,35 @@ internal class MessageOptionItemVisibilityTest {
212214

213215
@JvmStatic
214216
fun canMarkAsUnreadArguments() = listOf(
217+
// case: visibility disabled
215218
Arguments.of(
216219
MessageOptionItemVisibility(isMarkAsUnreadVisible = false),
217-
randomChannelCapabilities(),
220+
currentUser,
221+
randomMessage(),
222+
randomChannelCapabilities(include = setOf(ChannelCapabilities.READ_EVENTS)),
218223
false,
219224
),
225+
// case: no READ_EVENTS capability
220226
Arguments.of(
221-
MessageOptionItemVisibility(),
227+
MessageOptionItemVisibility(isMarkAsUnreadVisible = true),
228+
currentUser,
229+
randomMessage(),
222230
randomChannelCapabilities(exclude = setOf(ChannelCapabilities.READ_EVENTS)),
223231
false,
224232
),
233+
// case: own message
225234
Arguments.of(
226235
MessageOptionItemVisibility(isMarkAsUnreadVisible = true),
236+
currentUser,
237+
randomMessage(user = currentUser),
238+
randomChannelCapabilities(include = setOf(ChannelCapabilities.READ_EVENTS)),
239+
false,
240+
),
241+
// case: all conditions met
242+
Arguments.of(
243+
MessageOptionItemVisibility(isMarkAsUnreadVisible = true),
244+
currentUser,
245+
randomMessage(),
227246
randomChannelCapabilities(include = setOf(ChannelCapabilities.READ_EVENTS)),
228247
true,
229248
),

stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/messages/MessageComposerViewModelTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ internal class MessageComposerViewModelTest {
446446
private val clientState: ClientState = mock()
447447
private val channelState: ChannelState = mock()
448448
private val storageHelper: AttachmentStorageHelper = mock {
449-
on { resolveAttachmentFiles(any()) } doAnswer { it.getArgument(0) }
449+
onBlocking { resolveAttachmentFiles(any()) } doAnswer { it.getArgument(0) }
450450
}
451451
private val appSettings: AppSettings = AppSettings(
452452
app = App(
Loading
Loading

stream-chat-android-ui-common/api/stream-chat-android-ui-common.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3293,7 +3293,7 @@ public final class io/getstream/chat/android/ui/common/utils/CapabilitiesHelperK
32933293
public static final fun canDeleteMessage (ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/models/Message;Ljava/util/Set;)Z
32943294
public static final fun canEditMessage (ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/models/Message;Ljava/util/Set;)Z
32953295
public static final fun canFlagMessage (ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/models/Message;Ljava/util/Set;)Z
3296-
public static final fun canMarkAsUnread (ZLjava/util/Set;)Z
3296+
public static final fun canMarkAsUnread (ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/models/Message;Ljava/util/Set;)Z
32973297
public static final fun canMuteUser (ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/Channel;)Z
32983298
public static final fun canPinMessage (ZLio/getstream/chat/android/models/Message;Ljava/util/Set;)Z
32993299
public static final fun canReplyToMessage (ZLio/getstream/chat/android/models/Message;Ljava/util/Set;)Z

stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/composer/MessageComposerController.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -746,9 +746,7 @@ public class MessageComposerController(
746746

747747
if (resolveAttachments != null) {
748748
scope.launch {
749-
val resolved = withContext(DispatcherProvider.IO) {
750-
resolveAttachments(preparedMessage.attachments)
751-
}
749+
val resolved = resolveAttachments(preparedMessage.attachments)
752750
enqueueSendMessage(preparedMessage.copy(attachments = resolved), callback)
753751
}
754752
} else {
@@ -763,8 +761,7 @@ public class MessageComposerController(
763761
) {
764762
scope.launch {
765763
val resolvedMessage = resolveAttachments?.let { resolve ->
766-
val resolved = withContext(DispatcherProvider.IO) { resolve(message.attachments) }
767-
message.copy(attachments = resolved)
764+
message.copy(attachments = resolve(message.attachments))
768765
} ?: message
769766
chatClient.editMessage(channelType, channelId, resolvedMessage).enqueue(callback)
770767
}

stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/AudioPlayerController.kt

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,20 @@ public class AudioPlayerController(
8282
"[togglePlayback] audioHash: $audioHash, currentPlayingId; $currentPlayingId, " +
8383
"isCurrentTrack: $isCurrentTrack, isProgressRunning: $isProgressRunning, state: ${curState.stringify()}"
8484
}
85-
when (isCurrentTrack && isProgressRunning) {
86-
true -> when (curState.current.isPlaying) {
87-
true -> pause()
88-
else -> resume()
85+
86+
val hasPartialProgress = isCurrentTrack && isProgressRunning
87+
val isLoadedInPlayer = currentPlayingId == audioHash
88+
when {
89+
// Audio is partially played and currently loaded -> toggle play/pause
90+
hasPartialProgress && isLoadedInPlayer -> {
91+
if (curState.current.isPlaying) pause() else resume()
92+
}
93+
// Audio is partially played but another audio is loaded -> save progress and switch
94+
hasPartialProgress -> {
95+
setState(curState.copy(seekTo = curState.seekTo + (audioHash to curState.current.playingProgress)))
96+
play(attachment)
8997
}
98+
// No prior progress -> start from the beginning
9099
else -> play(attachment)
91100
}
92101
}
@@ -140,6 +149,7 @@ public class AudioPlayerController(
140149
isPlaying = audioState == AudioState.PLAYING,
141150
isSeeking = true,
142151
)
152+
143153
else -> curState.current
144154
},
145155
)
@@ -173,6 +183,7 @@ public class AudioPlayerController(
173183
playingProgress = progress,
174184
playbackInMs = positionInMs,
175185
)
186+
176187
else -> curState.current
177188
},
178189
seekTo = curState.seekTo + (audioHash to progress),

stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/helper/internal/AttachmentStorageHelper.kt

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ import androidx.annotation.WorkerThread
2424
import io.getstream.chat.android.client.utils.attachment.isImage
2525
import io.getstream.chat.android.client.utils.attachment.isVideo
2626
import io.getstream.chat.android.core.internal.InternalStreamChatApi
27+
import io.getstream.chat.android.core.internal.coroutines.DispatcherProvider
2728
import io.getstream.chat.android.models.Attachment
2829
import io.getstream.chat.android.ui.common.helper.internal.AttachmentStorageHelper.Companion.EXTRA_SOURCE_URI
2930
import io.getstream.chat.android.ui.common.state.messages.composer.AttachmentMetaData
3031
import io.getstream.log.taggedLogger
32+
import kotlinx.coroutines.withContext
3133
import java.io.File
3234

3335
/**
@@ -98,37 +100,37 @@ public class AttachmentStorageHelper(
98100
* @param attachments The attachments to resolve.
99101
* @return Attachments with [Attachment.upload] populated for every entry that had a source URI.
100102
*/
101-
@WorkerThread
102-
public fun resolveAttachmentFiles(
103-
attachments: List<Attachment>,
104-
): List<Attachment> = attachments.mapNotNull { attachment ->
105-
if (attachment.upload != null) return@mapNotNull attachment
106-
val sourceUri = (attachment.extraData[EXTRA_SOURCE_URI] as? String)
107-
?.let(Uri::parse) ?: return@mapNotNull attachment
108-
val metaData = AttachmentMetaData(
109-
uri = sourceUri,
110-
type = attachment.type,
111-
mimeType = attachment.mimeType,
112-
title = attachment.name,
113-
).apply { size = attachment.fileSize.toLong() }
114-
val file = storageHelper.getCachedFileFromUri(context, metaData)
115-
if (file == null) {
116-
logger.w { "[resolveAttachmentFiles] Failed to resolve file for URI: $sourceUri" }
117-
return@mapNotNull null
118-
}
103+
public suspend fun resolveAttachmentFiles(attachments: List<Attachment>): List<Attachment> =
104+
withContext(DispatcherProvider.IO) {
105+
attachments.mapNotNull { attachment ->
106+
if (attachment.upload != null) return@mapNotNull attachment
107+
val sourceUri = (attachment.extraData[EXTRA_SOURCE_URI] as? String)
108+
?.let(Uri::parse) ?: return@mapNotNull attachment
109+
val metaData = AttachmentMetaData(
110+
uri = sourceUri,
111+
type = attachment.type,
112+
mimeType = attachment.mimeType,
113+
title = attachment.name,
114+
).apply { size = attachment.fileSize.toLong() }
115+
val file = storageHelper.getCachedFileFromUri(context, metaData)
116+
if (file == null) {
117+
logger.w { "[resolveAttachmentFiles] Failed to resolve file for URI: $sourceUri" }
118+
return@mapNotNull null
119+
}
119120

120-
val (width, height) = if (attachment.originalWidth == null && attachment.originalHeight == null) {
121-
resolveLocalDimensions(file, attachment)
122-
} else {
123-
attachment.originalWidth to attachment.originalHeight
121+
val (width, height) = if (attachment.originalWidth == null && attachment.originalHeight == null) {
122+
resolveLocalDimensions(file, attachment)
123+
} else {
124+
attachment.originalWidth to attachment.originalHeight
125+
}
126+
attachment.copy(
127+
upload = file,
128+
extraData = attachment.extraData - EXTRA_SOURCE_URI,
129+
originalWidth = width,
130+
originalHeight = height,
131+
)
132+
}
124133
}
125-
attachment.copy(
126-
upload = file,
127-
extraData = attachment.extraData - EXTRA_SOURCE_URI,
128-
originalWidth = width,
129-
originalHeight = height,
130-
)
131-
}
132134

133135
/**
134136
* Resolves a list of file [Uri]s into [AttachmentMetaData].

0 commit comments

Comments
 (0)