Migrate to glide v4
This commit is contained in:
parent
fc2bbe857b
commit
a2cec21b18
|
@ -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',
|
||||
|
|
|
@ -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']}"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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<String?> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder<Drawable> {
|
||||
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<Int> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): RequestBuilder<Drawable> {
|
||||
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<String?> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder<Drawable> {
|
||||
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<String?> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder<Drawable> {
|
||||
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<String?> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder<Drawable> {
|
||||
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<String?> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): RequestBuilder<Drawable> {
|
||||
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<String?> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f): RequestBuilder<Drawable> {
|
||||
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<String?> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, size: String? = null): RequestBuilder<Drawable> {
|
||||
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<String> {
|
||||
): RequestBuilder<Drawable> {
|
||||
return configureLoadProfileImage(context, shapeStyle, cornerRadius, cornerRadiusRatio) {
|
||||
load(user.originalProfileImage)
|
||||
}
|
||||
}
|
||||
|
||||
fun RequestManager.loadProfileBanner(context: Context, user: ParcelableUser, width: Int): DrawableTypeRequest<String?> {
|
||||
fun RequestManager.loadProfileBanner(context: Context, user: ParcelableUser, width: Int): RequestBuilder<Drawable> {
|
||||
val ratio = context.resources.getFraction(R.fraction.aspect_ratio_profile_banner, 1, 1)
|
||||
return load(user.getBestProfileBanner(width, (width / ratio).toInt()))
|
||||
}
|
||||
|
||||
internal inline fun <T> configureLoadProfileImage(context: Context, @ImageShapeStyle shapeStyle: Int,
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, create: () -> DrawableTypeRequest<T>
|
||||
): DrawableRequestBuilder<T> {
|
||||
cornerRadius: Float = 0f, cornerRadiusRatio: Float = 0f, create: () -> RequestBuilder<T>
|
||||
): RequestBuilder<T> {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.*
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -102,7 +102,7 @@ open class BaseFragment : Fragment(), IBaseFragment<BaseFragment> {
|
|||
|
||||
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<BaseFragment> {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
requestManager.onDestroy()
|
||||
// requestManager.onDestroy()
|
||||
extraFeaturesService.release()
|
||||
super.onDestroy()
|
||||
// DebugModeUtils.watchReferenceLeak(this)
|
||||
|
|
|
@ -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<GlideDrawable, Exception> {
|
||||
private fun loadProfileImage(): Promise<Drawable, Exception> {
|
||||
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 {
|
||||
|
|
|
@ -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<AuthenticatedUri, InputStream> {
|
||||
|
||||
override fun getResourceFetcher(model: AuthenticatedUri, width: Int, height: Int): DataFetcher<InputStream> {
|
||||
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<AuthenticatedUri, InputStream> {
|
||||
override fun build(context: Context, factories: GenericLoaderFactory) = AuthenticatedUriLoader(context, client)
|
||||
|
||||
class Factory(val context: Context, val client: OkHttpClient) : ModelLoaderFactory<AuthenticatedUri, InputStream> {
|
||||
override fun build(factory: MultiModelLoaderFactory) = AuthenticatedUriLoader(context, client)
|
||||
override fun teardown() {}
|
||||
}
|
||||
|
||||
override fun buildLoadData(model: AuthenticatedUri, width: Int, height: Int, options: Options): LoadData<InputStream>? {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
|
@ -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<R>(private val deferredInstance: Deferred<R, Exception> = deferred()) : SimpleTarget<R>() {
|
||||
class DeferredTarget<R>(private val deferredInstance: Deferred<R, Exception> = deferred()) : CustomTarget<R>() {
|
||||
|
||||
val promise: Promise<R, Exception> 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<in R>) {
|
||||
override fun onResourceReady(resource: R, transition: Transition<in R>?) {
|
||||
if (deferredInstance.promise.isDone()) return
|
||||
deferredInstance.resolve(resource)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
if (deferredInstance.promise.isDone()) return
|
||||
deferredInstance.reject(Exception())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<NoThumborUrl, InputStream> {
|
||||
|
||||
override fun getResourceFetcher(model: NoThumborUrl, width: Int, height: Int): DataFetcher<InputStream> {
|
||||
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<NoThumborUrl, InputStream> {
|
||||
override fun build(context: Context, factories: GenericLoaderFactory) = NoThumborUrlLoader(context, client)
|
||||
class Factory(val context: Context, val client: OkHttpClient) : ModelLoaderFactory<NoThumborUrl, InputStream> {
|
||||
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<InputStream>? {
|
||||
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
|
||||
}
|
||||
|
||||
}
|
|
@ -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<Bitmap>, outWidth: Int, outHeight: Int): Resource<Bitmap> {
|
||||
override fun transform(context: Context, resource: Resource<Bitmap>, outWidth: Int, outHeight: Int): Resource<Bitmap> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<View>(lp.videoViewId)?.visibility = View.VISIBLE
|
||||
} else {
|
||||
Glide.clear(this)
|
||||
Glide.with(this).clear(this)
|
||||
this.visibility = View.GONE
|
||||
findViewById<View>(lp.videoViewId)?.visibility = View.GONE
|
||||
}
|
||||
|
|
|
@ -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<String, GlideDrawable> {
|
||||
override fun onException(e: Exception?, model: String?, target: Target<GlideDrawable>?,
|
||||
isFirstResource: Boolean): Boolean {
|
||||
private val requestListener = object : RequestListener<Drawable> {
|
||||
|
||||
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?,
|
||||
dataSource: DataSource?, isFirstResource: Boolean): Boolean {
|
||||
loadProgress.visibility = View.GONE
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(resource: GlideDrawable?, model: String?,
|
||||
target: Target<GlideDrawable>?, isFromMemoryCache: Boolean,
|
||||
isFirstResource: Boolean): Boolean {
|
||||
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?,
|
||||
isFirstResource: Boolean): Boolean {
|
||||
loadProgress.visibility = View.GONE
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue