@@ -32,46 +32,67 @@ import com.wire.android.util.FileManager
3232import com.wire.kalium.cells.domain.usecase.GetEditorUrlUseCase
3333import com.wire.kalium.cells.domain.usecase.GetWireCellConfigurationUseCase
3434import com.wire.kalium.cells.domain.usecase.download.DownloadCellFileUseCase
35+ import com.wire.kalium.cells.domain.usecase.offline.ObserveOfflineFilesByConversationUseCase
3536import com.wire.kalium.common.functional.onSuccess
3637import com.wire.kalium.logic.data.asset.AssetTransferStatus
3738import com.wire.kalium.logic.data.asset.KaliumFileSystem
3839import com.wire.kalium.logic.data.featureConfig.CollaboraEdition
40+ import com.wire.kalium.logic.data.id.ConversationId
3941import com.wire.kalium.logic.data.message.AssetContent
4042import com.wire.kalium.logic.data.message.CellAssetContent
4143import com.wire.kalium.logic.data.message.MessageAttachment
4244import com.wire.kalium.logic.featureFlags.KaliumConfigs
4345import dagger.hilt.android.lifecycle.HiltViewModel
4446import kotlinx.collections.immutable.toImmutableList
47+ import kotlinx.coroutines.flow.SharingStarted
48+ import kotlinx.coroutines.flow.StateFlow
49+ import kotlinx.coroutines.flow.map
50+ import kotlinx.coroutines.flow.stateIn
51+ import kotlinx.coroutines.flow.MutableStateFlow
4552import kotlinx.coroutines.launch
4653import okio.Path.Companion.toPath
4754import javax.inject.Inject
4855
4956interface MultipartAttachmentsViewModel {
57+ val offlineAttachmentIds: StateFlow <Set <String >>
5058 fun onClick (attachment : MultipartAttachmentUi , openInImageViewer : (String ) -> Unit )
59+ fun mapAttachment (attachment : MessageAttachment ): MultipartAttachmentUi {
60+ val isAvailableOffline = attachment.assetId() in offlineAttachmentIds.value
61+ return attachment.toUiModel(isAvailableOffline = isAvailableOffline)
62+ }
63+
5164 fun mapAttachments (
52- attachments : List <MessageAttachment >
65+ attachments : List <MessageAttachment >,
5366 ): List <MultipartAttachmentGroup > {
67+ val offlineIds = offlineAttachmentIds.value
5468
5569 val result = mutableListOf<MultipartAttachmentGroup >()
5670 var group: MultipartAttachmentGroup ? = null
5771
5872 attachments.forEach {
73+ val isAvailableOffline = it.assetId() in offlineIds
5974 if (it.isMediaAttachment()) {
6075 group = when (group) {
61- null -> MultipartAttachmentGroup .Media (listOf (it.toUiModel()))
62- is MultipartAttachmentGroup .Media -> group.copy(group.attachments + it.toUiModel())
76+ null -> MultipartAttachmentGroup .Media (listOf (it.toUiModel(isAvailableOffline = isAvailableOffline)))
77+ is MultipartAttachmentGroup .Media -> {
78+ val newAttachment = it.toUiModel(isAvailableOffline = isAvailableOffline)
79+ group.copy(attachments = group.attachments + newAttachment)
80+ }
6381 else -> {
6482 result.add(group)
65- MultipartAttachmentGroup .Media (listOf (it.toUiModel()))
83+ MultipartAttachmentGroup .Media (listOf (it.toUiModel(isAvailableOffline = isAvailableOffline )))
6684 }
6785 }
6886 } else {
6987 group = when (group) {
70- null -> MultipartAttachmentGroup .Files (listOf (it.toUiModel()))
71- is MultipartAttachmentGroup .Files -> group.copy(group.attachments + it.toUiModel())
88+ null -> MultipartAttachmentGroup .Files (listOf (it.toUiModel(isAvailableOffline = isAvailableOffline)))
89+ is MultipartAttachmentGroup .Files -> {
90+ val newAttachment = it.toUiModel(isAvailableOffline = isAvailableOffline)
91+ group.copy(attachments = group.attachments + newAttachment)
92+ }
7293 else -> {
7394 result.add(group)
74- MultipartAttachmentGroup .Files (listOf (it.toUiModel()))
95+ MultipartAttachmentGroup .Files (listOf (it.toUiModel(isAvailableOffline = isAvailableOffline )))
7596 }
7697 }
7798 }
@@ -95,13 +116,16 @@ interface MultipartAttachmentsViewModel {
95116
96117@Suppress(" EmptyFunctionBlock" )
97118object MultipartAttachmentsViewModelPreview : MultipartAttachmentsViewModel {
119+ override val offlineAttachmentIds: StateFlow <Set <String >> = MutableStateFlow (emptySet<String >())
98120 override fun onClick (attachment : MultipartAttachmentUi , openInImageViewer : (String ) -> Unit ) {}
99121 override fun onAttachmentsVisible (attachments : List <MessageAttachment >) {}
100122 override fun onAttachmentsHidden (attachments : List <MessageAttachment >) {}
101123}
102124
103125@HiltViewModel
126+ @Suppress(" LongParameterList" )
104127class MultipartAttachmentsViewModelImpl @Inject constructor(
128+ private val conversationId : ConversationId ,
105129 private val refreshHelper : CellAssetRefreshHelper ,
106130 private val download : DownloadCellFileUseCase ,
107131 private val getEditorUrl : GetEditorUrlUseCase ,
@@ -110,17 +134,24 @@ class MultipartAttachmentsViewModelImpl @Inject constructor(
110134 private val kaliumFileSystem : KaliumFileSystem ,
111135 private val featureFlags : KaliumConfigs ,
112136 private val getWireCellsConfig : GetWireCellConfigurationUseCase ,
137+ observeOfflineFilesByConversation : ObserveOfflineFilesByConversationUseCase ,
113138) : ViewModel(), MultipartAttachmentsViewModel {
114139
115140 private val uploadProgress = mutableStateMapOf<String , Float >()
141+ override val offlineAttachmentIds: StateFlow <Set <String >> = observeOfflineFilesByConversation(conversationId)
142+ .map { offlineFiles -> offlineFiles.mapTo(mutableSetOf ()) { it.id } }
143+ .stateIn(viewModelScope, SharingStarted .Eagerly , emptySet())
116144
117145 private var isCollaboraEnabled: Boolean = false
118146
119147 init {
120148 loadWireCellConfig()
121149 }
122150
123- override fun onClick (attachment : MultipartAttachmentUi , openInImageViewer : (String ) -> Unit ) {
151+ override fun onClick (
152+ attachment : MultipartAttachmentUi ,
153+ openInImageViewer : (String ) -> Unit ,
154+ ) {
124155 when {
125156 attachment.isImage() && ! attachment.fileNotFound() -> openInImageViewer(attachment.uuid)
126157 attachment.isEditSupported && isCollaboraEnabled && featureFlags.collaboraIntegration ->
@@ -174,7 +205,7 @@ class MultipartAttachmentsViewModelImpl @Inject constructor(
174205
175206 download(
176207 assetId = attachment.uuid,
177- conversationId = null , // TODO to replace with real conversation id in next PR
208+ conversationId = conversationId.value,
178209 outFilePath = path,
179210 assetSize = attachment.assetSize ? : 0 ,
180211 ) { progress ->
@@ -208,7 +239,7 @@ class MultipartAttachmentsViewModelImpl @Inject constructor(
208239 }
209240}
210241
211- private fun MessageAttachment.assetId () =
242+ internal fun MessageAttachment.assetId () =
212243 when (this ) {
213244 is AssetContent -> remoteData.assetId
214245 is CellAssetContent -> id
0 commit comments