mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-17 15:39:16 +01:00
Improvements for downloads fragment
This commit is contained in:
parent
49a38821f2
commit
4aee1ca8a3
@ -84,7 +84,7 @@ public class DownloadManager {
|
|||||||
if (finished) {
|
if (finished) {
|
||||||
DownloadService.stop(context);
|
DownloadService.stop(context);
|
||||||
}
|
}
|
||||||
}, e -> Timber.e(e.fillInStackTrace(), e.getMessage()));
|
}, e -> Timber.e(e.getCause(), e.getMessage()));
|
||||||
|
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
}
|
}
|
||||||
@ -238,10 +238,12 @@ public class DownloadManager {
|
|||||||
try {
|
try {
|
||||||
DiskUtils.saveBufferedSourceToDirectory(resp.body().source(), directory, filename);
|
DiskUtils.saveBufferedSourceToDirectory(resp.body().source(), directory, filename);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
Timber.e(e.getCause(), e.getMessage());
|
||||||
return Observable.error(e);
|
return Observable.error(e);
|
||||||
}
|
}
|
||||||
return Observable.just(page);
|
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
|
// 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);
|
pages = gson.fromJson(reader, collectionType);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Timber.e(e.fillInStackTrace(), e.getMessage());
|
Timber.e(e.getCause(), e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
if (reader != null) try { reader.close(); } catch (IOException e) { /* Do nothing */ }
|
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.write(gson.toJson(pages).getBytes());
|
||||||
out.flush();
|
out.flush();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Timber.e(e.fillInStackTrace(), e.getMessage());
|
Timber.e(e.getCause(), e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
if (out != null) try { out.close(); } catch (IOException e) { /* Do nothing */ }
|
if (out != null) try { out.close(); } catch (IOException e) { /* Do nothing */ }
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,50 @@
|
|||||||
package eu.kanade.mangafeed.ui.download;
|
package eu.kanade.mangafeed.ui.download;
|
||||||
|
|
||||||
import android.content.Context;
|
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 eu.kanade.mangafeed.data.download.model.Download;
|
||||||
import uk.co.ribot.easyadapter.EasyRecyclerAdapter;
|
|
||||||
|
|
||||||
public class DownloadAdapter extends EasyRecyclerAdapter<Download> {
|
public class DownloadAdapter extends FlexibleAdapter<DownloadHolder, Download> {
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
public DownloadAdapter(Context context) {
|
public DownloadAdapter(Context context) {
|
||||||
super(context, DownloadHolder.class);
|
this.context = context;
|
||||||
|
mItems = new ArrayList<>();
|
||||||
|
setHasStableIds(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPositionForItem(Download item) {
|
@Override
|
||||||
return getItems() != null && getItems().size() > 0 ? getItems().indexOf(item) : -1;
|
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<Download> downloads) {
|
||||||
|
mItems = downloads;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDataSet(String param) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package eu.kanade.mangafeed.ui.download;
|
package eu.kanade.mangafeed.ui.download;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ProgressBar;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -21,8 +20,7 @@ import nucleus.factory.RequiresPresenter;
|
|||||||
@RequiresPresenter(DownloadPresenter.class)
|
@RequiresPresenter(DownloadPresenter.class)
|
||||||
public class DownloadFragment extends BaseRxFragment<DownloadPresenter> {
|
public class DownloadFragment extends BaseRxFragment<DownloadPresenter> {
|
||||||
|
|
||||||
@Bind(R.id.download_list) RecyclerView downloadList;
|
@Bind(R.id.download_list) RecyclerView recyclerView;
|
||||||
private LinearLayoutManager downloadListLayout;
|
|
||||||
private DownloadAdapter adapter;
|
private DownloadAdapter adapter;
|
||||||
|
|
||||||
public static DownloadFragment newInstance() {
|
public static DownloadFragment newInstance() {
|
||||||
@ -38,8 +36,8 @@ public class DownloadFragment extends BaseRxFragment<DownloadPresenter> {
|
|||||||
|
|
||||||
setToolbarTitle(R.string.label_download_queue);
|
setToolbarTitle(R.string.label_download_queue);
|
||||||
|
|
||||||
downloadListLayout = new LinearLayoutManager(getActivity());
|
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||||
downloadList.setLayoutManager(downloadListLayout);
|
recyclerView.setHasFixedSize(true);
|
||||||
createAdapter();
|
createAdapter();
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
@ -47,39 +45,30 @@ public class DownloadFragment extends BaseRxFragment<DownloadPresenter> {
|
|||||||
|
|
||||||
private void createAdapter() {
|
private void createAdapter() {
|
||||||
adapter = new DownloadAdapter(getActivity());
|
adapter = new DownloadAdapter(getActivity());
|
||||||
downloadList.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNextDownloads(List<Download> downloads) {
|
public void onNextDownloads(List<Download> downloads) {
|
||||||
adapter.setItems(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) {
|
public void updateProgress(Download download) {
|
||||||
View row = getDownloadRow(download);
|
DownloadHolder holder = getHolder(download);
|
||||||
if (row != null) {
|
if (holder != null) {
|
||||||
ProgressBar progress = (ProgressBar) row.findViewById(R.id.download_progress);
|
holder.setDownloadProgress(download);
|
||||||
if (progress.getMax() == 1) progress.setMax(download.pages.size() * 100);
|
|
||||||
progress.setProgress(download.totalProgress);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateDownloadedPages(Download download) {
|
public void updateDownloadedPages(Download download) {
|
||||||
View row = getDownloadRow(download);
|
DownloadHolder holder = getHolder(download);
|
||||||
if (row != null) {
|
if (holder != null) {
|
||||||
TextView progress = (TextView) row.findViewById(R.id.download_progress_text);
|
holder.setDownloadedPages(download);
|
||||||
String progressText = download.downloadedImages + "/" + download.pages.size();
|
|
||||||
progress.setText(progressText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private DownloadHolder getHolder(Download download) {
|
||||||
|
return (DownloadHolder) recyclerView.findViewHolderForItemId(download.chapter.id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,27 @@
|
|||||||
package eu.kanade.mangafeed.ui.download;
|
package eu.kanade.mangafeed.ui.download;
|
||||||
|
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import butterknife.Bind;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
import eu.kanade.mangafeed.R;
|
import eu.kanade.mangafeed.R;
|
||||||
import eu.kanade.mangafeed.data.download.model.Download;
|
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 RecyclerView.ViewHolder {
|
||||||
public class DownloadHolder extends ItemViewHolder<Download> {
|
|
||||||
|
|
||||||
@ViewId(R.id.download_title) TextView downloadTitle;
|
@Bind(R.id.download_title) TextView downloadTitle;
|
||||||
@ViewId(R.id.download_progress) ProgressBar downloadProgress;
|
@Bind(R.id.download_progress) ProgressBar downloadProgress;
|
||||||
@ViewId(R.id.download_progress_text) TextView downloadProgressText;
|
@Bind(R.id.download_progress_text) TextView downloadProgressText;
|
||||||
|
|
||||||
public DownloadHolder(View view) {
|
public DownloadHolder(View view) {
|
||||||
super(view);
|
super(view);
|
||||||
|
ButterKnife.bind(this, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void onSetValues(Download download) {
|
||||||
public void onSetValues(Download download, PositionInfo positionInfo) {
|
|
||||||
downloadTitle.setText(download.chapter.name);
|
downloadTitle.setText(download.chapter.name);
|
||||||
|
|
||||||
if (download.pages == null) {
|
if (download.pages == null) {
|
||||||
@ -32,10 +30,20 @@ public class DownloadHolder extends ItemViewHolder<Download> {
|
|||||||
downloadProgressText.setText("");
|
downloadProgressText.setText("");
|
||||||
} else {
|
} else {
|
||||||
downloadProgress.setMax(download.pages.size() * 100);
|
downloadProgress.setMax(download.pages.size() * 100);
|
||||||
downloadProgress.setProgress(download.totalProgress);
|
setDownloadProgress(download);
|
||||||
String progressText = download.downloadedImages + "/" + download.pages.size();
|
setDownloadedPages(download);
|
||||||
downloadProgressText.setText(progressText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ import rx.Observable;
|
|||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
import rx.schedulers.Schedulers;
|
import rx.schedulers.Schedulers;
|
||||||
import rx.subjects.PublishSubject;
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class DownloadPresenter extends BasePresenter<DownloadFragment> {
|
public class DownloadPresenter extends BasePresenter<DownloadFragment> {
|
||||||
@ -25,8 +24,8 @@ public class DownloadPresenter extends BasePresenter<DownloadFragment> {
|
|||||||
|
|
||||||
private DownloadQueue downloadQueue;
|
private DownloadQueue downloadQueue;
|
||||||
private Subscription statusSubscription;
|
private Subscription statusSubscription;
|
||||||
|
private Subscription pageProgressSubscription;
|
||||||
private HashMap<Download, Subscription> progressSubscriptions;
|
private HashMap<Download, Subscription> progressSubscriptions;
|
||||||
private HashMap<Download, Subscription> pageStatusSubscriptions;
|
|
||||||
|
|
||||||
public final static int GET_DOWNLOAD_QUEUE = 1;
|
public final static int GET_DOWNLOAD_QUEUE = 1;
|
||||||
|
|
||||||
@ -36,7 +35,6 @@ public class DownloadPresenter extends BasePresenter<DownloadFragment> {
|
|||||||
|
|
||||||
downloadQueue = downloadManager.getQueue();
|
downloadQueue = downloadManager.getQueue();
|
||||||
progressSubscriptions = new HashMap<>();
|
progressSubscriptions = new HashMap<>();
|
||||||
pageStatusSubscriptions = new HashMap<>();
|
|
||||||
|
|
||||||
restartableLatestCache(GET_DOWNLOAD_QUEUE,
|
restartableLatestCache(GET_DOWNLOAD_QUEUE,
|
||||||
() -> Observable.just(downloadQueue.get()),
|
() -> Observable.just(downloadQueue.get()),
|
||||||
@ -57,6 +55,10 @@ public class DownloadPresenter extends BasePresenter<DownloadFragment> {
|
|||||||
.subscribe(download -> {
|
.subscribe(download -> {
|
||||||
processStatus(download, view);
|
processStatus(download, view);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
add(pageProgressSubscription = downloadQueue.getProgressObservable()
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(view::updateDownloadedPages));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -69,17 +71,16 @@ public class DownloadPresenter extends BasePresenter<DownloadFragment> {
|
|||||||
switch (download.getStatus()) {
|
switch (download.getStatus()) {
|
||||||
case Download.DOWNLOADING:
|
case Download.DOWNLOADING:
|
||||||
observeProgress(download, view);
|
observeProgress(download, view);
|
||||||
observePagesStatus(download, view);
|
// Initial update of the downloaded pages
|
||||||
|
view.updateDownloadedPages(download);
|
||||||
break;
|
break;
|
||||||
case Download.DOWNLOADED:
|
case Download.DOWNLOADED:
|
||||||
unsubscribeProgress(download);
|
unsubscribeProgress(download);
|
||||||
unsubscribePagesStatus(download);
|
|
||||||
view.updateProgress(download);
|
view.updateProgress(download);
|
||||||
view.updateDownloadedPages(download);
|
view.updateDownloadedPages(download);
|
||||||
break;
|
break;
|
||||||
case Download.ERROR:
|
case Download.ERROR:
|
||||||
unsubscribeProgress(download);
|
unsubscribeProgress(download);
|
||||||
unsubscribePagesStatus(download);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,62 +105,19 @@ public class DownloadPresenter extends BasePresenter<DownloadFragment> {
|
|||||||
progressSubscriptions.put(download, subscription);
|
progressSubscriptions.put(download, subscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void observePagesStatus(Download download, DownloadFragment view) {
|
|
||||||
// Initial update of the downloaded pages
|
|
||||||
view.updateDownloadedPages(download);
|
|
||||||
|
|
||||||
PublishSubject<Integer> 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) {
|
private void unsubscribeProgress(Download download) {
|
||||||
Subscription subscription = progressSubscriptions.remove(download);
|
Subscription subscription = progressSubscriptions.remove(download);
|
||||||
if (subscription != null)
|
if (subscription != null)
|
||||||
subscription.unsubscribe();
|
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() {
|
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()) {
|
for (Subscription subscription : progressSubscriptions.values()) {
|
||||||
subscription.unsubscribe();
|
subscription.unsubscribe();
|
||||||
}
|
}
|
||||||
progressSubscriptions.clear();
|
progressSubscriptions.clear();
|
||||||
|
|
||||||
|
remove(pageProgressSubscription);
|
||||||
remove(statusSubscription);
|
remove(statusSubscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user