From 8da5c83cb3ac992dd34d63486db8d0a42fd45905 Mon Sep 17 00:00:00 2001 From: inorichi Date: Sat, 17 Oct 2015 02:39:16 +0200 Subject: [PATCH] Add catalogue detail page. Add simple tests for sources --- app/src/main/AndroidManifest.xml | 2 + .../presenter/CataloguePresenter.java | 21 +- .../mangafeed/presenter/LibraryPresenter.java | 8 - .../presenter/MangaCataloguePresenter.java | 1 + .../ui/activity/MangaCatalogueActivity.java | 37 +++- .../mangafeed/view/MangaCatalogueView.java | 3 + .../res/drawable-xhdpi/bkg_shadow_img.9.png | Bin 0 -> 1164 bytes .../res/layout/activity_manga_catalogue.xml | 185 ++++++++++++++++++ app/src/main/res/values/strings.xml | 7 + app/src/main/res/values/styles.xml | 17 ++ .../java/eu/kanade/mangafeed/BatotoTest.java | 35 +++- .../eu/kanade/mangafeed/MangahereTest.java | 80 ++++++++ 12 files changed, 382 insertions(+), 14 deletions(-) create mode 100644 app/src/main/res/drawable-xhdpi/bkg_shadow_img.9.png create mode 100644 app/src/test/java/eu/kanade/mangafeed/MangahereTest.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a6a08d1aa..bd15ddba9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ @@ -34,6 +35,7 @@ android:name=".ui.activity.CatalogueActivity" android:label="@string/title_activity_catalogue_list" android:parentActivityName=".ui.activity.MainActivity" + android:launchMode="singleTop" android:theme="@style/AppTheme" > { private Subscription mMangaDetailFetchSubscription; private PublishSubject> mSearchViewPublishSubject; private PublishSubject>> mMangaDetailPublishSubject; + private SubscriptionList mResultSubscriptions = new SubscriptionList(); private final String CURRENT_PAGE = "CATALOGUE_CURRENT_PAGE"; @@ -81,6 +83,12 @@ public class CataloguePresenter extends RxPresenter { state.putInt(CURRENT_PAGE, mCurrentPage); } + @Override + protected void onDestroy() { + super.onDestroy(); + mResultSubscriptions.unsubscribe(); + } + private void initializeSearch() { remove(mSearchViewSubscription); @@ -126,16 +134,17 @@ public class CataloguePresenter extends RxPresenter { .filter(manga -> manga.initialized) .onBackpressureBuffer() .observeOn(AndroidSchedulers.mainThread()) - .subscribe(manga -> { + .compose(deliverReplay()) + .subscribe(this.split((view, manga) -> { // Get manga index in the adapter int index = getMangaIndex(manga); // Get the image view associated with the manga. // If it's null (not visible in the screen) there's no need to update the image. - ImageView imageView = getView().getImageView(index); + ImageView imageView = view.getImageView(index); if (imageView != null) { updateImage(imageView, manga.thumbnail_url); } - }); + })); add(mMangaDetailFetchSubscription); } @@ -143,11 +152,15 @@ public class CataloguePresenter extends RxPresenter { public void getMangasFromSource(int page) { mMangaFetchSubscription = getMangasSubscriber( selectedSource.pullPopularMangasFromNetwork(page)); + + mResultSubscriptions.add(mMangaFetchSubscription); } public void getMangasFromSearch(int page) { mMangaSearchSubscription = getMangasSubscriber( selectedSource.searchMangasFromNetwork(mSearchName, page)); + + mResultSubscriptions.add(mMangaSearchSubscription); } private Subscription getMangasSubscriber(Observable> mangas) { @@ -195,10 +208,12 @@ public class CataloguePresenter extends RxPresenter { // If going to search mode else if (mSearchName.equals("") && !query.equals("")) { mSearchMode = true; + mResultSubscriptions.clear(); } // If going to normal mode else if (!mSearchName.equals("") && query.equals("")) { mSearchMode = false; + mResultSubscriptions.clear(); } mSearchName = query; diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java index ca5982484..f8158ee82 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java @@ -33,14 +33,6 @@ public class LibraryPresenter extends BasePresenter { public LibraryPresenter(LibraryView view) { this.view = view; App.getComponent(view.getActivity()).inject(this); - - //TODO remove, only for testing - if (prefs.isFirstRun()) { - db.insertMangas(DummyDataUtil.createDummyManga()).toBlocking().single(); - db.insertChapters(DummyDataUtil.createDummyChapters()).subscribe(); - prefs.setNotFirstRun(); - } - } public void onMangaClick(int position) { diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaCataloguePresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaCataloguePresenter.java index 9505bb94d..8c3efd6f8 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaCataloguePresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaCataloguePresenter.java @@ -25,5 +25,6 @@ public class MangaCataloguePresenter extends BasePresenter { private void initializeManga() { view.setTitle(manga.title); + view.setMangaInformation(manga); } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaCatalogueActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaCatalogueActivity.java index 44a6915d0..7893c6e7e 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaCatalogueActivity.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaCatalogueActivity.java @@ -2,17 +2,30 @@ package eu.kanade.mangafeed.ui.activity; import android.os.Bundle; import android.support.v7.widget.Toolbar; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; import butterknife.Bind; import butterknife.ButterKnife; import eu.kanade.mangafeed.R; +import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.presenter.MangaCataloguePresenter; import eu.kanade.mangafeed.view.MangaCatalogueView; public class MangaCatalogueActivity extends BaseActivity implements MangaCatalogueView { - @Bind(R.id.toolbar) - Toolbar toolbar; + @Bind(R.id.toolbar) Toolbar toolbar; + + @Bind(R.id.manga_artist) TextView mArtist; + @Bind(R.id.manga_author) TextView mAuthor; + @Bind(R.id.manga_chapters) TextView mChapters; + @Bind(R.id.manga_genres) TextView mGenres; + @Bind(R.id.manga_status) TextView mStatus; + @Bind(R.id.manga_summary) TextView mDescription; + @Bind(R.id.manga_cover) ImageView mCover; private MangaCataloguePresenter presenter; @@ -40,8 +53,28 @@ public class MangaCatalogueActivity extends BaseActivity implements MangaCatalog super.onStop(); } + // MangaCatalogueView + @Override public void setTitle(String title) { setToolbarTitle(title); } + + @Override + public void setMangaInformation(Manga manga) { + mArtist.setText(manga.artist); + mAuthor.setText(manga.author); + mChapters.setText("0"); // TODO + mGenres.setText(manga.genre); + mStatus.setText("Ongoing"); //TODO + mDescription.setText(manga.description); + + Glide.with(getActivity()) + .load(manga.thumbnail_url) + .diskCacheStrategy(DiskCacheStrategy.RESULT) + .centerCrop() + .into(mCover); + } + + } diff --git a/app/src/main/java/eu/kanade/mangafeed/view/MangaCatalogueView.java b/app/src/main/java/eu/kanade/mangafeed/view/MangaCatalogueView.java index d31db7078..e56ece0c9 100644 --- a/app/src/main/java/eu/kanade/mangafeed/view/MangaCatalogueView.java +++ b/app/src/main/java/eu/kanade/mangafeed/view/MangaCatalogueView.java @@ -1,5 +1,8 @@ package eu.kanade.mangafeed.view; +import eu.kanade.mangafeed.data.models.Manga; + public interface MangaCatalogueView extends BaseView { void setTitle(String title); + void setMangaInformation(Manga manga); } diff --git a/app/src/main/res/drawable-xhdpi/bkg_shadow_img.9.png b/app/src/main/res/drawable-xhdpi/bkg_shadow_img.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6bd9c52050864491801f5abd91f59429551d1a1c GIT binary patch literal 1164 zcmV;71atd|P)C<|!?B+H>9yzu>17l7pk{5@md)3b040c)zeCx6M90AG02+sV zP=FNl5VtY?Y|vi7O+gvbM{o=kQtF2WpsAQ>8i) zVMHVjhX!g$X;`VCGy)YN^SyvJLj<3MtwGpkSlcvs1ZtwmkS2-=I5BV%r(u~rq(wx#fG>2z1 zXj4O<3V`zz-6(v8;M*ja;d%hd(F|e!a3u4Higq>$01dRLw5+tEv?`>Zy+)gP^qEAI zO9X2oJK!+|?zcsrnI7JD4SIBR^cA)%@RdZ6T7m{KM`ASWIzy+GmRy4#92|Uy z?J@Y0^Yjs@Or$t=kr51yUK3YbgYNC^{eOG#eD*6;2YPVySux; zV0!|-G6+&jP?PZqN+i9byi$7W8gyr8XA`z-@RbEE%6UaKhtZaZll}kKDw`tq_VYEuh*wxJJsZL?|BR5>^DUR13N-jWpfjq z!@)w|G?#=H@NSN7pj8Zafgt0SB(j3a0z`nW%o28(?)GC?tZRUn5}L%jaVkUQxVwm_TDv;%% zA)%ZomZi`)W~n=QLH2f1b_`N5=QDeN7;HyD8#w0hbH65vrH6 zA_NwuGNY|F+I2D4Ru=CQ&;~ptD$rbE4iT7y^S4nR@4Aj}tL3*V|5NMt-Trms>rhVr e!uc=%5c>-VI4NJ04kI!E0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2ca0265fb..c9c8f6211 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -36,5 +36,12 @@ Delete Selected CatalogueList + MangaCatalogue + Author + Chapters + Genres + Artist + Status + Description diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 71b087af5..9e911bf99 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -81,4 +81,21 @@ gone + + diff --git a/app/src/test/java/eu/kanade/mangafeed/BatotoTest.java b/app/src/test/java/eu/kanade/mangafeed/BatotoTest.java index cd9198e71..42046965b 100644 --- a/app/src/test/java/eu/kanade/mangafeed/BatotoTest.java +++ b/app/src/test/java/eu/kanade/mangafeed/BatotoTest.java @@ -15,8 +15,10 @@ import java.util.List; import eu.kanade.mangafeed.data.caches.CacheManager; import eu.kanade.mangafeed.data.helpers.NetworkHelper; +import eu.kanade.mangafeed.data.models.Chapter; import eu.kanade.mangafeed.data.models.Manga; import eu.kanade.mangafeed.sources.Batoto; +import eu.kanade.mangafeed.sources.Source; import rx.android.schedulers.AndroidSchedulers; import rx.observers.TestSubscriber; import rx.schedulers.Schedulers; @@ -27,8 +29,11 @@ public class BatotoTest { NetworkHelper net; CacheManager cache; - Batoto b; + Source b; final String chapterUrl ="http://bato.to/read/_/345144/minamoto-kun-monogatari_ch178_by_vortex-scans"; + final String mangaUrl = "http://bato.to/comic/_/comics/natsuzora-and-run-r9597"; + final String mangaUrl2 = "http://bato.to/comic/_/comics/bungaku-shoujo-to-shinitagari-no-pierrot-r534"; + final String nisekoiUrl = "http://bato.to/comic/_/comics/nisekoi-r951"; @Before public void setUp() { @@ -50,6 +55,34 @@ public class BatotoTest { List mangaList = b.pullPopularMangasFromNetwork(1) .toBlocking().first(); + Manga m = mangaList.get(0); + Assert.assertNotNull(m.title); + Assert.assertNotNull(m.artist); + Assert.assertNotNull(m.author); + Assert.assertNotNull(m.url); + Assert.assertTrue(mangaList.size() > 25); } + + @Test + public void testChapterList() { + List mangaList = b.pullChaptersFromNetwork(mangaUrl) + .toBlocking().first(); + + Assert.assertTrue(mangaList.size() > 5); + } + + @Test + public void testMangaDetails() { + Manga nisekoi = b.pullMangaFromNetwork(nisekoiUrl) + .toBlocking().single(); + + Assert.assertEquals("Nisekoi", nisekoi.title); + Assert.assertEquals("Komi Naoshi", nisekoi.author); + Assert.assertEquals("Komi Naoshi", nisekoi.artist); + Assert.assertEquals("http://bato.to/comic/_/nisekoi-r951", nisekoi.url); + Assert.assertEquals("http://img.bato.to/forums/uploads/a2a850c644a50bccc462f36922c1cbf2.jpg", nisekoi.thumbnail_url); + Assert.assertTrue(nisekoi.description.length() > 20); + Assert.assertTrue(nisekoi.genre.length() > 20); + } } diff --git a/app/src/test/java/eu/kanade/mangafeed/MangahereTest.java b/app/src/test/java/eu/kanade/mangafeed/MangahereTest.java new file mode 100644 index 000000000..c494a8c04 --- /dev/null +++ b/app/src/test/java/eu/kanade/mangafeed/MangahereTest.java @@ -0,0 +1,80 @@ +package eu.kanade.mangafeed; + +import android.os.Build; + +import junit.framework.Assert; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.List; + +import eu.kanade.mangafeed.data.caches.CacheManager; +import eu.kanade.mangafeed.data.helpers.NetworkHelper; +import eu.kanade.mangafeed.data.models.Chapter; +import eu.kanade.mangafeed.data.models.Manga; +import eu.kanade.mangafeed.sources.MangaHere; +import eu.kanade.mangafeed.sources.Source; + +@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP) +@RunWith(RobolectricGradleTestRunner.class) +public class MangahereTest { + + NetworkHelper net; + CacheManager cache; + Source b; + final String chapterUrl ="http://www.mangahere.co/manga/kimi_ni_todoke/v15/c099/"; + final String mangaUrl = "http://www.mangahere.co/manga/kimi_ni_todoke/"; + + @Before + public void setUp() { + net = new NetworkHelper(); + cache = new CacheManager(RuntimeEnvironment.application.getApplicationContext()); + b = new MangaHere(net, cache); + } + + @Test + public void testImageList() { + List imageUrls = b.getImageUrlsFromNetwork(chapterUrl) + .toList().toBlocking().single(); + + Assert.assertTrue(imageUrls.size() > 5); + } + + @Test + public void testMangaList() { + List mangaList = b.pullPopularMangasFromNetwork(1) + .toBlocking().first(); + + Manga m = mangaList.get(0); + Assert.assertNotNull(m.title); + Assert.assertNotNull(m.url); + + Assert.assertTrue(mangaList.size() > 25); + } + + @Test + public void testChapterList() { + List mangaList = b.pullChaptersFromNetwork(mangaUrl) + .toBlocking().first(); + + Assert.assertTrue(mangaList.size() > 5); + } + + @Test + public void testMangaDetails() { + Manga manga = b.pullMangaFromNetwork(mangaUrl) + .toBlocking().single(); + + Assert.assertEquals("Shiina Karuho", manga.author); + Assert.assertEquals("Shiina Karuho", manga.artist); + Assert.assertEquals("http://www.mangahere.co/manga/kimi_ni_todoke/", manga.url); + Assert.assertEquals("http://a.mhcdn.net/store/manga/4999/cover.jpg?v=1433950383", manga.thumbnail_url); + Assert.assertTrue(manga.description.length() > 20); + Assert.assertTrue(manga.genre.length() > 20); + } +}