Use local filtering. Use long class instead of primitives again for database keys (they can be null)

This commit is contained in:
inorichi 2015-12-02 21:45:41 +01:00
parent 6b8ccbe01b
commit ab216a3608
8 changed files with 69 additions and 61 deletions

View File

@ -10,10 +10,10 @@ import eu.kanade.mangafeed.util.UrlUtil;
public class Chapter { public class Chapter {
@StorIOSQLiteColumn(name = ChapterTable.COLUMN_ID, key = true) @StorIOSQLiteColumn(name = ChapterTable.COLUMN_ID, key = true)
public long id; public Long id;
@StorIOSQLiteColumn(name = ChapterTable.COLUMN_MANGA_ID) @StorIOSQLiteColumn(name = ChapterTable.COLUMN_MANGA_ID)
public long manga_id; public Long manga_id;
@StorIOSQLiteColumn(name = ChapterTable.COLUMN_URL) @StorIOSQLiteColumn(name = ChapterTable.COLUMN_URL)
public String url; public String url;

View File

@ -10,7 +10,7 @@ import eu.kanade.mangafeed.util.UrlUtil;
public class Manga { public class Manga {
@StorIOSQLiteColumn(name = MangaTable.COLUMN_ID, key = true) @StorIOSQLiteColumn(name = MangaTable.COLUMN_ID, key = true)
public long id; public Long id;
@StorIOSQLiteColumn(name = MangaTable.COLUMN_SOURCE) @StorIOSQLiteColumn(name = MangaTable.COLUMN_SOURCE)
public int source; public int source;

View File

@ -133,7 +133,7 @@ public class DownloadManager {
private boolean prepareDownload(Download download) { private boolean prepareDownload(Download download) {
// If the chapter is already queued, don't add it again // If the chapter is already queued, don't add it again
for (Download queuedDownload : queue.get()) { for (Download queuedDownload : queue.get()) {
if (download.chapter.id == queuedDownload.chapter.id) if (download.chapter.id.equals(queuedDownload.chapter.id))
return true; return true;
} }

View File

@ -31,7 +31,7 @@ public class DownloadQueue {
public void remove(Chapter chapter) { public void remove(Chapter chapter) {
for (Download download : queue) { for (Download download : queue) {
if (download.chapter.id == chapter.id) { if (download.chapter.id.equals(chapter.id)) {
remove(download); remove(download);
break; break;
} }

View File

@ -155,7 +155,7 @@ public class CatalogueFragment extends BaseRxFragment<CataloguePresenter> {
private int getMangaIndex(Manga manga) { private int getMangaIndex(Manga manga) {
for (int i = adapter.getCount() - 1; i >= 0; i--) { for (int i = adapter.getCount() - 1; i >= 0; i--) {
if (manga.id == adapter.getItem(i).id) { if (manga.id.equals(adapter.getItem(i).id)) {
return i; return i;
} }
} }

View File

@ -160,13 +160,13 @@ public class ChaptersFragment extends BaseRxFragment<ChaptersPresenter> implemen
public void onEventMainThread(DownloadStatusEvent event) { public void onEventMainThread(DownloadStatusEvent event) {
Manga manga = getPresenter().getManga(); Manga manga = getPresenter().getManga();
// If the download status is from another manga, don't bother // If the download status is from another manga, don't bother
if (manga != null && event.getChapter().manga_id != manga.id) if (manga != null && !event.getChapter().manga_id.equals(manga.id))
return; return;
Chapter chapter; Chapter chapter;
for (int i = 0; i < adapter.getItemCount(); i++) { for (int i = 0; i < adapter.getItemCount(); i++) {
chapter = adapter.getItem(i); chapter = adapter.getItem(i);
if (event.getChapter().id == chapter.id) { if (event.getChapter().id.equals(chapter.id)) {
chapter.status = event.getStatus(); chapter.status = event.getStatus();
adapter.notifyItemChanged(i); adapter.notifyItemChanged(i);
break; break;

View File

@ -24,6 +24,7 @@ import eu.kanade.mangafeed.util.PostResult;
import rx.Observable; import rx.Observable;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers; import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
public class ChaptersPresenter extends BasePresenter<ChaptersFragment> { public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
@ -34,11 +35,14 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
private Manga manga; private Manga manga;
private Source source; private Source source;
private List<Chapter> chapters;
private boolean isCatalogueManga; private boolean isCatalogueManga;
private boolean sortOrderAToZ = true; private boolean sortOrderAToZ = true;
private boolean onlyUnread = true; private boolean onlyUnread = true;
private boolean onlyDownloaded; private boolean onlyDownloaded;
private PublishSubject<List<Chapter>> chaptersSubject;
private static final int DB_CHAPTERS = 1; private static final int DB_CHAPTERS = 1;
private static final int FETCH_CHAPTERS = 2; private static final int FETCH_CHAPTERS = 2;
@ -46,12 +50,11 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
protected void onCreate(Bundle savedState) { protected void onCreate(Bundle savedState) {
super.onCreate(savedState); super.onCreate(savedState);
chaptersSubject = PublishSubject.create();
restartableLatestCache(DB_CHAPTERS, restartableLatestCache(DB_CHAPTERS,
this::getDbChaptersObs, this::getDbChaptersObs,
(view, chapters) -> { ChaptersFragment::onNextChapters
view.onNextChapters(chapters);
EventBus.getDefault().postSticky(new ChapterCountEvent(chapters.size()));
}
); );
restartableLatestCache(FETCH_CHAPTERS, restartableLatestCache(FETCH_CHAPTERS,
@ -85,6 +88,14 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
source = sourceManager.get(manga.source); source = sourceManager.get(manga.source);
start(DB_CHAPTERS); start(DB_CHAPTERS);
add(db.getChapters(manga).createObservable()
.subscribeOn(Schedulers.io())
.doOnNext(chapters -> {
this.chapters = chapters;
EventBus.getDefault().postSticky(new ChapterCountEvent(chapters.size()));
})
.subscribe(chaptersSubject::onNext));
// Get chapters if it's an online source // Get chapters if it's an online source
if (isCatalogueManga) { if (isCatalogueManga) {
fetchChapters(); fetchChapters();
@ -96,14 +107,6 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
start(FETCH_CHAPTERS); start(FETCH_CHAPTERS);
} }
private Observable<List<Chapter>> getDbChaptersObs() {
return db.getChapters(manga.id, sortOrderAToZ, onlyUnread).createObservable()
.doOnNext(this::checkChaptersStatus)
.flatMap(this::applyDownloadedFilter)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private Observable<PostResult> getOnlineChaptersObs() { private Observable<PostResult> getOnlineChaptersObs() {
return source return source
.pullChaptersFromNetwork(manga.url) .pullChaptersFromNetwork(manga.url)
@ -112,16 +115,54 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
.observeOn(AndroidSchedulers.mainThread()); .observeOn(AndroidSchedulers.mainThread());
} }
private Observable<List<Chapter>> getDbChaptersObs() {
return chaptersSubject
.observeOn(Schedulers.io())
.flatMap(this::applyChapterFilters)
.observeOn(AndroidSchedulers.mainThread());
}
private Observable<List<Chapter>> applyChapterFilters(List<Chapter> chapters) {
Observable<Chapter> observable = Observable.from(chapters);
if (onlyUnread) {
observable = observable.filter(chapter -> !chapter.read);
}
observable = observable.doOnNext(this::setChapterStatus);
if (onlyDownloaded) {
observable = observable.filter(chapter -> chapter.status == Download.DOWNLOADED);
}
return observable.toSortedList((chapter, chapter2) -> {
if (sortOrderAToZ) {
return Float.compare(chapter.chapter_number, chapter2.chapter_number);
} else {
return Float.compare(chapter2.chapter_number, chapter.chapter_number);
}
});
}
private void setChapterStatus(Chapter chapter) {
for (Download download : downloadManager.getQueue().get()) {
if (chapter.id.equals(download.chapter.id)) {
chapter.status = download.getStatus();
return;
}
}
if (downloadManager.isChapterDownloaded(source, manga, chapter)) {
chapter.status = Download.DOWNLOADED;
} else {
chapter.status = Download.NOT_DOWNLOADED;
}
}
public void onOpenChapter(Chapter chapter) { public void onOpenChapter(Chapter chapter) {
EventBus.getDefault().postSticky(new ReaderEvent(source, manga, chapter)); EventBus.getDefault().postSticky(new ReaderEvent(source, manga, chapter));
} }
public Chapter getNextUnreadChapter() { public Chapter getNextUnreadChapter() {
List<Chapter> chapters = db.getNextUnreadChapter(manga).executeAsBlocking(); List<Chapter> chapters = db.getNextUnreadChapter(manga).executeAsBlocking();
if (chapters.isEmpty()) { return !chapters.isEmpty() ? chapters.get(0) : null;
return null;
}
return chapters.get(0);
} }
public void markChaptersRead(Observable<Chapter> selectedChapters, boolean read) { public void markChaptersRead(Observable<Chapter> selectedChapters, boolean read) {
@ -154,51 +195,21 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
})); }));
} }
private void checkChaptersStatus(List<Chapter> chapters) {
for (Chapter chapter : chapters) {
checkIsChapterDownloaded(chapter);
}
}
private void checkIsChapterDownloaded(Chapter chapter) {
for (Download download : downloadManager.getQueue().get()) {
if (chapter.id == download.chapter.id) {
chapter.status = download.getStatus();
return;
}
}
if (downloadManager.isChapterDownloaded(source, manga, chapter)) {
chapter.status = Download.DOWNLOADED;
} else {
chapter.status = Download.NOT_DOWNLOADED;
}
}
private Observable<List<Chapter>> applyDownloadedFilter(List<Chapter> chapters) {
if (onlyDownloaded)
return Observable.from(chapters)
.filter(chapter -> chapter.status == Download.DOWNLOADED)
.toList();
return Observable.just(chapters);
}
public void revertSortOrder() { public void revertSortOrder() {
//TODO manga.chapter_order //TODO manga.chapter_order
sortOrderAToZ = !sortOrderAToZ; sortOrderAToZ = !sortOrderAToZ;
start(DB_CHAPTERS); chaptersSubject.onNext(chapters);
} }
public void setReadFilter(boolean onlyUnread) { public void setReadFilter(boolean onlyUnread) {
//TODO do we need save filter for manga? //TODO do we need save filter for manga?
this.onlyUnread = onlyUnread; this.onlyUnread = onlyUnread;
start(DB_CHAPTERS); chaptersSubject.onNext(chapters);
} }
public void setDownloadedFilter(boolean onlyDownloaded) { public void setDownloadedFilter(boolean onlyDownloaded) {
this.onlyDownloaded = onlyDownloaded; this.onlyDownloaded = onlyDownloaded;
start(DB_CHAPTERS); chaptersSubject.onNext(chapters);
} }
public void setIsCatalogueManga(boolean value) { public void setIsCatalogueManga(boolean value) {

View File

@ -215,10 +215,7 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
// Check whether the given chapter is downloaded // Check whether the given chapter is downloaded
public boolean isChapterDownloaded(Chapter chapter) { public boolean isChapterDownloaded(Chapter chapter) {
File dir = downloadManager.getAbsoluteChapterDirectory(source, manga, chapter); return downloadManager.isChapterDownloaded(source, manga, chapter);
List<Page> pageList = downloadManager.getSavedPageList(source, manga, chapter);
return pageList != null && pageList.size() + 1 == dir.listFiles().length;
} }
// Called before loading another chapter or leaving the reader. It allows to do operations // Called before loading another chapter or leaving the reader. It allows to do operations