Get rid of getView() calls in Chapters presenter. Minor changes in download manager

This commit is contained in:
inorichi 2015-12-02 09:50:01 +01:00
parent 771f49fa3b
commit b9da3cb914
9 changed files with 108 additions and 90 deletions

View File

@ -36,11 +36,7 @@ public class Chapter {
@StorIOSQLiteColumn(name = ChapterTable.COLUMN_CHAPTER_NUMBER)
public float chapter_number;
public int downloaded;
public static final int UNKNOWN = 0;
public static final int NOT_DOWNLOADED = 1;
public static final int DOWNLOADED = 2;
public int status;
public Chapter() {}

View File

@ -20,11 +20,11 @@ import eu.kanade.mangafeed.data.database.models.Chapter;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.download.model.Download;
import eu.kanade.mangafeed.data.download.model.DownloadQueue;
import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
import eu.kanade.mangafeed.data.source.SourceManager;
import eu.kanade.mangafeed.event.DownloadChaptersEvent;
import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.event.DownloadChaptersEvent;
import eu.kanade.mangafeed.util.DiskUtils;
import eu.kanade.mangafeed.util.DynamicConcurrentMergeOperator;
import rx.Observable;
@ -112,15 +112,25 @@ public class DownloadManager {
for (Chapter chapter : event.getChapters()) {
Download download = new Download(source, manga, chapter);
if (!isChapterDownloaded(download)) {
if (!prepareDownload(download)) {
queue.add(download);
if (isRunning) downloadsQueueSubject.onNext(download);
}
}
}
// Check if a chapter is already downloaded
private boolean isChapterDownloaded(Download download) {
// Public method to checks if a chapter is downloaded
public boolean isChapterDownloaded(Source source, Manga manga, Chapter chapter) {
File directory = getAbsoluteChapterDirectory(source, manga, chapter);
if (!directory.exists())
return false;
List<Page> pages = getSavedPageList(source, manga, chapter);
return isChapterDownloaded(directory, pages);
}
// Prepare the download. Returns true if the chapter is already downloaded
private boolean prepareDownload(Download download) {
// If the chapter is already queued, don't add it again
for (Download queuedDownload : queue.get()) {
if (download.chapter.id.equals(queuedDownload.chapter.id))
@ -135,8 +145,7 @@ public class DownloadManager {
return false;
}
// If the page list doesn't exist, the chapter isn't download (or maybe it's,
// but we consider it's not)
// If the page list doesn't exist, the chapter isn't downloaded
List<Page> savedPages = getSavedPageList(download);
if (savedPages == null)
return false;
@ -146,7 +155,12 @@ public class DownloadManager {
// If the number of files matches the number of pages, the chapter is downloaded.
// We have the index file, so we check one file more
return savedPages.size() + 1 == download.directory.listFiles().length;
return isChapterDownloaded(download.directory, download.pages);
}
// Check that all the images are downloaded
private boolean isChapterDownloaded(File directory, List<Page> pages) {
return pages != null && pages.size() + 1 == directory.listFiles().length;
}
// Download the entire chapter

View File

@ -22,16 +22,18 @@ public class Download {
private transient PublishSubject<Download> statusSubject;
public static final int QUEUE = 0;
public static final int DOWNLOADING = 1;
public static final int DOWNLOADED = 2;
public static final int ERROR = 3;
public static final int NOT_DOWNLOADED = 0;
public static final int QUEUE = 1;
public static final int DOWNLOADING = 2;
public static final int DOWNLOADED = 3;
public static final int ERROR = 4;
public Download(Source source, Manga manga, Chapter chapter) {
this.source = source;
this.manga = manga;
this.chapter = chapter;
this.status = QUEUE;
}
public int getStatus() {

View File

@ -4,13 +4,13 @@ import eu.kanade.mangafeed.data.database.models.Chapter;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.source.base.Source;
public class SourceMangaChapterEvent {
public class ReaderEvent {
private Source source;
private Manga manga;
private Chapter chapter;
public SourceMangaChapterEvent(Source source, Manga manga, Chapter chapter) {
public ReaderEvent(Source source, Manga manga, Chapter chapter) {
this.source = source;
this.manga = manga;
this.chapter = chapter;

View File

@ -92,7 +92,7 @@ public class MangaActivity extends BaseRxActivity<MangaPresenter> {
setToolbarTitle(manga.title);
}
public boolean isOnlineManga() {
public boolean isCatalogueManga() {
return is_online;
}

View File

@ -16,7 +16,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.List;
@ -30,6 +29,7 @@ import eu.kanade.mangafeed.ui.base.fragment.BaseRxFragment;
import eu.kanade.mangafeed.ui.decoration.DividerItemDecoration;
import eu.kanade.mangafeed.ui.manga.MangaActivity;
import eu.kanade.mangafeed.ui.reader.ReaderActivity;
import eu.kanade.mangafeed.util.ToastUtil;
import nucleus.factory.RequiresPresenter;
import rx.Observable;
@ -58,6 +58,7 @@ public class ChaptersFragment extends BaseRxFragment<ChaptersPresenter> implemen
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
setHasOptionsMenu(true);
getPresenter().setIsCatalogueManga(isCatalogueManga());
}
@Override
@ -67,21 +68,29 @@ public class ChaptersFragment extends BaseRxFragment<ChaptersPresenter> implemen
View view = inflater.inflate(R.layout.fragment_manga_chapters, container, false);
ButterKnife.bind(this, view);
// Init RecyclerView and adapter
chapters.setLayoutManager(new LinearLayoutManager(getActivity()));
chapters.addItemDecoration(new DividerItemDecoration(ContextCompat.getDrawable(this.getContext(), R.drawable.line_divider)));
createAdapter();
setSwipeRefreshListener();
adapter = new ChaptersAdapter(this);
chapters.setAdapter(adapter);
readCb.setOnCheckedChangeListener((arg, isCheked) -> getPresenter().setReadFilter(isCheked));
// Set initial values
setReadFilter(getPresenter().getReadFilter());
setSortIcon(getPresenter().getSortOrder());
// Init listeners
swipeRefresh.setOnRefreshListener(this::onFetchChapters);
readCb.setOnCheckedChangeListener((arg, isChecked) -> getPresenter().setReadFilter(isChecked));
sortBtn.setOnClickListener(v -> getPresenter().revertSortOrder());
nextUnreadBtn.setOnClickListener(v -> {
Chapter chapter = getPresenter().getNextUnreadChapter();
if (chapter != null) {
openChapter(chapter);
} else {
Toast.makeText(getContext(), R.string.no_next_chapter, Toast.LENGTH_SHORT).show();
ToastUtil.showShort(getContext(), R.string.no_next_chapter);
}
});
return view;
}
@ -89,49 +98,38 @@ public class ChaptersFragment extends BaseRxFragment<ChaptersPresenter> implemen
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.chapters, menu);
super.onCreateOptionsMenu(menu, inflater);
getPresenter().initSortIcon();
getPresenter().initReadCb();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
getPresenter().refreshChapters();
onFetchChapters();
break;
}
return super.onOptionsItemSelected(item);
}
private void createAdapter() {
adapter = new ChaptersAdapter(this);
chapters.setAdapter(adapter);
}
private void setSwipeRefreshListener() {
swipeRefresh.setOnRefreshListener(() -> getPresenter().refreshChapters());
}
public void onNextChapters(List<Chapter> chapters) {
adapter.setItems(chapters);
closeActionMode();
adapter.setItems(chapters);
}
public void onNextOnlineChapters() {
public void onFetchChapters() {
swipeRefresh.setRefreshing(true);
getPresenter().fetchChapters();
}
public void onFetchChaptersFinish() {
swipeRefresh.setRefreshing(false);
}
public void setSwipeRefreshing() {
swipeRefresh.setRefreshing(true);
}
public boolean isOnlineManga() {
return ((MangaActivity) getActivity()).isOnlineManga();
public boolean isCatalogueManga() {
return ((MangaActivity) getActivity()).isCatalogueManga();
}
protected void openChapter(Chapter chapter) {
getPresenter().onChapterClicked(chapter);
getPresenter().onOpenChapter(chapter);
Intent intent = ReaderActivity.newIntent(getActivity());
startActivity(intent);
}

View File

@ -15,6 +15,7 @@ import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.database.models.Chapter;
import eu.kanade.mangafeed.data.download.model.Download;
import rx.Observable;
public class ChaptersHolder extends RecyclerView.ViewHolder implements
@ -61,12 +62,9 @@ public class ChaptersHolder extends RecyclerView.ViewHolder implements
pages.setText("");
}
if (chapter.downloaded == Chapter.UNKNOWN) {
adapter.getChaptersFragment().getPresenter().checkIsChapterDownloaded(chapter);
}
if (chapter.downloaded == Chapter.DOWNLOADED) {
if (chapter.status == Download.DOWNLOADED) {
downloadText.setVisibility(View.VISIBLE);
} else if (chapter.downloaded == Chapter.NOT_DOWNLOADED) {
} else if (chapter.status == Download.NOT_DOWNLOADED) {
downloadText.setVisibility(View.INVISIBLE);
}

View File

@ -2,7 +2,6 @@ package eu.kanade.mangafeed.ui.manga.chapter;
import android.os.Bundle;
import java.io.File;
import java.util.List;
import javax.inject.Inject;
@ -12,13 +11,13 @@ import eu.kanade.mangafeed.data.database.DatabaseHelper;
import eu.kanade.mangafeed.data.database.models.Chapter;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.download.DownloadManager;
import eu.kanade.mangafeed.data.download.model.Download;
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
import eu.kanade.mangafeed.data.source.SourceManager;
import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.event.ChapterCountEvent;
import eu.kanade.mangafeed.event.DownloadChaptersEvent;
import eu.kanade.mangafeed.event.SourceMangaChapterEvent;
import eu.kanade.mangafeed.event.ReaderEvent;
import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
import eu.kanade.mangafeed.util.EventBusHook;
import eu.kanade.mangafeed.util.PostResult;
@ -36,11 +35,12 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
private Manga manga;
private Source source;
private boolean isCatalogueManga;
private boolean sortOrderAToZ = true;
private boolean onlyUnread = true;
private static final int DB_CHAPTERS = 1;
private static final int ONLINE_CHAPTERS = 2;
private static final int FETCH_CHAPTERS = 2;
private Subscription markReadSubscription;
private Subscription downloadSubscription;
@ -58,9 +58,9 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
}
);
restartableLatestCache(ONLINE_CHAPTERS,
restartableLatestCache(FETCH_CHAPTERS,
this::getOnlineChaptersObs,
(view, result) -> view.onNextOnlineChapters()
(view, result) -> view.onFetchChaptersFinish()
);
}
@ -90,21 +90,19 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
start(DB_CHAPTERS);
// Get chapters if it's an online source
if (getView() != null && getView().isOnlineManga()) {
refreshChapters();
if (isCatalogueManga) {
fetchChapters();
}
}
}
public void refreshChapters() {
if (getView() != null)
getView().setSwipeRefreshing();
start(ONLINE_CHAPTERS);
public void fetchChapters() {
start(FETCH_CHAPTERS);
}
private Observable<List<Chapter>> getDbChaptersObs() {
return db.getChapters(manga.id, sortOrderAToZ, onlyUnread).createObservable()
.doOnNext(this::checkChaptersStatus)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
@ -117,13 +115,13 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
.observeOn(AndroidSchedulers.mainThread());
}
public void onChapterClicked(Chapter chapter) {
EventBus.getDefault().postSticky(new SourceMangaChapterEvent(source, manga, chapter));
public void onOpenChapter(Chapter chapter) {
EventBus.getDefault().postSticky(new ReaderEvent(source, manga, chapter));
}
public Chapter getNextUnreadChapter() {
List<Chapter> chapters = db.getNextUnreadChapter(manga).executeAsBlocking();
if(chapters.size() < 1){
if (chapters.isEmpty()) {
return null;
}
return chapters.get(0);
@ -159,42 +157,54 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
.doOnCompleted(() -> remove(deleteSubscription))
.subscribe(chapter -> {
downloadManager.deleteChapter(source, manga, chapter);
chapter.downloaded = Chapter.NOT_DOWNLOADED;
chapter.status = Download.NOT_DOWNLOADED;
});
}
private void checkChaptersStatus(List<Chapter> chapters) {
for (Chapter chapter : chapters) {
checkIsChapterDownloaded(chapter);
}
}
public void checkIsChapterDownloaded(Chapter chapter) {
File dir = downloadManager.getAbsoluteChapterDirectory(source, manga, chapter);
List<Page> pageList = downloadManager.getSavedPageList(source, manga, chapter);
for (Download download : downloadManager.getQueue().get()) {
if (chapter.id.equals(download.chapter.id)) {
chapter.status = download.getStatus();
return;
}
}
if (pageList != null && pageList.size() + 1 == dir.listFiles().length) {
chapter.downloaded = Chapter.DOWNLOADED;
if (downloadManager.isChapterDownloaded(source, manga, chapter)) {
chapter.status = Download.DOWNLOADED;
} else {
chapter.downloaded = Chapter.NOT_DOWNLOADED;
}
}
public void initSortIcon() {
if (getView() != null) {
getView().setSortIcon(sortOrderAToZ);//TODO manga.chapter_order
}
}
public void initReadCb() {
if (getView() != null) {
getView().setReadFilter(onlyUnread);//TODO do we need save filter for manga?
chapter.status = Download.NOT_DOWNLOADED;
}
}
public void revertSortOrder() {
//TODO manga.chapter_order
sortOrderAToZ = !sortOrderAToZ;
initSortIcon();
start(DB_CHAPTERS);
}
public void setReadFilter(boolean onlyUnread) {
//TODO do we need save filter for manga?
this.onlyUnread = onlyUnread;
initReadCb();
start(DB_CHAPTERS);
}
public void setIsCatalogueManga(boolean value) {
isCatalogueManga = value;
}
public boolean getSortOrder() {
return sortOrderAToZ;
}
public boolean getReadFilter() {
return onlyUnread;
}
}

View File

@ -20,7 +20,7 @@ import eu.kanade.mangafeed.data.preference.PreferencesHelper;
import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.event.RetryPageEvent;
import eu.kanade.mangafeed.event.SourceMangaChapterEvent;
import eu.kanade.mangafeed.event.ReaderEvent;
import eu.kanade.mangafeed.event.UpdateChapterSyncEvent;
import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
import eu.kanade.mangafeed.util.EventBusHook;
@ -118,7 +118,7 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
}
@EventBusHook
public void onEventMainThread(SourceMangaChapterEvent event) {
public void onEventMainThread(ReaderEvent event) {
EventBus.getDefault().removeStickyEvent(event);
source = event.getSource();
manga = event.getManga();