mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Better handling of loading progress and image load.
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user