Use local filtering. Use long class instead of primitives again for database keys (they can be null)
This commit is contained in:
parent
6b8ccbe01b
commit
ab216a3608
8 changed files with 69 additions and 61 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Reference in a new issue