update(ChapterSync chapter);
}
diff --git a/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/ChapterSyncManager.java b/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/ChapterSyncManager.java
index 73d219bf0..e38f3faa4 100644
--- a/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/ChapterSyncManager.java
+++ b/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/ChapterSyncManager.java
@@ -26,4 +26,12 @@ public class ChapterSyncManager {
return services;
}
+ public BaseChapterSync getSyncService(int id) {
+ switch (id) {
+ case MYANIMELIST:
+ return myAnimeList;
+ }
+ return null;
+ }
+
}
diff --git a/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/MyAnimeList.java b/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/MyAnimeList.java
index 4e26b31c1..9786d0427 100644
--- a/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/MyAnimeList.java
+++ b/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/MyAnimeList.java
@@ -89,7 +89,7 @@ public class MyAnimeList extends BaseChapterSync {
.map(entry -> {
ChapterSync chapter = ChapterSync.create(this);
chapter.title = entry.select("title").first().text();
- chapter.remote_id = Long.parseLong(entry.select("id").first().text());
+ chapter.remote_id = Integer.parseInt(entry.select("id").first().text());
return chapter;
})
.toList();
@@ -111,7 +111,7 @@ public class MyAnimeList extends BaseChapterSync {
.map(entry -> {
ChapterSync chapter = ChapterSync.create(this);
chapter.title = entry.select("series_title").first().text();
- chapter.remote_id = Long.parseLong(
+ chapter.remote_id = Integer.parseInt(
entry.select("series_mangadb_id").first().text());
chapter.last_chapter_read = Integer.parseInt(
entry.select("my_read_chapters").first().text());
diff --git a/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/UpdateChapterSyncService.java b/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/UpdateChapterSyncService.java
new file mode 100644
index 000000000..c313355e1
--- /dev/null
+++ b/app/src/main/java/eu/kanade/mangafeed/data/chaptersync/UpdateChapterSyncService.java
@@ -0,0 +1,77 @@
+package eu.kanade.mangafeed.data.chaptersync;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+
+import javax.inject.Inject;
+
+import de.greenrobot.event.EventBus;
+import eu.kanade.mangafeed.App;
+import eu.kanade.mangafeed.data.database.DatabaseHelper;
+import eu.kanade.mangafeed.data.database.models.ChapterSync;
+import eu.kanade.mangafeed.data.network.NetworkHelper;
+import eu.kanade.mangafeed.event.UpdateChapterSyncEvent;
+import eu.kanade.mangafeed.util.EventBusHook;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
+import rx.subscriptions.CompositeSubscription;
+
+public class UpdateChapterSyncService extends Service {
+
+ @Inject ChapterSyncManager syncManager;
+ @Inject NetworkHelper networkManager;
+ @Inject DatabaseHelper db;
+
+ private CompositeSubscription subscriptions;
+
+ public static void start(Context context) {
+ context.startService(new Intent(context, UpdateChapterSyncService.class));
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ App.get(this).getComponent().inject(this);
+ subscriptions = new CompositeSubscription();
+ EventBus.getDefault().registerSticky(this);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ return START_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ EventBus.getDefault().unregister(this);
+ subscriptions.unsubscribe();
+ super.onDestroy();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @EventBusHook
+ public void onEventMainThread(UpdateChapterSyncEvent event) {
+ updateLastChapteRead(event.getChapterSync());
+ }
+
+ private void updateLastChapteRead(ChapterSync chapterSync) {
+ BaseChapterSync sync = syncManager.getSyncService(chapterSync.sync_id);
+
+ subscriptions.add(sync.update(chapterSync)
+ .flatMap(response -> db.insertChapterSync(chapterSync).createObservable())
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ stopSelf();
+ }, error -> {
+ stopSelf();
+ }));
+ }
+
+}
diff --git a/app/src/main/java/eu/kanade/mangafeed/data/database/models/ChapterSync.java b/app/src/main/java/eu/kanade/mangafeed/data/database/models/ChapterSync.java
index 2f4314e21..7a0897bfb 100644
--- a/app/src/main/java/eu/kanade/mangafeed/data/database/models/ChapterSync.java
+++ b/app/src/main/java/eu/kanade/mangafeed/data/database/models/ChapterSync.java
@@ -16,10 +16,10 @@ public class ChapterSync {
public long manga_id;
@StorIOSQLiteColumn(name = ChapterSyncTable.COLUMN_SYNC_ID)
- public long sync_id;
+ public int sync_id;
@StorIOSQLiteColumn(name = ChapterSyncTable.COLUMN_REMOTE_ID)
- public long remote_id;
+ public int remote_id;
@StorIOSQLiteColumn(name = ChapterSyncTable.COLUMN_TITLE)
public String title;
diff --git a/app/src/main/java/eu/kanade/mangafeed/event/UpdateChapterSyncEvent.java b/app/src/main/java/eu/kanade/mangafeed/event/UpdateChapterSyncEvent.java
new file mode 100644
index 000000000..965e10bb1
--- /dev/null
+++ b/app/src/main/java/eu/kanade/mangafeed/event/UpdateChapterSyncEvent.java
@@ -0,0 +1,17 @@
+package eu.kanade.mangafeed.event;
+
+import eu.kanade.mangafeed.data.database.models.ChapterSync;
+
+public class UpdateChapterSyncEvent {
+
+ private ChapterSync chapterSync;
+
+ public UpdateChapterSyncEvent(ChapterSync chapterSync) {
+ this.chapterSync = chapterSync;
+ }
+
+ public ChapterSync getChapterSync() {
+ return chapterSync;
+ }
+
+}
diff --git a/app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java b/app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java
index 53c98da6d..2b81f4f77 100644
--- a/app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java
+++ b/app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java
@@ -6,6 +6,7 @@ import javax.inject.Singleton;
import dagger.Component;
import eu.kanade.mangafeed.data.chaptersync.MyAnimeList;
+import eu.kanade.mangafeed.data.chaptersync.UpdateChapterSyncService;
import eu.kanade.mangafeed.data.download.DownloadService;
import eu.kanade.mangafeed.data.sync.LibraryUpdateService;
import eu.kanade.mangafeed.injection.module.AppModule;
@@ -55,6 +56,7 @@ public interface AppComponent {
void inject(LibraryUpdateService libraryUpdateService);
void inject(DownloadService downloadService);
+ void inject(UpdateChapterSyncService updateChapterSyncService);
Application application();
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/base/activity/BaseRxActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/base/activity/BaseRxActivity.java
index bcc1aa063..cfab9a313 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/base/activity/BaseRxActivity.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/base/activity/BaseRxActivity.java
@@ -4,7 +4,7 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import eu.kanade.mangafeed.App;
-import eu.kanade.mangafeed.ui.base.activity.BaseActivity;
+import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
import nucleus.factory.PresenterFactory;
import nucleus.factory.ReflectionPresenterFactory;
import nucleus.presenter.Presenter;
@@ -60,7 +60,9 @@ public abstract class BaseRxActivity extends BaseActivity i
final PresenterFactory
superFactory = getPresenterFactory();
setPresenterFactory(() -> {
P presenter = superFactory.createPresenter();
- ((App)getApplication()).getComponentReflection().inject(presenter);
+ App app = (App) getApplication();
+ app.getComponentReflection().inject(presenter);
+ ((BasePresenter)presenter).setContext(app.getApplicationContext());
return presenter;
});
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/base/fragment/BaseRxFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/base/fragment/BaseRxFragment.java
index 15aaf34c1..f8e811198 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/base/fragment/BaseRxFragment.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/base/fragment/BaseRxFragment.java
@@ -3,7 +3,7 @@ package eu.kanade.mangafeed.ui.base.fragment;
import android.os.Bundle;
import eu.kanade.mangafeed.App;
-import eu.kanade.mangafeed.ui.base.fragment.BaseFragment;
+import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
import nucleus.factory.PresenterFactory;
import nucleus.factory.ReflectionPresenterFactory;
import nucleus.presenter.Presenter;
@@ -57,7 +57,9 @@ public abstract class BaseRxFragment
extends BaseFragment i
final PresenterFactory
superFactory = getPresenterFactory();
setPresenterFactory(() -> {
P presenter = superFactory.createPresenter();
- ((App)getActivity().getApplication()).getComponentReflection().inject(presenter);
+ App app = (App) getActivity().getApplication();
+ app.getComponentReflection().inject(presenter);
+ ((BasePresenter)presenter).setContext(app.getApplicationContext());
return presenter;
});
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/base/presenter/BasePresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/base/presenter/BasePresenter.java
index 3023a7089..c03a7703c 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/base/presenter/BasePresenter.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/base/presenter/BasePresenter.java
@@ -1,5 +1,6 @@
package eu.kanade.mangafeed.ui.base.presenter;
+import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
@@ -10,6 +11,8 @@ import nucleus.view.ViewWithPresenter;
public class BasePresenter extends RxPresenter {
+ private Context context;
+
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
@@ -33,4 +36,13 @@ public class BasePresenter extends RxPresenter {
public void unregisterForEvents() {
EventBus.getDefault().unregister(this);
}
+
+ public void setContext(Context applicationContext) {
+ context = applicationContext;
+ }
+
+ public Context getContext() {
+ return context;
+ }
+
}
diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java
index 37e605d91..f99cc28f6 100644
--- a/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java
+++ b/app/src/main/java/eu/kanade/mangafeed/ui/reader/ReaderPresenter.java
@@ -8,8 +8,12 @@ import java.util.List;
import javax.inject.Inject;
import de.greenrobot.event.EventBus;
+import eu.kanade.mangafeed.data.chaptersync.ChapterSyncManager;
+import eu.kanade.mangafeed.data.chaptersync.MyAnimeList;
+import eu.kanade.mangafeed.data.chaptersync.UpdateChapterSyncService;
import eu.kanade.mangafeed.data.database.DatabaseHelper;
import eu.kanade.mangafeed.data.database.models.Chapter;
+import eu.kanade.mangafeed.data.database.models.ChapterSync;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.download.DownloadManager;
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
@@ -17,6 +21,7 @@ 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.UpdateChapterSyncEvent;
import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
import eu.kanade.mangafeed.util.EventBusHook;
import icepick.State;
@@ -32,6 +37,7 @@ public class ReaderPresenter extends BasePresenter {
@Inject PreferencesHelper prefs;
@Inject DatabaseHelper db;
@Inject DownloadManager downloadManager;
+ @Inject ChapterSyncManager syncManager;
private Source source;
private Manga manga;
@@ -135,10 +141,47 @@ public class ReaderPresenter extends BasePresenter {
}
private void onChapterChange() {
- if (pageList != null) {
- if (!isDownloaded)
- source.savePageList(chapter.url, pageList);
- saveChapterProgress();
+ if (pageList == null)
+ return;
+
+ // Cache page list for online chapters to allow a faster reopen
+ if (!isDownloaded)
+ source.savePageList(chapter.url, pageList);
+
+ // Save current progress of the chapter. Mark as read if the chapter is finished
+ // and update progress in remote services (like MyAnimeList)
+ chapter.last_page_read = currentPage;
+ if (isChapterFinished()) {
+ chapter.read = true;
+ updateChapterSyncLastChapterRead();
+ }
+ db.insertChapter(chapter).executeAsBlocking();
+ }
+
+ private boolean isChapterFinished() {
+ return !chapter.read && currentPage == pageList.size() - 1;
+ }
+
+ private void updateChapterSyncLastChapterRead() {
+ // TODO don't use MAL methods for possible alternatives to MAL
+ MyAnimeList mal = syncManager.getMyAnimeList();
+
+ if (!mal.isLogged())
+ return;
+
+ List result = db.getChapterSync(manga, mal).executeAsBlocking();
+ if (result.isEmpty())
+ return;
+
+ ChapterSync chapterSync = result.get(0);
+
+ int lastChapterReadLocal = (int) Math.floor(chapter.chapter_number);
+ int lastChapterReadRemote = chapterSync.last_chapter_read;
+
+ if (lastChapterReadLocal > lastChapterReadRemote) {
+ chapterSync.last_chapter_read = lastChapterReadLocal;
+ EventBus.getDefault().postSticky(new UpdateChapterSyncEvent(chapterSync));
+ UpdateChapterSyncService.start(getContext());
}
}
@@ -186,14 +229,6 @@ public class ReaderPresenter extends BasePresenter {
this.currentPage = currentPage;
}
- private void saveChapterProgress() {
- chapter.last_page_read = currentPage;
- if (currentPage == pageList.size() - 1) {
- chapter.read = true;
- }
- db.insertChapter(chapter).executeAsBlocking();
- }
-
private void getAdjacentChapters() {
if (nextChapterSubscription != null)
remove(nextChapterSubscription);