computing the image size before sending to allow it to be used in local echos

- fixes local echo images changing size
This commit is contained in:
Adam Brown 2022-10-01 12:22:19 +01:00 committed by Adam Brown
parent aa813fe67a
commit 03cb954ea8
8 changed files with 46 additions and 11 deletions

View File

@ -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()),

View File

@ -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),
)
}
}

View File

@ -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 {

View File

@ -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<MessengerScreenState> = defaultStateFactory(),
) : DapkViewModel<MessengerScreenState, MessengerEvent>(
@ -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(),

View File

@ -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()

View File

@ -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,
)
}
}
}

View File

@ -59,7 +59,7 @@ internal class SendMessageUseCase(
}
private suspend fun imageMessageRequest(message: Message.ImageMessage): HttpRequest<ApiSendResponse> {
val imageMeta = imageContentReader.meta(message.content.uri)
val imageMeta = message.content.meta
return when (message.sendEncrypted) {
true -> {

View File

@ -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,