Browse Source

Merge pull request #3694 from element-hq/feature/bma/oidcPrompt

OIDC prompt
pull/3698/merge
Benoit Marty 1 day ago committed by GitHub
parent
commit
1510141add
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt
  2. 68
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt
  3. 4
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt
  4. 4
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt
  5. 4
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventForTimestampViewProvider.kt
  6. 4
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt
  7. 14
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt
  8. 10
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessageMediaRepo.kt
  9. 12
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePlayer.kt
  10. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt
  11. 4
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/fixtures/MessageEventFixtures.kt
  12. 4
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt
  13. 2
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/DefaultVoiceMessageMediaRepoTest.kt
  14. 2
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/DefaultVoiceMessagePlayerTest.kt
  15. 7
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt
  16. 4
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenterTest.kt
  17. 2
      gradle/libs.versions.toml
  18. 2
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt
  19. 51
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/OidcPrompt.kt
  20. 4
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/MatrixMediaLoader.kt
  21. 3
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/CurrentUserMembership.kt
  22. 13
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt
  23. 22
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcPrompt.kt
  24. 8
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt
  25. 4
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt
  26. 2
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt
  27. 21
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt
  28. 11
      libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt
  29. 18
      libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustEventShieldsProvider.kt
  30. 11
      libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustLazyTimelineItemProvider.kt
  31. 3
      libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeMatrixAuthenticationService.kt
  32. 2
      libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/media/FakeMatrixMediaLoader.kt
  33. 4
      libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt
  34. 2
      libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerPresenter.kt
  35. 2
      libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt
  36. 8
      libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationMediaRepo.kt
  37. 2
      libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationMediaRepo.kt

4
features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt

@ -27,6 +27,7 @@ import io.element.android.libraries.architecture.AsyncData @@ -27,6 +27,7 @@ import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.auth.OidcPrompt
import io.element.android.libraries.oidc.api.OidcAction
import io.element.android.libraries.oidc.api.OidcActionFlow
import kotlinx.coroutines.CoroutineScope
@ -92,7 +93,8 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor( @@ -92,7 +93,8 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
val matrixHomeServerDetails = authenticationService.getHomeserverDetails().value!!
if (matrixHomeServerDetails.supportsOidcLogin) {
// Retrieve the details right now
LoginFlow.OidcFlow(authenticationService.getOidcUrl().getOrThrow())
val oidcPrompt = if (params.isAccountCreation) OidcPrompt.Create else OidcPrompt.Consent
LoginFlow.OidcFlow(authenticationService.getOidcUrl(oidcPrompt).getOrThrow())
} else if (params.isAccountCreation) {
val url = webClientUrlForAuthenticationRetriever.retrieve(homeserverUrl)
LoginFlow.AccountCreationFlow(url)

68
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt

@ -31,103 +31,109 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> { @@ -31,103 +31,109 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
return sequenceOf(
anActionListState(),
anActionListState().copy(target = ActionListState.Target.Loading(aTimelineItemEvent())),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent().copy(
reactionsState = reactionsState
event = aTimelineItemEvent(
timelineItemReactions = reactionsState
),
displayEmojiReactions = true,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemActionList(),
)
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(
content = aTimelineItemImageContent(),
displayNameAmbiguous = true,
).copy(
reactionsState = reactionsState,
timelineItemReactions = reactionsState,
),
displayEmojiReactions = true,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemActionList(),
)
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemVideoContent()).copy(
reactionsState = reactionsState
event = aTimelineItemEvent(
content = aTimelineItemVideoContent(),
timelineItemReactions = reactionsState
),
displayEmojiReactions = true,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemActionList(),
)
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemFileContent()).copy(
reactionsState = reactionsState
event = aTimelineItemEvent(
content = aTimelineItemFileContent(),
timelineItemReactions = reactionsState
),
displayEmojiReactions = true,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemActionList(),
)
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemAudioContent()).copy(
reactionsState = reactionsState
event = aTimelineItemEvent(
content = aTimelineItemAudioContent(),
timelineItemReactions = reactionsState
),
displayEmojiReactions = true,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemActionList(),
)
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemVoiceContent()).copy(
reactionsState = reactionsState
event = aTimelineItemEvent(
content = aTimelineItemVoiceContent(),
timelineItemReactions = reactionsState
),
displayEmojiReactions = true,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemActionList(),
)
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy(
reactionsState = reactionsState
event = aTimelineItemEvent(
content = aTimelineItemLocationContent(),
timelineItemReactions = reactionsState
),
displayEmojiReactions = true,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemActionList(),
)
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy(
reactionsState = reactionsState
event = aTimelineItemEvent(
content = aTimelineItemLocationContent(),
timelineItemReactions = reactionsState
),
displayEmojiReactions = false,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemActionList(),
),
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemPollContent()).copy(
reactionsState = reactionsState
event = aTimelineItemEvent(
content = aTimelineItemPollContent(),
timelineItemReactions = reactionsState
),
displayEmojiReactions = false,
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = aTimelineItemPollActionList(),
),
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent().copy(
reactionsState = reactionsState,
event = aTimelineItemEvent(
timelineItemReactions = reactionsState,
messageShield = MessageShield.UnknownDevice(isCritical = true)
),
displayEmojiReactions = true,
@ -135,7 +141,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> { @@ -135,7 +141,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
actions = aTimelineItemActionList(),
)
),
anActionListState().copy(
anActionListState(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(),
displayEmojiReactions = true,

4
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt

@ -164,10 +164,10 @@ internal fun aTimelineItemEvent( @@ -164,10 +164,10 @@ internal fun aTimelineItemEvent(
groupPosition = groupPosition,
localSendState = sendState,
inReplyTo = inReplyTo,
debugInfoProvider = { debugInfo },
isThreaded = isThreaded,
origin = null,
messageShield = messageShield,
timelineItemDebugInfoProvider = { debugInfo },
messageShieldProvider = { messageShield },
)
}

4
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt

@ -26,7 +26,9 @@ internal fun TimelineViewMessageShieldPreview() = ElementPreview { @@ -26,7 +26,9 @@ internal fun TimelineViewMessageShieldPreview() = ElementPreview {
// For consistency, ensure that there is a message in the timeline (the last one) with an error.
val messageShield = aCriticalShield()
val items = listOf(
(timelineItems.first() as TimelineItem.Event).copy(messageShield = messageShield)
(timelineItems.first() as TimelineItem.Event).copy(
messageShieldProvider = { messageShield },
)
) + timelineItems.drop(1)
CompositionLocalProvider(
LocalTimelineItemPresenterFactories provides aFakeTimelineItemPresenterFactories(),

4
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventForTimestampViewProvider.kt

@ -27,10 +27,10 @@ class TimelineItemEventForTimestampViewProvider : PreviewParameterProvider<Timel @@ -27,10 +27,10 @@ class TimelineItemEventForTimestampViewProvider : PreviewParameterProvider<Timel
localSendState = LocalEventSendState.Failed.Unknown("AN_ERROR"),
content = aTimelineItemTextContent().copy(isEdited = true),
),
aTimelineItemEvent().copy(
aTimelineItemEvent(
messageShield = MessageShield.AuthenticityNotGuaranteed(isCritical = false),
),
aTimelineItemEvent().copy(
aTimelineItemEvent(
messageShield = MessageShield.UnknownDevice(isCritical = true),
),
)

4
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt

@ -85,9 +85,9 @@ class TimelineItemEventFactory @AssistedInject constructor( @@ -85,9 +85,9 @@ class TimelineItemEventFactory @AssistedInject constructor(
localSendState = currentTimelineItem.event.localSendState,
inReplyTo = currentTimelineItem.event.inReplyTo()?.map(permalinkParser = permalinkParser),
isThreaded = currentTimelineItem.event.isThreaded(),
debugInfoProvider = currentTimelineItem.event.debugInfoProvider,
origin = currentTimelineItem.event.origin,
messageShield = currentTimelineItem.event.messageShieldProvider.getShield(strict = false)
timelineItemDebugInfoProvider = currentTimelineItem.event.timelineItemDebugInfoProvider,
messageShieldProvider = currentTimelineItem.event.messageShieldProvider,
)
}

14
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt

@ -17,10 +17,12 @@ import io.element.android.libraries.matrix.api.core.EventId @@ -17,10 +17,12 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.core.UniqueId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.event.EventDebugInfoProvider
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShieldProvider
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemDebugInfoProvider
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin
import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
@ -74,9 +76,9 @@ sealed interface TimelineItem { @@ -74,9 +76,9 @@ sealed interface TimelineItem {
val localSendState: LocalEventSendState?,
val inReplyTo: InReplyToDetails?,
val isThreaded: Boolean,
val debugInfoProvider: EventDebugInfoProvider,
val origin: TimelineItemEventOrigin?,
val messageShield: MessageShield?,
val timelineItemDebugInfoProvider: TimelineItemDebugInfoProvider,
val messageShieldProvider: MessageShieldProvider,
) : TimelineItem {
val showSenderInformation = groupPosition.isNew() && !isMine
@ -90,7 +92,11 @@ sealed interface TimelineItem { @@ -90,7 +92,11 @@ sealed interface TimelineItem {
val isRemote = eventId != null
val debugInfo = debugInfoProvider.get()
// No need to be lazy here?
val messageShield: MessageShield? = messageShieldProvider(strict = false)
val debugInfo: TimelineItemDebugInfo
get() = timelineItemDebugInfoProvider()
}
@Immutable

10
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessageMediaRepo.kt

@ -35,12 +35,12 @@ interface VoiceMessageMediaRepo { @@ -35,12 +35,12 @@ interface VoiceMessageMediaRepo {
*
* @param mediaSource the media source of the voice message.
* @param mimeType the mime type of the voice message.
* @param body the body of the voice message.
* @param filename the filename of the voice message.
*/
fun create(
mediaSource: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
): VoiceMessageMediaRepo
}
@ -61,7 +61,7 @@ class DefaultVoiceMessageMediaRepo @AssistedInject constructor( @@ -61,7 +61,7 @@ class DefaultVoiceMessageMediaRepo @AssistedInject constructor(
private val matrixMediaLoader: MatrixMediaLoader,
@Assisted private val mediaSource: MediaSource,
@Assisted("mimeType") private val mimeType: String?,
@Assisted("body") private val body: String?,
@Assisted("filename") private val filename: String?,
) : VoiceMessageMediaRepo {
@ContributesBinding(RoomScope::class)
@AssistedFactory
@ -69,7 +69,7 @@ class DefaultVoiceMessageMediaRepo @AssistedInject constructor( @@ -69,7 +69,7 @@ class DefaultVoiceMessageMediaRepo @AssistedInject constructor(
override fun create(
mediaSource: MediaSource,
@Assisted("mimeType") mimeType: String?,
@Assisted("body") body: String?,
@Assisted("filename") filename: String?,
): DefaultVoiceMessageMediaRepo
}
@ -79,7 +79,7 @@ class DefaultVoiceMessageMediaRepo @AssistedInject constructor( @@ -79,7 +79,7 @@ class DefaultVoiceMessageMediaRepo @AssistedInject constructor(
else -> matrixMediaLoader.downloadMediaFile(
source = mediaSource,
mimeType = mimeType,
body = body,
filename = filename,
).mapCatching {
it.use { mediaFile ->
val dest = cachedFile.apply { parentFile?.mkdirs() }

12
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePlayer.kt

@ -37,13 +37,13 @@ interface VoiceMessagePlayer { @@ -37,13 +37,13 @@ interface VoiceMessagePlayer {
* @param eventId The eventId of the voice message event.
* @param mediaSource The media source of the voice message.
* @param mimeType The mime type of the voice message.
* @param body The body of the voice message.
* @param filename The filename of the voice message.
*/
fun create(
eventId: EventId?,
mediaSource: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
): VoiceMessagePlayer
}
@ -113,7 +113,7 @@ class DefaultVoiceMessagePlayer( @@ -113,7 +113,7 @@ class DefaultVoiceMessagePlayer(
private val eventId: EventId?,
mediaSource: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
) : VoiceMessagePlayer {
@ContributesBinding(RoomScope::class) // Scoped types can't use @AssistedInject.
class Factory @Inject constructor(
@ -124,21 +124,21 @@ class DefaultVoiceMessagePlayer( @@ -124,21 +124,21 @@ class DefaultVoiceMessagePlayer(
eventId: EventId?,
mediaSource: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
): DefaultVoiceMessagePlayer = DefaultVoiceMessagePlayer(
mediaPlayer = mediaPlayer,
voiceMessageMediaRepoFactory = voiceMessageMediaRepoFactory,
eventId = eventId,
mediaSource = mediaSource,
mimeType = mimeType,
body = body,
filename = filename,
)
}
private val repo = voiceMessageMediaRepoFactory.create(
mediaSource = mediaSource,
mimeType = mimeType,
body = body
filename = filename,
)
private var internalState = MutableStateFlow(

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt

@ -59,7 +59,7 @@ class VoiceMessagePresenter @AssistedInject constructor( @@ -59,7 +59,7 @@ class VoiceMessagePresenter @AssistedInject constructor(
eventId = content.eventId,
mediaSource = content.mediaSource,
mimeType = content.mimeType,
body = content.caption,
filename = content.filename,
)
private val play = mutableStateOf<AsyncData<Unit>>(AsyncData.Uninitialized)

4
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/fixtures/MessageEventFixtures.kt

@ -58,8 +58,8 @@ internal fun aMessageEvent( @@ -58,8 +58,8 @@ internal fun aMessageEvent(
readReceiptState = TimelineItemReadReceipts(emptyList<ReadReceiptData>().toImmutableList()),
localSendState = sendState,
inReplyTo = inReplyTo,
debugInfoProvider = { debugInfo },
isThreaded = isThreaded,
origin = null,
messageShield = messageShield,
timelineItemDebugInfoProvider = { debugInfo },
messageShieldProvider = { messageShield },
)

4
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/groups/TimelineItemGrouperTest.kt

@ -41,9 +41,9 @@ class TimelineItemGrouperTest { @@ -41,9 +41,9 @@ class TimelineItemGrouperTest {
canBeRepliedTo = false,
inReplyTo = null,
isThreaded = false,
debugInfoProvider = { aTimelineItemDebugInfo() },
origin = null,
messageShield = null,
timelineItemDebugInfoProvider = { aTimelineItemDebugInfo() },
messageShieldProvider = { null },
)
private val aNonGroupableItem = aMessageEvent()
private val aNonGroupableItemNoEvent = TimelineItem.Virtual(UniqueId("virtual"), aTimelineItemDaySeparatorModel("Today"))

2
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/DefaultVoiceMessageMediaRepoTest.kt

@ -137,7 +137,7 @@ private fun createDefaultVoiceMessageMediaRepo( @@ -137,7 +137,7 @@ private fun createDefaultVoiceMessageMediaRepo(
json = null
),
mimeType = MimeTypes.Ogg,
body = "someBody.ogg"
filename = "someBody.ogg"
)
private const val MXC_URI = "mxc://matrix.org/1234567890abcdefg"

2
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/DefaultVoiceMessagePlayerTest.kt

@ -279,7 +279,7 @@ private fun createDefaultVoiceMessagePlayer( @@ -279,7 +279,7 @@ private fun createDefaultVoiceMessagePlayer(
json = null
),
mimeType = MimeTypes.Ogg,
body = "someBody.ogg"
filename = "someBody.ogg"
)
private const val MXC_URI = "mxc://matrix.org/1234567890abcdefg"

7
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt

@ -78,7 +78,6 @@ fun aRedactedMatrixTimeline(eventId: EventId) = listOf<MatrixTimelineItem>( @@ -78,7 +78,6 @@ fun aRedactedMatrixTimeline(eventId: EventId) = listOf<MatrixTimelineItem>(
transactionId = null,
isEditable = false,
canBeRepliedTo = false,
isLocal = false,
isOwn = false,
isRemote = false,
localSendState = null,
@ -88,14 +87,14 @@ fun aRedactedMatrixTimeline(eventId: EventId) = listOf<MatrixTimelineItem>( @@ -88,14 +87,14 @@ fun aRedactedMatrixTimeline(eventId: EventId) = listOf<MatrixTimelineItem>(
senderProfile = ProfileTimelineDetails.Unavailable,
timestamp = 9442,
content = RedactedContent,
debugInfoProvider = {
origin = null,
timelineItemDebugInfoProvider = {
TimelineItemDebugInfo(
model = "enim",
originalJson = null,
latestEditedJson = null
latestEditedJson = null,
)
},
origin = null,
messageShieldProvider = { null },
),
)

4
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenterTest.kt

@ -226,14 +226,14 @@ fun TestScope.createVoiceMessagePresenter( @@ -226,14 +226,14 @@ fun TestScope.createVoiceMessagePresenter(
analyticsService: AnalyticsService = FakeAnalyticsService(),
content: TimelineItemVoiceContent = aTimelineItemVoiceContent(),
) = VoiceMessagePresenter(
voiceMessagePlayerFactory = { eventId, mediaSource, mimeType, body ->
voiceMessagePlayerFactory = { eventId, mediaSource, mimeType, filename ->
DefaultVoiceMessagePlayer(
mediaPlayer = mediaPlayer,
voiceMessageMediaRepoFactory = { _, _, _ -> voiceMessageMediaRepo },
eventId = eventId,
mediaSource = mediaSource,
mimeType = mimeType,
body = body
filename = filename
)
},
analyticsService = analyticsService,

2
gradle/libs.versions.toml

@ -168,7 +168,7 @@ jsoup = "org.jsoup:jsoup:1.18.1" @@ -168,7 +168,7 @@ jsoup = "org.jsoup:jsoup:1.18.1"
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0"
timber = "com.jakewharton.timber:timber:5.0.1"
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.53"
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.54"
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }

2
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt

@ -43,7 +43,7 @@ interface MatrixAuthenticationService { @@ -43,7 +43,7 @@ interface MatrixAuthenticationService {
/**
* Get the Oidc url to display to the user.
*/
suspend fun getOidcUrl(): Result<OidcDetails>
suspend fun getOidcUrl(prompt: OidcPrompt): Result<OidcDetails>
/**
* Cancel Oidc login sequence.

51
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/OidcPrompt.kt

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only
* Please see LICENSE in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.auth
sealed interface OidcPrompt {
/**
* The Authorization Server must not display any authentication or consent
* user interface pages.
*/
data object None : OidcPrompt
/**
* The Authorization Server should prompt the End-User for
* reauthentication.
*/
data object Login : OidcPrompt
/**
* The Authorization Server should prompt the End-User for consent before
* returning information to the Client.
*/
data object Consent : OidcPrompt
/**
* The Authorization Server should prompt the End-User to select a user
* account.
*
* This enables an End-User who has multiple accounts at the Authorization
* Server to select amongst the multiple accounts that they might have
* current sessions for.
*/
data object SelectAccount : OidcPrompt
/**
* The Authorization Server should prompt the End-User to create a user
* account.
*
* Defined in [Initiating User Registration via OpenID Connect](https://openid.net/specs/openid-connect-prompt-create-1_0.html).
*/
data object Create : OidcPrompt
/**
* An unknown value.
*/
data class Unknown(val value: String) : OidcPrompt
}

4
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/media/MatrixMediaLoader.kt

@ -25,14 +25,14 @@ interface MatrixMediaLoader { @@ -25,14 +25,14 @@ interface MatrixMediaLoader {
/**
* @param source to fetch the data for.
* @param mimeType: optional mime type.
* @param body: optional body which will be used to name the file.
* @param filename: optional String which will be used to name the file.
* @param useCache: if true, the rust sdk will cache the media in its store.
* @return a [Result] of [MediaFile]
*/
suspend fun downloadMediaFile(
source: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
useCache: Boolean = true,
): Result<MediaFile>
}

3
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/CurrentUserMembership.kt

@ -10,5 +10,6 @@ package io.element.android.libraries.matrix.api.room @@ -10,5 +10,6 @@ package io.element.android.libraries.matrix.api.room
enum class CurrentUserMembership {
INVITED,
JOINED,
LEFT
LEFT,
KNOCKED,
}

13
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt

@ -18,7 +18,6 @@ data class EventTimelineItem( @@ -18,7 +18,6 @@ data class EventTimelineItem(
val transactionId: TransactionId?,
val isEditable: Boolean,
val canBeRepliedTo: Boolean,
val isLocal: Boolean,
val isOwn: Boolean,
val isRemote: Boolean,
val localSendState: LocalEventSendState?,
@ -28,9 +27,9 @@ data class EventTimelineItem( @@ -28,9 +27,9 @@ data class EventTimelineItem(
val senderProfile: ProfileTimelineDetails,
val timestamp: Long,
val content: EventContent,
val debugInfoProvider: EventDebugInfoProvider,
val origin: TimelineItemEventOrigin?,
val messageShieldProvider: EventShieldsProvider,
val timelineItemDebugInfoProvider: TimelineItemDebugInfoProvider,
val messageShieldProvider: MessageShieldProvider,
) {
fun inReplyTo(): InReplyTo? {
return (content as? MessageContent)?.inReplyTo
@ -46,10 +45,10 @@ data class EventTimelineItem( @@ -46,10 +45,10 @@ data class EventTimelineItem(
}
}
fun interface EventDebugInfoProvider {
fun get(): TimelineItemDebugInfo
fun interface TimelineItemDebugInfoProvider {
operator fun invoke(): TimelineItemDebugInfo
}
fun interface EventShieldsProvider {
fun getShield(strict: Boolean): MessageShield?
fun interface MessageShieldProvider {
operator fun invoke(strict: Boolean): MessageShield?
}

22
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcPrompt.kt

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only
* Please see LICENSE in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.auth
import io.element.android.libraries.matrix.api.auth.OidcPrompt
import org.matrix.rustcomponents.sdk.OidcPrompt as RustOidcPrompt
internal fun OidcPrompt.toRustPrompt(): RustOidcPrompt {
return when (this) {
OidcPrompt.None -> RustOidcPrompt.None
OidcPrompt.Login -> RustOidcPrompt.Login
OidcPrompt.Consent -> RustOidcPrompt.Consent
OidcPrompt.SelectAccount -> RustOidcPrompt.SelectAccount
OidcPrompt.Create -> RustOidcPrompt.Create
is OidcPrompt.Unknown -> RustOidcPrompt.Unknown(value)
}
}

8
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt

@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.MatrixClient @@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.auth.MatrixHomeServerDetails
import io.element.android.libraries.matrix.api.auth.OidcDetails
import io.element.android.libraries.matrix.api.auth.OidcPrompt
import io.element.android.libraries.matrix.api.auth.external.ExternalSession
import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData
import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep
@ -181,11 +182,14 @@ class RustMatrixAuthenticationService @Inject constructor( @@ -181,11 +182,14 @@ class RustMatrixAuthenticationService @Inject constructor(
private var pendingOidcAuthorizationData: OidcAuthorizationData? = null
override suspend fun getOidcUrl(): Result<OidcDetails> {
override suspend fun getOidcUrl(prompt: OidcPrompt): Result<OidcDetails> {
return withContext(coroutineDispatchers.io) {
runCatching {
val client = currentClient ?: error("You need to call `setHomeserver()` first")
val oidcAuthenticationData = client.urlForOidcLogin(oidcConfigurationProvider.get())
val oidcAuthenticationData = client.urlForOidc(
oidcConfiguration = oidcConfigurationProvider.get(),
prompt = prompt.toRustPrompt(),
)
val url = oidcAuthenticationData.loginUrl()
pendingOidcAuthorizationData = oidcAuthenticationData
OidcDetails(url)

4
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt

@ -63,7 +63,7 @@ class RustMediaLoader( @@ -63,7 +63,7 @@ class RustMediaLoader(
override suspend fun downloadMediaFile(
source: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
useCache: Boolean,
): Result<MediaFile> =
withContext(mediaDispatcher) {
@ -71,7 +71,7 @@ class RustMediaLoader( @@ -71,7 +71,7 @@ class RustMediaLoader(
source.toRustMediaSource().use { mediaSource ->
val mediaFile = innerClient.getMediaFile(
mediaSource = mediaSource,
body = body,
filename = filename,
mimeType = mimeType?.takeIf { MimeTypes.hasSubtype(it) } ?: MimeTypes.OctetStream,
useCache = useCache,
tempDir = cacheDirectory.path,

2
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt

@ -19,6 +19,7 @@ import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper @@ -19,6 +19,7 @@ import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentMap
import org.matrix.rustcomponents.sdk.Membership
import org.matrix.rustcomponents.sdk.RoomHero
import org.matrix.rustcomponents.sdk.Membership as RustMembership
import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo
@ -65,6 +66,7 @@ fun RustMembership.map(): CurrentUserMembership = when (this) { @@ -65,6 +66,7 @@ fun RustMembership.map(): CurrentUserMembership = when (this) {
RustMembership.INVITED -> CurrentUserMembership.INVITED
RustMembership.JOINED -> CurrentUserMembership.JOINED
RustMembership.LEFT -> CurrentUserMembership.LEFT
Membership.KNOCKED -> CurrentUserMembership.KNOCKED
}
fun RustRoomNotificationMode.map(): RoomNotificationMode = when (this) {

21
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt

@ -12,9 +12,7 @@ import io.element.android.libraries.matrix.api.core.EventId @@ -12,9 +12,7 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.matrix.api.timeline.item.event.EventDebugInfoProvider
import io.element.android.libraries.matrix.api.timeline.item.event.EventReaction
import io.element.android.libraries.matrix.api.timeline.item.event.EventShieldsProvider
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
@ -27,12 +25,10 @@ import kotlinx.collections.immutable.persistentListOf @@ -27,12 +25,10 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import org.matrix.rustcomponents.sdk.EventOrTransactionId
import org.matrix.rustcomponents.sdk.EventSendState
import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfoProvider
import org.matrix.rustcomponents.sdk.Reaction
import org.matrix.rustcomponents.sdk.ShieldState
import uniffi.matrix_sdk_common.ShieldStateCode
import org.matrix.rustcomponents.sdk.EventSendState as RustEventSendState
import org.matrix.rustcomponents.sdk.EventShieldsProvider as RustEventShieldsProvider
import org.matrix.rustcomponents.sdk.EventTimelineItem as RustEventTimelineItem
import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfo as RustEventTimelineItemDebugInfo
import org.matrix.rustcomponents.sdk.ProfileDetails as RustProfileDetails
@ -48,7 +44,6 @@ class EventTimelineItemMapper( @@ -48,7 +44,6 @@ class EventTimelineItemMapper(
transactionId = eventOrTransactionId.transactionId(),
isEditable = isEditable,
canBeRepliedTo = canBeRepliedTo,
isLocal = isLocal,
isOwn = isOwn,
isRemote = isRemote,
localSendState = localSendState?.map(),
@ -58,9 +53,9 @@ class EventTimelineItemMapper( @@ -58,9 +53,9 @@ class EventTimelineItemMapper(
senderProfile = senderProfile.map(),
timestamp = timestamp.toLong(),
content = contentMapper.map(content),
debugInfoProvider = RustEventDebugInfoProvider(debugInfoProvider),
origin = origin?.map(),
messageShieldProvider = RustEventShieldsProvider(shieldsProvider)
timelineItemDebugInfoProvider = { lazyProvider.debugInfo().map() },
messageShieldProvider = { strict -> lazyProvider.getShields(strict)?.map() },
)
}
}
@ -168,18 +163,6 @@ private fun ShieldState?.map(): MessageShield? { @@ -168,18 +163,6 @@ private fun ShieldState?.map(): MessageShield? {
}
}
class RustEventDebugInfoProvider(private val debugInfoProvider: EventTimelineItemDebugInfoProvider) : EventDebugInfoProvider {
override fun get(): TimelineItemDebugInfo {
return debugInfoProvider.get().map()
}
}
class RustEventShieldsProvider(private val shieldsProvider: RustEventShieldsProvider) : EventShieldsProvider {
override fun getShield(strict: Boolean): MessageShield? {
return shieldsProvider.getShields(strict)?.map()
}
}
private fun EventOrTransactionId.eventId(): EventId? {
return (this as? EventOrTransactionId.EventId)?.let { EventId(it.eventId) }
}

11
libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt

@ -7,8 +7,7 @@ @@ -7,8 +7,7 @@
package io.element.android.libraries.matrix.impl.fixtures.factories
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustEventShieldsProvider
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustEventTimelineItemDebugInfoProvider
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustLazyTimelineItemProvider
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_USER_ID
import org.matrix.rustcomponents.sdk.EventOrTransactionId
@ -23,7 +22,6 @@ import org.matrix.rustcomponents.sdk.TimelineItemContent @@ -23,7 +22,6 @@ import org.matrix.rustcomponents.sdk.TimelineItemContent
import uniffi.matrix_sdk_ui.EventItemOrigin
fun aRustEventTimelineItem(
isLocal: Boolean = false,
isRemote: Boolean = true,
eventOrTransactionId: EventOrTransactionId = EventOrTransactionId.EventId(AN_EVENT_ID.value),
sender: String = A_USER_ID.value,
@ -40,7 +38,6 @@ fun aRustEventTimelineItem( @@ -40,7 +38,6 @@ fun aRustEventTimelineItem(
canBeRepliedTo: Boolean = true,
shieldsState: ShieldState? = null,
) = EventTimelineItem(
isLocal = isLocal,
isRemote = isRemote,
eventOrTransactionId = eventOrTransactionId,
sender = sender,
@ -50,10 +47,12 @@ fun aRustEventTimelineItem( @@ -50,10 +47,12 @@ fun aRustEventTimelineItem(
isEditable = isEditable,
canBeRepliedTo = canBeRepliedTo,
content = content,
debugInfoProvider = FakeRustEventTimelineItemDebugInfoProvider(debugInfo),
shieldsProvider = FakeRustEventShieldsProvider(shieldsState),
localSendState = localSendState,
reactions = reactions,
readReceipts = readReceipts,
origin = origin,
lazyProvider = FakeRustLazyTimelineItemProvider(
debugInfo = debugInfo,
shieldsState = shieldsState,
)
)

18
libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustEventShieldsProvider.kt

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only
* Please see LICENSE in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.fixtures.fakes
import org.matrix.rustcomponents.sdk.EventShieldsProvider
import org.matrix.rustcomponents.sdk.NoPointer
import org.matrix.rustcomponents.sdk.ShieldState
class FakeRustEventShieldsProvider(
private val shieldsState: ShieldState? = null,
) : EventShieldsProvider(NoPointer) {
override fun getShields(strict: Boolean): ShieldState? = shieldsState
}

11
libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustEventTimelineItemDebugInfoProvider.kt → libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeRustLazyTimelineItemProvider.kt

@ -9,11 +9,14 @@ package io.element.android.libraries.matrix.impl.fixtures.fakes @@ -9,11 +9,14 @@ package io.element.android.libraries.matrix.impl.fixtures.fakes
import io.element.android.libraries.matrix.impl.fixtures.factories.anEventTimelineItemDebugInfo
import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfo
import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfoProvider
import org.matrix.rustcomponents.sdk.LazyTimelineItemProvider
import org.matrix.rustcomponents.sdk.NoPointer
import org.matrix.rustcomponents.sdk.ShieldState
class FakeRustEventTimelineItemDebugInfoProvider(
class FakeRustLazyTimelineItemProvider(
private val debugInfo: EventTimelineItemDebugInfo = anEventTimelineItemDebugInfo(),
) : EventTimelineItemDebugInfoProvider(NoPointer) {
override fun get(): EventTimelineItemDebugInfo = debugInfo
private val shieldsState: ShieldState? = null,
) : LazyTimelineItemProvider(NoPointer) {
override fun getShields(strict: Boolean) = shieldsState
override fun debugInfo() = debugInfo
}

3
libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeMatrixAuthenticationService.kt

@ -11,6 +11,7 @@ import io.element.android.libraries.matrix.api.MatrixClient @@ -11,6 +11,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.auth.MatrixHomeServerDetails
import io.element.android.libraries.matrix.api.auth.OidcDetails
import io.element.android.libraries.matrix.api.auth.OidcPrompt
import io.element.android.libraries.matrix.api.auth.external.ExternalSession
import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData
import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep
@ -80,7 +81,7 @@ class FakeMatrixAuthenticationService( @@ -80,7 +81,7 @@ class FakeMatrixAuthenticationService(
return importCreatedSessionLambda(externalSession)
}
override suspend fun getOidcUrl(): Result<OidcDetails> = simulateLongTask {
override suspend fun getOidcUrl(prompt: OidcPrompt): Result<OidcDetails> = simulateLongTask {
oidcError?.let { Result.failure(it) } ?: Result.success(A_OIDC_DATA)
}

2
libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/media/FakeMatrixMediaLoader.kt

@ -35,7 +35,7 @@ class FakeMatrixMediaLoader : MatrixMediaLoader { @@ -35,7 +35,7 @@ class FakeMatrixMediaLoader : MatrixMediaLoader {
override suspend fun downloadMediaFile(
source: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
useCache: Boolean,
): Result<MediaFile> = simulateLongTask {
if (shouldFail) {

4
libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt

@ -42,7 +42,6 @@ fun anEventTimelineItem( @@ -42,7 +42,6 @@ fun anEventTimelineItem(
transactionId: TransactionId? = null,
isEditable: Boolean = false,
canBeRepliedTo: Boolean = false,
isLocal: Boolean = false,
isOwn: Boolean = false,
isRemote: Boolean = false,
localSendState: LocalEventSendState? = null,
@ -59,7 +58,6 @@ fun anEventTimelineItem( @@ -59,7 +58,6 @@ fun anEventTimelineItem(
transactionId = transactionId,
isEditable = isEditable,
canBeRepliedTo = canBeRepliedTo,
isLocal = isLocal,
isOwn = isOwn,
isRemote = isRemote,
localSendState = localSendState,
@ -69,8 +67,8 @@ fun anEventTimelineItem( @@ -69,8 +67,8 @@ fun anEventTimelineItem(
senderProfile = senderProfile,
timestamp = timestamp,
content = content,
debugInfoProvider = { debugInfo },
origin = null,
timelineItemDebugInfoProvider = { debugInfo },
messageShieldProvider = { messageShield },
)

2
libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerPresenter.kt

@ -92,7 +92,7 @@ class MediaViewerPresenter @AssistedInject constructor( @@ -92,7 +92,7 @@ class MediaViewerPresenter @AssistedInject constructor(
mediaLoader.downloadMediaFile(
source = inputs.mediaSource,
mimeType = inputs.mediaInfo.mimeType,
body = inputs.mediaInfo.filename
filename = inputs.mediaInfo.filename
)
.onSuccess {
mediaFile.value = it

2
libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt

@ -299,7 +299,7 @@ class DefaultNotifiableEventResolver @Inject constructor( @@ -299,7 +299,7 @@ class DefaultNotifiableEventResolver @Inject constructor(
.getMediaFile(
mediaSource = messageType.source,
mimeType = messageType.info?.mimetype,
body = messageType.filename,
filename = messageType.filename,
)
is VideoMessageType -> null // Use the thumbnail here?
else -> null

8
libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationMediaRepo.kt

@ -47,13 +47,13 @@ interface NotificationMediaRepo { @@ -47,13 +47,13 @@ interface NotificationMediaRepo {
*
* @param mediaSource the media source of the media.
* @param mimeType the mime type of the media.
* @param body optional body which will be used to name the file.
* @param filename optional String which will be used to name the file.
* @return A [Result] holding either the media [File] from the cache directory or an [Exception].
*/
suspend fun getMediaFile(
mediaSource: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
): Result<File>
}
@ -75,7 +75,7 @@ class DefaultNotificationMediaRepo @AssistedInject constructor( @@ -75,7 +75,7 @@ class DefaultNotificationMediaRepo @AssistedInject constructor(
override suspend fun getMediaFile(
mediaSource: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
): Result<File> {
val cachedFile = mediaSource.cachedFile()
return when {
@ -84,7 +84,7 @@ class DefaultNotificationMediaRepo @AssistedInject constructor( @@ -84,7 +84,7 @@ class DefaultNotificationMediaRepo @AssistedInject constructor(
else -> matrixMediaLoader.downloadMediaFile(
source = mediaSource,
mimeType = mimeType,
body = body,
filename = filename,
).mapCatching {
it.use { mediaFile ->
val dest = cachedFile.apply { parentFile?.mkdirs() }

2
libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationMediaRepo.kt

@ -15,7 +15,7 @@ class FakeNotificationMediaRepo : NotificationMediaRepo { @@ -15,7 +15,7 @@ class FakeNotificationMediaRepo : NotificationMediaRepo {
override suspend fun getMediaFile(
mediaSource: MediaSource,
mimeType: String?,
body: String?,
filename: String?,
): Result<File> {
return Result.failure(IllegalStateException("Fake class"))
}

Loading…
Cancel
Save