diff --git a/build.gradle b/build.gradle index 8962660e6..26c48267f 100644 --- a/build.gradle +++ b/build.gradle @@ -77,9 +77,9 @@ subprojects { Chameleon : '0.9.28', UniqR : '0.9.4', SQLiteQB : '0.9.15', - Glide : '3.7.0', - GlideOkHttp3 : '1.4.0', - GlideTransformations : '2.0.2', + Glide : '4.11.0', + GlideOkHttp3 : '4.11.0', + GlideTransformations : '4.1.0', AndroidImageCropper : '2.4.6', ExportablePreferences: '0.9.7', ACRA : '4.9.2', diff --git a/twidere/build.gradle b/twidere/build.gradle index 0de070290..82a3adfa0 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -253,6 +253,7 @@ dependencies { implementation "com.google.android.exoplayer:exoplayer:${libVersions['Exoplayer']}" implementation "com.google.android.exoplayer:extension-okhttp:${libVersions['Exoplayer']}" implementation "com.github.bumptech.glide:glide:${libVersions['Glide']}" + kapt "com.github.bumptech.glide:compiler:${libVersions['Glide']}" implementation "com.github.bumptech.glide:okhttp3-integration:${libVersions['GlideOkHttp3']}@aar" implementation "jp.wasabeef:glide-transformations:${libVersions['GlideTransformations']}" implementation "com.theartofdev.edmodo:android-image-cropper:${libVersions['AndroidImageCropper']}" diff --git a/twidere/proguard-rules.pro b/twidere/proguard-rules.pro index 790064f42..95440a3fa 100644 --- a/twidere/proguard-rules.pro +++ b/twidere/proguard-rules.pro @@ -74,7 +74,16 @@ } # https://github.com/bumptech/glide --keep class * extends com.bumptech.glide.module.GlideModule +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public class * extends com.bumptech.glide.module.AppGlideModule +-keep public enum com.bumptech.glide.load.ImageHeaderParser$** { + **[] $VALUES; + public *; +} + +# for DexGuard only +-keepresourcexmlelements manifest/application/meta-data@value=GlideModule + # Essential components -keep class * extends org.mariotaku.twidere.util.Analyzer diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt index d9dd6e598..92f675f62 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt @@ -858,7 +858,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener accountsCount.setText(null) if (displayDoneIcon) { - Glide.clear(accountProfileImage) + Glide.with(this).clear(accountProfileImage) accountProfileImage.setColorFilter(ThemeUtils.getColorFromAttribute(this, android.R.attr.colorForeground)) accountProfileImage.scaleType = ImageView.ScaleType.CENTER_INSIDE @@ -874,7 +874,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener } else { accountsCount.setText(accounts.size.toString()) - Glide.clear(accountProfileImage) + Glide.with(this).clear(accountProfileImage) if (displayDoneIcon) { accountProfileImage.setColorFilter(ThemeUtils.getColorFromAttribute(this, android.R.attr.colorForeground)) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/GlideExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/GlideExtensions.kt index 4af2191c3..7bff836d4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/GlideExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/GlideExtensions.kt @@ -20,11 +20,10 @@ package org.mariotaku.twidere.extension import android.content.Context -import com.bumptech.glide.DrawableRequestBuilder -import com.bumptech.glide.DrawableTypeRequest +import android.graphics.drawable.Drawable +import com.bumptech.glide.RequestBuilder import com.bumptech.glide.RequestManager import com.bumptech.glide.load.engine.DiskCacheStrategy -import jp.wasabeef.glide.transformations.CropCircleTransformation import org.mariotaku.twidere.R import org.mariotaku.twidere.annotation.ImageShapeStyle import org.mariotaku.twidere.extension.model.getBestProfileBanner @@ -35,7 +34,7 @@ import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.glide.RoundedRectTransformation fun RequestManager.loadProfileImage(context: Context, url: String?, @ImageShapeStyle style: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder { return configureLoadProfileImage(context, style, cornerRadius, cornerRadiusRatio) { if (url == null || size == null) { return@configureLoadProfileImage load(url) @@ -46,17 +45,17 @@ fun RequestManager.loadProfileImage(context: Context, url: String?, @ImageShapeS } fun RequestManager.loadProfileImage(context: Context, resourceId: Int, @ImageShapeStyle shapeStyle: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): RequestBuilder { return configureLoadProfileImage(context, shapeStyle, cornerRadius, cornerRadiusRatio) { load(resourceId) } } fun RequestManager.loadProfileImage(context: Context, account: AccountDetails, @ImageShapeStyle shapeStyle: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder { return loadProfileImage(context, account.user, shapeStyle, cornerRadius, cornerRadiusRatio, size) } fun RequestManager.loadProfileImage(context: Context, user: ParcelableUser, @ImageShapeStyle shapeStyle: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder { if (user.extras != null && user.extras?.profile_image_url_fallback == null) { // No fallback image, use compatible logic return loadProfileImage(context, user.profile_image_url, shapeStyle, cornerRadius, @@ -72,7 +71,7 @@ fun RequestManager.loadProfileImage(context: Context, user: ParcelableUser, @Ima } fun RequestManager.loadProfileImage(context: Context, user: ParcelableLiteUser, @ImageShapeStyle shapeStyle: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder { return configureLoadProfileImage(context, shapeStyle, cornerRadius, cornerRadiusRatio) { if (size != null) { return@configureLoadProfileImage load(Utils.getTwitterProfileImageOfSize(user.profile_image_url, size)) @@ -84,7 +83,7 @@ fun RequestManager.loadProfileImage(context: Context, user: ParcelableLiteUser, fun RequestManager.loadProfileImage(context: Context, userList: ParcelableUserList, @ImageShapeStyle shapeStyle: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): RequestBuilder { return configureLoadProfileImage(context, shapeStyle, cornerRadius, cornerRadiusRatio) { load(userList.user_profile_image_url) } @@ -92,14 +91,14 @@ fun RequestManager.loadProfileImage(context: Context, userList: ParcelableUserLi fun RequestManager.loadProfileImage(context: Context, group: ParcelableGroup, @ImageShapeStyle shapeStyle: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): RequestBuilder { return configureLoadProfileImage(context, shapeStyle, cornerRadius, cornerRadiusRatio) { load(group.homepage_logo) } } fun RequestManager.loadProfileImage(context: Context, status: ParcelableStatus, @ImageShapeStyle shapeStyle: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder { if (status.extras?.user_profile_image_url_fallback == null) { // No fallback image, use compatible logic return loadProfileImage(context, status.user_profile_image_url, shapeStyle, cornerRadius, @@ -112,7 +111,7 @@ fun RequestManager.loadProfileImage(context: Context, status: ParcelableStatus, fun RequestManager.loadProfileImage(context: Context, conversation: ParcelableMessageConversation, @ImageShapeStyle shapeStyle: Int, cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, - size: String? = null): DrawableRequestBuilder<*> { + size: String? = null): RequestBuilder<*> { if (conversation.conversation_type == ParcelableMessageConversation.ConversationType.ONE_TO_ONE) { val user = conversation.user if (user != null) { @@ -135,30 +134,30 @@ fun RequestManager.loadProfileImage(context: Context, conversation: ParcelableMe fun RequestManager.loadOriginalProfileImage(context: Context, user: ParcelableUser, @ImageShapeStyle shapeStyle: Int, cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f -): DrawableRequestBuilder { +): RequestBuilder { return configureLoadProfileImage(context, shapeStyle, cornerRadius, cornerRadiusRatio) { load(user.originalProfileImage) } } -fun RequestManager.loadProfileBanner(context: Context, user: ParcelableUser, width: Int): DrawableTypeRequest { +fun RequestManager.loadProfileBanner(context: Context, user: ParcelableUser, width: Int): RequestBuilder { val ratio = context.resources.getFraction(R.fraction.aspect_ratio_profile_banner, 1, 1) return load(user.getBestProfileBanner(width, (width / ratio).toInt())) } internal inline fun configureLoadProfileImage(context: Context, @ImageShapeStyle shapeStyle: Int, - cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, create: () -> DrawableTypeRequest -): DrawableRequestBuilder { + cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, create: () -> RequestBuilder +): RequestBuilder { val builder = create() - builder.diskCacheStrategy(DiskCacheStrategy.RESULT) - builder.centerCrop() - builder.dontAnimate() + .diskCacheStrategy(DiskCacheStrategy.RESOURCE) + .centerCrop() + .dontAnimate() when (shapeStyle) { ImageShapeStyle.SHAPE_CIRCLE -> { - builder.bitmapTransform(CropCircleTransformation(context)) + builder.circleCrop() } ImageShapeStyle.SHAPE_RECTANGLE -> { - builder.bitmapTransform(RoundedRectTransformation(context, cornerRadius, + builder.transform(RoundedRectTransformation(context, cornerRadius, cornerRadiusRatio)) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/CredentialsExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/CredentialsExtensions.kt index 3a4b864be..2a673d0e5 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/CredentialsExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/CredentialsExtensions.kt @@ -3,6 +3,8 @@ package org.mariotaku.twidere.extension.model import android.content.Context import android.net.Uri import android.text.TextUtils +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.fanfou.FanfouStream @@ -21,6 +23,7 @@ import org.mariotaku.restfu.oauth.OAuthAuthorization import org.mariotaku.restfu.oauth.OAuthEndpoint import org.mariotaku.restfu.oauth.OAuthToken import org.mariotaku.restfu.oauth2.OAuth2Authorization +import org.mariotaku.restfu.okhttp3.OkHttpRestClient import org.mariotaku.twidere.TwidereConstants.DEFAULT_TWITTER_API_URL_FORMAT import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.model.account.cred.* diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseDialogFragment.kt index c7e03ec69..180e863b4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseDialogFragment.kt @@ -63,7 +63,7 @@ open class BaseDialogFragment : DialogFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - requestManager = Glide.with(context)// TODO: Upgrade Glide usage + requestManager = Glide.with(context!!)// TODO: Upgrade Glide usage } override fun onStart() { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseFragment.kt index 116708a4b..dd2930912 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseFragment.kt @@ -102,7 +102,7 @@ open class BaseFragment : Fragment(), IBaseFragment { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - requestManager = Glide.with(context)// TODO: Upgrade Glide usage + requestManager = Glide.with(context!!)// TODO: Upgrade Glide usage } override fun onStart() { @@ -126,7 +126,7 @@ open class BaseFragment : Fragment(), IBaseFragment { } override fun onDestroy() { - requestManager.onDestroy() +// requestManager.onDestroy() extraFeaturesService.release() super.onDestroy() // DebugModeUtils.watchReferenceLeak(this) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserQrDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserQrDialogFragment.kt index ff18f5156..5c127cb02 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserQrDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserQrDialogFragment.kt @@ -23,6 +23,7 @@ import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Color import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable import android.os.Bundle import androidx.palette.graphics.Palette import android.view.LayoutInflater @@ -30,7 +31,6 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.drawable.GlideDrawable import com.bumptech.glide.request.target.Target import io.nayuki.qrcodegen.QrCode import io.nayuki.qrcodegen.QrSegment @@ -114,13 +114,13 @@ class UserQrDialogFragment : BaseDialogFragment() { } } - private fun loadProfileImage(): Promise { + private fun loadProfileImage(): Promise { if (context == null || isDetached || dialog == null || (activity?.isFinishing != false)) { return Promise.ofFail(InterruptedException()) } val profileImageSize = getString(R.string.profile_image_size) val context = context?.applicationContext - val requestManager = Glide.with(context) + val requestManager = Glide.with(context!!) val user = this.user return task { try { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/AuthenticatedUriLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/AuthenticatedUriLoader.kt index 3b67211bd..0a93a1fbf 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/AuthenticatedUriLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/AuthenticatedUriLoader.kt @@ -23,8 +23,11 @@ import android.accounts.AccountManager import android.content.Context import android.net.Uri import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher +import com.bumptech.glide.load.Options import com.bumptech.glide.load.data.DataFetcher import com.bumptech.glide.load.model.* +import com.bumptech.glide.load.model.ModelLoader.LoadData +import com.bumptech.glide.signature.ObjectKey import okhttp3.OkHttpClient import org.mariotaku.twidere.extension.model.authorizationHeader import org.mariotaku.twidere.extension.model.getCredentials @@ -40,16 +43,6 @@ class AuthenticatedUriLoader( val client: OkHttpClient ) : ModelLoader { - override fun getResourceFetcher(model: AuthenticatedUri, width: Int, height: Int): DataFetcher { - val headersBuilder = LazyHeaders.Builder() - val credentials = model.accountKey?.credentials - if (credentials != null && TwidereMediaDownloader.isAuthRequired(credentials, model.uri)) { - headersBuilder.addHeader("Authorization", AuthorizationHeaderFactory(model.uri, credentials)) - } - val glideUrl = GlideUrl(model.uri.toString(), headersBuilder.build()) - return OkHttpStreamFetcher(client, glideUrl) - } - val UserKey.credentials: Credentials? get() { val am = AccountManager.get(context) return AccountUtils.findByAccountKey(am, this)?.getCredentials(am) @@ -59,10 +52,24 @@ class AuthenticatedUriLoader( override fun buildHeader() = credentials.authorizationHeader(uri) } - class Factory(val client: OkHttpClient) : ModelLoaderFactory { - override fun build(context: Context, factories: GenericLoaderFactory) = AuthenticatedUriLoader(context, client) - + class Factory(val context: Context, val client: OkHttpClient) : ModelLoaderFactory { + override fun build(factory: MultiModelLoaderFactory) = AuthenticatedUriLoader(context, client) override fun teardown() {} } + override fun buildLoadData(model: AuthenticatedUri, width: Int, height: Int, options: Options): LoadData? { + + val headersBuilder = LazyHeaders.Builder() + val credentials = model.accountKey?.credentials + if (credentials != null && TwidereMediaDownloader.isAuthRequired(credentials, model.uri)) { + headersBuilder.addHeader("Authorization", AuthorizationHeaderFactory(model.uri, credentials)) + } + val glideUrl = GlideUrl(model.uri.toString(), headersBuilder.build()) + return LoadData(ObjectKey(model), OkHttpStreamFetcher(client, glideUrl)) + } + + override fun handles(model: AuthenticatedUri): Boolean { + return true + } + } \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/DeferredTarget.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/DeferredTarget.kt index 90d70806e..3dd2f47f7 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/DeferredTarget.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/DeferredTarget.kt @@ -20,8 +20,8 @@ package org.mariotaku.twidere.util.glide import android.graphics.drawable.Drawable -import com.bumptech.glide.request.animation.GlideAnimation -import com.bumptech.glide.request.target.SimpleTarget +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition import nl.komponents.kovenant.Deferred import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred @@ -30,18 +30,23 @@ import nl.komponents.kovenant.deferred * Created by mariotaku on 2017/3/21. */ -class DeferredTarget(private val deferredInstance: Deferred = deferred()) : SimpleTarget() { +class DeferredTarget(private val deferredInstance: Deferred = deferred()) : CustomTarget() { val promise: Promise get() = deferredInstance.promise - override fun onLoadFailed(e: Exception, errorDrawable: Drawable?) { + override fun onLoadFailed(errorDrawable: Drawable?) { if (deferredInstance.promise.isDone()) return - deferredInstance.reject(e) + deferredInstance.reject(Exception()) } - override fun onResourceReady(resource: R, glideAnimation: GlideAnimation) { + override fun onResourceReady(resource: R, transition: Transition?) { if (deferredInstance.promise.isDone()) return deferredInstance.resolve(resource) } + override fun onLoadCleared(placeholder: Drawable?) { + if (deferredInstance.promise.isDone()) return + deferredInstance.reject(Exception()) + } + } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/NoThumborUrlLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/NoThumborUrlLoader.kt index ce45e4ad9..a5998598d 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/NoThumborUrlLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/NoThumborUrlLoader.kt @@ -21,8 +21,10 @@ package org.mariotaku.twidere.util.glide import android.content.Context import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher +import com.bumptech.glide.load.Options import com.bumptech.glide.load.data.DataFetcher import com.bumptech.glide.load.model.* +import com.bumptech.glide.signature.ObjectKey import okhttp3.OkHttpClient import org.mariotaku.twidere.model.media.NoThumborUrl import java.io.InputStream @@ -32,15 +34,9 @@ class NoThumborUrlLoader( val client: OkHttpClient ) : ModelLoader { - override fun getResourceFetcher(model: NoThumborUrl, width: Int, height: Int): DataFetcher { - val headersBuilder = LazyHeaders.Builder() - headersBuilder.addHeader(HEADER_NO_THUMBOR, "true") - val glideUrl = GlideUrl(model.url, headersBuilder.build()) - return OkHttpStreamFetcher(client, glideUrl) - } - class Factory(val client: OkHttpClient) : ModelLoaderFactory { - override fun build(context: Context, factories: GenericLoaderFactory) = NoThumborUrlLoader(context, client) + class Factory(val context: Context, val client: OkHttpClient) : ModelLoaderFactory { + override fun build(factory: MultiModelLoaderFactory) = NoThumborUrlLoader(context, client) override fun teardown() {} } @@ -49,4 +45,16 @@ class NoThumborUrlLoader( const val HEADER_NO_THUMBOR = "X-Twidere-No-Thumbor" } + override fun buildLoadData(model: NoThumborUrl, width: Int, height: Int, options: Options): ModelLoader.LoadData? { + val headersBuilder = LazyHeaders.Builder() + headersBuilder.addHeader(HEADER_NO_THUMBOR, "true") + val glideUrl = GlideUrl(model.url, headersBuilder.build()) + val fetcher = OkHttpStreamFetcher(client, glideUrl) + return ModelLoader.LoadData(ObjectKey(model), fetcher) + } + + override fun handles(model: NoThumborUrl): Boolean { + return true + } + } \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/RoundedRectTransformation.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/RoundedRectTransformation.kt index 16225e6b9..70d005bcb 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/RoundedRectTransformation.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/RoundedRectTransformation.kt @@ -26,6 +26,8 @@ import com.bumptech.glide.load.Transformation import com.bumptech.glide.load.engine.Resource import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool import com.bumptech.glide.load.resource.bitmap.BitmapResource +import java.security.MessageDigest + class RoundedRectTransformation( private val bitmapPool: BitmapPool, @@ -37,7 +39,7 @@ class RoundedRectTransformation( constructor(context: Context, radius: Float, radiusPercent: Float) : this(Glide.get(context).bitmapPool, radius, radiusPercent) - override fun transform(resource: Resource, outWidth: Int, outHeight: Int): Resource { + override fun transform(context: Context, resource: Resource, outWidth: Int, outHeight: Int): Resource { val source = resource.get() val width = source.width @@ -59,14 +61,26 @@ class RoundedRectTransformation( radius } drawRoundRect(canvas, calculatedRadius, paint) - return BitmapResource.obtain(bitmap, bitmapPool) + return BitmapResource.obtain(bitmap, bitmapPool)!! } private fun drawRoundRect(canvas: Canvas, radius: Float, paint: Paint) { canvas.drawRoundRect(rectF, radius, radius, paint) } - override fun getId(): String { + fun getId(): String { return "RoundedRectTransformation(radius=$radius, radiusPercent=$radius)" } + + override fun equals(o: Any?): Boolean { + return o is RoundedRectTransformation + } + + override fun hashCode(): Int { + return getId().hashCode() + } + + override fun updateDiskCacheKey(messageDigest: MessageDigest) { + messageDigest.update(getId().toByteArray()) + } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/TwidereGlideModule.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/TwidereGlideModule.kt index bb66365cf..88122b3e4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/TwidereGlideModule.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/glide/TwidereGlideModule.kt @@ -23,8 +23,10 @@ import android.content.Context import android.os.Build import com.bumptech.glide.Glide import com.bumptech.glide.GlideBuilder +import com.bumptech.glide.Registry import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.module.AppGlideModule import com.bumptech.glide.module.GlideModule import okhttp3.OkHttpClient import okhttp3.Request @@ -38,12 +40,13 @@ import org.mariotaku.twidere.util.media.ThumborWrapper import org.mariotaku.twidere.util.okhttp.ModifyRequestInterceptor import java.io.InputStream -class TwidereGlideModule : GlideModule { +@com.bumptech.glide.annotation.GlideModule +class TwidereGlideModule : AppGlideModule() { override fun applyOptions(context: Context, builder: GlideBuilder) { // Do nothing. } - override fun registerComponents(context: Context, glide: Glide) { + override fun registerComponents(context: Context, glide: Glide, registry: Registry) { val holder = DependencyHolder.get(context) val builder = OkHttpClient.Builder() val conf = HttpClientFactory.HttpClientConfiguration(holder.preferences) @@ -56,9 +59,13 @@ class TwidereGlideModule : GlideModule { } builder.addInterceptor(ModifyRequestInterceptor(ThumborModifier(thumbor), UserAgentModifier(userAgent))) val client = builder.build() - glide.register(GlideUrl::class.java, InputStream::class.java, OkHttpUrlLoader.Factory(client)) - glide.register(AuthenticatedUri::class.java, InputStream::class.java, AuthenticatedUriLoader.Factory(client)) - glide.register(NoThumborUrl::class.java, InputStream::class.java, NoThumborUrlLoader.Factory(client)) + registry.append(GlideUrl::class.java, InputStream::class.java, OkHttpUrlLoader.Factory(client)) + registry.append(AuthenticatedUri::class.java, InputStream::class.java, AuthenticatedUriLoader.Factory(context, client)) + registry.append(NoThumborUrl::class.java, InputStream::class.java, NoThumborUrlLoader.Factory(context, client)) + } + + override fun isManifestParsingEnabled(): Boolean { + return false; } class ThumborModifier(val thumbor: ThumborWrapper) : ModifyRequestInterceptor.RequestModifier { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/CardMediaContainer.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/CardMediaContainer.kt index ceec5b075..42a2566bc 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/CardMediaContainer.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/CardMediaContainer.kt @@ -117,9 +117,9 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr item.media_url } val request = if (withCredentials) { - requestManager.load(AuthenticatedUri(Uri.parse(url), accountKey)).asBitmap() + requestManager.load(AuthenticatedUri(Uri.parse(url), accountKey)) } else { - requestManager.load(url).asBitmap() + requestManager.load(url) } when (style) { PreviewStyle.ACTUAL_SIZE -> { @@ -148,7 +148,7 @@ class CardMediaContainer(context: Context, attrs: AttributeSet? = null) : ViewGr this.visibility = View.VISIBLE findViewById(lp.videoViewId)?.visibility = View.VISIBLE } else { - Glide.clear(this) + Glide.with(this).clear(this) this.visibility = View.GONE findViewById(lp.videoViewId)?.visibility = View.GONE } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/compose/MediaPreviewViewHolder.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/compose/MediaPreviewViewHolder.kt index 280c5f4ce..a2990d7f1 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/compose/MediaPreviewViewHolder.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/compose/MediaPreviewViewHolder.kt @@ -19,9 +19,11 @@ package org.mariotaku.twidere.view.holder.compose +import android.graphics.drawable.Drawable import androidx.recyclerview.widget.RecyclerView import android.view.View -import com.bumptech.glide.load.resource.drawable.GlideDrawable +import com.bumptech.glide.load.DataSource +import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.target.Target import kotlinx.android.synthetic.main.grid_item_media_editor.view.* @@ -39,16 +41,16 @@ class MediaPreviewViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) private val removeView = itemView.remove private val editView = itemView.edit - private val requestListener = object : RequestListener { - override fun onException(e: Exception?, model: String?, target: Target?, - isFirstResource: Boolean): Boolean { + private val requestListener = object : RequestListener { + + override fun onResourceReady(resource: Drawable?, model: Any?, target: Target?, + dataSource: DataSource?, isFirstResource: Boolean): Boolean { loadProgress.visibility = View.GONE return false } - override fun onResourceReady(resource: GlideDrawable?, model: String?, - target: Target?, isFromMemoryCache: Boolean, - isFirstResource: Boolean): Boolean { + override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, + isFirstResource: Boolean): Boolean { loadProgress.visibility = View.GONE return false }