Переглянути джерело

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

inorichi 9 роки тому
батько
коміт
ceb56e2c8a

+ 8 - 1
app/src/main/java/eu/kanade/mangafeed/data/helpers/DownloadManager.java

@@ -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() {

+ 1 - 0
app/src/main/java/eu/kanade/mangafeed/data/models/Download.java

@@ -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;

+ 25 - 15
app/src/main/java/eu/kanade/mangafeed/presenter/DownloadQueuePresenter.java

@@ -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();
         }

+ 18 - 0
app/src/main/java/eu/kanade/mangafeed/ui/adapter/DownloadAdapter.java

@@ -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;
+    }
+}

+ 32 - 11
app/src/main/java/eu/kanade/mangafeed/ui/fragment/DownloadQueueFragment.java

@@ -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);
+        }
+    }
 }

+ 4 - 0
app/src/main/java/eu/kanade/mangafeed/ui/holder/DownloadHolder.java

@@ -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);
         }
     }