diff --git a/design-library/src/main/kotlin/app/dapk/st/design/components/Icon.kt b/design-library/src/main/kotlin/app/dapk/st/design/components/Icon.kt index 8db9a78..93f9529 100644 --- a/design-library/src/main/kotlin/app/dapk/st/design/components/Icon.kt +++ b/design-library/src/main/kotlin/app/dapk/st/design/components/Icon.kt @@ -10,12 +10,14 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.ExperimentalUnitApi import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.TextUnitType -import coil.compose.rememberImagePainter +import coil.compose.rememberAsyncImagePainter +import coil.request.ImageRequest import coil.transform.CircleCropTransformation @OptIn(ExperimentalUnitApi::class) @@ -25,7 +27,8 @@ fun BoxScope.CircleishAvatar(avatarUrl: String?, fallbackLabel: String, size: Dp null -> { val colors = SmallTalkTheme.extendedColors.getMissingImageColor(fallbackLabel) Box( - Modifier.align(Alignment.Center) + Modifier + .align(Alignment.Center) .background(color = colors.first, shape = CircleShape) .size(size), contentAlignment = Alignment.Center @@ -40,14 +43,16 @@ fun BoxScope.CircleishAvatar(avatarUrl: String?, fallbackLabel: String, size: Dp } else -> { Image( - painter = rememberImagePainter( - data = avatarUrl, - builder = { - transformations(CircleCropTransformation()) - } + painter = rememberAsyncImagePainter( + model = ImageRequest.Builder(LocalContext.current) + .data(avatarUrl) + .transformations(CircleCropTransformation()) + .build() ), contentDescription = null, - modifier = Modifier.size(size).align(Alignment.Center) + modifier = Modifier + .size(size) + .align(Alignment.Center) ) } } @@ -56,7 +61,11 @@ fun BoxScope.CircleishAvatar(avatarUrl: String?, fallbackLabel: String, size: Dp @Composable fun MissingAvatarIcon(displayName: String, displayImageSize: Dp) { val colors = SmallTalkTheme.extendedColors.getMissingImageColor(displayName) - Box(Modifier.background(color = colors.first, shape = CircleShape).size(displayImageSize), contentAlignment = Alignment.Center) { + Box( + Modifier + .background(color = colors.first, shape = CircleShape) + .size(displayImageSize), contentAlignment = Alignment.Center + ) { Text( text = (displayName).first().toString().uppercase(), color = colors.second @@ -67,11 +76,11 @@ fun MissingAvatarIcon(displayName: String, displayImageSize: Dp) { @Composable fun MessengerUrlIcon(avatarUrl: String, displayImageSize: Dp) { Image( - painter = rememberImagePainter( - data = avatarUrl, - builder = { - transformations(CircleCropTransformation()) - } + painter = rememberAsyncImagePainter( + model = ImageRequest.Builder(LocalContext.current) + .data(avatarUrl) + .transformations(CircleCropTransformation()) + .build() ), contentDescription = null, modifier = Modifier.size(displayImageSize) diff --git a/features/messenger/src/main/kotlin/app/dapk/st/messenger/DecryptingFetcher.kt b/features/messenger/src/main/kotlin/app/dapk/st/messenger/DecryptingFetcher.kt index 0907592..0c89d90 100644 --- a/features/messenger/src/main/kotlin/app/dapk/st/messenger/DecryptingFetcher.kt +++ b/features/messenger/src/main/kotlin/app/dapk/st/messenger/DecryptingFetcher.kt @@ -1,14 +1,15 @@ package app.dapk.st.messenger +import android.content.Context import android.util.Base64 import app.dapk.st.matrix.sync.RoomEvent -import coil.bitmap.BitmapPool +import coil.ImageLoader import coil.decode.DataSource -import coil.decode.Options +import coil.decode.ImageSource import coil.fetch.FetchResult import coil.fetch.Fetcher import coil.fetch.SourceResult -import coil.size.Size +import coil.request.Options import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response @@ -23,18 +24,23 @@ private const val CIPHER_ALGORITHM = "AES/CTR/NoPadding" private const val SECRET_KEY_SPEC_ALGORITHM = "AES" private const val MESSAGE_DIGEST_ALGORITHM = "SHA-256" -class DecryptingFetcher : Fetcher { +class DecryptingFetcherFactory(private val context: Context) : Fetcher.Factory { + override fun create(data: RoomEvent.Image, options: Options, imageLoader: ImageLoader): Fetcher { + return DecryptingFetcher(data, context) + } +} - private val http = OkHttpClient() +private val http = OkHttpClient() - override suspend fun fetch(pool: BitmapPool, data: RoomEvent.Image, size: Size, options: Options): FetchResult { +class DecryptingFetcher(private val data: RoomEvent.Image, private val context: Context) : Fetcher { + + override suspend fun fetch(): FetchResult { val response = http.newCall(Request.Builder().url(data.imageMeta.url).build()).execute() val outputStream = when { data.imageMeta.keys != null -> handleEncrypted(response, data.imageMeta.keys!!) - else -> response.body()?.source() ?: throw IllegalArgumentException("No bitmap response found") + else -> response.body?.source() ?: throw IllegalArgumentException("No bitmap response found") } - - return SourceResult(outputStream, null, DataSource.NETWORK) + return SourceResult(ImageSource(outputStream, context), null, DataSource.NETWORK) } private fun handleEncrypted(response: Response, keys: RoomEvent.Image.ImageMeta.Keys): Buffer { @@ -53,7 +59,7 @@ class DecryptingFetcher : Fetcher { var decodedBytes: ByteArray val outputStream = Buffer() - response.body()?.let { + response.body?.let { it.byteStream().use { read = it.read(d) while (read != -1) { @@ -66,7 +72,4 @@ class DecryptingFetcher : Fetcher { } return outputStream } - - override fun key(data: RoomEvent.Image) = data.imageMeta.url - } \ No newline at end of file diff --git a/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerScreen.kt b/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerScreen.kt index 3296678..4018eca 100644 --- a/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerScreen.kt +++ b/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerScreen.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.* @@ -37,7 +38,8 @@ import app.dapk.st.matrix.sync.RoomEvent import app.dapk.st.matrix.sync.RoomEvent.Message import app.dapk.st.matrix.sync.RoomState import app.dapk.st.navigator.Navigator -import coil.compose.rememberImagePainter +import coil.compose.rememberAsyncImagePainter +import coil.request.ImageRequest import kotlinx.coroutines.launch @Composable @@ -212,8 +214,6 @@ private fun LazyItemScope.AlignedBubble( } } -private val decryptingFetcher = DecryptingFetcher() - @Composable private fun MessageImage(content: BubbleContent) { Box(modifier = Modifier.padding(start = 6.dp)) { @@ -242,9 +242,11 @@ private fun MessageImage(content: BubbleContent) { Spacer(modifier = Modifier.height(4.dp)) Image( modifier = Modifier.size(content.message.imageMeta.scale(LocalDensity.current, LocalConfiguration.current)), - painter = rememberImagePainter( - data = content.message, - builder = { fetcher(decryptingFetcher) } + painter = rememberAsyncImagePainter( + model = ImageRequest.Builder(LocalContext.current) + .fetcherFactory(DecryptingFetcherFactory(LocalContext.current)) + .data(content.message) + .build() ), contentDescription = null, ) @@ -410,9 +412,11 @@ private fun ReplyBubbleContent(content: BubbleContent) { Spacer(modifier = Modifier.height(4.dp)) Image( modifier = Modifier.size(replyingTo.imageMeta.scale(LocalDensity.current, LocalConfiguration.current)), - painter = rememberImagePainter( - data = replyingTo, - builder = { fetcher(DecryptingFetcher()) } + painter = rememberAsyncImagePainter( + model = ImageRequest.Builder(LocalContext.current) + .fetcherFactory(DecryptingFetcherFactory(LocalContext.current)) + .data(replyingTo) + .build() ), contentDescription = null, ) @@ -445,9 +449,11 @@ private fun ReplyBubbleContent(content: BubbleContent) { Spacer(modifier = Modifier.height(4.dp)) Image( modifier = Modifier.size(message.imageMeta.scale(LocalDensity.current, LocalConfiguration.current)), - painter = rememberImagePainter( - data = content.message, - builder = { fetcher(DecryptingFetcher()) } + painter = rememberAsyncImagePainter( + model = ImageRequest.Builder(LocalContext.current) + .data(content.message) + .fetcherFactory(DecryptingFetcherFactory(LocalContext.current)) + .build() ), contentDescription = null, ) diff --git a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt index f6371e9..7dbb2a3 100644 --- a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt +++ b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt @@ -154,11 +154,10 @@ private fun RoomInvite.inviterName() = this.from.displayName?.let { "$it (${this @Composable private fun ProfileViewModel.ObserveEvents() { - val context = LocalContext.current - StartObserving { - this@ObserveEvents.events.launch { - when (it) { - } - } - } +// StartObserving { +// this@ObserveEvents.events.launch { +// when (it) { +// } +// } +// } } \ No newline at end of file