Update number of downloaded images in the queue, and improve the way the view refreshes the data

This commit is contained in:
inorichi 2015-11-09 03:31:50 +01:00
parent 7c37262a9f
commit ceb56e2c8a
6 changed files with 88 additions and 27 deletions

View File

@ -77,7 +77,6 @@ public class DownloadManager {
.subscribe(threadsNumber::onNext);
downloadsSubscription = downloadsQueueSubject
.observeOn(Schedulers.newThread())
.lift(new DynamicConcurrentMergeOperator<>(this::downloadChapter, threadsNumber))
.onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread())
@ -167,6 +166,8 @@ public class DownloadManager {
Observable.just(download.pages);
return pageListObservable
.subscribeOn(Schedulers.io())
.doOnNext(pages -> download.downloadedImages = 0)
.doOnNext(pages -> download.setStatus(Download.DOWNLOADING))
// Get all the URLs to the source images, fetch pages if necessary
.flatMap(pageList -> Observable.merge(
@ -174,6 +175,7 @@ public class DownloadManager {
download.source.getRemainingImageUrlsFromPageList(pageList)))
// Start downloading images, consider we can have downloaded images already
.concatMap(page -> getDownloadedImage(page, download.source, download.directory))
.doOnNext(p -> download.downloadedImages++)
// Do after download completes
.doOnCompleted(() -> onDownloadCompleted(download))
.toList()
@ -363,6 +365,11 @@ public class DownloadManager {
public void stopDownloads() {
destroySubscriptions();
for (Download download : queue.get()) {
if (download.getStatus() == Download.DOWNLOADING) {
download.setStatus(Download.ERROR);
}
}
}
public boolean isRunning() {

View File

@ -14,6 +14,7 @@ public class Download {
public File directory;
public transient volatile int totalProgress;
public transient volatile int downloadedImages;
private transient volatile int status;
private transient PublishSubject<Download> statusSubject;

View File

@ -4,7 +4,6 @@ import android.os.Bundle;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject;
@ -76,12 +75,17 @@ public class DownloadQueuePresenter extends BasePresenter<DownloadQueueFragment>
unsubscribeProgress(download);
unsubscribePagesStatus(download);
view.updateProgress(download);
view.updateDownloadedPages(download);
break;
case Download.ERROR:
unsubscribeProgress(download);
unsubscribePagesStatus(download);
break;
}
}
private void observeProgress(Download download, DownloadQueueFragment view) {
Subscription subscription = Observable.interval(75, TimeUnit.MILLISECONDS, Schedulers.newThread())
Subscription subscription = Observable.interval(50, TimeUnit.MILLISECONDS, Schedulers.newThread())
.flatMap(tick -> Observable.from(download.pages)
.map(Page::getProgress)
.reduce((x, y) -> x + y))
@ -93,26 +97,31 @@ public class DownloadQueuePresenter extends BasePresenter<DownloadQueueFragment>
}
});
// Avoid leaking subscriptions
Subscription oldSubscription = progressSubscriptions.remove(download);
if (oldSubscription != null) oldSubscription.unsubscribe();
progressSubscriptions.put(download, subscription);
}
private void observePagesStatus(Download download, DownloadQueueFragment view) {
PublishSubject<Integer> pageStatusSubject = PublishSubject.create();
for (Page page : download.pages)
page.setStatusSubject(pageStatusSubject);
final AtomicInteger downloadedPages = new AtomicInteger(0);
for (Page page : download.pages) {
if (page.getStatus() != Page.READY)
page.setStatusSubject(pageStatusSubject);
}
Subscription subscription = pageStatusSubject
.startWith(Observable.from(download.pages)
.filter(page -> page.getStatus() == Page.READY)
.map(page -> Page.READY))
.filter(status -> status == Page.READY)
.map(status -> downloadedPages.incrementAndGet())
.subscribe(count -> {
// TODO
.observeOn(AndroidSchedulers.mainThread())
.subscribe(status -> {
view.updateDownloadedPages(download);
});
// Avoid leaking subscriptions
Subscription oldSubscription = progressSubscriptions.remove(download);
if (oldSubscription != null) oldSubscription.unsubscribe();
pageStatusSubscriptions.put(download, subscription);
}
@ -123,8 +132,10 @@ public class DownloadQueuePresenter extends BasePresenter<DownloadQueueFragment>
}
private void unsubscribePagesStatus(Download download) {
for (Page page : download.pages)
page.setStatusSubject(null);
if (download.pages != null) {
for (Page page : download.pages)
page.setStatusSubject(null);
}
Subscription subscription = pageStatusSubscriptions.remove(download);
if (subscription != null)
@ -136,7 +147,6 @@ public class DownloadQueuePresenter extends BasePresenter<DownloadQueueFragment>
for (Page page : download.pages)
page.setStatusSubject(null);
}
for (Subscription subscription : pageStatusSubscriptions.values()) {
subscription.unsubscribe();
}

View File

@ -0,0 +1,18 @@
package eu.kanade.mangafeed.ui.adapter;
import android.content.Context;
import eu.kanade.mangafeed.data.models.Download;
import eu.kanade.mangafeed.ui.holder.DownloadHolder;
import uk.co.ribot.easyadapter.EasyRecyclerAdapter;
public class DownloadAdapter extends EasyRecyclerAdapter<Download> {
public DownloadAdapter(Context context) {
super(context, DownloadHolder.class);
}
public int getPositionForItem(Download item) {
return getItems() != null && getItems().size() > 0 ? getItems().indexOf(item) : -1;
}
}

View File

@ -6,6 +6,8 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.List;
@ -14,16 +16,16 @@ import butterknife.ButterKnife;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.models.Download;
import eu.kanade.mangafeed.presenter.DownloadQueuePresenter;
import eu.kanade.mangafeed.ui.adapter.DownloadAdapter;
import eu.kanade.mangafeed.ui.fragment.base.BaseRxFragment;
import eu.kanade.mangafeed.ui.holder.DownloadHolder;
import nucleus.factory.RequiresPresenter;
import uk.co.ribot.easyadapter.EasyRecyclerAdapter;
@RequiresPresenter(DownloadQueuePresenter.class)
public class DownloadQueueFragment extends BaseRxFragment<DownloadQueuePresenter> {
@Bind(R.id.download_list) RecyclerView downloadList;
private EasyRecyclerAdapter<Download> adapter;
private LinearLayoutManager downloadListLayout;
private DownloadAdapter adapter;
public static DownloadQueueFragment newInstance() {
return new DownloadQueueFragment();
@ -38,14 +40,15 @@ public class DownloadQueueFragment extends BaseRxFragment<DownloadQueuePresenter
setToolbarTitle(R.string.download_title);
downloadList.setLayoutManager(new LinearLayoutManager(getActivity()));
downloadListLayout = new LinearLayoutManager(getActivity());
downloadList.setLayoutManager(downloadListLayout);
createAdapter();
return view;
}
private void createAdapter() {
adapter = new EasyRecyclerAdapter<>(getActivity(), DownloadHolder.class);
adapter = new DownloadAdapter(getActivity());
downloadList.setAdapter(adapter);
}
@ -53,14 +56,32 @@ public class DownloadQueueFragment extends BaseRxFragment<DownloadQueuePresenter
adapter.setItems(downloads);
}
// TODO use a better approach
private View getDownloadRow(Download download) {
int first = downloadListLayout.findFirstVisibleItemPosition();
int last = downloadListLayout.findLastVisibleItemPosition();
int pos = adapter.getPositionForItem(download);
if (pos != -1 && pos >= first && pos <= last) {
return downloadListLayout.getChildAt(pos - first);
}
return null;
}
public void updateProgress(Download download) {
for (int i = 0; i < adapter.getItems().size(); i++) {
if (adapter.getItem(i) == download) {
adapter.notifyItemChanged(i);
break;
}
View row = getDownloadRow(download);
if (row != null) {
ProgressBar progress = (ProgressBar) row.findViewById(R.id.download_progress);
if (progress.getMax() == 1) progress.setMax(download.pages.size() * 100);
progress.setProgress(download.totalProgress);
}
}
public void updateDownloadedPages(Download download) {
View row = getDownloadRow(download);
if (row != null) {
TextView progress = (TextView) row.findViewById(R.id.download_progress_text);
String progressText = download.downloadedImages + "/" + download.pages.size();
progress.setText(progressText);
}
}
}

View File

@ -28,9 +28,13 @@ public class DownloadHolder extends ItemViewHolder<Download> {
if (download.pages == null) {
downloadProgress.setProgress(0);
downloadProgress.setMax(1);
downloadProgressText.setText("");
} else {
downloadProgress.setMax(download.pages.size() * 100);
downloadProgress.setProgress(download.totalProgress);
String progressText = download.downloadedImages + "/" + download.pages.size();
downloadProgressText.setText(progressText);
}
}