Allow to set status, score and last chapter read in MAL. Other minor changes

This commit is contained in:
inorichi
2015-12-20 20:10:04 +01:00
parent 5f44e5d492
commit 50d6632d0e
15 changed files with 370 additions and 153 deletions

View File

@ -20,6 +20,7 @@ import java.util.List;
import javax.inject.Inject;
import eu.kanade.mangafeed.App;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.database.models.MangaSync;
import eu.kanade.mangafeed.data.mangasync.MangaSyncManager;
import eu.kanade.mangafeed.data.mangasync.base.MangaSyncService;
@ -52,7 +53,10 @@ public class MyAnimeList extends MangaSyncService {
public static final int DEFAULT_STATUS = READING;
public static final int DEFAULT_SCORE = 0;
private Context context;
public MyAnimeList(Context context) {
this.context = context;
App.get(context).getComponent().inject(this);
String username = preferences.getMangaSyncUsername(this);
@ -228,15 +232,15 @@ public class MyAnimeList extends MangaSyncService {
public String getStatus(int status) {
switch (status) {
case READING:
return "Reading";
return context.getString(R.string.reading);
case COMPLETED:
return "Completed";
return context.getString(R.string.completed);
case ON_HOLD:
return "On hold";
return context.getString(R.string.on_hold);
case DROPPED:
return "Dropped";
return context.getString(R.string.dropped);
case PLAN_TO_READ:
return "Plan to read";
return context.getString(R.string.plan_to_read);
}
return "";
}

View File

@ -29,7 +29,6 @@ public class LibraryPresenter extends BasePresenter<LibraryFragment> {
restartableLatestCache(GET_MANGAS,
() -> db.getFavoriteMangasWithUnread().createObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()),
LibraryFragment::onNextMangas);

View File

@ -1,21 +1,21 @@
package eu.kanade.mangafeed.ui.manga.myanimelist;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
import java.text.DecimalFormat;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.database.models.MangaSync;
import eu.kanade.mangafeed.ui.base.fragment.BaseRxFragment;
@ -25,10 +25,9 @@ import nucleus.factory.RequiresPresenter;
public class MyAnimeListFragment extends BaseRxFragment<MyAnimeListPresenter> {
@Bind(R.id.myanimelist_title) TextView title;
@Bind(R.id.last_chapter_read) EditText lastChapterRead;
@Bind(R.id.score) TextView score;
@Bind(R.id.status) TextView status;
@Bind(R.id.update_button) Button updateButton;
@Bind(R.id.myanimelist_chapters) TextView chapters;
@Bind(R.id.myanimelist_score) TextView score;
@Bind(R.id.myanimelist_status) TextView status;
private MyAnimeListDialogFragment dialog;
@ -38,43 +37,17 @@ public class MyAnimeListFragment extends BaseRxFragment<MyAnimeListPresenter> {
return new MyAnimeListFragment();
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_myanimelist, container, false);
ButterKnife.bind(this, view);
updateButton.setOnClickListener(v -> getPresenter().updateLastChapter(
Integer.parseInt(lastChapterRead.getText().toString())));
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.myanimelist, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.myanimelist_edit:
showSearchDialog();
return true;
}
return super.onOptionsItemSelected(item);
}
public void setMangaSync(MangaSync mangaSync) {
title.setText(mangaSync.title);
lastChapterRead.setText(mangaSync.last_chapter_read + "");
score.setText(decimalFormat.format(mangaSync.score));
chapters.setText(mangaSync.last_chapter_read + "");
score.setText(mangaSync.score == 0 ? "-" : decimalFormat.format(mangaSync.score));
status.setText(getPresenter().myAnimeList.getStatus(mangaSync.status));
}
@ -89,4 +62,86 @@ public class MyAnimeListFragment extends BaseRxFragment<MyAnimeListPresenter> {
if (dialog != null)
dialog.setResults(results);
}
@OnClick(R.id.myanimelist_title_layout)
void onTitleClick() {
showSearchDialog();
}
@OnClick(R.id.myanimelist_status_layout)
void onStatusClick() {
if (getPresenter().mangaSync == null)
return;
Context ctx = getActivity();
new MaterialDialog.Builder(ctx)
.title(R.string.status)
.items(getPresenter().getAllStatus(ctx))
.itemsCallbackSingleChoice(getPresenter().getIndexFromStatus(),
(materialDialog, view, i, charSequence) -> {
getPresenter().setStatus(i);
status.setText("...");
return true;
})
.show();
}
@OnClick(R.id.myanimelist_chapters_layout)
void onChaptersClick() {
if (getPresenter().mangaSync == null)
return;
MaterialDialog dialog = new MaterialDialog.Builder(getActivity())
.title(R.string.chapters)
.customView(R.layout.dialog_myanimelist_chapters, false)
.positiveText(R.string.button_ok)
.negativeText(R.string.button_cancel)
.onPositive((materialDialog, dialogAction) -> {
View view = materialDialog.getCustomView();
if (view != null) {
NumberPicker np = (NumberPicker) view.findViewById(R.id.chapters_picker);
getPresenter().setLastChapterRead(np.getValue());
chapters.setText("...");
}
})
.show();
View view = dialog.getCustomView();
if (view != null) {
NumberPicker np = (NumberPicker) view.findViewById(R.id.chapters_picker);
// Set initial value
np.setValue(getPresenter().mangaSync.last_chapter_read);
// Don't allow to go from 0 to 9999
np.setWrapSelectorWheel(false);
}
}
@OnClick(R.id.myanimelist_score_layout)
void onScoreClick() {
if (getPresenter().mangaSync == null)
return;
MaterialDialog dialog = new MaterialDialog.Builder(getActivity())
.title(R.string.score)
.customView(R.layout.dialog_myanimelist_score, false)
.positiveText(R.string.button_ok)
.negativeText(R.string.button_cancel)
.onPositive((materialDialog, dialogAction) -> {
View view = materialDialog.getCustomView();
if (view != null) {
NumberPicker np = (NumberPicker) view.findViewById(R.id.score_picker);
getPresenter().setScore(np.getValue());
score.setText("...");
}
})
.show();
View view = dialog.getCustomView();
if (view != null) {
NumberPicker np = (NumberPicker) view.findViewById(R.id.score_picker);
// Set initial value
np.setValue((int) getPresenter().mangaSync.score);
}
}
}

View File

@ -1,19 +1,20 @@
package eu.kanade.mangafeed.ui.manga.myanimelist;
import android.content.Context;
import android.os.Bundle;
import javax.inject.Inject;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.database.DatabaseHelper;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.database.models.MangaSync;
import eu.kanade.mangafeed.data.mangasync.MangaSyncManager;
import eu.kanade.mangafeed.data.mangasync.services.MyAnimeList;
import eu.kanade.mangafeed.data.database.DatabaseHelper;
import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
import eu.kanade.mangafeed.util.EventBusHook;
import eu.kanade.mangafeed.util.ToastUtil;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import timber.log.Timber;
@ -25,13 +26,11 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
protected MyAnimeList myAnimeList;
protected Manga manga;
private MangaSync mangaSync;
protected MangaSync mangaSync;
private String query;
private Subscription updateSubscription;
private static final int GET_CHAPTER_SYNC = 1;
private static final int GET_MANGA_SYNC = 1;
private static final int GET_SEARCH_RESULTS = 2;
@Override
@ -44,7 +43,7 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
myAnimeList = syncManager.getMyAnimeList();
restartableLatestCache(GET_CHAPTER_SYNC,
restartableLatestCache(GET_MANGA_SYNC,
() -> db.getMangaSync(manga, myAnimeList).createObservable()
.flatMap(Observable::from)
.doOnNext(mangaSync -> this.mangaSync = mangaSync)
@ -65,7 +64,7 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
}
private void onProcessRestart() {
stop(GET_CHAPTER_SYNC);
stop(GET_MANGA_SYNC);
stop(GET_SEARCH_RESULTS);
}
@ -84,22 +83,19 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
@EventBusHook
public void onEventMainThread(Manga manga) {
this.manga = manga;
start(GET_CHAPTER_SYNC);
start(GET_MANGA_SYNC);
}
public void updateLastChapter(int chapterNumber) {
if (updateSubscription != null)
remove(updateSubscription);
mangaSync.last_chapter_read = chapterNumber;
add(updateSubscription = myAnimeList.update(mangaSync)
private void updateRemote() {
add(myAnimeList.update(mangaSync)
.flatMap(response -> db.insertMangaSync(mangaSync).createObservable())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> {},
.subscribe(next -> {},
error -> {
Timber.e(error.getMessage());
// Restart on error to set old values
start(GET_MANGA_SYNC);
}
));
}
@ -114,15 +110,42 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
add(myAnimeList.bind(manga)
.flatMap(response -> {
if (response.isSuccessful()) {
return Observable.just(manga);
return db.insertMangaSync(manga).createObservable();
}
return Observable.error(new Exception("Could not add manga"));
return Observable.error(new Exception("Could not bind manga"));
})
.flatMap(manga2 -> db.insertMangaSync(manga2).createObservable())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(manga2 -> {},
error -> ToastUtil.showShort(getContext(), error.getMessage())));
}
public String[] getAllStatus(Context context) {
return new String[] {
context.getString(R.string.reading),
context.getString(R.string.completed),
context.getString(R.string.on_hold),
context.getString(R.string.dropped),
context.getString(R.string.plan_to_read)
};
}
public int getIndexFromStatus() {
return mangaSync.status == 6 ? 4 : mangaSync.status - 1;
}
public void setStatus(int index) {
mangaSync.status = index == 4 ? 6 : index + 1;
updateRemote();
}
public void setScore(int score) {
mangaSync.score = score;
updateRemote();
}
public void setLastChapterRead(int chapterNumber) {
mangaSync.last_chapter_read = chapterNumber;
updateRemote();
}
}

View File

@ -0,0 +1,36 @@
package eu.kanade.mangafeed.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.NumberPicker;
import eu.kanade.mangafeed.R;
public class MinMaxNumberPicker extends NumberPicker{
public MinMaxNumberPicker(Context context) {
super(context);
}
public MinMaxNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
processAttributeSet(context, attrs);
}
public MinMaxNumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
processAttributeSet(context, attrs);
}
private void processAttributeSet(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MinMaxNumberPicker, 0, 0);
try {
setMinValue(ta.getInt(R.styleable.MinMaxNumberPicker_min, 0));
setMaxValue(ta.getInt(R.styleable.MinMaxNumberPicker_max, 0));
} finally {
ta.recycle();
}
}
}