浏览代码

Allow to refresh data from MAL and show total chapters. Create nomedia file for default downloads folder on new installations.

inorichi 9 年之前
父节点
当前提交
4d9cd6cb6e

+ 7 - 0
app/src/main/java/eu/kanade/mangafeed/data/database/models/MangaSync.java

@@ -43,4 +43,11 @@ public class MangaSync implements Serializable {
         mangasync.sync_id = service.getId();
         return mangasync;
     }
+
+    public void copyPersonalFrom(MangaSync other) {
+        last_chapter_read = other.last_chapter_read;
+        score = other.score;
+        status = other.status;
+    }
+
 }

+ 3 - 6
app/src/main/java/eu/kanade/mangafeed/data/mangasync/services/MyAnimeList.java

@@ -43,7 +43,6 @@ public class MyAnimeList extends MangaSyncService {
     private static final String SCORE_TAG = "score";
     private static final String STATUS_TAG = "status";
 
-    public static final int NOT_IN_LIST = 0;
     public static final int READING = 1;
     public static final int COMPLETED = 2;
     public static final int ON_HOLD = 3;
@@ -125,7 +124,7 @@ public class MyAnimeList extends MangaSyncService {
                 .toString();
     }
 
-    public Observable<List<MangaSync>> getList(String username) {
+    public Observable<List<MangaSync>> getList() {
         // TODO cache this list for a few minutes
         return networkService.getStringResponse(getListUrl(username), headers, null)
                 .map(Jsoup::parse)
@@ -215,15 +214,13 @@ public class MyAnimeList extends MangaSyncService {
     }
 
     public Observable<Response> bind(MangaSync manga) {
-        return getList(username)
+        return getList()
                 .flatMap(list -> {
                     manga.sync_id = getId();
                     for (MangaSync remoteManga : list) {
                         if (remoteManga.remote_id == manga.remote_id) {
                             // Manga is already in the list
-                            manga.score = remoteManga.score;
-                            manga.status = remoteManga.status;
-                            manga.last_chapter_read = remoteManga.last_chapter_read;
+                            manga.copyPersonalFrom(remoteManga);
                             return update(manga);
                         }
                     }

+ 7 - 1
app/src/main/java/eu/kanade/mangafeed/data/preference/PreferencesHelper.java

@@ -9,6 +9,7 @@ import com.f2prateek.rx.preferences.Preference;
 import com.f2prateek.rx.preferences.RxSharedPreferences;
 
 import java.io.File;
+import java.io.IOException;
 
 import eu.kanade.mangafeed.R;
 import eu.kanade.mangafeed.data.mangasync.base.MangaSyncService;
@@ -38,8 +39,13 @@ public class PreferencesHelper {
                 File.separator + context.getString(R.string.app_name), "downloads");
 
         // Create default directory
-        if (getDownloadsDirectory().equals(defaultDownloadsDir.getAbsolutePath()))
+        if (getDownloadsDirectory().equals(defaultDownloadsDir.getAbsolutePath()) &&
+                !defaultDownloadsDir.exists()) {
             defaultDownloadsDir.mkdirs();
+            try {
+                new File(defaultDownloadsDir, ".nomedia").createNewFile();
+            } catch (IOException e) { /* Ignore */ }
+        }
     }
 
     private String getKey(int keyResource) {

+ 5 - 9
app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersAdapter.java

@@ -10,18 +10,14 @@ import java.util.List;
 import eu.davidea.flexibleadapter.FlexibleAdapter;
 import eu.kanade.mangafeed.R;
 import eu.kanade.mangafeed.data.database.models.Chapter;
-import eu.kanade.mangafeed.ui.base.adapter.FlexibleViewHolder;
-import eu.kanade.mangafeed.ui.base.fragment.BaseFragment;
 
 public class ChaptersAdapter extends FlexibleAdapter<ChaptersHolder, Chapter> {
 
-    private BaseFragment fragment;
-    public FlexibleViewHolder.OnListItemClickListener clickListener;
+    private ChaptersFragment fragment;
 
-    public ChaptersAdapter(BaseFragment fragment) {
+    public ChaptersAdapter(ChaptersFragment fragment) {
         this.fragment = fragment;
         mItems = new ArrayList<>();
-        clickListener = (FlexibleViewHolder.OnListItemClickListener) fragment;
         setHasStableIds(true);
     }
 
@@ -31,7 +27,7 @@ public class ChaptersAdapter extends FlexibleAdapter<ChaptersHolder, Chapter> {
     @Override
     public ChaptersHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         View v = LayoutInflater.from(fragment.getActivity()).inflate(R.layout.item_chapter, parent, false);
-        return new ChaptersHolder(v, this, clickListener);
+        return new ChaptersHolder(v, this, fragment);
     }
 
     @Override
@@ -53,7 +49,7 @@ public class ChaptersAdapter extends FlexibleAdapter<ChaptersHolder, Chapter> {
         notifyDataSetChanged();
     }
 
-    public ChaptersFragment getChaptersFragment() {
-        return (ChaptersFragment) fragment;
+    public ChaptersFragment getFragment() {
+        return fragment;
     }
 }

+ 5 - 5
app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersHolder.java

@@ -81,7 +81,7 @@ public class ChaptersHolder extends FlexibleViewHolder {
 
     private void showPopupMenu(View view) {
         // Create a PopupMenu, giving it the clicked view for an anchor
-        PopupMenu popup = new PopupMenu(adapter.getChaptersFragment().getActivity(), view);
+        PopupMenu popup = new PopupMenu(adapter.getFragment().getActivity(), view);
 
         // Inflate our menu resource into the PopupMenu's Menu
         popup.getMenuInflater().inflate(R.menu.chapter_single, popup.getMenu());
@@ -92,13 +92,13 @@ public class ChaptersHolder extends FlexibleViewHolder {
 
             switch (menuItem.getItemId()) {
                 case R.id.action_mark_as_read:
-                    return adapter.getChaptersFragment().onMarkAsRead(chapter);
+                    return adapter.getFragment().onMarkAsRead(chapter);
                 case R.id.action_mark_as_unread:
-                    return adapter.getChaptersFragment().onMarkAsUnread(chapter);
+                    return adapter.getFragment().onMarkAsUnread(chapter);
                 case R.id.action_download:
-                    return adapter.getChaptersFragment().onDownload(chapter);
+                    return adapter.getFragment().onDownload(chapter);
                 case R.id.action_delete:
-                    return adapter.getChaptersFragment().onDelete(chapter);
+                    return adapter.getFragment().onDelete(chapter);
             }
             return false;
         });

+ 16 - 1
app/src/main/java/eu/kanade/mangafeed/ui/manga/myanimelist/MyAnimeListFragment.java

@@ -2,6 +2,7 @@ package eu.kanade.mangafeed.ui.manga.myanimelist;
 
 import android.content.Context;
 import android.os.Bundle;
+import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -28,6 +29,7 @@ public class MyAnimeListFragment extends BaseRxFragment<MyAnimeListPresenter> {
     @Bind(R.id.myanimelist_chapters) TextView chapters;
     @Bind(R.id.myanimelist_score) TextView score;
     @Bind(R.id.myanimelist_status) TextView status;
+    @Bind(R.id.swipe_refresh) SwipeRefreshLayout swipeRefresh;
 
     private MyAnimeListDialogFragment dialog;
 
@@ -43,18 +45,31 @@ public class MyAnimeListFragment extends BaseRxFragment<MyAnimeListPresenter> {
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         View view = inflater.inflate(R.layout.fragment_myanimelist, container, false);
         ButterKnife.bind(this, view);
+
+        swipeRefresh.setEnabled(false);
+        swipeRefresh.setOnRefreshListener(() -> getPresenter().refresh());
         return view;
     }
 
     public void setMangaSync(MangaSync mangaSync) {
+        swipeRefresh.setEnabled(mangaSync != null);
         if (mangaSync != null) {
             title.setText(mangaSync.title);
-            chapters.setText(mangaSync.last_chapter_read + "");
+            chapters.setText(mangaSync.last_chapter_read + "/" +
+                    (mangaSync.total_chapters > 0 ? mangaSync.total_chapters : "-"));
             score.setText(mangaSync.score == 0 ? "-" : decimalFormat.format(mangaSync.score));
             status.setText(getPresenter().myAnimeList.getStatus(mangaSync.status));
         }
     }
 
+    public void onRefreshDone() {
+        swipeRefresh.setRefreshing(false);
+    }
+
+    public void onRefreshError() {
+        swipeRefresh.setRefreshing(false);
+    }
+
     public void setSearchResults(List<MangaSync> results) {
         findSearchFragmentIfNeeded();
 

+ 25 - 0
app/src/main/java/eu/kanade/mangafeed/ui/manga/myanimelist/MyAnimeListPresenter.java

@@ -33,6 +33,7 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
 
     private static final int GET_MANGA_SYNC = 1;
     private static final int GET_SEARCH_RESULTS = 2;
+    private static final int REFRESH = 3;
 
     @Override
     protected void onCreate(Bundle savedState) {
@@ -62,11 +63,29 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
                     view.setSearchResultsError();
                 });
 
+        restartableFirst(REFRESH,
+                () -> myAnimeList.getList()
+                        .flatMap(myList -> {
+                            for (MangaSync myManga : myList) {
+                                if (myManga.remote_id == mangaSync.remote_id) {
+                                    mangaSync.copyPersonalFrom(myManga);
+                                    return Observable.just(mangaSync);
+                                }
+                            }
+                            return Observable.error(new Exception("Could not find manga"));
+                        })
+                        .flatMap(myManga -> db.insertMangaSync(myManga).createObservable())
+                        .subscribeOn(Schedulers.io())
+                        .observeOn(AndroidSchedulers.mainThread()),
+                (view, result) -> view.onRefreshDone(),
+                (view, error) -> view.onRefreshError());
+
     }
 
     private void onProcessRestart() {
         stop(GET_MANGA_SYNC);
         stop(GET_SEARCH_RESULTS);
+        stop(REFRESH);
     }
 
     @Override
@@ -157,4 +176,10 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
         mangaSync.last_chapter_read = chapterNumber;
         updateRemote();
     }
+
+    public void refresh() {
+        if (mangaSync != null) {
+            start(REFRESH);
+        }
+    }
 }

+ 20 - 10
app/src/main/res/layout/fragment_myanimelist.xml

@@ -1,17 +1,27 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:padding="10dp">
+<android.support.v4.widget.SwipeRefreshLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/swipe_refresh"
+    android:paddingTop="@dimen/margin_top"
+    android:paddingBottom="@dimen/margin_bottom"
+    android:paddingRight="@dimen/margin_right"
+    android:paddingLeft="@dimen/margin_left">
 
-    <android.support.v7.widget.CardView
+    <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="match_parent">
 
-        <include layout="@layout/card_myanimelist_personal"/>
+        <android.support.v7.widget.CardView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
 
-    </android.support.v7.widget.CardView>
+            <include layout="@layout/card_myanimelist_personal"/>
 
+        </android.support.v7.widget.CardView>
 
-</LinearLayout>
+    </ScrollView>
+
+</android.support.v4.widget.SwipeRefreshLayout>