mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-19 08:09:12 +01:00
Move GlideImage into the glide module.
This commit is contained in:
committed by
Alex Hart
parent
2f6baf8743
commit
986923ea6c
@@ -52,13 +52,13 @@ import androidx.compose.ui.viewinterop.AndroidView
|
||||
import org.signal.core.ui.compose.Buttons
|
||||
import org.signal.core.ui.compose.NightPreview
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.glide.compose.GlideImage
|
||||
import org.signal.glide.compose.GlideImageScaleType
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.avatar.AvatarImage
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.BadgeImageLarge
|
||||
import org.thoughtcrime.securesms.components.webrtc.TextureViewRenderer
|
||||
import org.thoughtcrime.securesms.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.compose.GlideImageScaleType
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto
|
||||
import org.thoughtcrime.securesms.events.CallParticipant
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
||||
@@ -37,9 +37,9 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.signal.core.ui.compose.NightPreview
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.glide.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.avatar.AvatarImage
|
||||
import org.thoughtcrime.securesms.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
||||
private val textShadow = Shadow(
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.compose
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.widget.ImageView
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.DisposableEffectResult
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.TransitionOptions
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
||||
import org.thoughtcrime.securesms.glide.cache.ApngOptions
|
||||
|
||||
/**
|
||||
* Our very own GlideImage. The GlideImage composable provided by the bumptech library is not suitable because it was is using our encrypted cache decoder/encoder.
|
||||
*/
|
||||
@Composable
|
||||
fun <T> GlideImage(
|
||||
modifier: Modifier = Modifier,
|
||||
model: T?,
|
||||
imageSize: DpSize? = null,
|
||||
scaleType: GlideImageScaleType = GlideImageScaleType.FIT_CENTER,
|
||||
fallback: Drawable? = null,
|
||||
error: Drawable? = fallback,
|
||||
transition: TransitionOptions<*, Drawable>? = null,
|
||||
diskCacheStrategy: DiskCacheStrategy = DiskCacheStrategy.ALL,
|
||||
enableApngAnimation: Boolean = false
|
||||
) {
|
||||
if (enableApngAnimation) {
|
||||
val density = LocalDensity.current
|
||||
|
||||
AndroidView(
|
||||
factory = { context -> ImageView(context) },
|
||||
update = { imageView ->
|
||||
Glide.with(imageView.context)
|
||||
.load(model)
|
||||
.fallback(fallback)
|
||||
.error(error)
|
||||
.diskCacheStrategy(diskCacheStrategy)
|
||||
.set(ApngOptions.ANIMATE, enableApngAnimation)
|
||||
.apply {
|
||||
scaleType.applyTo(this)
|
||||
transition?.let(this::transition)
|
||||
|
||||
if (imageSize != null) {
|
||||
with(density) {
|
||||
this@apply.override(imageSize.width.toPx().toInt(), imageSize.height.toPx().toInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
.into(imageView)
|
||||
},
|
||||
modifier = modifier
|
||||
)
|
||||
} else {
|
||||
GlideImage(
|
||||
model = model,
|
||||
imageSize = imageSize,
|
||||
scaleType = scaleType,
|
||||
fallback = fallback,
|
||||
error = error,
|
||||
transition = transition,
|
||||
diskCacheStrategy = diskCacheStrategy,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun <T> GlideImage(
|
||||
modifier: Modifier = Modifier,
|
||||
model: T?,
|
||||
imageSize: DpSize? = null,
|
||||
scaleType: GlideImageScaleType = GlideImageScaleType.FIT_CENTER,
|
||||
fallback: Drawable? = null,
|
||||
error: Drawable? = fallback,
|
||||
transition: TransitionOptions<*, Drawable>? = null,
|
||||
diskCacheStrategy: DiskCacheStrategy = DiskCacheStrategy.ALL
|
||||
) {
|
||||
var drawable by remember {
|
||||
mutableStateOf<Drawable?>(null)
|
||||
}
|
||||
|
||||
val target = remember {
|
||||
object : CustomTarget<Drawable>() {
|
||||
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
|
||||
drawable = resource
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
drawable = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val density = LocalDensity.current
|
||||
val context = LocalContext.current
|
||||
DisposableEffect(model, fallback, error, diskCacheStrategy, density, imageSize) {
|
||||
val requestManager = Glide.with(context)
|
||||
val builder = requestManager
|
||||
.load(model)
|
||||
.fallback(fallback)
|
||||
.error(error)
|
||||
.diskCacheStrategy(diskCacheStrategy)
|
||||
.apply {
|
||||
scaleType.applyTo(this)
|
||||
transition?.let(this::transition)
|
||||
}
|
||||
|
||||
if (imageSize != null) {
|
||||
with(density) {
|
||||
builder.override(imageSize.width.toPx().toInt(), imageSize.height.toPx().toInt()).into(target)
|
||||
}
|
||||
} else {
|
||||
builder.into(target)
|
||||
}
|
||||
|
||||
object : DisposableEffectResult {
|
||||
override fun dispose() {
|
||||
requestManager.clear(target)
|
||||
drawable = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (drawable != null) {
|
||||
Image(
|
||||
painter = rememberDrawablePainter(drawable),
|
||||
contentDescription = null,
|
||||
contentScale = if (model == null) ContentScale.Inside else ContentScale.Crop,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
enum class GlideImageScaleType {
|
||||
/** @see [com.bumptech.glide.request.RequestOptions.fitCenter] */
|
||||
FIT_CENTER,
|
||||
|
||||
/** @see [com.bumptech.glide.request.RequestOptions.centerInside] */
|
||||
CENTER_INSIDE,
|
||||
|
||||
/** @see [com.bumptech.glide.request.RequestOptions.centerCrop] */
|
||||
CENTER_CROP,
|
||||
|
||||
/** @see [com.bumptech.glide.request.RequestOptions.circleCrop] */
|
||||
CIRCLE_CROP;
|
||||
|
||||
fun <TranscodeT> applyTo(builder: com.bumptech.glide.RequestBuilder<TranscodeT>): com.bumptech.glide.RequestBuilder<TranscodeT> {
|
||||
return when (this) {
|
||||
FIT_CENTER -> builder.fitCenter()
|
||||
CENTER_INSIDE -> builder.centerInside()
|
||||
CENTER_CROP -> builder.centerCrop()
|
||||
CIRCLE_CROP -> builder.circleCrop()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,9 +48,9 @@ import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import org.signal.core.ui.compose.DropdownMenus
|
||||
import org.signal.core.ui.compose.theme.SignalTheme
|
||||
import org.signal.glide.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
import org.thoughtcrime.securesms.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.conversation.ConversationMessage
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package org.thoughtcrime.securesms.glide.cache;
|
||||
|
||||
import com.bumptech.glide.load.Option;
|
||||
|
||||
import org.signal.core.util.Conversions;
|
||||
|
||||
/**
|
||||
* Holds options that can be used to alter how APNGs are decoded in Glide.
|
||||
*/
|
||||
public final class ApngOptions {
|
||||
|
||||
private static final String KEY = "org.signal.skip_apng";
|
||||
|
||||
public static Option<Boolean> ANIMATE = Option.disk(KEY, true, (keyBytes, value, messageDigest) -> {
|
||||
messageDigest.update(keyBytes);
|
||||
messageDigest.update(Conversions.intToByteArray(value ? 1 : 0));
|
||||
});
|
||||
|
||||
private ApngOptions() {}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
|
||||
import org.signal.glide.apng.ApngOptions;
|
||||
import org.signal.glide.common.io.ByteBufferReader;
|
||||
import org.signal.glide.common.loader.ByteBufferLoader;
|
||||
import org.signal.glide.common.loader.Loader;
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
|
||||
import org.signal.core.util.StreamUtil;
|
||||
import org.signal.glide.apng.ApngOptions;
|
||||
import org.signal.glide.common.io.StreamReader;
|
||||
import org.signal.glide.load.resource.apng.decode.APNGDecoder;
|
||||
import org.signal.glide.load.resource.apng.decode.APNGParser;
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.bumptech.glide.load.Options
|
||||
import com.bumptech.glide.load.ResourceDecoder
|
||||
import com.bumptech.glide.load.engine.Resource
|
||||
import org.signal.core.util.StreamUtil
|
||||
import org.signal.glide.apng.ApngOptions
|
||||
import org.signal.glide.common.io.InputStreamFactory
|
||||
import org.signal.glide.load.ImageHeaderParserUtils
|
||||
import org.signal.glide.load.resource.apng.decode.APNGDecoder
|
||||
|
||||
@@ -6,9 +6,9 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.bumptech.glide.RequestManager
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import org.signal.glide.apng.ApngOptions
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.database.model.StickerRecord
|
||||
import org.thoughtcrime.securesms.glide.cache.ApngOptions
|
||||
import org.thoughtcrime.securesms.mms.DecryptableUri
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
|
||||
@@ -5,8 +5,8 @@ import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.core.widget.ImageViewCompat
|
||||
import com.bumptech.glide.RequestManager
|
||||
import org.signal.glide.apng.ApngOptions
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.glide.cache.ApngOptions
|
||||
import org.thoughtcrime.securesms.mms.DecryptableUri
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
|
||||
@@ -36,11 +36,11 @@ import org.signal.core.ui.compose.DropdownMenus
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.theme.SignalTheme
|
||||
import org.signal.core.util.nullIfBlank
|
||||
import org.signal.glide.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.compose.RoundCheckbox
|
||||
import org.thoughtcrime.securesms.components.transfercontrols.TransferProgressIndicator
|
||||
import org.thoughtcrime.securesms.components.transfercontrols.TransferProgressState
|
||||
import org.thoughtcrime.securesms.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.mms.DecryptableUri
|
||||
import org.thoughtcrime.securesms.stickers.StickerPreviewDataFactory
|
||||
import org.thoughtcrime.securesms.stickers.manage.AvailableStickerPack.DownloadStatus
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.thoughtcrime.securesms.PassphraseRequiredActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment;
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs;
|
||||
import org.thoughtcrime.securesms.glide.cache.ApngOptions;
|
||||
import org.signal.glide.apng.ApngOptions;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.sharing.MultiShareArgs;
|
||||
import org.thoughtcrime.securesms.stickers.StickerManifest;
|
||||
|
||||
@@ -54,9 +54,9 @@ import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.Scaffolds
|
||||
import org.signal.core.util.orNull
|
||||
import org.signal.core.util.toOptional
|
||||
import org.signal.glide.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.compose.GlideImage
|
||||
import org.thoughtcrime.securesms.compose.SignalTheme
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.bumptech.glide.RequestManager;
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.glide.cache.ApngOptions;
|
||||
import org.signal.glide.apng.ApngOptions;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.stickers.StickerManifest;
|
||||
import org.thoughtcrime.securesms.stickers.StickerRemoteUri;
|
||||
|
||||
Reference in New Issue
Block a user