Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/src/main/kotlin/com/wire/android/di/ViewModelScoped.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package com.wire.android.di
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.lifecycle.ViewModel
import com.sebaslogen.resaca.KeyInScopeResolver
import com.sebaslogen.resaca.hilt.hiltViewModelScoped

/**
Expand Down Expand Up @@ -51,6 +52,25 @@ inline fun <reified T, reified S, reified R : ScopedArgs, reified F : AssistedVi
}
}

@Suppress("BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER")
@Composable
inline fun <reified T, reified S, reified R : ScopedArgs, reified F : AssistedViewModelFactory<T, R>>
hiltViewModelScoped(
arguments: R,
noinline keyInScopeResolver: KeyInScopeResolver<String>,
): S where T : ViewModel, T : S = when {
LocalInspectionMode.current -> ViewModelScopedPreviews.firstNotNullOf { it as? S }
espresso -> ViewModelScopedPreviews.firstNotNullOf { it as? S }
else -> {
val scopedKey = requireNotNull(arguments.key?.toString()) {
"Scoped key must not be null for ${T::class.qualifiedName}"
}
hiltViewModelScoped<T, F, String>(key = scopedKey, keyInScopeResolver = keyInScopeResolver) { factory ->
factory.create(arguments)
}
}
}

/**
* Custom implementation of [hiltViewModelScoped] that uses our generated previews for scoped ViewModels.
* This is version that does not take and pass any arguments, it does not use any key to generate a new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import com.wire.android.ui.home.conversations.model.messagetypes.image.VisualMed
import com.wire.android.ui.markdown.toMarkdownDocument
import com.wire.android.ui.markdown.toMarkdownTextWithMentions
import com.wire.android.ui.theme.Accent
import com.wire.android.util.getVideoMetaData
import com.wire.android.util.time.ISOFormatter
import com.wire.android.util.ui.UIText
import com.wire.kalium.logic.data.asset.AttachmentType
Expand Down Expand Up @@ -297,12 +296,11 @@ class RegularMessageMapper @Inject constructor(
}

assetMessageContentMetadata.isVideo() -> {
val metaData = localData?.assetDataPath?.let { getVideoMetaData(it) }
val metaData = metadata as? AssetContent.AssetMetadata.Video
UIMessageContent.VideoMessage(
assetName = name ?: "",
assetExtension = name?.split(".")?.last() ?: "",
assetId = AssetId(remoteData.assetId, remoteData.assetDomain.orEmpty()),
assetDataPath = localData?.assetDataPath,
assetSizeInBytes = sizeInBytes,
deliveryStatus = mapRecipientsFailure(userList, deliveryStatus),
params = VisualMediaParams(metaData?.width ?: 0, metaData?.height ?: 0),
Expand All @@ -317,7 +315,6 @@ class RegularMessageMapper @Inject constructor(
assetExtension = name?.split(".")?.last() ?: "",
assetId = AssetId(remoteData.assetId, remoteData.assetDomain.orEmpty()),
assetSizeInBytes = sizeInBytes,
assetDataPath = localData?.assetDataPath,
deliveryStatus = mapRecipientsFailure(userList, deliveryStatus)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.firstOrNull
Expand Down Expand Up @@ -92,8 +93,14 @@ class AudioMessageViewModelImpl @AssistedInject constructor(

private fun preloadAudioMessage() {
viewModelScope.launch {
// calls preload to initially fetch the audio asset data to be ready and schedule waves mask generation if needed
audioMessagePlayer.preloadAudioMessage(args.conversationId, args.messageId)
try {
// calls preload to initially fetch the audio asset data to be ready and schedule waves mask generation if needed
audioMessagePlayer.preloadAudioMessage(args.conversationId, args.messageId)
Comment thread
saleniuk marked this conversation as resolved.
} catch (ce: CancellationException) {
throw ce
} catch (_: Throwable) {
Comment thread
sbakhtiarov marked this conversation as resolved.
// no-op: preloading is best-effort
}
}
}

Expand All @@ -108,8 +115,10 @@ class AudioMessageViewModelImpl @AssistedInject constructor(
}
}
.distinctUntilChanged()
.firstOrNull { it != null } // wait for the first non-null value
.let { state = state.copy(wavesMask = it) }
.firstOrNull { it != null }
Comment thread
sbakhtiarov marked this conversation as resolved.
?.let {
state = state.copy(wavesMask = it)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,10 @@

suspend fun preloadAudioMessage(conversationId: ConversationId, messageId: String) {
val currentAccountResult = coreLogic.getGlobalScope().session.currentSession()
if (currentAccountResult is CurrentSessionResult.Failure) return
val userId = (currentAccountResult as CurrentSessionResult.Success).accountInfo.userId
getAssetMessage(userId, conversationId, messageId)
if (currentAccountResult is CurrentSessionResult.Success) {
val userId = currentAccountResult.accountInfo.userId
getAssetMessage(userId, conversationId, messageId)

Check warning on line 352 in app/src/main/kotlin/com/wire/android/media/audiomessage/ConversationAudioMessagePlayer.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/media/audiomessage/ConversationAudioMessagePlayer.kt#L351-L352

Added lines #L351 - L352 were not covered by tests
}
}

private suspend fun resumeOrPause(conversationId: ConversationId, messageId: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ fun AssetContent.toUiModel(progress: Float?) = MultipartAttachmentUi(
uuid = this.remoteData.assetId,
source = AssetSource.ASSET_STORAGE,
fileName = this.name,
localPath = this.localData?.assetDataPath,
Comment thread
sbakhtiarov marked this conversation as resolved.
localPath = null,
previewUrl = null,
mimeType = this.mimeType,
assetType = AttachmentFileType.fromMimeType(mimeType),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Wire
* Copyright (C) 2026 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

package com.wire.android.ui.home.conversations
Comment thread
sbakhtiarov marked this conversation as resolved.

import androidx.compose.runtime.staticCompositionLocalOf
import com.sebaslogen.resaca.KeyInScopeResolver

val LocalAudioMessageKeyInScopeResolver = staticCompositionLocalOf<KeyInScopeResolver<String>?> { null }
val LocalAssetLocalPathKeyInScopeResolver = staticCompositionLocalOf<KeyInScopeResolver<String>?> { null }

Check warning on line 25 in app/src/main/kotlin/com/wire/android/ui/home/conversations/AudioMessageScopeResolver.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/home/conversations/AudioMessageScopeResolver.kt#L24-L25

Added lines #L24 - L25 were not covered by tests
Loading
Loading