@ -5,6 +5,7 @@ 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 kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.suspendCancellableCoroutine
@ -17,32 +18,41 @@ suspend fun <R> RequestBuilder<R>.submitAsync(
height : Int = Target . SIZE _ORIGINAL
) : R {
return suspendCancellableCoroutine { continuation ->
val target = addListener (
object : RequestListener < R > {
override fun onLoadFailed (
e : GlideException ? ,
model : Any ? ,
target : Target < R > ,
isFirstResource : Boolean
) : Boolean {
continuation . resumeWithException ( e ?: GlideException ( " Image loading failed " ) )
return false
}
val target = addListener ( ContinuationRequestListener ( continuation ) )
. submit ( width , height )
continuation . invokeOnCancellation { target . cancel ( true ) }
}
}
private class ContinuationRequestListener < R > ( continuation : Continuation < R > ) : RequestListener < R > {
private var continuation : Continuation < R > ? = continuation
override fun onResourceReady (
resource : R & Any ,
model : Any ,
target : Target < R > ? ,
dataSource : DataSource ,
isFirstResource : Boolean
) : Boolean {
if ( target ?. request ?. isComplete == true ) {
continuation . resume ( resource )
}
return false
}
override fun onLoadFailed (
e : GlideException ? ,
model : Any ? ,
target : Target < R > ,
isFirstResource : Boolean
) : Boolean {
continuation ?. let {
continuation = null
it . resumeWithException ( e ?: GlideException ( " Image loading failed " ) )
}
return false
}
override fun onResourceReady (
resource : R & Any ,
model : Any ,
target : Target < R > ? ,
dataSource : DataSource ,
isFirstResource : Boolean
) : Boolean {
continuation ?. let {
if ( target ?. request ?. isComplete == true ) {
continuation = null
it . resume ( resource )
}
) . submit ( width , height )
continuation . invokeOnCancellation { target . cancel ( true ) }
}
return false
}
}