Better handling of loading progress and image load.
This commit is contained in:
parent
d26049155c
commit
e160f53bb2
11 changed files with 108 additions and 87 deletions
|
@ -1,6 +1,7 @@
|
|||
package eu.kanade.mangafeed.data.models;
|
||||
|
||||
import eu.kanade.mangafeed.data.helpers.NetworkHelper;
|
||||
import rx.subjects.PublishSubject;
|
||||
|
||||
public class Page implements NetworkHelper.ProgressListener {
|
||||
|
||||
|
@ -8,12 +9,16 @@ public class Page implements NetworkHelper.ProgressListener {
|
|||
private String url;
|
||||
private String imageUrl;
|
||||
private String imagePath;
|
||||
private int status;
|
||||
private int progress;
|
||||
private transient int status;
|
||||
private transient int progress;
|
||||
|
||||
public static final int DOWNLOAD = 0;
|
||||
public static final int READY = 1;
|
||||
public static final int ERROR = 2;
|
||||
private transient PublishSubject<Integer> statusSubject;
|
||||
|
||||
public static final int QUEUE = 0;
|
||||
public static final int LOAD_PAGE = 1;
|
||||
public static final int DOWNLOAD_IMAGE = 2;
|
||||
public static final int READY = 3;
|
||||
public static final int ERROR = 4;
|
||||
|
||||
public Page(int pageNumber, String url, String imageUrl, String imagePath) {
|
||||
this.pageNumber = pageNumber;
|
||||
|
@ -56,6 +61,8 @@ public class Page implements NetworkHelper.ProgressListener {
|
|||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
if (statusSubject != null)
|
||||
statusSubject.onNext(status);
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
|
@ -76,4 +83,8 @@ public class Page implements NetworkHelper.ProgressListener {
|
|||
progress = (int) ((100 * bytesRead) / contentLength);
|
||||
}
|
||||
|
||||
public void setStatusSubject(PublishSubject<Integer> subject) {
|
||||
this.statusSubject = subject;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,10 +47,6 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
|
|||
restartableReplay(GET_PAGE_IMAGES,
|
||||
this::getPageImagesObservable,
|
||||
(view, page) -> {
|
||||
view.onNextPage(page);
|
||||
if (page.getPageNumber() == savedSelectedPage) {
|
||||
view.setCurrentPage(savedSelectedPage);
|
||||
}
|
||||
},
|
||||
(view, error) -> Timber.e("An error occurred while downloading an image"));
|
||||
}
|
||||
|
|
|
@ -80,7 +80,6 @@ public abstract class Source extends BaseSource {
|
|||
public Observable<Page> getRemainingImageUrlsFromPageList(final List<Page> pages) {
|
||||
return Observable.from(pages)
|
||||
.filter(page -> page.getImageUrl() == null)
|
||||
.doOnNext(page -> page.setStatus(Page.DOWNLOAD))
|
||||
.window(overrideNumberOfConcurrentPageDownloads())
|
||||
.concatMap(batchedPages ->
|
||||
batchedPages.concatMap(this::getImageUrlFromPage)
|
||||
|
@ -88,6 +87,7 @@ public abstract class Source extends BaseSource {
|
|||
}
|
||||
|
||||
private Observable<Page> getImageUrlFromPage(final Page page) {
|
||||
page.setStatus(Page.LOAD_PAGE);
|
||||
return mNetworkService
|
||||
.getStringResponse(overrideRemainingPagesUrl(page.getUrl()), mRequestHeaders, null)
|
||||
.flatMap(unparsedHtml -> Observable.just(parseHtmlToImageUrl(unparsedHtml)))
|
||||
|
@ -108,7 +108,7 @@ public abstract class Source extends BaseSource {
|
|||
return obs;
|
||||
|
||||
if (!mCacheManager.isImageInCache(page.getImageUrl())) {
|
||||
page.setStatus(Page.DOWNLOAD);
|
||||
page.setStatus(Page.DOWNLOAD_IMAGE);
|
||||
obs = cacheImage(page);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,10 +71,6 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
|
|||
viewer.onPageListReady(pages);
|
||||
}
|
||||
|
||||
public void onNextPage(Page page) {
|
||||
viewer.onNextPage(page);
|
||||
}
|
||||
|
||||
public void onPageChanged(int currentPage, int totalPages) {
|
||||
String page = currentPage + "/" + totalPages;
|
||||
pageNumber.setText(page);
|
||||
|
|
|
@ -38,13 +38,4 @@ public class ReaderPageAdapter extends SmartFragmentStatePagerAdapter {
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void replacePage(int position, Page page) {
|
||||
pages.set(position, page);
|
||||
|
||||
ReaderPageFragment fragment = (ReaderPageFragment)getRegisteredFragment(position);
|
||||
if (fragment != null) {
|
||||
fragment.replacePage(page);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import rx.Observable;
|
|||
import rx.Subscription;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
import rx.subjects.PublishSubject;
|
||||
|
||||
public class ReaderPageFragment extends Fragment {
|
||||
|
||||
|
@ -35,6 +36,7 @@ public class ReaderPageFragment extends Fragment {
|
|||
|
||||
private Page page;
|
||||
private Subscription progressSubscription;
|
||||
private Subscription statusSubscription;
|
||||
|
||||
public static ReaderPageFragment newInstance(Page page) {
|
||||
ReaderPageFragment fragment = new ReaderPageFragment();
|
||||
|
@ -48,35 +50,6 @@ public class ReaderPageFragment extends Fragment {
|
|||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
public void replacePage(Page page) {
|
||||
unsubscribeProgress();
|
||||
this.page = page;
|
||||
loadImage();
|
||||
}
|
||||
|
||||
public void setPage(Page page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
private void loadImage() {
|
||||
if (page == null)
|
||||
return;
|
||||
|
||||
switch (page.getStatus()) {
|
||||
case (Page.READY):
|
||||
imageView.setImage(ImageSource.uri(page.getImagePath()).tilingDisabled());
|
||||
progressContainer.setVisibility(View.GONE);
|
||||
break;
|
||||
case (Page.DOWNLOAD):
|
||||
progressContainer.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
case (Page.ERROR):
|
||||
progressContainer.setVisibility(View.GONE);
|
||||
errorText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_page, container, false);
|
||||
|
@ -88,42 +61,111 @@ public class ReaderPageFragment extends Fragment {
|
|||
imageView.setOnTouchListener((v, motionEvent) ->
|
||||
((ReaderActivity) getActivity()).onImageTouch(motionEvent));
|
||||
|
||||
observeProgress();
|
||||
loadImage();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
observeStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
unsubscribeProgress();
|
||||
unsubscribeStatus();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
public void setPage(Page page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
private void showImage() {
|
||||
if (page == null || page.getImagePath() == null)
|
||||
return;
|
||||
|
||||
imageView.setImage(ImageSource.uri(page.getImagePath()));
|
||||
progressContainer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void showDownloading() {
|
||||
progressText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void showLoading() {
|
||||
progressText.setVisibility(View.VISIBLE);
|
||||
progressText.setText(R.string.downloading);
|
||||
}
|
||||
|
||||
private void showError() {
|
||||
progressContainer.setVisibility(View.GONE);
|
||||
errorText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void processStatus(int status) {
|
||||
switch (status) {
|
||||
case Page.READY:
|
||||
showImage();
|
||||
unsubscribeProgress();
|
||||
unsubscribeStatus();
|
||||
break;
|
||||
case Page.LOAD_PAGE:
|
||||
showLoading();
|
||||
break;
|
||||
case Page.DOWNLOAD_IMAGE:
|
||||
showDownloading();
|
||||
break;
|
||||
case Page.ERROR:
|
||||
showError();
|
||||
unsubscribeProgress();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void observeStatus() {
|
||||
if (page == null)
|
||||
return;
|
||||
|
||||
if (page.getStatus() == Page.READY) {
|
||||
showImage();
|
||||
} else {
|
||||
processStatus(page.getStatus());
|
||||
|
||||
PublishSubject<Integer> statusSubject = PublishSubject.create();
|
||||
page.setStatusSubject(statusSubject);
|
||||
|
||||
observeProgress();
|
||||
|
||||
statusSubscription = statusSubject
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::processStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private void observeProgress() {
|
||||
if (page == null || page.getStatus() != Page.DOWNLOAD)
|
||||
return;
|
||||
|
||||
progressSubscription = Observable.interval(75, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(tick -> {
|
||||
if (page.getProgress() == 0) {
|
||||
progressText.setText(R.string.downloading);
|
||||
}
|
||||
else if (page.getProgress() == 100) {
|
||||
progressContainer.setVisibility(View.GONE);
|
||||
unsubscribeProgress();
|
||||
}
|
||||
else {
|
||||
progressText.setText(getString(R.string.download_progress, page.getProgress()));
|
||||
}
|
||||
if (page.getProgress() != 0)
|
||||
progressText.setText(
|
||||
getString(R.string.download_progress, page.getProgress()));
|
||||
});
|
||||
}
|
||||
|
||||
private void unsubscribeStatus() {
|
||||
if (statusSubscription != null) {
|
||||
page.setStatusSubject(null);
|
||||
statusSubscription.unsubscribe();
|
||||
statusSubscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void unsubscribeProgress() {
|
||||
if (progressSubscription != null)
|
||||
if (progressSubscription != null) {
|
||||
progressSubscription.unsubscribe();
|
||||
progressSubscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,11 +58,6 @@ public class VerticalViewer extends BaseViewer {
|
|||
updatePageNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextPage(Page page) {
|
||||
adapter.replacePage(getPosFromPage(page), page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onImageTouch(MotionEvent motionEvent) {
|
||||
return false;
|
||||
|
|
|
@ -33,11 +33,6 @@ public class WebtoonViewer extends BaseViewer {
|
|||
return adapter.getItemCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextPage(Page page) {
|
||||
adapter.setPage(getPosFromPage(page), page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageListReady(List<Page> pages) {
|
||||
adapter.setPages(pages);
|
||||
|
|
|
@ -33,6 +33,5 @@ public abstract class BaseViewer {
|
|||
|
||||
public abstract int getTotalPages();
|
||||
public abstract void onPageListReady(List<Page> pages);
|
||||
public abstract void onNextPage(Page page);
|
||||
public abstract boolean onImageTouch(MotionEvent motionEvent);
|
||||
}
|
||||
|
|
|
@ -71,11 +71,6 @@ public abstract class ViewPagerViewer extends BaseViewer {
|
|||
updatePageNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextPage(Page page) {
|
||||
adapter.replacePage(getPosFromPage(page), page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onImageTouch(MotionEvent motionEvent) {
|
||||
return viewPager.onImageTouch(motionEvent);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
android:layout_marginTop="16dp"
|
||||
android:id="@+id/progress_text"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="invisible"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
Reference in a new issue