Add CoilImagesPlugin
This commit is contained in:
parent
ba22ca88e2
commit
a1182e209a
@ -72,7 +72,8 @@ ext {
|
||||
'adapt' : 'io.noties:adapt:2.0.0',
|
||||
'dagger' : "com.google.dagger:dagger:$daggerVersion",
|
||||
'picasso' : 'com.squareup.picasso:picasso:2.71828',
|
||||
'glide' : 'com.github.bumptech.glide:glide:4.9.0'
|
||||
'glide' : 'com.github.bumptech.glide:glide:4.9.0',
|
||||
'coil' : 'io.coil-kt:coil:0.8.0'
|
||||
]
|
||||
|
||||
deps['annotationProcessor'] = [
|
||||
|
24
docs/docs/v4/image-coil/README.md
Normal file
24
docs/docs/v4/image-coil/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Image Coil
|
||||
|
||||
<MavenBadge4 :artifact="'image-coil'" />
|
||||
|
||||
Image loading based on `Coil` library
|
||||
|
||||
```kt
|
||||
val markwon = Markwon.builder(context)
|
||||
// automatically create Coil instance
|
||||
.usePlugin(CoilImagesPlugin.create(context))
|
||||
// if you need more control
|
||||
.usePlugin(CoilImagesPlugin.create(object : CoilImagesPlugin.CoilStore() {
|
||||
override load(drawable: AsyncDrawable, target: Target): RequestDisposable {
|
||||
return Coil.load(context, drawable.destination) {
|
||||
target(target)
|
||||
}
|
||||
}
|
||||
|
||||
override cancel(requestDisposable: RequestDisposable) {
|
||||
requestDisposable.dispose()
|
||||
}
|
||||
}))
|
||||
.build()
|
||||
```
|
3
markwon-image-coil/README.md
Normal file
3
markwon-image-coil/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Images (Coil)
|
||||
|
||||
https://noties.io/Markwon/docs/v4/image-coil/
|
21
markwon-image-coil/build.gradle
Normal file
21
markwon-image-coil/build.gradle
Normal file
@ -0,0 +1,21 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
|
||||
compileSdkVersion config['compile-sdk']
|
||||
buildToolsVersion config['build-tools']
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion config['min-sdk']
|
||||
targetSdkVersion config['target-sdk']
|
||||
versionCode 1
|
||||
versionName version
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api project(':markwon-core')
|
||||
api deps['coil']
|
||||
}
|
||||
|
||||
registerArtifact(this)
|
4
markwon-image-coil/gradle.properties
Normal file
4
markwon-image-coil/gradle.properties
Normal file
@ -0,0 +1,4 @@
|
||||
POM_NAME=Image Coil
|
||||
POM_ARTIFACT_ID=image-coil
|
||||
POM_DESCRIPTION=Markwon image loading module (based on Coil library)
|
||||
POM_PACKAGING=aar
|
1
markwon-image-coil/src/main/AndroidManifest.xml
Normal file
1
markwon-image-coil/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
||||
<manifest package="io.noties.markwon.image.coil" />
|
@ -0,0 +1,186 @@
|
||||
package io.noties.markwon.image.coil;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Spanned;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.commonmark.node.Image;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import coil.Coil;
|
||||
import coil.ImageLoader;
|
||||
import coil.api.ImageLoaders;
|
||||
import coil.request.LoadRequest;
|
||||
import coil.request.LoadRequestBuilder;
|
||||
import coil.request.RequestDisposable;
|
||||
import coil.target.Target;
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
import io.noties.markwon.MarkwonConfiguration;
|
||||
import io.noties.markwon.MarkwonSpansFactory;
|
||||
import io.noties.markwon.image.AsyncDrawable;
|
||||
import io.noties.markwon.image.AsyncDrawableLoader;
|
||||
import io.noties.markwon.image.AsyncDrawableScheduler;
|
||||
import io.noties.markwon.image.DrawableUtils;
|
||||
import io.noties.markwon.image.ImageSpanFactory;
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class CoilImagesPlugin extends AbstractMarkwonPlugin {
|
||||
|
||||
public interface CoilStore {
|
||||
|
||||
@NonNull
|
||||
RequestDisposable load(@NonNull AsyncDrawable drawable, @NonNull Target target);
|
||||
|
||||
void cancel(@NonNull RequestDisposable disposable);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static CoilImagesPlugin create(@NonNull final Context context) {
|
||||
return create(new CoilStore() {
|
||||
@NonNull
|
||||
@Override
|
||||
public RequestDisposable load(@NonNull AsyncDrawable drawable, @NonNull Target target) {
|
||||
ImageLoader imageLoader = Coil.loader();
|
||||
LoadRequest request = ImageLoaders.newLoadBuilder(imageLoader, context)
|
||||
.data(drawable.getDestination())
|
||||
.target(target)
|
||||
.build();
|
||||
return imageLoader.load(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(@NonNull RequestDisposable disposable) {
|
||||
disposable.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static CoilImagesPlugin create(@NonNull final LoadRequestBuilder loadRequestBuilder) {
|
||||
return create(new CoilStore() {
|
||||
@NonNull
|
||||
@Override
|
||||
public RequestDisposable load(@NonNull AsyncDrawable drawable, @NonNull Target target) {
|
||||
ImageLoader imageLoader = Coil.loader();
|
||||
LoadRequest request = loadRequestBuilder
|
||||
.data(drawable.getDestination())
|
||||
.target(target)
|
||||
.build();
|
||||
return imageLoader.load(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(@NonNull RequestDisposable disposable) {
|
||||
disposable.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static CoilImagesPlugin create(@NonNull CoilStore coilStore) {
|
||||
return new CoilImagesPlugin(coilStore);
|
||||
}
|
||||
|
||||
private final CoilAsyncDrawableLoader coilAsyncDrawableLoader;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
CoilImagesPlugin(@NonNull CoilStore coilStore) {
|
||||
this.coilAsyncDrawableLoader = new CoilAsyncDrawableLoader(coilStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||
builder.setFactory(Image.class, new ImageSpanFactory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
||||
builder.asyncDrawableLoader(coilAsyncDrawableLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {
|
||||
AsyncDrawableScheduler.unschedule(textView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSetText(@NonNull TextView textView) {
|
||||
AsyncDrawableScheduler.schedule(textView);
|
||||
}
|
||||
|
||||
private static class CoilAsyncDrawableLoader extends AsyncDrawableLoader {
|
||||
|
||||
private final CoilStore coilStore;
|
||||
private final Map<AsyncDrawable, RequestDisposable> cache = new HashMap<>(2);
|
||||
|
||||
CoilAsyncDrawableLoader(@NonNull CoilStore coilStore) {
|
||||
this.coilStore = coilStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(@NonNull AsyncDrawable drawable) {
|
||||
final Target target = new AsyncDrawableTarget(drawable);
|
||||
RequestDisposable disposable = coilStore.load(drawable, target);
|
||||
cache.put(drawable, disposable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(@NonNull AsyncDrawable drawable) {
|
||||
final RequestDisposable disposable = cache.remove(drawable);
|
||||
if (disposable != null) {
|
||||
coilStore.cancel(disposable);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Drawable placeholder(@NonNull AsyncDrawable drawable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private class AsyncDrawableTarget implements Target {
|
||||
|
||||
private final AsyncDrawable drawable;
|
||||
|
||||
AsyncDrawableTarget(@NonNull AsyncDrawable drawable) {
|
||||
this.drawable = drawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(@NonNull Drawable loadedDrawable) {
|
||||
if (cache.remove(drawable) != null) {
|
||||
if (drawable.isAttached()) {
|
||||
DrawableUtils.applyIntrinsicBoundsIfEmpty(loadedDrawable);
|
||||
drawable.setResult(loadedDrawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(@Nullable Drawable placeholder) {
|
||||
if (placeholder != null && drawable.isAttached()) {
|
||||
DrawableUtils.applyIntrinsicBoundsIfEmpty(placeholder);
|
||||
drawable.setResult(placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@Nullable Drawable errorDrawable) {
|
||||
if (cache.remove(drawable) != null) {
|
||||
if (errorDrawable != null && drawable.isAttached()) {
|
||||
DrawableUtils.applyIntrinsicBoundsIfEmpty(errorDrawable);
|
||||
drawable.setResult(errorDrawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -82,6 +82,7 @@ public class RecyclerActivity extends Activity {
|
||||
// }))
|
||||
.usePlugin(PicassoImagesPlugin.create(context))
|
||||
// .usePlugin(GlideImagesPlugin.create(context))
|
||||
// .usePlugin(CoilImagesPlugin.create(context))
|
||||
// important to use TableEntryPlugin instead of TablePlugin
|
||||
.usePlugin(TableEntryPlugin.create(context))
|
||||
.usePlugin(HtmlPlugin.create())
|
||||
|
@ -7,6 +7,7 @@ include ':app', ':sample',
|
||||
':markwon-ext-tasklist',
|
||||
':markwon-html',
|
||||
':markwon-image',
|
||||
':markwon-image-coil',
|
||||
':markwon-image-glide',
|
||||
':markwon-image-picasso',
|
||||
':markwon-linkify',
|
||||
|
Loading…
x
Reference in New Issue
Block a user