From 4aee1ca8a3fa4eabd01abbf7e0ac99da740395bf Mon Sep 17 00:00:00 2001 From: inorichi Date: Sun, 6 Dec 2015 12:27:05 +0100 Subject: [PATCH] Improvements for downloads fragment --- .../data/download/DownloadManager.java | 10 ++-- .../ui/download/DownloadAdapter.java | 43 ++++++++++++-- .../ui/download/DownloadFragment.java | 45 ++++++-------- .../mangafeed/ui/download/DownloadHolder.java | 36 +++++++----- .../ui/download/DownloadPresenter.java | 58 +++---------------- 5 files changed, 91 insertions(+), 101 deletions(-) diff --git a/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java b/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java index dbf9025dd7..0ead41ff9f 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java @@ -84,7 +84,7 @@ public class DownloadManager { if (finished) { DownloadService.stop(context); } - }, e -> Timber.e(e.fillInStackTrace(), e.getMessage())); + }, e -> Timber.e(e.getCause(), e.getMessage())); isRunning = true; } @@ -238,10 +238,12 @@ public class DownloadManager { try { DiskUtils.saveBufferedSourceToDirectory(resp.body().source(), directory, filename); } catch (Exception e) { + Timber.e(e.getCause(), e.getMessage()); return Observable.error(e); } return Observable.just(page); - }); + }) + .retry(2); } // Public method to get the image from the filesystem. It does NOT provide any way to download the image @@ -310,7 +312,7 @@ public class DownloadManager { pages = gson.fromJson(reader, collectionType); } } catch (FileNotFoundException e) { - Timber.e(e.fillInStackTrace(), e.getMessage()); + Timber.e(e.getCause(), e.getMessage()); } finally { if (reader != null) try { reader.close(); } catch (IOException e) { /* Do nothing */ } } @@ -333,7 +335,7 @@ public class DownloadManager { out.write(gson.toJson(pages).getBytes()); out.flush(); } catch (IOException e) { - Timber.e(e.fillInStackTrace(), e.getMessage()); + Timber.e(e.getCause(), e.getMessage()); } finally { if (out != null) try { out.close(); } catch (IOException e) { /* Do nothing */ } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadAdapter.java b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadAdapter.java index 25d021a2e6..0f6695d8bd 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadAdapter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadAdapter.java @@ -1,17 +1,50 @@ package eu.kanade.mangafeed.ui.download; import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import java.util.ArrayList; +import java.util.List; + +import eu.davidea.flexibleadapter.FlexibleAdapter; +import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.data.download.model.Download; -import uk.co.ribot.easyadapter.EasyRecyclerAdapter; -public class DownloadAdapter extends EasyRecyclerAdapter { +public class DownloadAdapter extends FlexibleAdapter { + + private Context context; public DownloadAdapter(Context context) { - super(context, DownloadHolder.class); + this.context = context; + mItems = new ArrayList<>(); + setHasStableIds(true); } - public int getPositionForItem(Download item) { - return getItems() != null && getItems().size() > 0 ? getItems().indexOf(item) : -1; + @Override + public DownloadHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View v = LayoutInflater.from(context).inflate(R.layout.item_download, parent, false); + return new DownloadHolder(v); } + + @Override + public void onBindViewHolder(DownloadHolder holder, int position) { + final Download download = getItem(position); + holder.onSetValues(download); + } + + @Override + public long getItemId(int position) { + return getItem(position).chapter.id; + } + + public void setItems(List downloads) { + mItems = downloads; + notifyDataSetChanged(); + } + + @Override + public void updateDataSet(String param) {} + } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadFragment.java index 258c5bc2f6..9c3c7db789 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadFragment.java @@ -1,13 +1,12 @@ package eu.kanade.mangafeed.ui.download; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; 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; @@ -21,8 +20,7 @@ import nucleus.factory.RequiresPresenter; @RequiresPresenter(DownloadPresenter.class) public class DownloadFragment extends BaseRxFragment { - @Bind(R.id.download_list) RecyclerView downloadList; - private LinearLayoutManager downloadListLayout; + @Bind(R.id.download_list) RecyclerView recyclerView; private DownloadAdapter adapter; public static DownloadFragment newInstance() { @@ -38,8 +36,8 @@ public class DownloadFragment extends BaseRxFragment { setToolbarTitle(R.string.label_download_queue); - downloadListLayout = new LinearLayoutManager(getActivity()); - downloadList.setLayoutManager(downloadListLayout); + recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + recyclerView.setHasFixedSize(true); createAdapter(); return view; @@ -47,39 +45,30 @@ public class DownloadFragment extends BaseRxFragment { private void createAdapter() { adapter = new DownloadAdapter(getActivity()); - downloadList.setAdapter(adapter); + recyclerView.setAdapter(adapter); } public void onNextDownloads(List downloads) { adapter.setItems(downloads); } - 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) { - 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); + DownloadHolder holder = getHolder(download); + if (holder != null) { + holder.setDownloadProgress(download); } } 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); + DownloadHolder holder = getHolder(download); + if (holder != null) { + holder.setDownloadedPages(download); } } + + @Nullable + private DownloadHolder getHolder(Download download) { + return (DownloadHolder) recyclerView.findViewHolderForItemId(download.chapter.id); + } + } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadHolder.java b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadHolder.java index 2e3201bda8..aef912ce68 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadHolder.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadHolder.java @@ -1,29 +1,27 @@ package eu.kanade.mangafeed.ui.download; +import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; +import butterknife.Bind; +import butterknife.ButterKnife; import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.data.download.model.Download; -import uk.co.ribot.easyadapter.ItemViewHolder; -import uk.co.ribot.easyadapter.PositionInfo; -import uk.co.ribot.easyadapter.annotations.LayoutId; -import uk.co.ribot.easyadapter.annotations.ViewId; -@LayoutId(R.layout.item_download) -public class DownloadHolder extends ItemViewHolder { +public class DownloadHolder extends RecyclerView.ViewHolder { - @ViewId(R.id.download_title) TextView downloadTitle; - @ViewId(R.id.download_progress) ProgressBar downloadProgress; - @ViewId(R.id.download_progress_text) TextView downloadProgressText; + @Bind(R.id.download_title) TextView downloadTitle; + @Bind(R.id.download_progress) ProgressBar downloadProgress; + @Bind(R.id.download_progress_text) TextView downloadProgressText; public DownloadHolder(View view) { super(view); + ButterKnife.bind(this, view); } - @Override - public void onSetValues(Download download, PositionInfo positionInfo) { + public void onSetValues(Download download) { downloadTitle.setText(download.chapter.name); if (download.pages == null) { @@ -32,10 +30,20 @@ public class DownloadHolder extends ItemViewHolder { downloadProgressText.setText(""); } else { downloadProgress.setMax(download.pages.size() * 100); - downloadProgress.setProgress(download.totalProgress); - String progressText = download.downloadedImages + "/" + download.pages.size(); - downloadProgressText.setText(progressText); + setDownloadProgress(download); + setDownloadedPages(download); } } + public void setDownloadedPages(Download download) { + String progressText = download.downloadedImages + "/" + download.pages.size(); + downloadProgressText.setText(progressText); + } + + public void setDownloadProgress(Download download) { + if (downloadProgress.getMax() == 1) + downloadProgress.setMax(download.pages.size() * 100); + downloadProgress.setProgress(download.totalProgress); + } + } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java index be6880a34b..4d4954c6b2 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java @@ -16,7 +16,6 @@ import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; -import rx.subjects.PublishSubject; import timber.log.Timber; public class DownloadPresenter extends BasePresenter { @@ -25,8 +24,8 @@ public class DownloadPresenter extends BasePresenter { private DownloadQueue downloadQueue; private Subscription statusSubscription; + private Subscription pageProgressSubscription; private HashMap progressSubscriptions; - private HashMap pageStatusSubscriptions; public final static int GET_DOWNLOAD_QUEUE = 1; @@ -36,7 +35,6 @@ public class DownloadPresenter extends BasePresenter { downloadQueue = downloadManager.getQueue(); progressSubscriptions = new HashMap<>(); - pageStatusSubscriptions = new HashMap<>(); restartableLatestCache(GET_DOWNLOAD_QUEUE, () -> Observable.just(downloadQueue.get()), @@ -57,6 +55,10 @@ public class DownloadPresenter extends BasePresenter { .subscribe(download -> { processStatus(download, view); })); + + add(pageProgressSubscription = downloadQueue.getProgressObservable() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(view::updateDownloadedPages)); } @Override @@ -69,17 +71,16 @@ public class DownloadPresenter extends BasePresenter { switch (download.getStatus()) { case Download.DOWNLOADING: observeProgress(download, view); - observePagesStatus(download, view); + // Initial update of the downloaded pages + view.updateDownloadedPages(download); break; case Download.DOWNLOADED: unsubscribeProgress(download); - unsubscribePagesStatus(download); view.updateProgress(download); view.updateDownloadedPages(download); break; case Download.ERROR: unsubscribeProgress(download); - unsubscribePagesStatus(download); break; } } @@ -104,62 +105,19 @@ public class DownloadPresenter extends BasePresenter { progressSubscriptions.put(download, subscription); } - private void observePagesStatus(Download download, DownloadFragment view) { - // Initial update of the downloaded pages - view.updateDownloadedPages(download); - - PublishSubject pageStatusSubject = PublishSubject.create(); - for (Page page : download.pages) { - if (page.getStatus() != Page.READY) - page.setStatusSubject(pageStatusSubject); - } - - Subscription subscription = pageStatusSubject - .filter(status -> status == Page.READY) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(status -> { - view.updateDownloadedPages(download); - }); - - // Avoid leaking subscriptions - Subscription oldSubscription = pageStatusSubscriptions.remove(download); - if (oldSubscription != null) oldSubscription.unsubscribe(); - - pageStatusSubscriptions.put(download, subscription); - } - private void unsubscribeProgress(Download download) { Subscription subscription = progressSubscriptions.remove(download); if (subscription != null) subscription.unsubscribe(); } - private void unsubscribePagesStatus(Download download) { - if (download.pages != null) { - for (Page page : download.pages) - page.setStatusSubject(null); - } - - Subscription subscription = pageStatusSubscriptions.remove(download); - if (subscription != null) - subscription.unsubscribe(); - } - private void destroySubscriptions() { - for (Download download : pageStatusSubscriptions.keySet()) { - for (Page page : download.pages) - page.setStatusSubject(null); - } - for (Subscription subscription : pageStatusSubscriptions.values()) { - subscription.unsubscribe(); - } - pageStatusSubscriptions.clear(); - for (Subscription subscription : progressSubscriptions.values()) { subscription.unsubscribe(); } progressSubscriptions.clear(); + remove(pageProgressSubscription); remove(statusSubscription); }