Cache chapter images from presenter with glide.
This commit is contained in:
parent
fefc6ba0e9
commit
ef7613f7ad
10 changed files with 93 additions and 71 deletions
|
@ -5,10 +5,10 @@ import android.content.Context;
|
|||
|
||||
import org.acra.annotation.ReportsCrashes;
|
||||
|
||||
import eu.kanade.mangafeed.injection.component.AppComponent;
|
||||
import eu.kanade.mangafeed.injection.module.AppModule;
|
||||
import eu.kanade.mangafeed.injection.ComponentReflectionInjector;
|
||||
import eu.kanade.mangafeed.injection.component.AppComponent;
|
||||
import eu.kanade.mangafeed.injection.component.DaggerAppComponent;
|
||||
import eu.kanade.mangafeed.injection.module.AppModule;
|
||||
import timber.log.Timber;
|
||||
|
||||
@ReportsCrashes(
|
||||
|
|
|
@ -5,15 +5,17 @@ public class Page {
|
|||
private int pageNumber;
|
||||
private String url;
|
||||
private String imageUrl;
|
||||
private String imagePath;
|
||||
|
||||
public Page(int pageNumber, String url, String imageUrl) {
|
||||
public Page(int pageNumber, String url, String imageUrl, String imagePath) {
|
||||
this.pageNumber = pageNumber;
|
||||
this.url = url;
|
||||
this.imageUrl = imageUrl;
|
||||
this.imagePath = imagePath;
|
||||
}
|
||||
|
||||
public Page(int pageNumber, String url) {
|
||||
this(pageNumber, url, null);
|
||||
this(pageNumber, url, null, null);
|
||||
}
|
||||
|
||||
public int getPageNumber() {
|
||||
|
@ -32,6 +34,14 @@ public class Page {
|
|||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public String getImagePath() {
|
||||
return imagePath;
|
||||
}
|
||||
|
||||
public void setImagePath(String imagePath) {
|
||||
this.imagePath = imagePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Page{" +
|
||||
|
@ -40,4 +50,5 @@ public class Page {
|
|||
", imageUrl='" + imageUrl + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@ package eu.kanade.mangafeed.injection.module;
|
|||
|
||||
import android.app.Application;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.RequestManager;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Module;
|
||||
|
@ -55,4 +58,10 @@ public class DataModule {
|
|||
SourceManager provideSourceManager(NetworkHelper networkHelper, CacheManager cacheManager) {
|
||||
return new SourceManager(networkHelper, cacheManager);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
RequestManager provideGlideDownloader(Application app) {
|
||||
return Glide.with(app);
|
||||
}
|
||||
}
|
|
@ -13,11 +13,11 @@ import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
|
|||
import eu.kanade.mangafeed.data.helpers.SourceManager;
|
||||
import eu.kanade.mangafeed.data.models.Chapter;
|
||||
import eu.kanade.mangafeed.data.models.Manga;
|
||||
import eu.kanade.mangafeed.events.ChapterCountEvent;
|
||||
import eu.kanade.mangafeed.events.SourceChapterEvent;
|
||||
import eu.kanade.mangafeed.sources.Source;
|
||||
import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment;
|
||||
import eu.kanade.mangafeed.util.EventBusHook;
|
||||
import eu.kanade.mangafeed.events.ChapterCountEvent;
|
||||
import eu.kanade.mangafeed.events.SourceChapterEvent;
|
||||
import rx.Observable;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
|
|
@ -6,9 +6,9 @@ import javax.inject.Inject;
|
|||
|
||||
import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
|
||||
import eu.kanade.mangafeed.data.models.Manga;
|
||||
import eu.kanade.mangafeed.events.ChapterCountEvent;
|
||||
import eu.kanade.mangafeed.ui.fragment.MangaInfoFragment;
|
||||
import eu.kanade.mangafeed.util.EventBusHook;
|
||||
import eu.kanade.mangafeed.events.ChapterCountEvent;
|
||||
import rx.Observable;
|
||||
|
||||
public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
|
||||
|
|
|
@ -2,6 +2,11 @@ package eu.kanade.mangafeed.presenter;
|
|||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.bumptech.glide.RequestManager;
|
||||
import com.bumptech.glide.request.FutureTarget;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -10,10 +15,10 @@ import de.greenrobot.event.EventBus;
|
|||
import eu.kanade.mangafeed.data.helpers.PreferencesHelper;
|
||||
import eu.kanade.mangafeed.data.models.Chapter;
|
||||
import eu.kanade.mangafeed.data.models.Page;
|
||||
import eu.kanade.mangafeed.events.SourceChapterEvent;
|
||||
import eu.kanade.mangafeed.sources.Source;
|
||||
import eu.kanade.mangafeed.ui.activity.ReaderActivity;
|
||||
import eu.kanade.mangafeed.util.EventBusHook;
|
||||
import eu.kanade.mangafeed.events.SourceChapterEvent;
|
||||
import icepick.State;
|
||||
import rx.Observable;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
|
@ -22,6 +27,7 @@ import rx.schedulers.Schedulers;
|
|||
public class ReaderPresenter extends BasePresenter<ReaderActivity> {
|
||||
|
||||
@Inject PreferencesHelper prefs;
|
||||
@Inject RequestManager glideDownloader;
|
||||
|
||||
private Source source;
|
||||
private Chapter chapter;
|
||||
|
@ -97,10 +103,26 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
|
|||
Observable.from(pageList).filter(page -> page.getImageUrl() != null),
|
||||
source.getRemainingImageUrlsFromPageList(pageList)
|
||||
.doOnNext(this::replacePageUrl))
|
||||
.flatMap(this::downloadImage)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread());
|
||||
}
|
||||
|
||||
private Observable<Page> downloadImage(Page page) {
|
||||
FutureTarget<File> future = glideDownloader.load(page.getImageUrl())
|
||||
.downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
|
||||
|
||||
try {
|
||||
File cacheFile = future.get();
|
||||
page.setImagePath(cacheFile.getCanonicalPath());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return Observable.just(page);
|
||||
}
|
||||
|
||||
private void replacePageUrl(Page page) {
|
||||
for (int i = 0; i < pageList.size(); i++) {
|
||||
if (pageList.get(i).getPageNumber() == page.getPageNumber()) {
|
||||
|
|
|
@ -46,7 +46,7 @@ public abstract class Source {
|
|||
}
|
||||
|
||||
// Number of images to download at the same time
|
||||
protected int getNumberOfConcurrentImageDownloads() {
|
||||
protected int getNumberOfConcurrentPageDownloads() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -111,14 +111,10 @@ public abstract class Source {
|
|||
public Observable<Page> getRemainingImageUrlsFromPageList(final List<Page> pages) {
|
||||
return Observable.from(pages)
|
||||
.filter(page -> page.getImageUrl() == null)
|
||||
.buffer(getNumberOfConcurrentImageDownloads())
|
||||
.concatMap(batchedPages -> {
|
||||
List<Observable<Page>> pageObservable = new ArrayList<>();
|
||||
for (Page page : batchedPages) {
|
||||
pageObservable.add(getImageUrlFromPage(page));
|
||||
}
|
||||
return Observable.merge(pageObservable);
|
||||
});
|
||||
.window(getNumberOfConcurrentPageDownloads())
|
||||
.concatMap(batchedPages ->
|
||||
batchedPages.concatMap(this::getImageUrlFromPage)
|
||||
);
|
||||
}
|
||||
|
||||
private Observable<Page> getImageUrlFromPage(final Page page) {
|
||||
|
|
|
@ -6,27 +6,29 @@ import android.support.v4.app.Fragment;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource;
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
import eu.kanade.mangafeed.R;
|
||||
import eu.kanade.mangafeed.data.models.Page;
|
||||
import eu.kanade.mangafeed.ui.activity.ReaderActivity;
|
||||
import eu.kanade.mangafeed.util.MangaImageRegionDecoder;
|
||||
import eu.kanade.mangafeed.util.PageFileTarget;
|
||||
|
||||
public class ReaderPageFragment extends Fragment {
|
||||
public static final String URL_ARGUMENT_KEY = "UrlArgumentKey";
|
||||
|
||||
private SubsamplingScaleImageView imageView;
|
||||
@Bind(R.id.page_image_view) SubsamplingScaleImageView imageView;
|
||||
@Bind(R.id.progress) ProgressBar progressBar;
|
||||
|
||||
private String mUrl;
|
||||
private String imagePath;
|
||||
|
||||
public static ReaderPageFragment newInstance(Page page) {
|
||||
ReaderPageFragment newInstance = new ReaderPageFragment();
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putString(URL_ARGUMENT_KEY, page.getImageUrl());
|
||||
arguments.putString(URL_ARGUMENT_KEY, page.getImagePath());
|
||||
newInstance.setArguments(arguments);
|
||||
return newInstance;
|
||||
}
|
||||
|
@ -40,39 +42,42 @@ public class ReaderPageFragment extends Fragment {
|
|||
Bundle arguments = getArguments();
|
||||
if (arguments != null) {
|
||||
if (arguments.containsKey(URL_ARGUMENT_KEY)) {
|
||||
mUrl = arguments.getString(URL_ARGUMENT_KEY);
|
||||
imagePath = arguments.getString(URL_ARGUMENT_KEY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPage(Page page) {
|
||||
if (!page.getImageUrl().equals(mUrl)) {
|
||||
mUrl = page.getImageUrl();
|
||||
if (!page.getImageUrl().equals(imagePath)) {
|
||||
imagePath = page.getImagePath();
|
||||
loadImage();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadImage() {
|
||||
if (mUrl != null) {
|
||||
Glide.with(getActivity())
|
||||
.load(mUrl)
|
||||
.downloadOnly(new PageFileTarget(imageView));
|
||||
if (imagePath != null) {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
imageView.setImage(ImageSource.uri(imagePath).tilingDisabled());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
imageView = (SubsamplingScaleImageView)inflater.inflate(R.layout.fragment_page, container, false);
|
||||
View view = inflater.inflate(R.layout.fragment_page, container, false);
|
||||
ButterKnife.bind(this, view);
|
||||
|
||||
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
|
||||
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
|
||||
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
|
||||
imageView.setOnTouchListener((view, motionEvent) ->
|
||||
imageView.setOnTouchListener((v, motionEvent) ->
|
||||
((ReaderActivity) getActivity()).getViewPager().onImageTouch(motionEvent));
|
||||
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
loadImage();
|
||||
|
||||
return imageView;
|
||||
return view;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package eu.kanade.mangafeed.util;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
import com.bumptech.glide.request.target.ViewTarget;
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource;
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import eu.kanade.mangafeed.R;
|
||||
|
||||
public class PageFileTarget extends ViewTarget<SubsamplingScaleImageView, File> {
|
||||
|
||||
public PageFileTarget(SubsamplingScaleImageView view) {
|
||||
super(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(Drawable placeholder) {
|
||||
view.setImage(ImageSource.resource(R.drawable.ic_action_refresh));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadStarted(Drawable placeholder) {
|
||||
view.setImage(ImageSource.resource(R.drawable.ic_action_refresh));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {
|
||||
view.setImage(ImageSource.uri(Uri.fromFile(resource))
|
||||
.tilingDisabled());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/page_image_view" />
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
style="?android:attr/progressBarStyleLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/page_image_view" />
|
||||
|
||||
</FrameLayout>
|
Reference in a new issue