diff --git a/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt b/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt index f424c2b..0732e31 100644 --- a/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt +++ b/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt @@ -93,7 +93,9 @@ internal class AppModule(context: Application, logger: MatrixLogger) { private val workModule = WorkModule(context) private val imageLoaderModule = ImageLoaderModule(context) - private val matrixModules = MatrixModules(storeModule, trackingModule, workModule, logger, coroutineDispatchers, context.contentResolver, base64, buildMeta) + private val imageContentReader by unsafeLazy { AndroidImageContentReader(context.contentResolver) } + private val matrixModules = MatrixModules(storeModule, trackingModule, workModule, logger, coroutineDispatchers, imageContentReader, base64, buildMeta) + val domainModules = DomainModules(matrixModules, trackingModule.errorTracker, workModule, storeModule, context, coroutineDispatchers) val coreAndroidModule = CoreAndroidModule( @@ -133,6 +135,7 @@ internal class AppModule(context: Application, logger: MatrixLogger) { trackingModule, coreAndroidModule, imageLoaderModule, + imageContentReader, context, buildMeta, deviceMeta, @@ -149,6 +152,7 @@ internal class FeatureModules internal constructor( private val trackingModule: TrackingModule, private val coreAndroidModule: CoreAndroidModule, imageLoaderModule: ImageLoaderModule, + imageContentReader: ImageContentReader, context: Context, buildMeta: BuildMeta, deviceMeta: DeviceMeta, @@ -185,6 +189,7 @@ internal class FeatureModules internal constructor( clock, context, base64, + imageContentReader, ) } val homeModule by unsafeLazy { HomeModule(storeModule.value, matrixModules.profile, matrixModules.sync, buildMeta) } @@ -238,7 +243,7 @@ internal class MatrixModules( private val workModule: WorkModule, private val logger: MatrixLogger, private val coroutineDispatchers: CoroutineDispatchers, - private val contentResolver: ContentResolver, + private val imageContentReader: ImageContentReader, private val base64: Base64, private val buildMeta: BuildMeta, ) { @@ -280,7 +285,6 @@ internal class MatrixModules( base64 = base64, coroutineDispatchers = coroutineDispatchers, ) - val imageContentReader = AndroidImageContentReader(contentResolver) installMessageService( store.localEchoStore, BackgroundWorkAdapter(workModule.workScheduler()), diff --git a/features/messenger/src/main/kotlin/app/dapk/st/messenger/LocalEchoMapper.kt b/features/messenger/src/main/kotlin/app/dapk/st/messenger/LocalEchoMapper.kt index e65bb0d..8fc2fa7 100644 --- a/features/messenger/src/main/kotlin/app/dapk/st/messenger/LocalEchoMapper.kt +++ b/features/messenger/src/main/kotlin/app/dapk/st/messenger/LocalEchoMapper.kt @@ -39,7 +39,7 @@ internal class LocalEchoMapper(private val metaMapper: MetaMapper) { author = member, utcTimestamp = message.timestampUtc, meta = metaMapper.toMeta(this), - imageMeta = RoomEvent.Image.ImageMeta(100, 100, message.content.uri, null), + imageMeta = RoomEvent.Image.ImageMeta(message.content.meta.width, message.content.meta.height, message.content.uri, null), ) } } diff --git a/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerModule.kt b/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerModule.kt index 90446f9..4caff56 100644 --- a/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerModule.kt +++ b/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerModule.kt @@ -6,6 +6,7 @@ import app.dapk.st.core.ProvidableModule import app.dapk.st.matrix.common.CredentialsStore import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.message.MessageService +import app.dapk.st.matrix.message.internal.ImageContentReader import app.dapk.st.matrix.room.RoomService import app.dapk.st.matrix.sync.RoomStore import app.dapk.st.matrix.sync.SyncService @@ -20,10 +21,11 @@ class MessengerModule( private val clock: Clock, private val context: Context, private val base64: Base64, + private val imageMetaReader: ImageContentReader, ) : ProvidableModule { internal fun messengerViewModel(): MessengerViewModel { - return MessengerViewModel(messageService, roomService, roomStore, credentialsStore, timelineUseCase(), LocalIdFactory(), clock) + return MessengerViewModel(messageService, roomService, roomStore, credentialsStore, timelineUseCase(), LocalIdFactory(), imageMetaReader, clock) } private fun timelineUseCase(): TimelineUseCaseImpl { diff --git a/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerViewModel.kt b/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerViewModel.kt index e01b55a..4ba6163 100644 --- a/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerViewModel.kt +++ b/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerViewModel.kt @@ -8,6 +8,7 @@ import app.dapk.st.matrix.common.EventId import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.common.UserId import app.dapk.st.matrix.message.MessageService +import app.dapk.st.matrix.message.internal.ImageContentReader import app.dapk.st.matrix.room.RoomService import app.dapk.st.matrix.sync.RoomEvent import app.dapk.st.matrix.sync.RoomStore @@ -28,6 +29,7 @@ internal class MessengerViewModel( private val credentialsStore: CredentialsStore, private val observeTimeline: ObserveTimelineUseCase, private val localIdFactory: LocalIdFactory, + private val imageContentReader: ImageContentReader, private val clock: Clock, factory: MutableStateFactory = defaultStateFactory(), ) : DapkViewModel( @@ -147,9 +149,20 @@ internal class MessengerViewModel( state.roomState.takeIfContent()?.let { content -> val roomState = content.roomState viewModelScope.launch { + val imageUri = copy.values.first().uri.value + val meta = imageContentReader.meta(imageUri) + messageService.scheduleMessage( MessageService.Message.ImageMessage( - MessageService.Message.Content.ApiImageContent(uri = copy.values.first().uri.value), + MessageService.Message.Content.ImageContent( + uri = imageUri, MessageService.Message.Content.ImageContent.Meta( + height = meta.height, + width = meta.width, + size = meta.size, + fileName = meta.fileName, + mimeType = meta.mimeType, + ) + ), roomId = roomState.roomOverview.roomId, sendEncrypted = roomState.roomOverview.isEncrypted, localId = localIdFactory.create(), diff --git a/features/messenger/src/test/kotlin/app/dapk/st/messenger/MessengerViewModelTest.kt b/features/messenger/src/test/kotlin/app/dapk/st/messenger/MessengerViewModelTest.kt index d05bee3..2ce7567 100644 --- a/features/messenger/src/test/kotlin/app/dapk/st/messenger/MessengerViewModelTest.kt +++ b/features/messenger/src/test/kotlin/app/dapk/st/messenger/MessengerViewModelTest.kt @@ -6,6 +6,7 @@ import app.dapk.st.matrix.common.EventId import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.common.UserId import app.dapk.st.matrix.message.MessageService +import app.dapk.st.matrix.message.internal.ImageContentReader import app.dapk.st.matrix.room.RoomService import app.dapk.st.matrix.sync.RoomState import app.dapk.st.matrix.sync.SyncService @@ -47,6 +48,7 @@ class MessengerViewModelTest { fakeCredentialsStore, fakeObserveTimelineUseCase, localIdFactory = FakeLocalIdFactory().also { it.givenCreate().returns(A_LOCAL_ID) }.instance, + imageContentReader = FakeImageContentReader(), clock = fixedClock(A_CURRENT_TIMESTAMP), factory = runViewModelTest.testMutableStateFactory(), ) @@ -150,3 +152,5 @@ class FakeRoomService : RoomService by mockk() { } fun fixedClock(timestamp: Long = 0) = Clock.fixed(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC) + +class FakeImageContentReader: ImageContentReader by mockk() \ No newline at end of file diff --git a/matrix/services/message/src/main/kotlin/app/dapk/st/matrix/message/MessageService.kt b/matrix/services/message/src/main/kotlin/app/dapk/st/matrix/message/MessageService.kt index 475ae1f..94ee5a9 100644 --- a/matrix/services/message/src/main/kotlin/app/dapk/st/matrix/message/MessageService.kt +++ b/matrix/services/message/src/main/kotlin/app/dapk/st/matrix/message/MessageService.kt @@ -54,7 +54,7 @@ interface MessageService : MatrixService { @Serializable @SerialName("image_message") data class ImageMessage( - @SerialName("content") val content: Content.ApiImageContent, + @SerialName("content") val content: Content.ImageContent, @SerialName("send_encrypted") val sendEncrypted: Boolean, @SerialName("room_id") val roomId: RoomId, @SerialName("local_id") val localId: String, @@ -70,9 +70,21 @@ interface MessageService : MatrixService { ) : Content() @Serializable - data class ApiImageContent( + data class ImageContent( @SerialName("uri") val uri: String, - ) : Content() + @SerialName("meta") val meta: Meta, + ) : Content() { + + @Serializable + data class Meta( + val height: Int, + val width: Int, + val size: Long, + val fileName: String, + val mimeType: String, + ) + + } } } diff --git a/matrix/services/message/src/main/kotlin/app/dapk/st/matrix/message/internal/SendMessageUseCase.kt b/matrix/services/message/src/main/kotlin/app/dapk/st/matrix/message/internal/SendMessageUseCase.kt index 385fffb..0703d8d 100644 --- a/matrix/services/message/src/main/kotlin/app/dapk/st/matrix/message/internal/SendMessageUseCase.kt +++ b/matrix/services/message/src/main/kotlin/app/dapk/st/matrix/message/internal/SendMessageUseCase.kt @@ -59,7 +59,7 @@ internal class SendMessageUseCase( } private suspend fun imageMessageRequest(message: Message.ImageMessage): HttpRequest { - val imageMeta = imageContentReader.meta(message.content.uri) + val imageMeta = message.content.meta return when (message.sendEncrypted) { true -> { diff --git a/test-harness/src/test/kotlin/test/Test.kt b/test-harness/src/test/kotlin/test/Test.kt index 08b4e4c..222b06e 100644 --- a/test-harness/src/test/kotlin/test/Test.kt +++ b/test-harness/src/test/kotlin/test/Test.kt @@ -183,7 +183,7 @@ class MatrixTestScope(private val testScope: TestScope) { println("sending ${file.name}") this.client.messageService().scheduleMessage( MessageService.Message.ImageMessage( - content = MessageService.Message.Content.ApiImageContent( + content = MessageService.Message.Content.ImageContent( uri = file.absolutePath, ), roomId = roomId,