Initial support for read chapters

This commit is contained in:
inorichi 2015-10-29 00:45:51 +01:00
parent 5e01937cce
commit afebfec737
19 changed files with 77 additions and 53 deletions

View file

@ -73,6 +73,11 @@ public class DatabaseHelper implements MangaManager, ChapterManager {
return mChapterManager.insertChapters(chapters); return mChapterManager.insertChapters(chapters);
} }
@Override
public PutResult insertChapterBlock(Chapter chapter) {
return mChapterManager.insertChapterBlock(chapter);
}
@Override @Override
public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) { public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
return mChapterManager.insertOrRemoveChapters(manga, chapters); return mChapterManager.insertOrRemoveChapters(manga, chapters);

View file

@ -15,7 +15,6 @@ import java.net.CookieManager;
import java.net.CookiePolicy; import java.net.CookiePolicy;
import java.net.CookieStore; import java.net.CookieStore;
import eu.kanade.mangafeed.data.models.Page;
import okio.Buffer; import okio.Buffer;
import okio.BufferedSource; import okio.BufferedSource;
import okio.ForwardingSource; import okio.ForwardingSource;
@ -91,7 +90,7 @@ public final class NetworkHelper {
}); });
} }
public Observable<Response> getProgressResponse(final String url, final Headers headers, final Page page) { public Observable<Response> getProgressResponse(final String url, final Headers headers, final ProgressListener listener) {
return Observable.<Response>create(subscriber -> { return Observable.<Response>create(subscriber -> {
try { try {
if (!subscriber.isUnsubscribed()) { if (!subscriber.isUnsubscribed()) {
@ -106,7 +105,7 @@ public final class NetworkHelper {
progressClient.networkInterceptors().add(chain -> { progressClient.networkInterceptors().add(chain -> {
Response originalResponse = chain.proceed(chain.request()); Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder() return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse.body(), page)) .body(new ProgressResponseBody(originalResponse.body(), listener))
.build(); .build();
}); });
subscriber.onNext(progressClient.newCall(request).execute()); subscriber.onNext(progressClient.newCall(request).execute());

View file

@ -22,6 +22,8 @@ public interface ChapterManager {
Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters); Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters);
PutResult insertChapterBlock(Chapter chapter);
Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters); Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters);
Observable<DeleteResult> deleteChapter(Chapter chapter); Observable<DeleteResult> deleteChapter(Chapter chapter);

View file

@ -67,6 +67,14 @@ public class ChapterManagerImpl extends BaseManager implements ChapterManager {
.createObservable(); .createObservable();
} }
@Override
public PutResult insertChapterBlock(Chapter chapter) {
return db.put()
.object(chapter)
.prepare()
.executeAsBlocking();
}
// Add new chapters or delete if the source deletes them // Add new chapters or delete if the source deletes them
@Override @Override
public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) { public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {

View file

@ -1,8 +1,5 @@
package eu.kanade.mangafeed.data.models; package eu.kanade.mangafeed.data.models;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn; import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType; import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
@ -11,31 +8,27 @@ import eu.kanade.mangafeed.data.tables.ChaptersTable;
@StorIOSQLiteType(table = ChaptersTable.TABLE) @StorIOSQLiteType(table = ChaptersTable.TABLE)
public class Chapter { public class Chapter {
@Nullable
@StorIOSQLiteColumn(name = ChaptersTable.COLUMN_ID, key = true) @StorIOSQLiteColumn(name = ChaptersTable.COLUMN_ID, key = true)
public Long id; public Long id;
@NonNull
@StorIOSQLiteColumn(name = ChaptersTable.COLUMN_MANGA_ID) @StorIOSQLiteColumn(name = ChaptersTable.COLUMN_MANGA_ID)
public Long manga_id; public Long manga_id;
@NonNull
@StorIOSQLiteColumn(name = ChaptersTable.COLUMN_URL) @StorIOSQLiteColumn(name = ChaptersTable.COLUMN_URL)
public String url; public String url;
@NonNull
@StorIOSQLiteColumn(name = ChaptersTable.COLUMN_NAME) @StorIOSQLiteColumn(name = ChaptersTable.COLUMN_NAME)
public String name; public String name;
@NonNull
@StorIOSQLiteColumn(name = ChaptersTable.COLUMN_READ) @StorIOSQLiteColumn(name = ChaptersTable.COLUMN_READ)
public int read; public boolean read;
@StorIOSQLiteColumn(name = ChaptersTable.COLUMN_LAST_PAGE_READ)
public int last_page_read;
@NonNull
@StorIOSQLiteColumn(name = ChaptersTable.COLUMN_DATE_FETCH) @StorIOSQLiteColumn(name = ChaptersTable.COLUMN_DATE_FETCH)
public long date_fetch; public long date_fetch;
@NonNull
@StorIOSQLiteColumn(name = ChaptersTable.COLUMN_DATE_UPLOAD) @StorIOSQLiteColumn(name = ChaptersTable.COLUMN_DATE_UPLOAD)
public long date_upload; public long date_upload;

View file

@ -28,6 +28,9 @@ public class ChaptersTable {
@NonNull @NonNull
public static final String COLUMN_DATE_UPLOAD = "date_upload"; public static final String COLUMN_DATE_UPLOAD = "date_upload";
@NonNull
public static final String COLUMN_LAST_PAGE_READ = "last_page_read";
@NonNull @NonNull
public static String getCreateTableQuery() { public static String getCreateTableQuery() {
return "CREATE TABLE " + TABLE + "(" return "CREATE TABLE " + TABLE + "("
@ -36,6 +39,7 @@ public class ChaptersTable {
+ COLUMN_URL + " TEXT NOT NULL, " + COLUMN_URL + " TEXT NOT NULL, "
+ COLUMN_NAME + " TEXT NOT NULL, " + COLUMN_NAME + " TEXT NOT NULL, "
+ COLUMN_READ + " BOOLEAN NOT NULL, " + COLUMN_READ + " BOOLEAN NOT NULL, "
+ COLUMN_LAST_PAGE_READ + " INT NOT NULL, "
+ COLUMN_DATE_FETCH + " LONG NOT NULL, " + COLUMN_DATE_FETCH + " LONG NOT NULL, "
+ COLUMN_DATE_UPLOAD + " LONG NOT NULL, " + COLUMN_DATE_UPLOAD + " LONG NOT NULL, "
+ "FOREIGN KEY(" + COLUMN_MANGA_ID + ") REFERENCES " + MangasTable.TABLE + "(" + MangasTable.COLUMN_ID + ") " + "FOREIGN KEY(" + COLUMN_MANGA_ID + ") REFERENCES " + MangasTable.TABLE + "(" + MangasTable.COLUMN_ID + ") "

View file

@ -7,6 +7,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import de.greenrobot.event.EventBus; import de.greenrobot.event.EventBus;
import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
import eu.kanade.mangafeed.data.helpers.PreferencesHelper; import eu.kanade.mangafeed.data.helpers.PreferencesHelper;
import eu.kanade.mangafeed.data.models.Chapter; import eu.kanade.mangafeed.data.models.Chapter;
import eu.kanade.mangafeed.data.models.Page; import eu.kanade.mangafeed.data.models.Page;
@ -23,11 +24,13 @@ import timber.log.Timber;
public class ReaderPresenter extends BasePresenter<ReaderActivity> { public class ReaderPresenter extends BasePresenter<ReaderActivity> {
@Inject PreferencesHelper prefs; @Inject PreferencesHelper prefs;
@Inject DatabaseHelper db;
private Source source; private Source source;
private Chapter chapter; private Chapter chapter;
private List<Page> pageList; private List<Page> pageList;
@State int savedSelectedPage = 0; private boolean initialStart = true;
@State int currentPage = 0;
private static final int GET_PAGE_LIST = 1; private static final int GET_PAGE_LIST = 1;
private static final int GET_PAGE_IMAGES = 2; private static final int GET_PAGE_IMAGES = 2;
@ -42,9 +45,10 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
.doOnCompleted(() -> start(GET_PAGE_IMAGES)), .doOnCompleted(() -> start(GET_PAGE_IMAGES)),
(view, pages) -> { (view, pages) -> {
view.onPageListReady(pages); view.onPageListReady(pages);
if (savedSelectedPage != 0) { if (initialStart && !chapter.read)
view.setSelectedPage(savedSelectedPage); view.setSelectedPage(chapter.last_page_read - 1);
} else if (currentPage != 0)
view.setSelectedPage(currentPage);
}, },
(view, error) -> Timber.e("An error occurred while downloading page list") (view, error) -> Timber.e("An error occurred while downloading page list")
); );
@ -69,14 +73,16 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
@Override @Override
protected void onDropView() { protected void onDropView() {
unregisterForEvents(); unregisterForEvents();
initialStart = false;
super.onDropView(); super.onDropView();
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().removeStickyEvent(SourceChapterEvent.class); EventBus.getDefault().removeStickyEvent(SourceChapterEvent.class);
source.savePageList(chapter.url, pageList); source.savePageList(chapter.url, pageList);
saveChapter();
super.onDestroy();
} }
@EventBusHook @EventBusHook
@ -99,23 +105,22 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
return Observable.merge( return Observable.merge(
Observable.from(pageList).filter(page -> page.getImageUrl() != null), Observable.from(pageList).filter(page -> page.getImageUrl() != null),
source.getRemainingImageUrlsFromPageList(pageList) source.getRemainingImageUrlsFromPageList(pageList)
.doOnNext(this::replacePageUrl)
) )
.flatMap(source::getCachedImage) .flatMap(source::getCachedImage)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()); .observeOn(AndroidSchedulers.mainThread());
} }
private void replacePageUrl(Page page) { public void setCurrentPage(int currentPage) {
for (int i = 0; i < pageList.size(); i++) { this.currentPage = currentPage;
if (pageList.get(i).getPageNumber() == page.getPageNumber()) {
pageList.set(i, page);
return;
}
}
} }
public void setCurrentPage(int savedPage) { private void saveChapter() {
this.savedSelectedPage = savedPage; chapter.last_page_read = currentPage + 1;
if (currentPage == pageList.size() - 1) {
chapter.read = true;
}
db.insertChapterBlock(chapter);
} }
} }

View file

@ -36,7 +36,6 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
@Inject PreferencesHelper prefs; @Inject PreferencesHelper prefs;
private int currentPage;
private BaseViewer viewer; private BaseViewer viewer;
private static final int LEFT_TO_RIGHT = 1; private static final int LEFT_TO_RIGHT = 1;
@ -61,18 +60,13 @@ public class ReaderActivity extends BaseRxActivity<ReaderPresenter> {
enableHardwareAcceleration(); enableHardwareAcceleration();
} }
@Override
public void onDestroy() {
getPresenter().setCurrentPage(currentPage);
super.onDestroy();
}
public void onPageListReady(List<Page> pages) { public void onPageListReady(List<Page> pages) {
viewer.onPageListReady(pages); viewer.onPageListReady(pages);
} }
public void onPageChanged(int currentPageIndex, int totalPages) { public void onPageChanged(int currentPageIndex, int totalPages) {
currentPage = currentPageIndex; if (currentPageIndex != 0)
getPresenter().setCurrentPage(currentPageIndex);
String page = (currentPageIndex + 1) + "/" + totalPages; String page = (currentPageIndex + 1) + "/" + totalPages;
pageNumber.setText(page); pageNumber.setText(page);
} }

View file

@ -7,6 +7,7 @@ import android.widget.Filterable;
import java.util.List; import java.util.List;
import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.data.models.Manga;
import eu.kanade.mangafeed.ui.holder.LibraryHolder;
import rx.Observable; import rx.Observable;
import uk.co.ribot.easyadapter.EasyAdapter; import uk.co.ribot.easyadapter.EasyAdapter;

View file

@ -24,7 +24,7 @@ import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.data.models.Manga;
import eu.kanade.mangafeed.presenter.CataloguePresenter; import eu.kanade.mangafeed.presenter.CataloguePresenter;
import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; import eu.kanade.mangafeed.ui.activity.MangaDetailActivity;
import eu.kanade.mangafeed.ui.adapter.CatalogueHolder; import eu.kanade.mangafeed.ui.holder.CatalogueHolder;
import eu.kanade.mangafeed.ui.fragment.base.BaseRxFragment; import eu.kanade.mangafeed.ui.fragment.base.BaseRxFragment;
import eu.kanade.mangafeed.util.PageBundle; import eu.kanade.mangafeed.util.PageBundle;
import eu.kanade.mangafeed.widget.EndlessScrollListener; import eu.kanade.mangafeed.widget.EndlessScrollListener;

View file

@ -22,7 +22,7 @@ import eu.kanade.mangafeed.data.models.Chapter;
import eu.kanade.mangafeed.presenter.MangaChaptersPresenter; import eu.kanade.mangafeed.presenter.MangaChaptersPresenter;
import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; import eu.kanade.mangafeed.ui.activity.MangaDetailActivity;
import eu.kanade.mangafeed.ui.activity.ReaderActivity; import eu.kanade.mangafeed.ui.activity.ReaderActivity;
import eu.kanade.mangafeed.ui.adapter.ChapterListHolder; import eu.kanade.mangafeed.ui.holder.ChapterListHolder;
import eu.kanade.mangafeed.ui.fragment.base.BaseRxFragment; import eu.kanade.mangafeed.ui.fragment.base.BaseRxFragment;
import nucleus.factory.RequiresPresenter; import nucleus.factory.RequiresPresenter;
import uk.co.ribot.easyadapter.EasyRecyclerAdapter; import uk.co.ribot.easyadapter.EasyRecyclerAdapter;

View file

@ -15,7 +15,7 @@ import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.presenter.SourcePresenter; import eu.kanade.mangafeed.presenter.SourcePresenter;
import eu.kanade.mangafeed.sources.base.Source; import eu.kanade.mangafeed.sources.base.Source;
import eu.kanade.mangafeed.ui.activity.MainActivity; import eu.kanade.mangafeed.ui.activity.MainActivity;
import eu.kanade.mangafeed.ui.adapter.SourceHolder; import eu.kanade.mangafeed.ui.holder.SourceHolder;
import eu.kanade.mangafeed.ui.fragment.base.BaseRxFragment; import eu.kanade.mangafeed.ui.fragment.base.BaseRxFragment;
import nucleus.factory.RequiresPresenter; import nucleus.factory.RequiresPresenter;
import uk.co.ribot.easyadapter.EasyAdapter; import uk.co.ribot.easyadapter.EasyAdapter;

View file

@ -1,4 +1,4 @@
package eu.kanade.mangafeed.ui.adapter; package eu.kanade.mangafeed.ui.holder;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;

View file

@ -1,5 +1,7 @@
package eu.kanade.mangafeed.ui.adapter; package eu.kanade.mangafeed.ui.holder;
import android.graphics.Color;
import android.support.v4.content.ContextCompat;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@ -14,11 +16,9 @@ import uk.co.ribot.easyadapter.annotations.ViewId;
@LayoutId(R.layout.item_chapter) @LayoutId(R.layout.item_chapter)
public class ChapterListHolder extends ItemViewHolder<Chapter> { public class ChapterListHolder extends ItemViewHolder<Chapter> {
@ViewId(R.id.chapter_title) @ViewId(R.id.chapter_title) TextView title;
TextView title; @ViewId(R.id.chapter_download_image) ImageView download_icon;
@ViewId(R.id.chapter_pages) TextView pages;
@ViewId(R.id.chapter_download_image)
ImageView download_icon;
View view; View view;
@ -30,6 +30,18 @@ public class ChapterListHolder extends ItemViewHolder<Chapter> {
public void onSetValues(Chapter chapter, PositionInfo positionInfo) { public void onSetValues(Chapter chapter, PositionInfo positionInfo) {
title.setText(chapter.name); title.setText(chapter.name);
download_icon.setImageResource(R.drawable.ic_file_download_black_48dp); download_icon.setImageResource(R.drawable.ic_file_download_black_48dp);
if (chapter.read) {
title.setTextColor(ContextCompat.getColor(getContext(), R.color.chapter_read_text));
} else {
title.setTextColor(Color.BLACK);
}
if (chapter.last_page_read > 0 && !chapter.read) {
pages.setText(getContext().getString(R.string.chapter_progress, chapter.last_page_read));
} else {
pages.setText("");
}
} }
@Override @Override

View file

@ -1,4 +1,4 @@
package eu.kanade.mangafeed.ui.adapter; package eu.kanade.mangafeed.ui.holder;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;

View file

@ -1,4 +1,4 @@
package eu.kanade.mangafeed.ui.adapter; package eu.kanade.mangafeed.ui.holder;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;

View file

@ -54,8 +54,7 @@ public class VerticalViewer extends BaseViewer {
@Override @Override
public void setSelectedPage(int pageNumber) { public void setSelectedPage(int pageNumber) {
// TODO viewPager.setCurrentItem(getCurrentPageIndex(pageNumber));
return;
} }
@Override @Override
@ -66,6 +65,6 @@ public class VerticalViewer extends BaseViewer {
@Override @Override
public boolean onImageTouch(MotionEvent motionEvent) { public boolean onImageTouch(MotionEvent motionEvent) {
return false; return true;
} }
} }

View file

@ -15,4 +15,5 @@
<color name="bg_light_grey">#E9E9E9</color> <color name="bg_light_grey">#E9E9E9</color>
<color name="black_87pc">#DD000000</color> <color name="black_87pc">#DD000000</color>
<color name="library_text_background">#E8E8E8</color> <color name="library_text_background">#E8E8E8</color>
<color name="chapter_read_text">#909090</color>
</resources> </resources>

View file

@ -75,5 +75,6 @@
<string name="action_favorite">Favorite</string> <string name="action_favorite">Favorite</string>
<string name="downloading">Downloading…</string> <string name="downloading">Downloading…</string>
<string name="download_progress">Downloaded %1$d%%</string> <string name="download_progress">Downloaded %1$d%%</string>
<string name="chapter_progress">Page: %1$d</string>
</resources> </resources>