From 3b1a346dfb46659593f3b6d811b944f7ccc92c7c Mon Sep 17 00:00:00 2001 From: Yamil Medina Date: Tue, 3 Dec 2024 11:46:52 +0000 Subject: [PATCH] Commit with unresolved merge conflicts outside of submodules --- .../com/wire/android/mapper/ContactMapper.kt | 8 +- .../wire/android/mapper/ConversationMapper.kt | 6 +- .../com/wire/android/mapper/MessageMapper.kt | 5 +- .../wire/android/mapper/OtherAccountMapper.kt | 16 + .../mapper/RegularMessageContentMapper.kt | 4 + .../mapper/SystemMessageContentMapper.kt | 6 +- .../android/mapper/UICallParticipantMapper.kt | 4 +- .../android/mapper/UIParticipantMapper.kt | 10 +- .../com/wire/android/model/ImageAsset.kt | 56 +- .../com/wire/android/model/UserAvatarData.kt | 3 - .../ui/calling/SharedCallingViewModel.kt | 4 +- .../com/wire/android/ui/home/HomeViewModel.kt | 11 +- .../conversations/ConversationMemberExt.kt | 15 +- .../info/ConversationInfoViewModel.kt | 4 +- .../messages/item/SystemMessageItem.kt | 29 +- .../messages/item/SystemMessageItemLeading.kt | 4 +- .../ui/home/conversations/mock/Mock.kt | 37 +- .../ui/home/conversations/model/UIMessage.kt | 580 ++++++++---------- .../conversations/model/UIQuotedMessage.kt | 14 +- .../GetConversationsFromSearchUseCase.kt | 23 + .../ConversationListViewModel.kt | 6 + .../conversationslist/model/BadgeEventType.kt | 41 +- .../model/ConversationItem.kt | 6 - .../ui/home/gallery/MediaGalleryViewModel.kt | 3 + .../ImportMediaAuthenticatedViewModel.kt | 4 +- .../other/OtherUserProfileScreenViewModel.kt | 4 +- .../self/SelfUserProfileViewModel.kt | 13 +- .../service/ServiceDetailsViewModel.kt | 4 +- .../util/ui/LocalizedStringResource.kt | 33 +- .../kotlin/com/wire/android/util/ui/UIText.kt | 5 - .../wire/android/mapper/MessageMapperTest.kt | 6 +- .../android/mapper/OtherAccountMapperTest.kt | 22 +- .../mapper/RegularMessageContentMapperTest.kt | 6 +- .../mapper/UICallParticipantMapperTest.kt | 3 +- .../android/mapper/UIParticipantMapperTest.kt | 12 +- .../com/wire/android/model/ImageAssetTest.kt | 11 +- .../android/navigation/NavigationUtilsTest.kt | 13 +- .../ui/calling/SharedCallingViewModelTest.kt | 10 +- .../ConnectionActionButtonViewModelTest.kt | 4 + .../wire/android/ui/home/HomeViewModelTest.kt | 8 + ...eParticipantsForConversationUseCaseTest.kt | 5 +- .../ConversationInfoViewModelArrangement.kt | 5 + .../GetConversationsFromSearchUseCaseTest.kt | 9 + .../ConversationListViewModelTest.kt | 9 + .../home/gallery/MediaGalleryViewModelTest.kt | 5 + .../ImportMediaAuthenticatedViewModelTest.kt | 5 + .../OtherUserProfileViewModelArrangement.kt | 7 +- .../SelfUserProfileViewModelArrangement.kt | 16 + .../service/ServiceDetailsViewModelTest.kt | 5 + .../android/util/ui/AssetImageFetcherTest.kt | 22 +- core/ui-common/build.gradle.kts | 5 +- .../common/bottomsheet/WireModalSheetState.kt | 45 +- 52 files changed, 680 insertions(+), 511 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/mapper/ContactMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/ContactMapper.kt index 3644579c3b8..af690cfbd0a 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/ContactMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/ContactMapper.kt @@ -25,6 +25,7 @@ import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.ui.home.newconversation.model.Contact import com.wire.android.ui.userprofile.common.UsernameMapper import com.wire.android.util.EMPTY +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.publicuser.model.UserSearchDetails import com.wire.kalium.logic.data.service.ServiceDetails import com.wire.kalium.logic.data.user.ConnectionState @@ -35,6 +36,7 @@ import javax.inject.Inject class ContactMapper @Inject constructor( private val userTypeMapper: UserTypeMapper, + private val wireSessionImageLoader: WireSessionImageLoader, ) { fun fromOtherUser(otherUser: OtherUser): Contact { @@ -46,7 +48,7 @@ class ContactMapper handle = handle.orEmpty(), label = UsernameMapper.fromOtherUser(otherUser), avatarData = UserAvatarData( - asset = previewPicture?.let { ImageAsset.UserAvatarAsset(it) }, + asset = previewPicture?.let { ImageAsset.UserAvatarAsset(wireSessionImageLoader, it) }, connectionState = connectionStatus, nameBasedAvatar = NameBasedAvatar(fullName = name, accentColor = otherUser.accentId) ), @@ -65,7 +67,7 @@ class ContactMapper handle = String.EMPTY, label = String.EMPTY, avatarData = UserAvatarData( - asset = previewAssetId?.let { ImageAsset.UserAvatarAsset(it) }, + asset = previewAssetId?.let { ImageAsset.UserAvatarAsset(wireSessionImageLoader, it) }, membership = Membership.Service ), membership = Membership.Service, @@ -83,7 +85,7 @@ class ContactMapper handle = handle.orEmpty(), label = mapUserHandle(user), avatarData = UserAvatarData( - asset = previewAssetId?.let { ImageAsset.UserAvatarAsset(it) }, + asset = previewAssetId?.let { ImageAsset.UserAvatarAsset(wireSessionImageLoader, it) }, nameBasedAvatar = NameBasedAvatar(fullName = name, accentColor = -1) ), membership = userTypeMapper.toMembership(type), diff --git a/app/src/main/kotlin/com/wire/android/mapper/ConversationMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/ConversationMapper.kt index 4098405e5c8..99820e48b3e 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/ConversationMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/ConversationMapper.kt @@ -26,6 +26,7 @@ import com.wire.android.ui.home.conversationslist.model.BlockState import com.wire.android.ui.home.conversationslist.model.ConversationInfo import com.wire.android.ui.home.conversationslist.model.ConversationItem import com.wire.android.ui.home.conversationslist.showLegalHoldIndicator +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.ConversationDetails.Connection import com.wire.kalium.logic.data.conversation.ConversationDetails.Group import com.wire.kalium.logic.data.conversation.ConversationDetails.OneOne @@ -40,6 +41,7 @@ import com.wire.kalium.logic.data.user.UserAvailabilityStatus @Suppress("LongMethod") fun ConversationDetailsWithEvents.toConversationItem( + wireSessionImageLoader: WireSessionImageLoader, userTypeMapper: UserTypeMapper, searchQuery: String, selfUserTeamId: TeamId? @@ -72,7 +74,7 @@ fun ConversationDetailsWithEvents.toConversationItem( is OneOne -> { ConversationItem.PrivateConversation( userAvatarData = UserAvatarData( - asset = conversationDetails.otherUser.previewPicture?.let { UserAvatarAsset(it) }, + asset = conversationDetails.otherUser.previewPicture?.let { UserAvatarAsset(wireSessionImageLoader, it) }, availabilityStatus = conversationDetails.otherUser.availabilityStatus, connectionState = conversationDetails.otherUser.connectionStatus, nameBasedAvatar = NameBasedAvatar(conversationDetails.otherUser.name, conversationDetails.otherUser.accentId) @@ -109,7 +111,7 @@ fun ConversationDetailsWithEvents.toConversationItem( is Connection -> { ConversationItem.ConnectionConversation( userAvatarData = UserAvatarData( - asset = conversationDetails.otherUser?.previewPicture?.let { UserAvatarAsset(it) }, + asset = conversationDetails.otherUser?.previewPicture?.let { UserAvatarAsset(wireSessionImageLoader, it) }, availabilityStatus = conversationDetails.otherUser?.availabilityStatus ?: UserAvailabilityStatus.NONE, nameBasedAvatar = NameBasedAvatar(conversationDetails.otherUser?.name, conversationDetails.otherUser?.accentId ?: -1) ), diff --git a/app/src/main/kotlin/com/wire/android/mapper/MessageMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/MessageMapper.kt index 386c7841ad9..cb0680e6e33 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/MessageMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/MessageMapper.kt @@ -37,6 +37,7 @@ import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.ui.theme.Accent import com.wire.android.util.time.ISOFormatter import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.message.DeliveryStatus import com.wire.kalium.logic.data.message.Message import com.wire.kalium.logic.data.message.MessageContent @@ -51,6 +52,8 @@ class MessageMapper @Inject constructor( private val userTypeMapper: UserTypeMapper, private val messageContentMapper: MessageContentMapper, private val isoFormatter: ISOFormatter, + // TODO(qol): a message mapper should not depend on a UI related component + private val wireSessionImageLoader: WireSessionImageLoader ) { fun memberIdList(messages: List): List = messages.flatMap { message -> @@ -197,7 +200,7 @@ class MessageMapper @Inject constructor( } private fun getUserAvatarData(sender: User?) = UserAvatarData( - asset = sender?.previewAsset(), + asset = sender?.previewAsset(wireSessionImageLoader), availabilityStatus = sender?.availabilityStatus ?: UserAvailabilityStatus.NONE, membership = sender?.userType?.let { userTypeMapper.toMembership(it) } ?: Membership.None, connectionState = getConnectionState(sender), diff --git a/app/src/main/kotlin/com/wire/android/mapper/OtherAccountMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/OtherAccountMapper.kt index 1c4fdf946b9..b6dad37e70c 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/OtherAccountMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/OtherAccountMapper.kt @@ -20,6 +20,7 @@ package com.wire.android.mapper import com.wire.android.ui.home.conversations.avatar import com.wire.android.ui.userprofile.self.model.OtherAccount +<<<<<<< HEAD import com.wire.kalium.logic.data.user.SelfUser import javax.inject.Inject @@ -29,5 +30,20 @@ class OtherAccountMapper @Inject constructor() { fullName = selfUser.name ?: "", avatarData = selfUser.avatar(selfUser.connectionStatus), handle = selfUser.handle +======= +import com.wire.android.util.ui.WireSessionImageLoader +import com.wire.kalium.logic.data.team.Team +import com.wire.kalium.logic.data.user.SelfUser +import javax.inject.Inject + +class OtherAccountMapper @Inject constructor( + private val wireSessionImageLoader: WireSessionImageLoader +) { + fun toOtherAccount(selfUser: SelfUser, team: Team?): OtherAccount = OtherAccount( + id = selfUser.id, + fullName = selfUser.name ?: "", + avatarData = selfUser.avatar(wireSessionImageLoader, selfUser.connectionStatus), + teamName = team?.name +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) ) } diff --git a/app/src/main/kotlin/com/wire/android/mapper/RegularMessageContentMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/RegularMessageContentMapper.kt index eabb1d96bec..6336f558bb4 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/RegularMessageContentMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/RegularMessageContentMapper.kt @@ -29,6 +29,7 @@ import com.wire.android.ui.home.conversations.model.UIMessageContent import com.wire.android.ui.home.conversations.model.UIQuotedMessage import com.wire.android.util.time.ISOFormatter import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.asset.AttachmentType import com.wire.kalium.logic.data.asset.isDisplayableImageMimeType import com.wire.kalium.logic.data.id.ConversationId @@ -49,6 +50,7 @@ import javax.inject.Inject @Suppress("TooManyFunctions") class RegularMessageMapper @Inject constructor( private val messageResourceProvider: MessageResourceProvider, + private val wireSessionImageLoader: WireSessionImageLoader, private val isoFormatter: ISOFormatter, ) { @@ -205,6 +207,7 @@ class RegularMessageMapper @Inject constructor( is MessageContent.QuotedMessageDetails.Asset -> when (AttachmentType.fromMimeTypeString(quotedContent.assetMimeType)) { AttachmentType.IMAGE -> UIQuotedMessage.UIQuotedData.DisplayableImage( ImageAsset.PrivateAsset( + wireSessionImageLoader, conversationId, it.messageId, it.isQuotingSelfUser @@ -246,6 +249,7 @@ class RegularMessageMapper @Inject constructor( UIMessageContent.ImageMessage( assetId = AssetId(remoteData.assetId, remoteData.assetDomain.orEmpty()), asset = ImageAsset.PrivateAsset( + wireSessionImageLoader, message.conversationId, message.id, sender is SelfUser diff --git a/app/src/main/kotlin/com/wire/android/mapper/SystemMessageContentMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/SystemMessageContentMapper.kt index 80183256282..611c6f1d0eb 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/SystemMessageContentMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/SystemMessageContentMapper.kt @@ -185,7 +185,7 @@ class SystemMessageContentMapper @Inject constructor( private fun mapTeamMemberRemovedMessage( content: MessageContent.TeamMemberRemoved - ): UIMessageContent.SystemMessage = UIMessageContent.SystemMessage.TeamMemberRemoved_Legacy(content.userName) + ): UIMessageContent.SystemMessage = UIMessageContent.SystemMessage.TeamMemberRemoved_Legacy(content) private fun mapConversationRenamedMessage( senderUserId: UserId, @@ -197,7 +197,7 @@ class SystemMessageContentMapper @Inject constructor( user = sender, type = SelfNameType.ResourceTitleCase ) - return UIMessageContent.SystemMessage.RenamedConversation(authorName, content.conversationName) + return UIMessageContent.SystemMessage.RenamedConversation(authorName, content) } fun mapMemberChangeMessage( @@ -271,7 +271,7 @@ class SystemMessageContentMapper @Inject constructor( UIMessageContent.SystemMessage.HistoryLost private fun mapMLSWrongEpochWarning(): UIMessageContent.SystemMessage = - UIMessageContent.SystemMessage.MLSWrongEpochWarning + UIMessageContent.SystemMessage.MLSWrongEpochWarning() private fun mapConversationHistoryListProtocolChanged(): UIMessageContent.SystemMessage = UIMessageContent.SystemMessage.HistoryLostProtocolChanged diff --git a/app/src/main/kotlin/com/wire/android/mapper/UICallParticipantMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/UICallParticipantMapper.kt index 3ce437b99df..4b84d17ca8a 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/UICallParticipantMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/UICallParticipantMapper.kt @@ -20,10 +20,12 @@ package com.wire.android.mapper import com.wire.android.model.ImageAsset import com.wire.android.ui.calling.model.UICallParticipant +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.call.Participant import javax.inject.Inject class UICallParticipantMapper @Inject constructor( + private val wireSessionImageLoader: WireSessionImageLoader, private val userTypeMapper: UserTypeMapper, ) { fun toUICallParticipant(participant: Participant) = UICallParticipant( @@ -34,7 +36,7 @@ class UICallParticipantMapper @Inject constructor( isSpeaking = participant.isSpeaking, isCameraOn = participant.isCameraOn, isSharingScreen = participant.isSharingScreen, - avatar = participant.avatarAssetId?.let { ImageAsset.UserAvatarAsset(it) }, + avatar = participant.avatarAssetId?.let { ImageAsset.UserAvatarAsset(wireSessionImageLoader, it) }, membership = userTypeMapper.toMembership(participant.userType), hasEstablishedAudio = participant.hasEstablishedAudio, accentId = participant.accentId diff --git a/app/src/main/kotlin/com/wire/android/mapper/UIParticipantMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/UIParticipantMapper.kt index 3610b892df8..87541dd46ab 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/UIParticipantMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/UIParticipantMapper.kt @@ -21,6 +21,7 @@ package com.wire.android.mapper import com.wire.android.ui.home.conversations.avatar import com.wire.android.ui.home.conversations.details.participants.model.UIParticipant import com.wire.android.ui.home.conversations.previewAsset +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.message.UserSummary import com.wire.kalium.logic.data.message.reaction.MessageReaction import com.wire.kalium.logic.data.message.receipt.DetailedReceipt @@ -32,6 +33,7 @@ import javax.inject.Inject class UIParticipantMapper @Inject constructor( private val userTypeMapper: UserTypeMapper, + private val wireSessionImageLoader: WireSessionImageLoader ) { fun toUIParticipant(user: User, isMLSVerified: Boolean = false): UIParticipant = with(user) { val (userType, connectionState, unavailable) = when (this) { @@ -43,7 +45,7 @@ class UIParticipantMapper @Inject constructor( id = id, name = name.orEmpty(), handle = handle.orEmpty(), - avatarData = avatar(connectionState), + avatarData = avatar(wireSessionImageLoader, connectionState), isSelf = user is SelfUser, isService = userType == UserType.SERVICE, membership = userTypeMapper.toMembership(userType), @@ -65,7 +67,7 @@ class UIParticipantMapper @Inject constructor( id = userSummary.userId, name = userSummary.userName.orEmpty(), handle = userSummary.userHandle.orEmpty(), - avatarData = userSummary.previewAsset(), + avatarData = userSummary.previewAsset(wireSessionImageLoader), membership = userTypeMapper.toMembership(userSummary.userType), unavailable = !userSummary.isUserDeleted && userSummary.userName.orEmpty().isEmpty(), isDeleted = userSummary.isUserDeleted, @@ -81,7 +83,7 @@ class UIParticipantMapper @Inject constructor( id = userSummary.userId, name = userSummary.userName.orEmpty(), handle = userSummary.userHandle.orEmpty(), - avatarData = userSummary.previewAsset(), + avatarData = userSummary.previewAsset(wireSessionImageLoader), membership = userTypeMapper.toMembership(userSummary.userType), unavailable = !userSummary.isUserDeleted && userSummary.userName.orEmpty().isEmpty(), isDeleted = userSummary.isUserDeleted, @@ -98,7 +100,7 @@ class UIParticipantMapper @Inject constructor( id = userSummary.userId, name = userSummary.userName.orEmpty(), handle = userSummary.userHandle.orEmpty(), - avatarData = previewAsset(), + avatarData = previewAsset(wireSessionImageLoader), membership = userTypeMapper.toMembership(userSummary.userType), unavailable = !userSummary.isUserDeleted && userSummary.userName.orEmpty().isEmpty(), isDeleted = userSummary.isUserDeleted, diff --git a/app/src/main/kotlin/com/wire/android/model/ImageAsset.kt b/app/src/main/kotlin/com/wire/android/model/ImageAsset.kt index b39c78d5095..aa3411778a7 100644 --- a/app/src/main/kotlin/com/wire/android/model/ImageAsset.kt +++ b/app/src/main/kotlin/com/wire/android/model/ImageAsset.kt @@ -18,33 +18,18 @@ package com.wire.android.model -import androidx.appcompat.app.AppCompatActivity import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.painterResource -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner import com.wire.android.R -import com.wire.android.ui.LocalActivity import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.id.QualifiedIdMapper import com.wire.kalium.logic.data.user.UserAssetId -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder import okio.Path -import okio.Path.Companion.toPath -import javax.inject.Inject @Stable -@Serializable sealed class ImageAsset { /** @@ -52,13 +37,16 @@ sealed class ImageAsset { * message, i.e. some preview images that the user selected from local device gallery. */ @Stable - @Serializable data class Local( - val dataPath: @Serializable(with = PathAsStringSerializer::class) Path, + val dataPath: Path, val idKey: String ) : ImageAsset() +<<<<<<< HEAD sealed class Remote : ImageAsset() { +======= + sealed class Remote(private val imageLoader: WireSessionImageLoader) : ImageAsset() { +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) /** * Value that uniquely identifies this Asset, @@ -72,53 +60,39 @@ sealed class ImageAsset { withCrossfadeAnimation: Boolean = false ) = when { LocalInspectionMode.current -> painterResource(id = R.drawable.ic_welcome_1) - else -> { - hiltViewModel( - // limit the scope of the ViewModel to the current activity so that there's one image loader instance for the Activity - viewModelStoreOwner = checkNotNull(LocalActivity.current as? AppCompatActivity ?: LocalViewModelStoreOwner.current) { - "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner" - }, - key = "remote_asset_image_loader" - ).imageLoader.paint(asset = this, fallbackData = fallbackData, withCrossfadeAnimation = withCrossfadeAnimation) - } + else -> imageLoader.paint(asset = this, fallbackData = fallbackData, withCrossfadeAnimation = withCrossfadeAnimation) } } @Stable - @Serializable data class UserAvatarAsset( + private val imageLoader: WireSessionImageLoader, val userAssetId: UserAssetId - ) : Remote() { + ) : Remote(imageLoader) { override val uniqueKey: String get() = userAssetId.toString() } @Stable - @Serializable data class PrivateAsset( + private val imageLoader: WireSessionImageLoader, val conversationId: ConversationId, val messageId: String, val isSelfAsset: Boolean, val isEphemeral: Boolean = false - ) : Remote() { + ) : Remote(imageLoader) { override fun toString(): String = "$conversationId:$messageId:$isSelfAsset:$isEphemeral" override val uniqueKey: String get() = toString() } } -fun String.parseIntoPrivateImageAsset(qualifiedIdMapper: QualifiedIdMapper): ImageAsset.PrivateAsset { +fun String.parseIntoPrivateImageAsset( + imageLoader: WireSessionImageLoader, + qualifiedIdMapper: QualifiedIdMapper, +): ImageAsset.PrivateAsset { val (conversationIdString, messageId, isSelfAsset, isEphemeral) = split(":") val conversationIdParam = qualifiedIdMapper.fromStringToQualifiedID(conversationIdString) - return ImageAsset.PrivateAsset(conversationIdParam, messageId, isSelfAsset.toBoolean(), isEphemeral.toBoolean()) + return ImageAsset.PrivateAsset(imageLoader, conversationIdParam, messageId, isSelfAsset.toBoolean(), isEphemeral.toBoolean()) } - -object PathAsStringSerializer : KSerializer { - override val descriptor = PrimitiveSerialDescriptor("Path", PrimitiveKind.STRING) - override fun serialize(encoder: Encoder, value: Path) = encoder.encodeString(value.toString()) - override fun deserialize(decoder: Decoder): Path = decoder.decodeString().toPath(normalize = true) -} - -@HiltViewModel -class RemoteAssetImageViewModel @Inject constructor(val imageLoader: WireSessionImageLoader) : ViewModel() diff --git a/app/src/main/kotlin/com/wire/android/model/UserAvatarData.kt b/app/src/main/kotlin/com/wire/android/model/UserAvatarData.kt index ed878820421..372e2ee474f 100644 --- a/app/src/main/kotlin/com/wire/android/model/UserAvatarData.kt +++ b/app/src/main/kotlin/com/wire/android/model/UserAvatarData.kt @@ -24,10 +24,8 @@ import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.util.EMPTY import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.UserAvailabilityStatus -import kotlinx.serialization.Serializable @Stable -@Serializable data class UserAvatarData( val asset: ImageAsset.UserAvatarAsset? = null, val availabilityStatus: UserAvailabilityStatus = UserAvailabilityStatus.NONE, @@ -52,7 +50,6 @@ data class UserAvatarData( /** * Holder that can be used to generate an avatar based on the user's full name initials and accent color. */ -@Serializable data class NameBasedAvatar(val fullName: String?, val accentColor: Int) { val initials: String get() { diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/SharedCallingViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/calling/SharedCallingViewModel.kt index 807f0600b43..975bfae950a 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/SharedCallingViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/SharedCallingViewModel.kt @@ -31,6 +31,7 @@ import com.wire.android.media.CallRinger import com.wire.android.model.ImageAsset import com.wire.android.ui.calling.model.UICallParticipant import com.wire.android.util.dispatchers.DispatcherProvider +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.call.Call import com.wire.kalium.logic.data.call.ConversationTypeForCall import com.wire.kalium.logic.data.call.VideoState @@ -85,6 +86,7 @@ class SharedCallingViewModel @AssistedInject constructor( private val observeSpeaker: ObserveSpeakerUseCase, private val callRinger: CallRinger, private val uiCallParticipantMapper: UICallParticipantMapper, + private val wireSessionImageLoader: WireSessionImageLoader, private val userTypeMapper: UserTypeMapper, private val dispatchers: DispatcherProvider ) : ViewModel() { @@ -135,7 +137,7 @@ class SharedCallingViewModel @AssistedInject constructor( callState.copy( conversationName = getConversationName(details.otherUser.name), avatarAssetId = details.otherUser.completePicture?.let { assetId -> - ImageAsset.UserAvatarAsset(assetId) + ImageAsset.UserAvatarAsset(wireSessionImageLoader, assetId) }, conversationTypeForCall = ConversationTypeForCall.OneOnOne, membership = userTypeMapper.toMembership(details.otherUser.userType), diff --git a/app/src/main/kotlin/com/wire/android/ui/home/HomeViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/home/HomeViewModel.kt index 8a549a03c4c..cc17af19eab 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/HomeViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/HomeViewModel.kt @@ -33,6 +33,7 @@ import com.wire.android.model.ImageAsset.UserAvatarAsset import com.wire.android.model.NameBasedAvatar import com.wire.android.model.UserAvatarData import com.wire.android.navigation.SavedStateViewModel +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.feature.client.NeedsToRegisterClientUseCase import com.wire.kalium.logic.feature.legalhold.LegalHoldStateForSelfUser import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldStateForSelfUserUseCase @@ -54,8 +55,13 @@ class HomeViewModel @Inject constructor( private val needsToRegisterClient: NeedsToRegisterClientUseCase, private val canMigrateFromPersonalToTeam: CanMigrateFromPersonalToTeamUseCase, private val observeLegalHoldStatusForSelfUser: ObserveLegalHoldStateForSelfUserUseCase, +<<<<<<< HEAD private val shouldTriggerMigrationForUser: ShouldTriggerMigrationForUserUserCase, private val analyticsManager: AnonymousAnalyticsManager +======= + private val wireSessionImageLoader: WireSessionImageLoader, + private val shouldTriggerMigrationForUser: ShouldTriggerMigrationForUserUserCase +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) ) : SavedStateViewModel(savedStateHandle) { @VisibleForTesting @@ -124,7 +130,10 @@ class HomeViewModel @Inject constructor( homeState = homeState.copy( userAvatarData = UserAvatarData( asset = selfUser.previewPicture?.let { - UserAvatarAsset(it) + UserAvatarAsset( + wireSessionImageLoader, + it + ) }, availabilityStatus = selfUser.availabilityStatus, nameBasedAvatar = NameBasedAvatar(selfUser.name, selfUser.accentId) diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/ConversationMemberExt.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/ConversationMemberExt.kt index 63c309e0006..f612d4ea10f 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/ConversationMemberExt.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/ConversationMemberExt.kt @@ -22,6 +22,7 @@ import com.wire.android.model.ImageAsset.UserAvatarAsset import com.wire.android.model.NameBasedAvatar import com.wire.android.model.UserAvatarData import com.wire.android.ui.home.conversationslist.model.Membership +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.MemberDetails import com.wire.kalium.logic.data.message.UserSummary import com.wire.kalium.logic.data.user.ConnectionState @@ -50,22 +51,24 @@ val MemberDetails.availabilityStatus: UserAvailabilityStatus is SelfUser -> (user as SelfUser).availabilityStatus } -fun User.previewAsset(): UserAvatarAsset? = when (this) { +fun User.previewAsset(wireSessionImageLoader: WireSessionImageLoader): UserAvatarAsset? = when (this) { is OtherUser -> previewPicture is SelfUser -> previewPicture -}?.let { UserAvatarAsset(it) } +}?.let { UserAvatarAsset(wireSessionImageLoader, it) } -fun User.avatar(connectionState: ConnectionState?): UserAvatarData = +fun User.avatar(wireSessionImageLoader: WireSessionImageLoader, connectionState: ConnectionState?): UserAvatarData = UserAvatarData( - asset = this.previewAsset(), + asset = this.previewAsset(wireSessionImageLoader), availabilityStatus = availabilityStatus, connectionState = connectionState, membership = if (userType == UserType.SERVICE) Membership.Service else Membership.None, nameBasedAvatar = NameBasedAvatar(fullName = name, accentColor = accentId) ) -fun UserSummary.previewAsset() = UserAvatarData( - asset = this.userPreviewAssetId?.let { UserAvatarAsset(it) }, +fun UserSummary.previewAsset( + wireSessionImageLoader: WireSessionImageLoader +) = UserAvatarData( + asset = this.userPreviewAssetId?.let { UserAvatarAsset(wireSessionImageLoader, it) }, availabilityStatus = this.availabilityStatus, connectionState = this.connectionStatus, nameBasedAvatar = NameBasedAvatar(fullName = userName, accentColor = accentId) diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/info/ConversationInfoViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/info/ConversationInfoViewModel.kt index 50fe76c34f7..5e36411a498 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/info/ConversationInfoViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/info/ConversationInfoViewModel.kt @@ -31,6 +31,7 @@ import com.wire.android.navigation.SavedStateViewModel import com.wire.android.ui.home.conversations.ConversationNavArgs import com.wire.android.ui.navArgs import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.android.util.ui.toUIText import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.conversation.ConversationDetails @@ -51,6 +52,7 @@ class ConversationInfoViewModel @Inject constructor( override val savedStateHandle: SavedStateHandle, private val observeConversationDetails: ObserveConversationDetailsUseCase, private val fetchConversationMLSVerificationStatus: FetchConversationMLSVerificationStatusUseCase, + private val wireSessionImageLoader: WireSessionImageLoader, @CurrentAccount private val selfUserId: UserId, ) : SavedStateViewModel(savedStateHandle) { @@ -152,7 +154,7 @@ class ConversationInfoViewModel @Inject constructor( is ConversationDetails.OneOne -> ConversationAvatar.OneOne( conversationDetails.otherUser.previewPicture?.let { - ImageAsset.UserAvatarAsset(it) + ImageAsset.UserAvatarAsset(wireSessionImageLoader, it) }, conversationDetails.otherUser.availabilityStatus ) diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItem.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItem.kt index 914aed7af53..e7441175174 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItem.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItem.kt @@ -235,7 +235,7 @@ fun SystemMessage.annotatedString( is SystemMessage.MemberJoined -> arrayOf(author.asString(res).markdownBold()) is SystemMessage.MemberLeft -> arrayOf(author.asString(res).markdownBold()) is SystemMessage.MissedCall -> arrayOf(author.asString(res).markdownBold()) - is SystemMessage.RenamedConversation -> arrayOf(author.asString(res).markdownBold(), conversationName.markdownBold()) + is SystemMessage.RenamedConversation -> arrayOf(author.asString(res).markdownBold(), content.conversationName.markdownBold()) is SystemMessage.CryptoSessionReset -> arrayOf(author.asString(res).markdownBold()) is SystemMessage.NewConversationReceiptMode -> arrayOf(receiptMode.asString(res).markdownBold()) is SystemMessage.ConversationReceiptModeChanged -> arrayOf( @@ -243,7 +243,7 @@ fun SystemMessage.annotatedString( receiptMode.asString(res).markdownBold() ) - is SystemMessage.TeamMemberRemoved_Legacy -> arrayOf(userName) + is SystemMessage.TeamMemberRemoved_Legacy -> arrayOf(content.userName) is SystemMessage.Knock -> arrayOf(author.asString(res).markdownBold()) is SystemMessage.HistoryLost -> arrayOf() is SystemMessage.MLSWrongEpochWarning -> arrayOf() @@ -274,15 +274,15 @@ fun SystemMessage.annotatedString( arrayOf(memberNames.limitUserNamesList(res, true).toUserNamesListMarkdownString(res)) } ?: arrayOf() } - val markdownString = when (stringRes) { - is LocalizedStringResource.Plural -> res.getQuantityString( - (stringRes as LocalizedStringResource.Plural).id, - (stringRes as LocalizedStringResource.Plural).quantity, + val markdownString = when (stringResId) { + is LocalizedStringResource.PluralResource -> res.getQuantityString( + (stringResId as LocalizedStringResource.PluralResource).id, + (stringResId as LocalizedStringResource.PluralResource).quantity, *markdownArgs ) - is LocalizedStringResource.String -> res.getString( - (stringRes as LocalizedStringResource.String).id, + is LocalizedStringResource.StringResource -> res.getString( + (stringResId as LocalizedStringResource.StringResource).id, *markdownArgs ) } @@ -321,7 +321,18 @@ private fun SystemMessage.MemberFailedToAdd.toFailedToAddMarkdownText( if (isMultipleUsersFailure) failedToAddAnnotatedText.append("\n\n") failedToAddAnnotatedText.append( markdownText( - res.getString(stringRes.id, memberNames.limitUserNamesList(res, true).toUserNamesListMarkdownString(res)), + when (stringResId) { + is LocalizedStringResource.PluralResource -> res.getQuantityString( + stringResId.id, + stringResId.quantity, + stringResId.formatArgs + ) + + is LocalizedStringResource.StringResource -> res.getString( + stringResId.id, + memberNames.limitUserNamesList(res, true).toUserNamesListMarkdownString(res) + ) + }, normalStyle, boldStyle, normalColor, diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItemLeading.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItemLeading.kt index 90d90139d63..3d89e323a07 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItemLeading.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItemLeading.kt @@ -30,9 +30,9 @@ import com.wire.android.ui.home.conversations.model.UIMessageContent.SystemMessa @Composable fun SystemMessageItemLeading(messageContent: SystemMessage, modifier: Modifier = Modifier) { - messageContent.iconResId?.let { iconResId -> + if (messageContent.iconResId != null) { Image( - painter = painterResource(id = iconResId), + painter = painterResource(id = messageContent.iconResId), contentDescription = null, colorFilter = getColorFilter(messageContent), modifier = modifier.size( diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/mock/Mock.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/mock/Mock.kt index d6fc0329e1e..35c80fbbdf1 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/mock/Mock.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/mock/Mock.kt @@ -18,6 +18,14 @@ package com.wire.android.ui.home.conversations.mock +import coil.ComponentRegistry +import coil.ImageLoader +import coil.disk.DiskCache +import coil.memory.MemoryCache +import coil.request.DefaultRequestOptions +import coil.request.Disposable +import coil.request.ImageRequest +import coil.request.ImageResult import com.wire.android.model.ImageAsset import com.wire.android.model.ImageAsset.UserAvatarAsset import com.wire.android.model.UserAvatarData @@ -35,12 +43,21 @@ import com.wire.android.ui.home.conversations.model.UIMessageContent import com.wire.android.ui.home.conversations.model.messagetypes.asset.UIAssetMessage import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.android.util.ui.toUIText import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.id.QualifiedID import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.UserAssetId import com.wire.kalium.logic.data.user.UserAvailabilityStatus +<<<<<<< HEAD +======= +import com.wire.kalium.network.NetworkState +import com.wire.kalium.network.NetworkStateObserver +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.datetime.Clock +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) import kotlinx.datetime.Instant import okio.Path.Companion.toPath @@ -270,10 +287,25 @@ val mockUsersUITexts = listOf( "Gudrun Gut".toUIText() ) +val mockImageLoader = WireSessionImageLoader(object : ImageLoader { + override val components: ComponentRegistry get() = TODO("Not yet implemented") + override val defaults: DefaultRequestOptions get() = TODO("Not yet implemented") + override val diskCache: DiskCache get() = TODO("Not yet implemented") + override val memoryCache: MemoryCache get() = TODO("Not yet implemented") + override fun enqueue(request: ImageRequest): Disposable = TODO("Not yet implemented") + override suspend fun execute(request: ImageRequest): ImageResult = TODO("Not yet implemented") + override fun newBuilder(): ImageLoader.Builder = TODO("Not yet implemented") + override fun shutdown() = TODO("Not yet implemented") +}, + object : NetworkStateObserver { + override fun observeNetworkState(): StateFlow = MutableStateFlow(NetworkState.ConnectedWithInternet) + } +) + fun mockAssetMessage(assetId: String = "asset1", messageId: String = "msg1") = UIMessage.Regular( conversationId = ConversationId("value", "domain"), userAvatarData = UserAvatarData( - UserAvatarAsset(UserAssetId("a", "domain")), + UserAvatarAsset(mockImageLoader, UserAssetId("a", "domain")), UserAvailabilityStatus.AVAILABLE ), header = MessageHeader( @@ -303,7 +335,7 @@ fun mockAssetMessage(assetId: String = "asset1", messageId: String = "msg1") = U fun mockAssetAudioMessage(assetId: String = "asset1", messageId: String = "msg1") = UIMessage.Regular( conversationId = ConversationId("value", "domain"), userAvatarData = UserAvatarData( - UserAvatarAsset(UserAssetId("a", "domain")), + UserAvatarAsset(mockImageLoader, UserAssetId("a", "domain")), UserAvailabilityStatus.AVAILABLE ), header = MessageHeader( @@ -349,6 +381,7 @@ fun mockedImg() = UIMessageContent.ImageMessage( ) fun mockedPrivateAsset() = ImageAsset.PrivateAsset( + imageLoader = mockImageLoader, conversationId = ConversationId("id", "domain"), messageId = "messageId", isSelfAsset = true diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt index e9c53a7269a..e66236f43c6 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt @@ -19,6 +19,7 @@ package com.wire.android.ui.home.conversations.model import android.content.res.Resources +import androidx.annotation.DrawableRes import androidx.annotation.PluralsRes import androidx.annotation.StringRes import androidx.compose.runtime.Stable @@ -40,6 +41,7 @@ import com.wire.kalium.logic.data.conversation.ClientId import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.message.Message +import com.wire.kalium.logic.data.message.MessageContent import com.wire.kalium.logic.data.user.AssetId import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.UserId @@ -51,10 +53,8 @@ import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableList import kotlinx.datetime.Instant -import kotlinx.serialization.Serializable import kotlin.time.Duration -@Serializable sealed interface UIMessage { val conversationId: ConversationId val header: MessageHeader @@ -64,7 +64,6 @@ sealed interface UIMessage { val decryptionFailed: Boolean val isPending: Boolean - @Serializable data class Regular( override val conversationId: ConversationId, override val header: MessageHeader, @@ -111,7 +110,6 @@ sealed interface UIMessage { val isLocation: Boolean = messageContent is UIMessageContent.Location } - @Serializable data class System( override val conversationId: ConversationId, override val header: MessageHeader, @@ -126,7 +124,6 @@ sealed interface UIMessage { } @Stable -@Serializable data class MessageHeader( val username: UIText, val membership: Membership, @@ -144,42 +141,41 @@ data class MessageHeader( ) @Stable -@Serializable data class MessageFooter( val messageId: String, val reactions: Map = emptyMap(), val ownReactions: Set = emptySet() ) -@Serializable -sealed interface ExpirationStatus { - - @Serializable +sealed class ExpirationStatus { data class Expirable( val expireAfter: Duration, val selfDeletionStatus: Message.ExpirationData.SelfDeletionStatus - ) : ExpirationStatus + ) : ExpirationStatus() - @Serializable - data object NotExpirable : ExpirationStatus + object NotExpirable : ExpirationStatus() } -@Serializable -sealed interface MessageEditStatus { - - @Serializable - data object NonEdited : MessageEditStatus - - @Serializable - data class Edited(val formattedEditTimeStamp: String) : MessageEditStatus +sealed class MessageEditStatus { + object NonEdited : MessageEditStatus() + data class Edited(val formattedEditTimeStamp: String) : MessageEditStatus() } -@Serializable -sealed interface MessageFlowStatus { - - @Serializable - data object Sending : MessageFlowStatus +sealed class MessageFlowStatus { + + data object Sending : MessageFlowStatus() + data object Sent : MessageFlowStatus() + sealed class Failure(val errorText: UIText) : MessageFlowStatus() { + sealed class Send(errorText: UIText) : Failure(errorText) { + data class Locally(val isEdited: Boolean) : Send( + if (isEdited) { + UIText.StringResource(R.string.label_message_edit_sent_failure) + } else { + UIText.StringResource(R.string.label_message_sent_failure) + } + ) +<<<<<<< HEAD @Serializable data object Sent : MessageFlowStatus @@ -204,25 +200,36 @@ sealed interface MessageFlowStatus { else -> UIText.StringResource(R.string.label_message_sent_remotely_failure, backendWithFailure) } } +======= + data class Remotely(val isEdited: Boolean, val backendWithFailure: String) : Send( + if (isEdited) { + UIText.StringResource( + R.string.label_message_edit_sent_remotely_failure, + backendWithFailure + ) + } else { + UIText.StringResource( + R.string.label_message_sent_remotely_failure, + backendWithFailure + ) + } + ) +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) } - @Serializable - data class Decryption(val isDecryptionResolved: Boolean, private val errorCode: Int?) : Failure { - override val errorText: UIText = errorCode?.let { + data class Decryption(val isDecryptionResolved: Boolean, private val errorCode: Int?) : Failure( + errorCode?.let { UIText.StringResource(R.string.label_message_decryption_failure_message_with_error_code, it) } ?: UIText.StringResource(R.string.label_message_decryption_failure_message) - } + ) } - @Serializable - data object Delivered : MessageFlowStatus + data object Delivered : MessageFlowStatus() - @Serializable - data class Read(val count: Long) : MessageFlowStatus + data class Read(val count: Long) : MessageFlowStatus() } @Stable -@Serializable data class MessageStatus( val flowStatus: MessageFlowStatus, val expirationStatus: ExpirationStatus, @@ -243,54 +250,47 @@ data class MessageStatus( } @Stable -@Serializable -sealed interface UILastMessageContent { +sealed class UILastMessageContent { + object None : UILastMessageContent() - @Serializable - data object None : UILastMessageContent + data class TextMessage(val messageBody: MessageBody) : UILastMessageContent() - @Serializable - data class TextMessage(val messageBody: MessageBody) : UILastMessageContent - - @Serializable data class SenderWithMessage( val sender: UIText, val message: UIText, val separator: String = MarkdownConstants.NON_BREAKING_SPACE - ) : UILastMessageContent + ) : UILastMessageContent() - @Serializable data class MultipleMessage( val messages: List, val separator: String = MarkdownConstants.NON_BREAKING_SPACE - ) : UILastMessageContent + ) : UILastMessageContent() - @Serializable - data class Connection(val connectionState: ConnectionState, val userId: UserId) : UILastMessageContent + data class Connection(val connectionState: ConnectionState, val userId: UserId) : UILastMessageContent() - @Serializable - data class VerificationChanged(@StringRes val textResId: Int) : UILastMessageContent + data class VerificationChanged(@StringRes val textResId: Int) : UILastMessageContent() } -@Serializable -sealed interface UIMessageContent { +sealed class UIMessageContent { +<<<<<<< HEAD @Serializable sealed interface Regular : UIMessageContent +======= + sealed class Regular : UIMessageContent() +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) /** * IncompleteAssetMessage is a displayable asset that's missing the remote data. * Sometimes client receives two events about the same asset, first one with only part of the data ("preview" type from web), * so such asset shouldn't be shown until all the required data is received. */ - @Serializable - data object IncompleteAssetMessage : UIMessageContent + object IncompleteAssetMessage : UIMessageContent() interface PartialDeliverable { val deliveryStatus: DeliveryStatusContent } - @Serializable data class TextMessage( val messageBody: MessageBody, override val deliveryStatus: DeliveryStatusContent = DeliveryStatusContent.CompleteDelivery @@ -298,7 +298,6 @@ sealed interface UIMessageContent { override fun textToCopy(resources: Resources): String = messageBody.message.asString(resources) } - @Serializable data class Composite( val messageBody: MessageBody?, val buttonList: PersistentList @@ -306,10 +305,13 @@ sealed interface UIMessageContent { override fun textToCopy(resources: Resources): String? = messageBody?.message?.asString(resources) } +<<<<<<< HEAD @Serializable data object Deleted : Regular +======= + object Deleted : Regular() +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) - @Serializable data class RestrictedAsset( val mimeType: String, val assetSizeInBytes: Long, @@ -318,7 +320,6 @@ sealed interface UIMessageContent { ) : Regular, PartialDeliverable @Stable - @Serializable data class AssetMessage( val assetName: String, val assetExtension: String, @@ -327,7 +328,6 @@ sealed interface UIMessageContent { override val deliveryStatus: DeliveryStatusContent = DeliveryStatusContent.CompleteDelivery ) : Regular, PartialDeliverable - @Serializable data class ImageMessage( val assetId: AssetId, val asset: ImageAsset.PrivateAsset?, @@ -337,7 +337,6 @@ sealed interface UIMessageContent { ) : Regular, PartialDeliverable @Stable - @Serializable data class AudioAssetMessage( val assetName: String, val assetExtension: String, @@ -347,7 +346,6 @@ sealed interface UIMessageContent { ) : Regular, PartialDeliverable @Stable - @Serializable data class Location( val latitude: Float, val longitude: Float, @@ -357,363 +355,308 @@ sealed interface UIMessageContent { override val deliveryStatus: DeliveryStatusContent = DeliveryStatusContent.CompleteDelivery ) : Regular, PartialDeliverable - @Serializable - sealed interface SystemMessage : UIMessageContent { - val iconResId: Int? - val stringRes: LocalizedStringResource - val learnMoreResId: Int? get() = null - val isSmallIcon: Boolean get() = true + sealed class SystemMessage( + @DrawableRes val iconResId: Int?, + open val stringResId: LocalizedStringResource, + @StringRes val learnMoreResId: Int? = null, + val isSmallIcon: Boolean = true, + ) : UIMessageContent() { + + constructor( + @DrawableRes iconResId: Int?, + @StringRes stringResId: Int, + isSmallIcon: Boolean = true, + @StringRes learnMoreResId: Int? = null + ) : this(iconResId, LocalizedStringResource.StringResource(stringResId), learnMoreResId, isSmallIcon) + + constructor( + @DrawableRes iconResId: Int?, + @PluralsRes stringResId: Int, + quantity: Int, + formatArgs: List, + isSmallIcon: Boolean = true, + @StringRes learnMoreResId: Int? = null + ) : this( + iconResId, + LocalizedStringResource.PluralResource(stringResId, quantity, formatArgs.toTypedArray()), + learnMoreResId, + isSmallIcon + ) - @Serializable - data class Knock( - val author: UIText, - val isSelfTriggered: Boolean - ) : SystemMessage { - override val iconResId = R.drawable.ic_ping - override val stringRes = when { - isSelfTriggered -> R.string.label_system_message_self_user_knock - else -> R.string.label_system_message_other_user_knock - }.toLocalizedStringResource() - } + data class Knock(val author: UIText, val isSelfTriggered: Boolean) : SystemMessage( + R.drawable.ic_ping, + if (isSelfTriggered) R.string.label_system_message_self_user_knock else R.string.label_system_message_other_user_knock + ) - @Serializable data class MemberAdded( val author: UIText, val memberNames: List, val isSelfTriggered: Boolean = false - ) : SystemMessage { - override val iconResId = R.drawable.ic_add - override val stringRes = when { - isSelfTriggered -> R.string.label_system_message_added_by_self - else -> R.string.label_system_message_added_by_other - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_add, + if (isSelfTriggered) R.string.label_system_message_added_by_self else R.string.label_system_message_added_by_other + ) - @Serializable data class MemberJoined( val author: UIText, val isSelfTriggered: Boolean = false - ) : SystemMessage { - override val iconResId = R.drawable.ic_add - override val stringRes = when { - isSelfTriggered -> R.string.label_system_message_joined_the_conversation_by_self - else -> R.string.label_system_message_joined_the_conversation_by_other - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_add, + if (isSelfTriggered) { + R.string.label_system_message_joined_the_conversation_by_self + } else { + R.string.label_system_message_joined_the_conversation_by_other + } + ) - @Serializable data class MemberRemoved( val author: UIText, val memberNames: List, val isSelfTriggered: Boolean = false - ) : SystemMessage { - override val iconResId = R.drawable.ic_minus - override val stringRes = when { - isSelfTriggered -> R.string.label_system_message_removed_by_self - else -> R.string.label_system_message_removed_by_other - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_minus, + if (isSelfTriggered) R.string.label_system_message_removed_by_self else R.string.label_system_message_removed_by_other + ) - @Serializable data class TeamMemberRemoved( val author: UIText, val memberNames: List, - ) : SystemMessage { - override val iconResId = R.drawable.ic_minus - override val stringRes = R.plurals.label_system_message_team_member_left.toLocalizedPluralResource(memberNames.size) - } + ) : SystemMessage( + R.drawable.ic_minus, + R.plurals.label_system_message_team_member_left, + quantity = memberNames.size, + formatArgs = memberNames + ) - @Serializable data class MemberLeft( val author: UIText, val isSelfTriggered: Boolean = false - ) : SystemMessage { - override val iconResId = R.drawable.ic_minus - override val stringRes = when { - isSelfTriggered -> R.string.label_system_message_left_the_conversation_by_self - else -> R.string.label_system_message_left_the_conversation_by_other - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_minus, + if (isSelfTriggered) { + R.string.label_system_message_left_the_conversation_by_self + } else { + R.string.label_system_message_left_the_conversation_by_other + } + ) - @Serializable data class FederationMemberRemoved( val memberNames: List - ) : SystemMessage { - override val iconResId = R.drawable.ic_minus - override val stringRes = when { - memberNames.size > 1 -> R.string.label_system_message_federation_many_member_removed - else -> R.string.label_system_message_federation_one_member_removed - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_minus, + if (memberNames.size > 1) { + R.string.label_system_message_federation_many_member_removed + } else { + R.string.label_system_message_federation_one_member_removed + } + ) - @Serializable data class FederationStopped( val domainList: List - ) : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = when { - domainList.size > 1 -> R.string.label_system_message_federation_conection_removed - else -> R.string.label_system_message_federation_removed - }.toLocalizedStringResource() - override val learnMoreResId = R.string.url_federation_support - } - - @Serializable - sealed interface MissedCall : SystemMessage { - val author: UIText - override val iconResId get() = R.drawable.ic_call_end - override val isSmallIcon get() = false + ) : SystemMessage( + R.drawable.ic_info, + if (domainList.size > 1) { + R.string.label_system_message_federation_conection_removed + } else { + R.string.label_system_message_federation_removed + }, + learnMoreResId = R.string.url_federation_support + ) - @Serializable - data class YouCalled(override val author: UIText) : MissedCall { - override val stringRes = R.string.label_system_message_you_called.toLocalizedStringResource() - } + sealed class MissedCall( + open val author: UIText, + @StringRes stringResId: Int, + ) : SystemMessage(R.drawable.ic_call_end, stringResId, isSmallIcon = false) { - @Serializable - data class OtherCalled(override val author: UIText) : MissedCall { - override val stringRes = R.string.label_system_message_other_called.toLocalizedStringResource() - } + data class YouCalled(override val author: UIText) : MissedCall(author, R.string.label_system_message_you_called) + data class OtherCalled(override val author: UIText) : MissedCall(author, R.string.label_system_message_other_called) } - @Serializable - data class RenamedConversation( - val author: UIText, - val conversationName: String - ) : SystemMessage { - override val iconResId = R.drawable.ic_edit - override val stringRes = R.string.label_system_message_renamed_the_conversation.toLocalizedStringResource() - } + data class RenamedConversation(val author: UIText, val content: MessageContent.ConversationRenamed) : + SystemMessage(R.drawable.ic_edit, R.string.label_system_message_renamed_the_conversation) @Deprecated("Use TeamMemberRemoved") @Suppress("ClassNaming") - @Serializable - data class TeamMemberRemoved_Legacy( - val userName: String - ) : SystemMessage { - override val iconResId = R.drawable.ic_minus - override val stringRes = R.plurals.label_system_message_team_member_left.toLocalizedPluralResource(0) - } + data class TeamMemberRemoved_Legacy(val content: MessageContent.TeamMemberRemoved) : + SystemMessage( + R.drawable.ic_minus, + R.plurals.label_system_message_team_member_left, + quantity = 0, + formatArgs = emptyList(), + true + ) - @Serializable - data class CryptoSessionReset( - val author: UIText - ) : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = R.string.label_system_message_session_reset.toLocalizedStringResource() - } + data class CryptoSessionReset(val author: UIText) : + SystemMessage(R.drawable.ic_info, R.string.label_system_message_session_reset) - @Serializable data class NewConversationReceiptMode( val receiptMode: UIText - ) : SystemMessage { - override val iconResId = R.drawable.ic_view - override val stringRes = R.string.label_system_message_new_conversation_receipt_mode.toLocalizedStringResource() - } + ) : SystemMessage(R.drawable.ic_view, R.string.label_system_message_new_conversation_receipt_mode) - @Serializable data class ConversationReceiptModeChanged( val author: UIText, val receiptMode: UIText, val isAuthorSelfUser: Boolean = false - ) : SystemMessage { - override val iconResId = R.drawable.ic_view - override val stringRes = when { - isAuthorSelfUser -> R.string.label_system_message_read_receipt_changed_by_self - else -> R.string.label_system_message_read_receipt_changed_by_other - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_view, + if (isAuthorSelfUser) { + R.string.label_system_message_read_receipt_changed_by_self + } else { + R.string.label_system_message_read_receipt_changed_by_other + } + ) - @Serializable data class ConversationMessageTimerActivated( val author: UIText, val isAuthorSelfUser: Boolean = false, val selfDeletionDuration: SelfDeletionDuration - ) : SystemMessage { - override val iconResId = R.drawable.ic_timer - override val stringRes = when { - isAuthorSelfUser -> R.string.label_system_message_conversation_message_timer_activated_by_self - else -> R.string.label_system_message_conversation_message_timer_activated_by_other - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_timer, + if (isAuthorSelfUser) { + R.string.label_system_message_conversation_message_timer_activated_by_self + } else { + R.string.label_system_message_conversation_message_timer_activated_by_other + } + ) - @Serializable data class ConversationMessageTimerDeactivated( val author: UIText, val isAuthorSelfUser: Boolean = false - ) : SystemMessage { - override val iconResId = R.drawable.ic_timer - override val stringRes = when { - isAuthorSelfUser -> R.string.label_system_message_conversation_message_timer_deactivated_by_self - else -> R.string.label_system_message_conversation_message_timer_deactivated_by_other - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_timer, + if (isAuthorSelfUser) { + R.string.label_system_message_conversation_message_timer_deactivated_by_self + } else { + R.string.label_system_message_conversation_message_timer_deactivated_by_other + } + ) - @Serializable - data object MLSWrongEpochWarning : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = R.string.label_system_message_conversation_mls_wrong_epoch_error_handled.toLocalizedStringResource() - override val learnMoreResId = R.string.url_system_message_learn_more_about_mls - } + class MLSWrongEpochWarning : SystemMessage( + iconResId = R.drawable.ic_info, + stringResId = R.string.label_system_message_conversation_mls_wrong_epoch_error_handled, + learnMoreResId = R.string.url_system_message_learn_more_about_mls + ) - @Serializable data class ConversationProtocolChanged( val protocol: Conversation.Protocol - ) : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = when (protocol) { + ) : SystemMessage( + iconResId = R.drawable.ic_info, + stringResId = when (protocol) { Conversation.Protocol.PROTEUS -> R.string.label_system_message_conversation_protocol_changed_proteus Conversation.Protocol.MIXED -> R.string.label_system_message_conversation_protocol_changed_mixed Conversation.Protocol.MLS -> R.string.label_system_message_conversation_protocol_changed_mls - }.toLocalizedStringResource() - override val learnMoreResId = when (protocol) { + }, + learnMoreResId = when (protocol) { Conversation.Protocol.PROTEUS -> null Conversation.Protocol.MIXED -> null Conversation.Protocol.MLS -> R.string.url_system_message_learn_more_about_mls } - } + ) - @Serializable - data object ConversationProtocolChangedWithCallOngoing : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = R.string.label_system_message_conversation_protocol_changed_during_a_call.toLocalizedStringResource() - } + data object ConversationProtocolChangedWithCallOngoing : SystemMessage( + R.drawable.ic_info, + R.string.label_system_message_conversation_protocol_changed_during_a_call + ) - @Serializable - data object HistoryLost : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = R.string.label_system_message_conversation_history_lost.toLocalizedStringResource() - } + object HistoryLost : SystemMessage( + R.drawable.ic_info, + R.string.label_system_message_conversation_history_lost + ) - @Serializable - data object HistoryLostProtocolChanged : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = R.string.label_system_message_conversation_history_lost_protocol_changed.toLocalizedStringResource() - } + object HistoryLostProtocolChanged : SystemMessage( + R.drawable.ic_info, + R.string.label_system_message_conversation_history_lost_protocol_changed + ) - @Serializable data class ConversationMessageCreated( val author: UIText, val isAuthorSelfUser: Boolean = false, val date: String - ) : SystemMessage { - override val iconResId = R.drawable.ic_conversation - override val stringRes = when { - isAuthorSelfUser -> R.string.label_system_message_conversation_started_by_self - else -> R.string.label_system_message_conversation_started_by_other - }.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_conversation, + if (isAuthorSelfUser) { + R.string.label_system_message_conversation_started_by_self + } else { + R.string.label_system_message_conversation_started_by_other + } + ) - @Serializable data class ConversationStartedWithMembers( val memberNames: List - ) : SystemMessage { - override val iconResId = R.drawable.ic_contact - override val stringRes = R.string.label_system_message_conversation_started_with_members.toLocalizedStringResource() - } + ) : SystemMessage( + R.drawable.ic_contact, + R.string.label_system_message_conversation_started_with_members + ) - @Serializable data class MemberFailedToAdd( val memberNames: List, val type: Type, - ) : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = when { - memberNames.size > 1 -> R.string.label_system_message_conversation_failed_add_many_members_details - else -> R.string.label_system_message_conversation_failed_add_one_member_details - }.toLocalizedStringResource() - override val learnMoreResId = when (type) { + ) : SystemMessage( + R.drawable.ic_info, + if (memberNames.size > 1) { + R.string.label_system_message_conversation_failed_add_many_members_details + } else { + R.string.label_system_message_conversation_failed_add_one_member_details + }, + learnMoreResId = when (type) { Type.Federation -> R.string.url_message_details_offline_backends_learn_more Type.LegalHold -> R.string.url_legal_hold_learn_more Type.Unknown -> null } + + ) { val usersCount = memberNames.size enum class Type { Federation, LegalHold, Unknown; } } - @Serializable - data class ConversationDegraded( - val protocol: Conversation.Protocol - ) : SystemMessage { - override val iconResId = - if (protocol == Conversation.Protocol.MLS) R.drawable.ic_conversation_degraded_mls - else R.drawable.ic_shield_holo - override val stringRes = LocalizedStringResource.String( - if (protocol == Conversation.Protocol.MLS) R.string.label_system_message_conversation_degraded_mls - else R.string.label_system_message_conversation_degraded_proteus - ) - } - - @Serializable - data class ConversationVerified( - val protocol: Conversation.Protocol - ) : SystemMessage { - override val iconResId = - if (protocol == Conversation.Protocol.MLS) R.drawable.ic_certificate_valid_mls - else R.drawable.ic_certificate_valid_proteus - override val stringRes = LocalizedStringResource.String( - if (protocol == Conversation.Protocol.MLS) R.string.label_system_message_conversation_verified_mls - else R.string.label_system_message_conversation_verified_proteus - ) - } + data class ConversationDegraded(val protocol: Conversation.Protocol) : SystemMessage( + iconResId = if (protocol == Conversation.Protocol.MLS) R.drawable.ic_conversation_degraded_mls + else R.drawable.ic_shield_holo, + stringResId = if (protocol == Conversation.Protocol.MLS) R.string.label_system_message_conversation_degraded_mls + else R.string.label_system_message_conversation_degraded_proteus + ) - @Serializable - data object ConversationMessageCreatedUnverifiedWarning : SystemMessage { - override val iconResId = R.drawable.ic_info - override val stringRes = LocalizedStringResource.String( - R.string.label_system_message_conversation_started_sensitive_information - ) - } + data class ConversationVerified(val protocol: Conversation.Protocol) : SystemMessage( + iconResId = if (protocol == Conversation.Protocol.MLS) R.drawable.ic_certificate_valid_mls + else R.drawable.ic_certificate_valid_proteus, + stringResId = if (protocol == Conversation.Protocol.MLS) R.string.label_system_message_conversation_verified_mls + else R.string.label_system_message_conversation_verified_proteus + ) - @Serializable - sealed interface LegalHold : SystemMessage { - val memberNames: List? get() = null - override val iconResId get() = R.drawable.ic_legal_hold + data object ConversationMessageCreatedUnverifiedWarning : SystemMessage( + R.drawable.ic_info, + R.string.label_system_message_conversation_started_sensitive_information + ) - @Serializable - sealed interface Enabled : LegalHold { - override val learnMoreResId get() = R.string.url_legal_hold_learn_more + sealed class LegalHold( + stringResId: LocalizedStringResource.StringResource, + @StringRes learnMoreResId: Int? = null, + open val memberNames: List? = null, + ) : SystemMessage(R.drawable.ic_legal_hold, stringResId, learnMoreResId) { - @Serializable - data object Self : Enabled { - override val stringRes = LocalizedStringResource.String(R.string.legal_hold_system_message_enabled_self) - } + sealed class Enabled(override val stringResId: LocalizedStringResource.StringResource) : + LegalHold(stringResId, R.string.url_legal_hold_learn_more) { - @Serializable - data class Others(override val memberNames: List) : Enabled { - override val stringRes = LocalizedStringResource.String(R.string.legal_hold_system_message_enabled_others) - } + constructor(@StringRes stringResId: Int) : this(LocalizedStringResource.StringResource(stringResId)) - @Serializable - data object Conversation : Enabled { - override val stringRes = LocalizedStringResource.String(R.string.legal_hold_system_message_enabled_conversation) - } + data object Self : Enabled(R.string.legal_hold_system_message_enabled_self) + data class Others(override val memberNames: List) : Enabled(R.string.legal_hold_system_message_enabled_others) + data object Conversation : Enabled(R.string.legal_hold_system_message_enabled_conversation) } - @Serializable - sealed interface Disabled : LegalHold { + sealed class Disabled(override val stringResId: LocalizedStringResource.StringResource) : LegalHold(stringResId, null) { - @Serializable - data object Self : Disabled { - override val stringRes = LocalizedStringResource.String(R.string.legal_hold_system_message_disabled_self) - } + constructor(@StringRes stringResId: Int) : this(LocalizedStringResource.StringResource(stringResId)) - @Serializable - data class Others(override val memberNames: List) : Disabled { - override val stringRes = LocalizedStringResource.String(R.string.legal_hold_system_message_disabled_others) - } - - @Serializable - data object Conversation : Disabled { - override val stringRes = - LocalizedStringResource.String(R.string.legal_hold_system_message_disabled_conversation) - } + data object Self : Disabled(R.string.legal_hold_system_message_disabled_self) + data class Others(override val memberNames: List) : Disabled(R.string.legal_hold_system_message_disabled_others) + data object Conversation : Disabled(R.string.legal_hold_system_message_disabled_conversation) } } } } -@Serializable data class MessageBody( val message: UIText, val quotedMessage: UIQuotedMessage? = null @@ -723,7 +666,6 @@ enum class MessageSource { Self, OtherUser } -@Serializable data class MessageTime(val instant: Instant) { val utcISO: String = instant.toIsoDateTimeString() val formattedDate: String = utcISO.uiMessageDateTime() ?: "" @@ -733,10 +675,7 @@ data class MessageTime(val instant: Instant) { } @Stable -@Serializable sealed interface DeliveryStatusContent { - - @Serializable class PartialDelivery( val failedRecipients: ImmutableList = persistentListOf(), val noClients: ImmutableMap> = persistentMapOf(), @@ -749,19 +688,14 @@ sealed interface DeliveryStatusContent { val totalUsersWithFailures by lazy { (failedRecipients.size + noClients.values.distinct().sumOf { it.size }) } } - @Serializable data object CompleteDelivery : DeliveryStatusContent } @Stable -@Serializable data class MessageButton( val id: String, val text: String, val isSelected: Boolean, ) -private fun @receiver:StringRes Int.toLocalizedStringResource() = LocalizedStringResource.String(this) -private fun @receiver:PluralsRes Int.toLocalizedPluralResource(quantity: Int) = LocalizedStringResource.Plural(this, quantity) - const val DEFAULT_LOCATION_ZOOM = 20 diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIQuotedMessage.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIQuotedMessage.kt index 04b90d310ab..4c0b6787ea1 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIQuotedMessage.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIQuotedMessage.kt @@ -21,15 +21,11 @@ import com.wire.android.appLogger import com.wire.android.model.ImageAsset import com.wire.android.util.ui.UIText import com.wire.kalium.logic.data.user.UserId -import kotlinx.serialization.Serializable -@Serializable sealed class UIQuotedMessage { - @Serializable - data object UnavailableData : UIQuotedMessage() + object UnavailableData : UIQuotedMessage() - @Serializable data class UIQuotedData( val messageId: String, val senderId: UserId, @@ -54,10 +50,18 @@ sealed class UIQuotedMessage { data class Location(val locationName: String) : Content +<<<<<<< HEAD object AudioMessage : Content object Deleted : Content object Invalid : Content +======= + data object AudioMessage : Content + + data object Deleted : Content + + data object Invalid : Content +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) } } diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/usecase/GetConversationsFromSearchUseCase.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/usecase/GetConversationsFromSearchUseCase.kt index a7d9584055b..890aa6c12db 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/usecase/GetConversationsFromSearchUseCase.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/usecase/GetConversationsFromSearchUseCase.kt @@ -27,7 +27,11 @@ import com.wire.android.mapper.UserTypeMapper import com.wire.android.mapper.toConversationItem import com.wire.android.ui.home.conversationslist.model.ConversationItem import com.wire.android.util.dispatchers.DispatcherProvider +<<<<<<< HEAD import com.wire.kalium.logic.data.conversation.ConversationFilter +======= +import com.wire.android.util.ui.WireSessionImageLoader +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) import com.wire.kalium.logic.data.conversation.ConversationQueryConfig import com.wire.kalium.logic.feature.conversation.GetPaginatedFlowOfConversationDetailsWithEventsBySearchQueryUseCase import com.wire.kalium.logic.feature.conversation.folder.GetFavoriteFolderUseCase @@ -42,8 +46,12 @@ import javax.inject.Inject class GetConversationsFromSearchUseCase @Inject constructor( private val useCase: GetPaginatedFlowOfConversationDetailsWithEventsBySearchQueryUseCase, +<<<<<<< HEAD private val getFavoriteFolderUseCase: GetFavoriteFolderUseCase, private val observeConversationsFromFromFolder: ObserveConversationsFromFolderUseCase, +======= + private val wireSessionImageLoader: WireSessionImageLoader, +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) private val userTypeMapper: UserTypeMapper, private val dispatchers: DispatcherProvider, private val observeSelfUser: GetSelfUserUseCase @@ -61,6 +69,7 @@ class GetConversationsFromSearchUseCase @Inject constructor( initialLoadSize = INITIAL_LOAD_SIZE, enablePlaceholders = true, ) +<<<<<<< HEAD return when (conversationFilter) { ConversationFilter.ALL, ConversationFilter.GROUPS, @@ -92,6 +101,20 @@ class GetConversationsFromSearchUseCase @Inject constructor( ) ) } +======= + return useCase( + queryConfig = ConversationQueryConfig( + searchQuery = searchQuery, + fromArchive = fromArchive, + newActivitiesOnTop = newActivitiesOnTop, + onlyInteractionEnabled = onlyInteractionEnabled + ), + pagingConfig = pagingConfig, + startingOffset = 0L, + ).map { pagingData -> + pagingData.map { + it.toConversationItem(wireSessionImageLoader, userTypeMapper, searchQuery) +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) } } .map { pagingData -> diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/ConversationListViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/ConversationListViewModel.kt index 3ec4d460b94..9853abde646 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/ConversationListViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/ConversationListViewModel.kt @@ -46,6 +46,7 @@ import com.wire.android.ui.home.conversationslist.model.ConversationsSource import com.wire.android.ui.home.conversationslist.model.DialogState import com.wire.android.ui.home.conversationslist.model.GroupDialogState import com.wire.android.util.dispatchers.DispatcherProvider +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.conversation.ConversationFilter import com.wire.kalium.logic.data.conversation.MutedConversationStatus @@ -138,8 +139,12 @@ class ConversationListViewModelImpl @AssistedInject constructor( private val refreshUsersWithoutMetadata: RefreshUsersWithoutMetadataUseCase, private val refreshConversationsWithoutMetadata: RefreshConversationsWithoutMetadataUseCase, private val updateConversationArchivedStatus: UpdateConversationArchivedStatusUseCase, +<<<<<<< HEAD private val observeLegalHoldStateForSelfUser: ObserveLegalHoldStateForSelfUserUseCase, @CurrentAccount val currentAccount: UserId, +======= + private val wireSessionImageLoader: WireSessionImageLoader, +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) private val userTypeMapper: UserTypeMapper, private val observeSelfUser: GetSelfUserUseCase ) : ConversationListViewModel, ViewModel() { @@ -236,6 +241,7 @@ class ConversationListViewModelImpl @AssistedInject constructor( ).combine(observeLegalHoldStateForSelfUser()) { conversations, selfUserLegalHoldStatus -> conversations.map { conversationDetails -> conversationDetails.toConversationItem( + wireSessionImageLoader = wireSessionImageLoader, userTypeMapper = userTypeMapper, searchQuery = searchQuery, selfUserTeamId = observeSelfUser().firstOrNull()?.teamId diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/model/BadgeEventType.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/model/BadgeEventType.kt index a1bbc3bad0a..722266a63ad 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/model/BadgeEventType.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/model/BadgeEventType.kt @@ -18,38 +18,15 @@ package com.wire.android.ui.home.conversationslist.model -import kotlinx.serialization.Serializable - -@Serializable sealed class BadgeEventType { - - @Serializable data class UnreadMessage(val unreadMessageCount: Int) : BadgeEventType() - - @Serializable - data object UnreadMention : BadgeEventType() - - @Serializable - data object UnreadReply : BadgeEventType() - - @Serializable - data object MissedCall : BadgeEventType() - - @Serializable - data object Knock : BadgeEventType() - - @Serializable - data object ReceivedConnectionRequest : BadgeEventType() - - @Serializable - data object SentConnectRequest : BadgeEventType() - - @Serializable - data object Blocked : BadgeEventType() - - @Serializable - data object Deleted : BadgeEventType() - - @Serializable - data object None : BadgeEventType() + object UnreadMention : BadgeEventType() + object UnreadReply : BadgeEventType() + object MissedCall : BadgeEventType() + object Knock : BadgeEventType() + object ReceivedConnectionRequest : BadgeEventType() + object SentConnectRequest : BadgeEventType() + object Blocked : BadgeEventType() + object Deleted : BadgeEventType() + object None : BadgeEventType() } diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/model/ConversationItem.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/model/ConversationItem.kt index d5ae38f7625..aefae1efbe4 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/model/ConversationItem.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/model/ConversationItem.kt @@ -29,9 +29,7 @@ import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.OtherUser import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.data.user.type.isTeammate -import kotlinx.serialization.Serializable -@Serializable sealed class ConversationItem : ConversationFolderItem { abstract val conversationId: ConversationId abstract val mutedStatus: MutedConversationStatus @@ -48,7 +46,6 @@ sealed class ConversationItem : ConversationFolderItem { val isTeamConversation get() = teamId != null - @Serializable data class GroupConversation( val groupName: String, val hasOnGoingCall: Boolean = false, @@ -69,7 +66,6 @@ sealed class ConversationItem : ConversationFolderItem { override val searchQuery: String = "", ) : ConversationItem() - @Serializable data class PrivateConversation( val userAvatarData: UserAvatarData, val conversationInfo: ConversationInfo, @@ -89,7 +85,6 @@ sealed class ConversationItem : ConversationFolderItem { override val searchQuery: String = "", ) : ConversationItem() - @Serializable data class ConnectionConversation( val userAvatarData: UserAvatarData, val conversationInfo: ConversationInfo, @@ -109,7 +104,6 @@ sealed class ConversationItem : ConversationFolderItem { } } -@Serializable data class ConversationInfo( val name: String, val membership: Membership = Membership.None, diff --git a/app/src/main/kotlin/com/wire/android/ui/home/gallery/MediaGalleryViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/home/gallery/MediaGalleryViewModel.kt index 8198a2a4201..9d10a6888d4 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/gallery/MediaGalleryViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/gallery/MediaGalleryViewModel.kt @@ -34,6 +34,7 @@ import com.wire.android.ui.navArgs import com.wire.android.util.FileManager import com.wire.android.util.dispatchers.DispatcherProvider import com.wire.android.util.startFileShareIntent +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.ConversationDetails import com.wire.kalium.logic.data.id.QualifiedID import com.wire.kalium.logic.feature.asset.GetMessageAssetUseCase @@ -56,6 +57,7 @@ import javax.inject.Inject @HiltViewModel class MediaGalleryViewModel @Inject constructor( savedStateHandle: SavedStateHandle, + wireSessionImageLoader: WireSessionImageLoader, private val getConversationDetails: ObserveConversationDetailsUseCase, private val dispatchers: DispatcherProvider, private val getImageData: GetMessageAssetUseCase, @@ -65,6 +67,7 @@ class MediaGalleryViewModel @Inject constructor( private val mediaGalleryNavArgs: MediaGalleryNavArgs = savedStateHandle.navArgs() val imageAsset: ImageAsset.PrivateAsset = ImageAsset.PrivateAsset( + wireSessionImageLoader, mediaGalleryNavArgs.conversationId, mediaGalleryNavArgs.messageId, mediaGalleryNavArgs.isSelfAsset, diff --git a/app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt index de0cfd71bfa..efda17b8c03 100644 --- a/app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModel.kt @@ -45,6 +45,7 @@ import com.wire.android.ui.home.messagecomposer.SelfDeletionDuration import com.wire.android.util.EMPTY import com.wire.android.util.dispatchers.DispatcherProvider import com.wire.android.util.parcelableArrayList +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.message.SelfDeletionTimer import com.wire.kalium.logic.data.message.SelfDeletionTimer.Companion.SELF_DELETION_LOG_TAG @@ -79,6 +80,7 @@ class ImportMediaAuthenticatedViewModel @Inject constructor( private val handleUriAsset: HandleUriAssetUseCase, private val persistNewSelfDeletionTimerUseCase: PersistNewSelfDeletionTimerUseCase, private val observeSelfDeletionSettingsForConversation: ObserveSelfDeletionTimerSettingsForConversationUseCase, + private val wireSessionImageLoader: WireSessionImageLoader, val dispatchers: DispatcherProvider, ) : ViewModel() { val searchQueryTextState: TextFieldState = TextFieldState() @@ -122,7 +124,7 @@ class ImportMediaAuthenticatedViewModel @Inject constructor( getSelf().collect { selfUser -> withContext(dispatchers.main()) { avatarAsset = selfUser.previewPicture?.let { - ImageAsset.UserAvatarAsset(it) + ImageAsset.UserAvatarAsset(wireSessionImageLoader, it) } } } diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileScreenViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileScreenViewModel.kt index 9f809c80afc..c57fa29f6d7 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileScreenViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileScreenViewModel.kt @@ -47,6 +47,7 @@ import com.wire.android.ui.userprofile.other.OtherUserProfileInfoMessageType.Rem import com.wire.android.ui.userprofile.other.OtherUserProfileInfoMessageType.UnblockingUserOperationError import com.wire.android.util.dispatchers.DispatcherProvider import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.conversation.MutedConversationStatus import com.wire.kalium.logic.data.id.ConversationId @@ -95,6 +96,7 @@ class OtherUserProfileScreenViewModel @Inject constructor( private val observeOneToOneConversation: GetOneToOneConversationUseCase, private val observeUserInfo: ObserveUserInfoUseCase, private val userTypeMapper: UserTypeMapper, + private val wireSessionImageLoader: WireSessionImageLoader, private val observeConversationRoleForUser: ObserveConversationRoleForUserUseCase, private val removeMemberFromConversation: RemoveMemberFromConversationUseCase, private val updateMemberRole: UpdateConversationMemberRoleUseCase, @@ -378,7 +380,7 @@ class OtherUserProfileScreenViewModel @Inject constructor( ) { val otherUser = userResult.otherUser val userAvatarAsset = otherUser.completePicture - ?.let { pic -> ImageAsset.UserAvatarAsset(pic) } + ?.let { pic -> ImageAsset.UserAvatarAsset(wireSessionImageLoader, pic) } state = state.copy( isDataLoading = false, diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModel.kt index 7ea1e925b6b..6b8fe0986f4 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModel.kt @@ -39,6 +39,11 @@ import com.wire.android.notification.WireNotificationManager import com.wire.android.ui.legalhold.banner.LegalHoldUIState import com.wire.android.ui.userprofile.self.dialog.StatusDialogData import com.wire.android.util.dispatchers.DispatcherProvider +<<<<<<< HEAD +======= +import com.wire.android.util.ui.WireSessionImageLoader +import com.wire.kalium.logic.configuration.server.ServerConfig +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) import com.wire.kalium.logic.data.call.Call import com.wire.kalium.logic.data.id.QualifiedIdMapper import com.wire.kalium.logic.data.id.toQualifiedID @@ -90,6 +95,12 @@ class SelfUserProfileViewModel @Inject constructor( private val logout: LogoutUseCase, private val observeLegalHoldStatusForSelfUser: ObserveLegalHoldStateForSelfUserUseCase, private val dispatchers: DispatcherProvider, +<<<<<<< HEAD +======= + private val wireSessionImageLoader: WireSessionImageLoader, + private val authServerConfigProvider: AuthServerConfigProvider, + private val selfServerLinks: SelfServerConfigUseCase, +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) private val otherAccountMapper: OtherAccountMapper, private val observeEstablishedCalls: ObserveEstablishedCallsUseCase, private val accountSwitch: AccountSwitchUseCase, @@ -218,7 +229,7 @@ class SelfUserProfileViewModel @Inject constructor( showLoadingAvatar(true) try { userProfileState = userProfileState.copy( - avatarAsset = UserAvatarAsset(avatarAssetId) + avatarAsset = UserAvatarAsset(wireSessionImageLoader, avatarAssetId) ) // Update avatar asset id on user data store // TODO: obtain the asset id through a useCase once we also store assets ids diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/service/ServiceDetailsViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/service/ServiceDetailsViewModel.kt index 53a5f518132..3fd3f129163 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/service/ServiceDetailsViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/service/ServiceDetailsViewModel.kt @@ -28,6 +28,7 @@ import com.wire.android.ui.home.conversations.details.participants.usecase.Obser import com.wire.android.ui.navArgs import com.wire.android.util.dispatchers.DispatcherProvider import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.QualifiedID @@ -61,6 +62,7 @@ class ServiceDetailsViewModel @Inject constructor( private val getServiceById: GetServiceByIdUseCase, private val observeIsServiceMember: ObserveIsServiceMemberUseCase, private val observeConversationRoleForUser: ObserveConversationRoleForUserUseCase, + private val wireSessionImageLoader: WireSessionImageLoader, private val removeMemberFromConversation: RemoveMemberFromConversationUseCase, private val addServiceToConversation: AddServiceToConversationUseCase, private val serviceDetailsMapper: ServiceDetailsMapper, @@ -135,7 +137,7 @@ class ServiceDetailsViewModel @Inject constructor( getServiceById(serviceId = serviceId).also { service -> if (service != null) { val serviceAvatarAsset = service.completeAssetId?.let { asset -> - ImageAsset.UserAvatarAsset(asset) + ImageAsset.UserAvatarAsset(wireSessionImageLoader, asset) } serviceDetailsState = serviceDetailsState.copy( diff --git a/app/src/main/kotlin/com/wire/android/util/ui/LocalizedStringResource.kt b/app/src/main/kotlin/com/wire/android/util/ui/LocalizedStringResource.kt index 7f8f3ebf9dc..b9a326ce9e6 100644 --- a/app/src/main/kotlin/com/wire/android/util/ui/LocalizedStringResource.kt +++ b/app/src/main/kotlin/com/wire/android/util/ui/LocalizedStringResource.kt @@ -17,16 +17,37 @@ */ package com.wire.android.util.ui +import android.content.Context import androidx.annotation.PluralsRes import androidx.annotation.StringRes -import kotlinx.serialization.Serializable -@Serializable sealed interface LocalizedStringResource { - @Serializable - data class String(@StringRes val id: Int) : LocalizedStringResource + fun getString(context: Context): String + data class StringResource(@StringRes val id: Int) : LocalizedStringResource { + override fun getString(context: Context): String = context.getString(id) + } - @Serializable - data class Plural(@PluralsRes val id: Int, val quantity: Int) : LocalizedStringResource + data class PluralResource(@PluralsRes val id: Int, val quantity: Int, val formatArgs: Array) : LocalizedStringResource { + override fun getString(context: Context): String = context.resources.getQuantityString(id, quantity, formatArgs) + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as PluralResource + + if (id != other.id) return false + if (quantity != other.quantity) return false + if (!formatArgs.contentEquals(other.formatArgs)) return false + + return true + } + + override fun hashCode(): Int { + var result = id + result = 31 * result + quantity + result = 31 * result + formatArgs.contentHashCode() + return result + } + } } diff --git a/app/src/main/kotlin/com/wire/android/util/ui/UIText.kt b/app/src/main/kotlin/com/wire/android/util/ui/UIText.kt index 14bdb4faea3..5d32b605757 100644 --- a/app/src/main/kotlin/com/wire/android/util/ui/UIText.kt +++ b/app/src/main/kotlin/com/wire/android/util/ui/UIText.kt @@ -29,22 +29,17 @@ import com.wire.kalium.logic.data.message.mention.MessageMention import com.wire.kalium.util.serialization.AnyPrimitiveValueSerializer import kotlinx.serialization.Serializable -@Serializable sealed class UIText { - - @Serializable data class DynamicString( val value: String, val mentions: List = listOf() ) : UIText() - @Serializable class StringResource( @StringRes val resId: Int, vararg val formatArgs: @Serializable(with = AnyPrimitiveValueSerializer::class) Any ) : UIText() - @Serializable class PluralResource( @PluralsRes val resId: Int, val count: Int, diff --git a/app/src/test/kotlin/com/wire/android/mapper/MessageMapperTest.kt b/app/src/test/kotlin/com/wire/android/mapper/MessageMapperTest.kt index 3cde050371e..d10a96f29d2 100644 --- a/app/src/test/kotlin/com/wire/android/mapper/MessageMapperTest.kt +++ b/app/src/test/kotlin/com/wire/android/mapper/MessageMapperTest.kt @@ -32,6 +32,7 @@ import com.wire.android.ui.home.conversations.model.UIMessageContent.TextMessage import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.util.time.ISOFormatter import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.android.util.uiMessageDateTime import com.wire.kalium.logic.data.message.Message import com.wire.kalium.logic.data.message.MessageContent @@ -219,8 +220,11 @@ class MessageMapperTest { @MockK lateinit var isoFormatter: ISOFormatter + @MockK + private lateinit var wireSessionImageLoader: WireSessionImageLoader + private val messageMapper by lazy { - MessageMapper(userTypeMapper, messageContentMapper, isoFormatter) + MessageMapper(userTypeMapper, messageContentMapper, isoFormatter, wireSessionImageLoader) } init { diff --git a/app/src/test/kotlin/com/wire/android/mapper/OtherAccountMapperTest.kt b/app/src/test/kotlin/com/wire/android/mapper/OtherAccountMapperTest.kt index 3f02c87dacb..e37d51236bb 100644 --- a/app/src/test/kotlin/com/wire/android/mapper/OtherAccountMapperTest.kt +++ b/app/src/test/kotlin/com/wire/android/mapper/OtherAccountMapperTest.kt @@ -20,9 +20,15 @@ package com.wire.android.mapper import com.wire.android.ui.home.conversations.avatar import com.wire.android.ui.userprofile.self.model.OtherAccount +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.team.Team import com.wire.kalium.logic.data.user.SelfUser import io.mockk.MockKAnnotations +<<<<<<< HEAD +======= +import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.ExperimentalCoroutinesApi +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test @@ -40,23 +46,37 @@ class OtherAccountMapperTest { val results = data.map { (selfUser, _) -> mapper.toOtherAccount(selfUser) } // Then results.forEachIndexed { index, result -> +<<<<<<< HEAD val (selfUser, _) = data[index] assert(compareResult(selfUser, result)) +======= + val (selfUser, team) = data[index] + assert(compareResult(arrangement.wireSessionImageLoader, selfUser, team, result)) +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) } } private fun compareResult( + wireSessionImageLoader: WireSessionImageLoader, selfUser: SelfUser, otherAccount: OtherAccount ): Boolean = selfUser.id == otherAccount.id && selfUser.name == otherAccount.fullName +<<<<<<< HEAD && selfUser.avatar(selfUser.connectionStatus) == otherAccount.avatarData && selfUser.handle == otherAccount.handle +======= + && selfUser.avatar(wireSessionImageLoader, selfUser.connectionStatus) == otherAccount.avatarData + && team?.name == otherAccount.teamName +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) private class Arrangement { - private val mapper: OtherAccountMapper by lazy { OtherAccountMapper() } + @MockK + lateinit var wireSessionImageLoader: WireSessionImageLoader + + private val mapper: OtherAccountMapper by lazy { OtherAccountMapper(wireSessionImageLoader) } init { MockKAnnotations.init(this, relaxUnitFun = true) diff --git a/app/src/test/kotlin/com/wire/android/mapper/RegularMessageContentMapperTest.kt b/app/src/test/kotlin/com/wire/android/mapper/RegularMessageContentMapperTest.kt index 8d4f4996230..3158c9fc66b 100644 --- a/app/src/test/kotlin/com/wire/android/mapper/RegularMessageContentMapperTest.kt +++ b/app/src/test/kotlin/com/wire/android/mapper/RegularMessageContentMapperTest.kt @@ -28,6 +28,7 @@ import com.wire.android.ui.home.conversations.model.UIMessageContent import com.wire.android.ui.home.conversations.model.UIMessageContent.AssetMessage import com.wire.android.util.time.ISOFormatter import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.id.QualifiedID import com.wire.kalium.logic.data.message.AssetContent import com.wire.kalium.logic.data.message.AssetContent.AssetMetadata @@ -219,8 +220,11 @@ class RegularMessageContentMapperTest { @MockK lateinit var messageResourceProvider: MessageResourceProvider + @MockK + private lateinit var wireSessionImageLoader: WireSessionImageLoader + private val messageContentMapper by lazy { - RegularMessageMapper(messageResourceProvider, ISOFormatter()) + RegularMessageMapper(messageResourceProvider, wireSessionImageLoader, ISOFormatter()) } init { diff --git a/app/src/test/kotlin/com/wire/android/mapper/UICallParticipantMapperTest.kt b/app/src/test/kotlin/com/wire/android/mapper/UICallParticipantMapperTest.kt index d3c23da2a63..0c34b0124ed 100644 --- a/app/src/test/kotlin/com/wire/android/mapper/UICallParticipantMapperTest.kt +++ b/app/src/test/kotlin/com/wire/android/mapper/UICallParticipantMapperTest.kt @@ -21,6 +21,7 @@ package com.wire.android.mapper import com.wire.kalium.logic.data.call.Participant import com.wire.kalium.logic.data.id.QualifiedID import io.mockk.MockKAnnotations +import io.mockk.mockk import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test @@ -53,7 +54,7 @@ class UICallParticipantMapperTest { private class Arrangement { - private val mapper: UICallParticipantMapper = UICallParticipantMapper(UserTypeMapper()) + private val mapper: UICallParticipantMapper = UICallParticipantMapper(mockk(), UserTypeMapper()) init { MockKAnnotations.init(this, relaxUnitFun = true) diff --git a/app/src/test/kotlin/com/wire/android/mapper/UIParticipantMapperTest.kt b/app/src/test/kotlin/com/wire/android/mapper/UIParticipantMapperTest.kt index de63bc438ba..a6f600441f0 100644 --- a/app/src/test/kotlin/com/wire/android/mapper/UIParticipantMapperTest.kt +++ b/app/src/test/kotlin/com/wire/android/mapper/UIParticipantMapperTest.kt @@ -23,6 +23,7 @@ import com.wire.android.ui.home.conversations.details.participants.model.UIParti import com.wire.android.ui.home.conversations.handle import com.wire.android.ui.home.conversations.name import com.wire.android.ui.home.conversations.userId +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.Conversation.Member import com.wire.kalium.logic.data.conversation.MemberDetails import com.wire.kalium.logic.data.id.TeamId @@ -35,6 +36,7 @@ import com.wire.kalium.logic.data.user.UserAvailabilityStatus import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.data.user.type.UserType import io.mockk.MockKAnnotations +import io.mockk.impl.annotations.MockK import kotlinx.coroutines.test.runTest import org.amshove.kluent.internal.assertEquals import org.junit.jupiter.api.Test @@ -56,7 +58,7 @@ class UIParticipantMapperTest { val results = data.map { mapper.toUIParticipant(it.user) } // Then results.forEachIndexed { index, result -> - assert(compareResult(data[index], result, arrangement.userTypeMapper)) + assert(compareResult(arrangement.wireSessionImageLoader, data[index], result, arrangement.userTypeMapper)) } } @@ -94,6 +96,7 @@ class UIParticipantMapperTest { } private fun compareResult( + wireSessionImageLoader: WireSessionImageLoader, memberDetails: MemberDetails, uiParticipant: UIParticipant, userTypeMapper: UserTypeMapper @@ -102,17 +105,20 @@ class UIParticipantMapperTest { return (memberDetails.userId == uiParticipant.id && memberDetails.name == uiParticipant.name && memberDetails.handle == uiParticipant.handle - && memberDetails.user.avatar(connectionState) == uiParticipant.avatarData + && memberDetails.user.avatar(wireSessionImageLoader, connectionState) == uiParticipant.avatarData && userTypeMapper.toMembership(memberDetails.user.userType) == uiParticipant.membership && memberDetails.user is SelfUser == uiParticipant.isSelf) } private class Arrangement { + @MockK + lateinit var wireSessionImageLoader: WireSessionImageLoader + val userTypeMapper: UserTypeMapper = UserTypeMapper() private val mapper: UIParticipantMapper by lazy { - UIParticipantMapper(userTypeMapper) + UIParticipantMapper(userTypeMapper, wireSessionImageLoader) } init { diff --git a/app/src/test/kotlin/com/wire/android/model/ImageAssetTest.kt b/app/src/test/kotlin/com/wire/android/model/ImageAssetTest.kt index eb8d3110c61..61bac0831af 100644 --- a/app/src/test/kotlin/com/wire/android/model/ImageAssetTest.kt +++ b/app/src/test/kotlin/com/wire/android/model/ImageAssetTest.kt @@ -19,10 +19,12 @@ package com.wire.android.model import android.net.Uri +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.user.UserAssetId import io.mockk.MockKAnnotations import io.mockk.every +import io.mockk.impl.annotations.MockK import io.mockk.mockk import io.mockk.mockkStatic import okio.Path @@ -34,6 +36,9 @@ import org.junit.jupiter.api.Test class ImageAssetTest { + @MockK + private lateinit var imageLoader: WireSessionImageLoader + @BeforeEach fun setup() { MockKAnnotations.init(this, relaxUnitFun = true) @@ -42,13 +47,15 @@ class ImageAssetTest { every { Uri.parse(any()) } returns mockUri } - private fun createUserAvatarAsset(userAssetId: UserAssetId) = ImageAsset.UserAvatarAsset(userAssetId) + private fun createUserAvatarAsset(userAssetId: UserAssetId) = ImageAsset.UserAvatarAsset( + imageLoader, userAssetId + ) private fun createPrivateAsset( conversationId: ConversationId, messageId: String, isSelfAsset: Boolean - ) = ImageAsset.PrivateAsset(conversationId, messageId, isSelfAsset) + ) = ImageAsset.PrivateAsset(imageLoader, conversationId, messageId, isSelfAsset) private fun createLocalAsset( dataPath: Path, diff --git a/app/src/test/kotlin/com/wire/android/navigation/NavigationUtilsTest.kt b/app/src/test/kotlin/com/wire/android/navigation/NavigationUtilsTest.kt index 97f32e2b119..ae5667d5c43 100644 --- a/app/src/test/kotlin/com/wire/android/navigation/NavigationUtilsTest.kt +++ b/app/src/test/kotlin/com/wire/android/navigation/NavigationUtilsTest.kt @@ -22,6 +22,7 @@ import com.wire.android.model.ImageAsset import com.wire.android.model.parseIntoPrivateImageAsset import com.wire.kalium.logic.data.id.QualifiedID import com.wire.kalium.logic.data.id.QualifiedIdMapperImpl +import io.mockk.mockk import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows @@ -43,7 +44,7 @@ internal class NavigationUtilsTest { "$mockConversationIdValue@$mockConversationIdDomain:$mockMessageId:$mockIsSelfAsset:$mockIsEphemeral" // When - val privateImgAsset = correctImagePrivateAssetString.parseIntoPrivateImageAsset(qualifiedIdMapper) + val privateImgAsset = correctImagePrivateAssetString.parseIntoPrivateImageAsset(mockk(), qualifiedIdMapper) // Then assertEquals(privateImgAsset.conversationId.value, mockConversationIdValue) @@ -61,7 +62,7 @@ internal class NavigationUtilsTest { val mockWrongImagePrivateAssetString = "wrong-private-asset@image" // When, Then - assertThrows { mockWrongImagePrivateAssetString.parseIntoPrivateImageAsset(qualifiedIdMapper) } + assertThrows { mockWrongImagePrivateAssetString.parseIntoPrivateImageAsset(mockk(), qualifiedIdMapper) } } @Test @@ -86,13 +87,11 @@ internal class NavigationUtilsTest { val mockQualifiedIdDomain = "mocked.domain" val mockMessageId = "mocked-message-id" val actualPrivateAssetImage = ImageAsset.PrivateAsset( - conversationId = QualifiedID( + mockk(), + QualifiedID( value = mockQualifiedIdValue, domain = mockQualifiedIdDomain - ), - messageId = mockMessageId, - isSelfAsset = true, - isEphemeral = true + ), mockMessageId, true, true ) val expectedPrivateAssetImage = "$mockQualifiedIdValue@$mockQualifiedIdDomain:$mockMessageId:true:true" diff --git a/app/src/test/kotlin/com/wire/android/ui/calling/SharedCallingViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/calling/SharedCallingViewModelTest.kt index 18e62a81877..6eaceb90506 100644 --- a/app/src/test/kotlin/com/wire/android/ui/calling/SharedCallingViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/calling/SharedCallingViewModelTest.kt @@ -25,6 +25,7 @@ import com.wire.android.config.TestDispatcherProvider import com.wire.android.mapper.UICallParticipantMapper import com.wire.android.mapper.UserTypeMapper import com.wire.android.media.CallRinger +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.call.VideoState import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.feature.call.usecase.EndCallUseCase @@ -99,6 +100,9 @@ class SharedCallingViewModelTest { @MockK private lateinit var view: View + @MockK + private lateinit var wireSessionImageLoader: WireSessionImageLoader + @MockK private lateinit var userTypeMapper: UserTypeMapper @@ -106,7 +110,10 @@ class SharedCallingViewModelTest { private lateinit var onCompleted: () -> Unit private val uiCallParticipantMapper: UICallParticipantMapper by lazy { - UICallParticipantMapper(userTypeMapper) + UICallParticipantMapper( + wireSessionImageLoader, + userTypeMapper + ) } private lateinit var sharedCallingViewModel: SharedCallingViewModel @@ -134,6 +141,7 @@ class SharedCallingViewModelTest { observeSpeaker = observeSpeaker, callRinger = callRinger, uiCallParticipantMapper = uiCallParticipantMapper, + wireSessionImageLoader = wireSessionImageLoader, userTypeMapper = userTypeMapper, dispatchers = TestDispatcherProvider() ) diff --git a/app/src/test/kotlin/com/wire/android/ui/connection/ConnectionActionButtonViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/connection/ConnectionActionButtonViewModelTest.kt index 034026ff597..58f1e3be4c8 100644 --- a/app/src/test/kotlin/com/wire/android/ui/connection/ConnectionActionButtonViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/connection/ConnectionActionButtonViewModelTest.kt @@ -30,6 +30,7 @@ import com.wire.android.framework.TestConversation import com.wire.android.framework.TestUser import com.wire.android.ui.userprofile.other.OtherUserProfileScreenViewModelTest import com.wire.android.util.ui.UIText +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.feature.connection.AcceptConnectionRequestUseCase @@ -342,6 +343,9 @@ internal class ConnectionActionButtonHiltArrangement { @MockK lateinit var ignoreConnectionRequest: IgnoreConnectionRequestUseCase + @MockK + lateinit var wireSessionImageLoader: WireSessionImageLoader + @MockK lateinit var unblockUser: UnblockUserUseCase diff --git a/app/src/test/kotlin/com/wire/android/ui/home/HomeViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/home/HomeViewModelTest.kt index 931a8ddad85..5b9b75aa38d 100644 --- a/app/src/test/kotlin/com/wire/android/ui/home/HomeViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/home/HomeViewModelTest.kt @@ -25,6 +25,7 @@ import com.wire.android.feature.analytics.AnonymousAnalyticsManager import com.wire.android.feature.analytics.model.AnalyticsEvent import com.wire.android.framework.TestUser import com.wire.android.migration.userDatabase.ShouldTriggerMigrationForUserUserCase +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.user.SelfUser import com.wire.kalium.logic.data.user.UserAvailabilityStatus import com.wire.kalium.logic.feature.client.NeedsToRegisterClientUseCase @@ -134,6 +135,8 @@ class HomeViewModelTest { @MockK lateinit var observeLegalHoldStatusForSelfUser: ObserveLegalHoldStateForSelfUserUseCase + @MockK + lateinit var wireSessionImageLoader: WireSessionImageLoader @MockK lateinit var shouldTriggerMigrationForUser: ShouldTriggerMigrationForUserUserCase @@ -151,9 +154,14 @@ class HomeViewModelTest { getSelf = getSelf, needsToRegisterClient = needsToRegisterClient, observeLegalHoldStatusForSelfUser = observeLegalHoldStatusForSelfUser, +<<<<<<< HEAD shouldTriggerMigrationForUser = shouldTriggerMigrationForUser, analyticsManager = analyticsManager, canMigrateFromPersonalToTeam = canMigrateFromPersonalToTeam +======= + wireSessionImageLoader = wireSessionImageLoader, + shouldTriggerMigrationForUser = shouldTriggerMigrationForUser +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) ) } diff --git a/app/src/test/kotlin/com/wire/android/ui/home/conversations/details/participants/usecase/ObserveParticipantsForConversationUseCaseTest.kt b/app/src/test/kotlin/com/wire/android/ui/home/conversations/details/participants/usecase/ObserveParticipantsForConversationUseCaseTest.kt index 4f4aba479ec..dc0e39f3f6c 100644 --- a/app/src/test/kotlin/com/wire/android/ui/home/conversations/details/participants/usecase/ObserveParticipantsForConversationUseCaseTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/home/conversations/details/participants/usecase/ObserveParticipantsForConversationUseCaseTest.kt @@ -23,6 +23,7 @@ import com.wire.android.config.TestDispatcherProvider import com.wire.android.mapper.UIParticipantMapper import com.wire.android.mapper.UserTypeMapper import com.wire.android.mapper.testOtherUser +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.Conversation.Member import com.wire.kalium.logic.data.conversation.MemberDetails import com.wire.kalium.logic.data.id.ConversationId @@ -219,7 +220,9 @@ internal class ObserveParticipantsForConversationUseCaseArrangement { @MockK lateinit var getMembersE2EICertificateStatuses: GetMembersE2EICertificateStatusesUseCase - private val uIParticipantMapper by lazy { UIParticipantMapper(UserTypeMapper()) } + @MockK + private lateinit var wireSessionImageLoader: WireSessionImageLoader + private val uIParticipantMapper by lazy { UIParticipantMapper(UserTypeMapper(), wireSessionImageLoader) } private val conversationMembersChannel = Channel>(capacity = Channel.UNLIMITED) private val useCase by lazy { ObserveParticipantsForConversationUseCase( diff --git a/app/src/test/kotlin/com/wire/android/ui/home/conversations/info/ConversationInfoViewModelArrangement.kt b/app/src/test/kotlin/com/wire/android/ui/home/conversations/info/ConversationInfoViewModelArrangement.kt index 778549c42ad..931b5f6280d 100644 --- a/app/src/test/kotlin/com/wire/android/ui/home/conversations/info/ConversationInfoViewModelArrangement.kt +++ b/app/src/test/kotlin/com/wire/android/ui/home/conversations/info/ConversationInfoViewModelArrangement.kt @@ -23,6 +23,7 @@ import com.wire.android.config.mockUri import com.wire.android.framework.TestUser import com.wire.android.ui.home.conversations.ConversationNavArgs import com.wire.android.ui.navArgs +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.conversation.ConversationDetails import com.wire.kalium.logic.data.id.ConversationId @@ -58,6 +59,9 @@ class ConversationInfoViewModelArrangement { @MockK lateinit var fetchConversationMLSVerificationStatus: FetchConversationMLSVerificationStatusUseCase + @MockK + private lateinit var wireSessionImageLoader: WireSessionImageLoader + @MockK(relaxed = true) lateinit var onNotFound: () -> Unit @@ -67,6 +71,7 @@ class ConversationInfoViewModelArrangement { savedStateHandle, observeConversationDetails, fetchConversationMLSVerificationStatus, + wireSessionImageLoader, selfUserId = TestUser.SELF_USER_ID, ) } diff --git a/app/src/test/kotlin/com/wire/android/ui/home/conversations/usecase/GetConversationsFromSearchUseCaseTest.kt b/app/src/test/kotlin/com/wire/android/ui/home/conversations/usecase/GetConversationsFromSearchUseCaseTest.kt index d60659aa43a..43368dfa2ed 100644 --- a/app/src/test/kotlin/com/wire/android/ui/home/conversations/usecase/GetConversationsFromSearchUseCaseTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/home/conversations/usecase/GetConversationsFromSearchUseCaseTest.kt @@ -26,6 +26,7 @@ import com.wire.android.framework.TestUser import com.wire.android.mapper.UserTypeMapper import com.wire.android.ui.home.conversationslist.model.ConversationItem import com.wire.android.ui.home.conversationslist.model.Membership +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.ConversationDetailsWithEvents import com.wire.kalium.logic.data.conversation.ConversationFilter import com.wire.kalium.logic.data.conversation.ConversationFolder @@ -173,10 +174,14 @@ class GetConversationsFromSearchUseCaseTest { lateinit var useCase: GetPaginatedFlowOfConversationDetailsWithEventsBySearchQueryUseCase @MockK +<<<<<<< HEAD lateinit var getFavoriteFolderUseCase: GetFavoriteFolderUseCase @MockK lateinit var observeConversationsFromFolderUseCase: ObserveConversationsFromFolderUseCase +======= + lateinit var wireSessionImageLoader: WireSessionImageLoader +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) @MockK lateinit var userTypeMapper: UserTypeMapper @@ -203,6 +208,7 @@ class GetConversationsFromSearchUseCaseTest { } returns flowOf(PagingData.from(conversations)) } +<<<<<<< HEAD fun withFavoriteFolderResult(result: GetFavoriteFolderUseCase.Result) = apply { coEvery { getFavoriteFolderUseCase.invoke() } returns result } @@ -225,5 +231,8 @@ class GetConversationsFromSearchUseCaseTest { dispatcherProvider, observeSelfUser ) +======= + fun arrange() = this to GetConversationsFromSearchUseCase(useCase, wireSessionImageLoader, userTypeMapper, dispatcherProvider) +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) } } diff --git a/app/src/test/kotlin/com/wire/android/ui/home/conversationslist/ConversationListViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/home/conversationslist/ConversationListViewModelTest.kt index a1a0fc548fa..f74ac1a210f 100644 --- a/app/src/test/kotlin/com/wire/android/ui/home/conversationslist/ConversationListViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/home/conversationslist/ConversationListViewModelTest.kt @@ -35,6 +35,7 @@ import com.wire.android.ui.common.dialogs.BlockUserDialogState import com.wire.android.ui.home.conversations.usecase.GetConversationsFromSearchUseCase import com.wire.android.ui.home.conversationslist.model.ConversationItem import com.wire.android.ui.home.conversationslist.model.ConversationsSource +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.conversation.ConversationDetailsWithEvents import com.wire.kalium.logic.data.conversation.ConversationFilter import com.wire.kalium.logic.data.conversation.MutedConversationStatus @@ -269,10 +270,14 @@ class ConversationListViewModelTest { ObserveConversationListDetailsWithEventsUseCase @MockK +<<<<<<< HEAD private lateinit var observeLegalHoldStateForSelfUserUseCase: ObserveLegalHoldStateForSelfUserUseCase @MockK private lateinit var observeSelfUser: GetSelfUserUseCase +======= + private lateinit var wireSessionImageLoader: WireSessionImageLoader +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) init { MockKAnnotations.init(this, relaxUnitFun = true) @@ -342,8 +347,12 @@ class ConversationListViewModelTest { observeConversationListDetailsWithEvents = observeConversationListDetailsWithEventsUseCase, observeLegalHoldStateForSelfUser = observeLegalHoldStateForSelfUserUseCase, userTypeMapper = UserTypeMapper(), +<<<<<<< HEAD observeSelfUser = observeSelfUser, usePagination = true +======= + wireSessionImageLoader = wireSessionImageLoader +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) ) } diff --git a/app/src/test/kotlin/com/wire/android/ui/home/gallery/MediaGalleryViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/home/gallery/MediaGalleryViewModelTest.kt index 80d101cae10..d41787b15ce 100644 --- a/app/src/test/kotlin/com/wire/android/ui/home/gallery/MediaGalleryViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/home/gallery/MediaGalleryViewModelTest.kt @@ -29,6 +29,7 @@ import com.wire.android.ui.home.conversations.delete.DeleteMessageDialogActiveSt import com.wire.android.ui.home.conversations.delete.DeleteMessageDialogsState import com.wire.android.ui.navArgs import com.wire.android.util.FileManager +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.conversation.ConversationDetails @@ -191,6 +192,9 @@ class MediaGalleryViewModelTest { @MockK private lateinit var savedStateHandle: SavedStateHandle + @MockK + private lateinit var wireSessionImageLoader: WireSessionImageLoader + @MockK lateinit var getConversationDetails: ObserveConversationDetailsUseCase @@ -267,6 +271,7 @@ class MediaGalleryViewModelTest { fun arrange() = this to MediaGalleryViewModel( savedStateHandle, + wireSessionImageLoader, getConversationDetails, TestDispatcherProvider(), getImageData, diff --git a/app/src/test/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModelTest.kt index e305a258bc6..f2623f18c9e 100644 --- a/app/src/test/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/sharing/ImportMediaAuthenticatedViewModelTest.kt @@ -28,6 +28,7 @@ import com.wire.android.framework.TestConversationItem import com.wire.android.framework.TestUser import com.wire.android.ui.home.conversations.usecase.GetConversationsFromSearchUseCase import com.wire.android.ui.home.conversations.usecase.HandleUriAssetUseCase +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTimerSettingsForConversationUseCase import com.wire.kalium.logic.feature.selfDeletingMessages.PersistNewSelfDeletionTimerUseCase import com.wire.kalium.logic.feature.user.GetSelfUserUseCase @@ -86,6 +87,9 @@ class ImportMediaAuthenticatedViewModelTest { @MockK lateinit var observeSelfDeletionSettingsForConversation: ObserveSelfDeletionTimerSettingsForConversationUseCase + @MockK + lateinit var wireSessionImageLoader: WireSessionImageLoader + init { MockKAnnotations.init(this, relaxUnitFun = true) coEvery { @@ -105,6 +109,7 @@ class ImportMediaAuthenticatedViewModelTest { handleUriAsset = handleUriAssetUseCase, persistNewSelfDeletionTimerUseCase = persistNewSelfDeletionTimerUseCase, observeSelfDeletionSettingsForConversation = observeSelfDeletionSettingsForConversation, + wireSessionImageLoader = wireSessionImageLoader, dispatchers = dispatcherProvider, ) } diff --git a/app/src/test/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileViewModelArrangement.kt b/app/src/test/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileViewModelArrangement.kt index f0a5443b530..e550f0188dc 100644 --- a/app/src/test/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileViewModelArrangement.kt +++ b/app/src/test/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileViewModelArrangement.kt @@ -28,6 +28,7 @@ import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.ui.navArgs import com.wire.android.ui.userprofile.other.OtherUserProfileScreenViewModelTest.Companion.CONVERSATION_ID import com.wire.android.ui.userprofile.other.OtherUserProfileScreenViewModelTest.Companion.USER_ID +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.feature.client.FetchUsersClientsFromRemoteUseCase import com.wire.kalium.logic.feature.client.ObserveClientsByUserIdUseCase @@ -43,8 +44,8 @@ import com.wire.kalium.logic.feature.conversation.UpdateConversationArchivedStat import com.wire.kalium.logic.feature.conversation.UpdateConversationMemberRoleResult import com.wire.kalium.logic.feature.conversation.UpdateConversationMemberRoleUseCase import com.wire.kalium.logic.feature.conversation.UpdateConversationMutedStatusUseCase -import com.wire.kalium.logic.feature.e2ei.usecase.GetUserE2eiCertificatesUseCase import com.wire.kalium.logic.feature.e2ei.usecase.IsOtherUserE2EIVerifiedUseCase +import com.wire.kalium.logic.feature.e2ei.usecase.GetUserE2eiCertificatesUseCase import com.wire.kalium.logic.feature.user.GetSelfUserUseCase import com.wire.kalium.logic.feature.user.GetUserInfoResult import com.wire.kalium.logic.feature.user.ObserveUserInfoUseCase @@ -65,6 +66,9 @@ internal class OtherUserProfileViewModelArrangement { @MockK lateinit var observeUserInfo: ObserveUserInfoUseCase + @MockK + lateinit var wireSessionImageLoader: WireSessionImageLoader + @MockK lateinit var observeConversationRoleForUserUseCase: ObserveConversationRoleForUserUseCase @@ -119,6 +123,7 @@ internal class OtherUserProfileViewModelArrangement { getOneToOneConversation, observeUserInfo, userTypeMapper, + wireSessionImageLoader, observeConversationRoleForUserUseCase, removeMemberFromConversationUseCase, updateConversationMemberRoleUseCase, diff --git a/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelArrangement.kt b/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelArrangement.kt index 47b10e19c10..0a71e66a9e4 100644 --- a/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelArrangement.kt +++ b/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelArrangement.kt @@ -28,6 +28,7 @@ import com.wire.android.framework.TestUser import com.wire.android.mapper.OtherAccountMapper import com.wire.android.notification.WireNotificationManager import com.wire.android.util.dispatchers.DispatcherProvider +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.data.id.QualifiedIdMapper import com.wire.kalium.logic.feature.auth.LogoutUseCase import com.wire.kalium.logic.feature.call.usecase.EndCallUseCase @@ -70,7 +71,16 @@ class SelfUserProfileViewModelArrangement { @MockK lateinit var dispatchers: DispatcherProvider +<<<<<<< HEAD +======= + @MockK + lateinit var wireSessionImageLoader: WireSessionImageLoader + @MockK + lateinit var authServerConfigProvider: AuthServerConfigProvider + @MockK + lateinit var selfServerLinks: SelfServerConfigUseCase +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) @MockK lateinit var otherAccountMapper: OtherAccountMapper @@ -112,6 +122,12 @@ class SelfUserProfileViewModelArrangement { logout = logout, observeLegalHoldStatusForSelfUser = observeLegalHoldStatusForSelfUser, dispatchers = TestDispatcherProvider(), +<<<<<<< HEAD +======= + wireSessionImageLoader = wireSessionImageLoader, + authServerConfigProvider = authServerConfigProvider, + selfServerLinks = selfServerLinks, +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) otherAccountMapper = otherAccountMapper, observeEstablishedCalls = observeEstablishedCalls, accountSwitch = accountSwitch, diff --git a/app/src/test/kotlin/com/wire/android/ui/userprofile/service/ServiceDetailsViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/userprofile/service/ServiceDetailsViewModelTest.kt index 44165d97274..d5a5026c0d7 100644 --- a/app/src/test/kotlin/com/wire/android/ui/userprofile/service/ServiceDetailsViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/userprofile/service/ServiceDetailsViewModelTest.kt @@ -28,6 +28,7 @@ import com.wire.android.ui.home.conversations.details.participants.usecase.Conve import com.wire.android.ui.home.conversations.details.participants.usecase.ObserveConversationRoleForUserUseCase import com.wire.android.ui.navArgs import com.wire.android.ui.userprofile.other.OtherUserProfileScreenViewModelTest +import com.wire.android.util.ui.WireSessionImageLoader import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.conversation.Conversation @@ -294,6 +295,9 @@ class ServiceDetailsViewModelTest { @MockK lateinit var observeConversationRoleForUser: ObserveConversationRoleForUserUseCase + @MockK + lateinit var wireSessionImageLoader: WireSessionImageLoader + @MockK lateinit var removeMemberFromConversation: RemoveMemberFromConversationUseCase @@ -312,6 +316,7 @@ class ServiceDetailsViewModelTest { getServiceById, observeIsServiceMember, observeConversationRoleForUser, + wireSessionImageLoader, removeMemberFromConversation, addServiceToConversation, serviceDetailsMapper, diff --git a/app/src/test/kotlin/com/wire/android/util/ui/AssetImageFetcherTest.kt b/app/src/test/kotlin/com/wire/android/util/ui/AssetImageFetcherTest.kt index c30e6346bce..bc9b49db4c4 100644 --- a/app/src/test/kotlin/com/wire/android/util/ui/AssetImageFetcherTest.kt +++ b/app/src/test/kotlin/com/wire/android/util/ui/AssetImageFetcherTest.kt @@ -53,7 +53,7 @@ internal class AssetImageFetcherTest { val someUserAssetId = AssetId("value", "domain") val someDummyData = "some-dummy-data".toByteArray() val someDummyName = "some-dummy-name" - val data = ImageAsset.UserAvatarAsset(someUserAssetId) + val data = ImageAsset.UserAvatarAsset(mockk(), someUserAssetId) val avatarPath = fakeKaliumFileSystem.selfUserAvatarPath() val (arrangement, assetImageFetcher) = Arrangement() .withSuccessfulImageData(data, avatarPath, someDummyData.size.toLong(), someDummyName) @@ -74,7 +74,7 @@ internal class AssetImageFetcherTest { val someUserAssetId = AssetId("value", "domain") val someDummyData = "some-dummy-data".toByteArray() val someDummyName = "some-dummy-name" - val data = ImageAsset.UserAvatarAsset(someUserAssetId) + val data = ImageAsset.UserAvatarAsset(mockk(), someUserAssetId) val avatarPath = fakeKaliumFileSystem.selfUserAvatarPath() val (arrangement, assetImageFetcher) = Arrangement() .withSuccessfulImageData(data, avatarPath, someDummyData.size.toLong(), someDummyName, 1) @@ -97,7 +97,7 @@ internal class AssetImageFetcherTest { val someMessageId = "some-message-id" val someDummyData = "some-dummy-data".toByteArray() val someDummyName = "some-dummy-name" - val data = ImageAsset.PrivateAsset(someConversationId, someMessageId, true) + val data = ImageAsset.PrivateAsset(mockk(), someConversationId, someMessageId, true) val avatarPath = fakeKaliumFileSystem.selfUserAvatarPath() val (arrangement, assetImageFetcher) = Arrangement() .withSuccessfulImageData(data, avatarPath, 1, someDummyName) @@ -117,7 +117,7 @@ internal class AssetImageFetcherTest { fun givenAUserAvatarAssetData_WhenCallingFetchUnsuccessfully_ThenFetchResultIsNotReturned() = runTest { // Given val someUserAssetId = AssetId("value", "domain") - val data = ImageAsset.UserAvatarAsset(someUserAssetId) + val data = ImageAsset.UserAvatarAsset(mockk(), someUserAssetId) val (arrangement, assetImageFetcher) = Arrangement().withErrorResponse(data).arrange() // When @@ -132,7 +132,7 @@ internal class AssetImageFetcherTest { // Given val someConversationId = ConversationId("some-value", "some-domain") val someMessageId = "some-message-id" - val data = ImageAsset.PrivateAsset(someConversationId, someMessageId, true) + val data = ImageAsset.PrivateAsset(mockk(), someConversationId, someMessageId, true) val (arrangement, assetImageFetcher) = Arrangement().withErrorResponse(data).arrange() // When @@ -147,7 +147,7 @@ internal class AssetImageFetcherTest { runTest { // Given val someUserAssetId = AssetId("value", "domain") - val data = ImageAsset.UserAvatarAsset(someUserAssetId) + val data = ImageAsset.UserAvatarAsset(mockk(), someUserAssetId) val (arrangement, assetImageFetcher) = Arrangement() .withErrorResponse( data = data, @@ -169,7 +169,7 @@ internal class AssetImageFetcherTest { runTest { // Given val someUserAssetId = AssetId("value", "domain") - val data = ImageAsset.UserAvatarAsset(someUserAssetId) + val data = ImageAsset.UserAvatarAsset(mockk(), someUserAssetId) val (arrangement, assetImageFetcher) = Arrangement() .withErrorResponse( data = data, @@ -191,7 +191,7 @@ internal class AssetImageFetcherTest { runTest { // Given val someUserAssetId = AssetId("value", "domain") - val data = ImageAsset.UserAvatarAsset(someUserAssetId) + val data = ImageAsset.UserAvatarAsset(mockk(), someUserAssetId) val (arrangement, assetImageFetcher) = Arrangement() .withErrorResponse( data = data, @@ -214,7 +214,7 @@ internal class AssetImageFetcherTest { // Given val someConversationId = ConversationId("some-value", "some-domain") val someMessageId = "some-message-id" - val data = ImageAsset.PrivateAsset(someConversationId, someMessageId, true) + val data = ImageAsset.PrivateAsset(mockk(), someConversationId, someMessageId, true) val (arrangement, assetImageFetcher) = Arrangement() .withErrorResponse( data = data, @@ -237,7 +237,7 @@ internal class AssetImageFetcherTest { // Given val someConversationId = ConversationId("some-value", "some-domain") val someMessageId = "some-message-id" - val data = ImageAsset.PrivateAsset(someConversationId, someMessageId, true) + val data = ImageAsset.PrivateAsset(mockk(), someConversationId, someMessageId, true) val (arrangement, assetImageFetcher) = Arrangement() .withErrorResponse( data = data, @@ -260,7 +260,7 @@ internal class AssetImageFetcherTest { // Given val someConversationId = ConversationId("some-value", "some-domain") val someMessageId = "some-message-id" - val data = ImageAsset.PrivateAsset(someConversationId, someMessageId, true) + val data = ImageAsset.PrivateAsset(mockk(), someConversationId, someMessageId, true) val (arrangement, assetImageFetcher) = Arrangement() .withErrorResponse( data = data, diff --git a/core/ui-common/build.gradle.kts b/core/ui-common/build.gradle.kts index 5f6cb899b8e..ceea6cde50d 100644 --- a/core/ui-common/build.gradle.kts +++ b/core/ui-common/build.gradle.kts @@ -1,7 +1,10 @@ plugins { id(libs.plugins.wire.android.library.get().pluginId) id(libs.plugins.wire.kover.get().pluginId) +<<<<<<< HEAD alias(libs.plugins.kotlin.serialization) +======= +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) } android { @@ -13,8 +16,6 @@ dependencies { implementation(libs.androidx.core) implementation(libs.androidx.appcompat) implementation(libs.material) - implementation(libs.ktx.serialization) - implementation(libs.bundlizer.core) val composeBom = platform(libs.compose.bom) implementation(composeBom) diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/bottomsheet/WireModalSheetState.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/bottomsheet/WireModalSheetState.kt index ffcdacf1cce..b1bb92f9c81 100644 --- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/bottomsheet/WireModalSheetState.kt +++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/bottomsheet/WireModalSheetState.kt @@ -17,7 +17,6 @@ */ package com.wire.android.ui.common.bottomsheet -import android.os.Bundle import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue @@ -32,16 +31,12 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.SoftwareKeyboardController import androidx.compose.ui.unit.Density -import dev.ahmedmourad.bundlizer.Bundlizer import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import kotlinx.serialization.InternalSerializationApi -import kotlinx.serialization.serializer -import kotlinx.serialization.serializerOrNull @OptIn(ExperimentalMaterial3Api::class) -open class WireModalSheetState( +open class WireModalSheetState internal constructor( density: Density, private val scope: CoroutineScope, private val keyboardController: SoftwareKeyboardController? = null, @@ -89,14 +84,20 @@ open class WireModalSheetState( companion object { const val DELAY_TO_SHOW_BOTTOM_SHEET_WHEN_KEYBOARD_IS_OPEN = 300L +<<<<<<< HEAD @OptIn(InternalSerializationApi::class) inline fun saver( +======= + @Suppress("UNCHECKED_CAST") + fun saver( +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) density: Density, softwareKeyboardController: SoftwareKeyboardController?, - noinline onDismissAction: () -> Unit, + onDismissAction: () -> Unit, scope: CoroutineScope ): Saver, *> = Saver( save = { +<<<<<<< HEAD when (it.currentValue) { is WireSheetValue.Hidden -> listOf(false) // hidden is WireSheetValue.Expanded -> { @@ -115,17 +116,27 @@ open class WireModalSheetState( } } } +======= + val isExpanded = it.currentValue is WireSheetValue.Expanded + val (isValueOfTypeUnit, value) = (it.currentValue as? WireSheetValue.Expanded)?.let { + val isValueOfTypeUnit = it.value is Unit // Unit cannot be saved into Bundle, need to handle it separately + val value = if (isValueOfTypeUnit) null else it.value + isValueOfTypeUnit to value + } ?: (false to null) + listOf(isExpanded, isValueOfTypeUnit, value) +>>>>>>> dda09e7ca (fix: revert of #3670 (WPB-14433) (#3700)) }, restore = { savedValue -> val isExpanded = savedValue[0] as Boolean val sheetValue = when (isExpanded) { - true -> when (savedValue[1] as SavedType) { - SavedType.Unit -> WireSheetValue.Expanded(Unit as T) - - SavedType.Regular -> WireSheetValue.Expanded(savedValue[2] as T) - - SavedType.SerializedBundle -> - WireSheetValue.Expanded(Bundlizer.unbundle(T::class.serializer(), savedValue[2] as Bundle)) + true -> { + val isValueOfTypeUnit = savedValue[1] as Boolean + if (isValueOfTypeUnit) { + WireSheetValue.Expanded(Unit as T) + } else { + val value = savedValue[2] as T + WireSheetValue.Expanded(value) + } } false -> WireSheetValue.Hidden @@ -136,8 +147,6 @@ open class WireModalSheetState( } } -enum class SavedType { Unit, Regular, SerializedBundle } - @OptIn(ExperimentalMaterial3Api::class) sealed class WireSheetValue(val originalValue: SheetValue) { data object Hidden : WireSheetValue(SheetValue.Hidden) @@ -152,9 +161,9 @@ sealed class WireSheetValue(val originalValue: SheetValue) { * @param onDismissAction The action to be executed when the sheet is dismissed. */ @Composable -inline fun rememberWireModalSheetState( +fun rememberWireModalSheetState( initialValue: WireSheetValue = WireSheetValue.Hidden, - noinline onDismissAction: () -> Unit = {} + onDismissAction: () -> Unit = {} ): WireModalSheetState { val softwareKeyboardController = LocalSoftwareKeyboardController.current val density = LocalDensity.current