Browse Source

Improve info fragment. Other minor changes and fixes.

inorichi 9 years ago
parent
commit
eb10d77374

+ 6 - 7
app/src/main/java/eu/kanade/mangafeed/data/download/DownloadManager.java

@@ -25,7 +25,6 @@ import eu.kanade.mangafeed.data.source.model.Page;
 import eu.kanade.mangafeed.event.DownloadChaptersEvent;
 import eu.kanade.mangafeed.util.DiskUtils;
 import eu.kanade.mangafeed.util.DynamicConcurrentMergeOperator;
-import eu.kanade.mangafeed.util.UrlUtil;
 import rx.Observable;
 import rx.Subscription;
 import rx.android.schedulers.AndroidSchedulers;
@@ -182,8 +181,10 @@ public class DownloadManager {
 
         return pageListObservable
                 .subscribeOn(Schedulers.io())
-                .doOnNext(pages -> download.setStatus(Download.DOWNLOADING))
-                .doOnNext(pages -> download.downloadedImages = 0)
+                .doOnNext(pages -> {
+                    download.downloadedImages = 0;
+                    download.setStatus(Download.DOWNLOADING);
+                })
                 // Get all the URLs to the source images, fetch pages if necessary
                 .flatMap(download.source::getAllImageUrlsFromPageList)
                 // Start downloading images, consider we can have downloaded images already
@@ -263,10 +264,8 @@ public class DownloadManager {
 
     // Get the filename for an image given the page
     private String getImageFilename(Page page) {
-        String url = UrlUtil.getPath(page.getImageUrl());
-        return url.substring(
-                url.lastIndexOf("/") + 1,
-                url.length());
+        String url = page.getImageUrl();
+        return url.substring(url.lastIndexOf("/") + 1, url.length());
     }
 
     private boolean isImageDownloaded(File imagePath) {

+ 2 - 2
app/src/main/java/eu/kanade/mangafeed/ui/catalogue/CatalogueFragment.java

@@ -39,10 +39,10 @@ public class CatalogueFragment extends BaseRxFragment<CataloguePresenter> {
 
     public final static String SOURCE_ID = "source_id";
 
-    public static CatalogueFragment newInstance(int source_id) {
+    public static CatalogueFragment newInstance(int sourceId) {
         CatalogueFragment fragment = new CatalogueFragment();
         Bundle args = new Bundle();
-        args.putInt(SOURCE_ID, source_id);
+        args.putInt(SOURCE_ID, sourceId);
         fragment.setArguments(args);
         return fragment;
     }

+ 3 - 0
app/src/main/java/eu/kanade/mangafeed/ui/download/DownloadPresenter.java

@@ -105,6 +105,9 @@ public class DownloadPresenter extends BasePresenter<DownloadFragment> {
     }
 
     private void observePagesStatus(Download download, DownloadFragment view) {
+        // Initial update of the downloaded pages
+        view.updateDownloadedPages(download);
+
         PublishSubject<Integer> pageStatusSubject = PublishSubject.create();
         for (Page page : download.pages) {
             if (page.getStatus() != Page.READY)

+ 4 - 10
app/src/main/java/eu/kanade/mangafeed/ui/manga/MangaPresenter.java

@@ -17,7 +17,6 @@ public class MangaPresenter extends BasePresenter<MangaActivity> {
     @Inject DatabaseHelper db;
 
     private long mangaId;
-    private Manga manga;
 
     private static final int DB_MANGA = 1;
 
@@ -25,19 +24,13 @@ public class MangaPresenter extends BasePresenter<MangaActivity> {
     protected void onCreate(Bundle savedState) {
         super.onCreate(savedState);
 
-        restartableLatestCache(DB_MANGA,
-                () -> getDbMangaObservable()
-                        .doOnNext(manga -> this.manga = manga),
-                (view, manga) -> {
-                    view.setManga(manga);
-                    EventBus.getDefault().postSticky(manga);
-                });
+        restartableLatestCache(DB_MANGA, this::getDbMangaObservable, MangaActivity::setManga);
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        // Avoid fragments receiving wrong manga
+        // Avoid new instances receiving wrong manga
         EventBus.getDefault().removeStickyEvent(Manga.class);
     }
 
@@ -45,7 +38,8 @@ public class MangaPresenter extends BasePresenter<MangaActivity> {
         return db.getManga(mangaId).createObservable()
                 .subscribeOn(Schedulers.io())
                 .flatMap(Observable::from)
-                .observeOn(AndroidSchedulers.mainThread());
+                .observeOn(AndroidSchedulers.mainThread())
+                .doOnNext(manga -> EventBus.getDefault().postSticky(manga));
     }
 
     public void queryManga(long mangaId) {

+ 21 - 34
app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java

@@ -56,61 +56,48 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
 
         restartableLatestCache(DB_CHAPTERS,
                 this::getDbChaptersObs,
-                ChaptersFragment::onNextChapters
-        );
+                ChaptersFragment::onNextChapters);
 
-        restartableLatestCache(FETCH_CHAPTERS,
+        restartableFirst(FETCH_CHAPTERS,
                 this::getOnlineChaptersObs,
                 (view, result) -> view.onFetchChaptersDone(),
-                (view, error) -> view.onFetchChaptersError()
-        );
+                (view, error) -> view.onFetchChaptersError());
 
         restartableLatestCache(CHAPTER_STATUS_CHANGES,
                 this::getChapterStatusObs,
                 (view, download) -> view.onChapterStatusChange(download),
-                (view, error) -> Timber.e(error.getCause(), error.getMessage())
-        );
-    }
+                (view, error) -> Timber.e(error.getCause(), error.getMessage()));
 
-    @Override
-    protected void onTakeView(ChaptersFragment view) {
-        super.onTakeView(view);
         registerForStickyEvents();
     }
 
-    @Override
-    protected void onDropView() {
-        unregisterForEvents();
-        super.onDropView();
-    }
-
     @Override
     protected void onDestroy() {
+        unregisterForEvents();
         EventBus.getDefault().removeStickyEvent(ChapterCountEvent.class);
         super.onDestroy();
     }
 
     @EventBusHook
     public void onEventMainThread(Manga manga) {
-        if (this.manga != null)
-            return;
-
         this.manga = manga;
-        source = sourceManager.get(manga.source);
-        start(DB_CHAPTERS);
 
-        add(db.getChapters(manga).createObservable()
-                .subscribeOn(Schedulers.io())
-                .doOnNext(chapters -> {
-                    stop(CHAPTER_STATUS_CHANGES);
-                    this.chapters = chapters;
-                    EventBus.getDefault().postSticky(new ChapterCountEvent(chapters.size()));
-                    for (Chapter chapter : chapters) {
-                        setChapterStatus(chapter);
-                    }
-                    start(CHAPTER_STATUS_CHANGES);
-                })
-                .subscribe(chaptersSubject::onNext));
+        if (!isStarted(DB_CHAPTERS)) {
+            source = sourceManager.get(manga.source);
+            start(DB_CHAPTERS);
+
+            add(db.getChapters(manga).createObservable()
+                    .subscribeOn(Schedulers.io())
+                    .doOnNext(chapters -> {
+                        this.chapters = chapters;
+                        EventBus.getDefault().postSticky(new ChapterCountEvent(chapters.size()));
+                        for (Chapter chapter : chapters) {
+                            setChapterStatus(chapter);
+                        }
+                        start(CHAPTER_STATUS_CHANGES);
+                    })
+                    .subscribe(chaptersSubject::onNext));
+        }
     }
 
     public void fetchChaptersFromSource() {

+ 49 - 20
app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoFragment.java

@@ -1,6 +1,7 @@
 package eu.kanade.mangafeed.ui.manga.info;
 
 import android.os.Bundle;
+import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -21,13 +22,15 @@ import nucleus.factory.RequiresPresenter;
 @RequiresPresenter(MangaInfoPresenter.class)
 public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
 
-    @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;
+    @Bind(R.id.swipe_refresh) SwipeRefreshLayout swipeRefresh;
+
+    @Bind(R.id.manga_artist) TextView artist;
+    @Bind(R.id.manga_author) TextView author;
+    @Bind(R.id.manga_chapters) TextView chapterCount;
+    @Bind(R.id.manga_genres) TextView genres;
+    @Bind(R.id.manga_status) TextView status;
+    @Bind(R.id.manga_summary) TextView description;
+    @Bind(R.id.manga_cover) ImageView cover;
 
     @Bind(R.id.action_favorite) Button favoriteBtn;
 
@@ -52,37 +55,63 @@ public class MangaInfoFragment extends BaseRxFragment<MangaInfoPresenter> {
         favoriteBtn.setOnClickListener(v -> {
             getPresenter().toggleFavorite();
         });
+        swipeRefresh.setOnRefreshListener(this::fetchMangaFromSource);
 
         return view;
     }
 
-    public void setMangaInfo(Manga manga) {
-        mArtist.setText(manga.artist);
-        mAuthor.setText(manga.author);
-        mGenres.setText(manga.genre);
-        mStatus.setText("Ongoing"); //TODO
-        mDescription.setText(manga.description);
+    public void onNextManga(Manga manga) {
+        if (manga.initialized) {
+            setMangaInfo(manga);
+        } else {
+            // Initialize manga
+            fetchMangaFromSource();
+        }
+    }
+
+    private void setMangaInfo(Manga manga) {
+        artist.setText(manga.artist);
+        author.setText(manga.author);
+        genres.setText(manga.genre);
+        status.setText("Ongoing"); //TODO
+        description.setText(manga.description);
 
         setFavoriteText(manga.favorite);
 
-        if (mCover.getDrawable() == null) {
-            CoverCache coverCache = getPresenter().coverCache;
-            LazyHeaders headers = getPresenter().source.getGlideHeaders();
+        CoverCache coverCache = getPresenter().coverCache;
+        LazyHeaders headers = getPresenter().source.getGlideHeaders();
+        if (manga.thumbnail_url != null && cover.getDrawable() == null) {
             if (manga.favorite) {
-                coverCache.saveAndLoadFromCache(mCover, manga.thumbnail_url, headers);
+                coverCache.saveAndLoadFromCache(cover, manga.thumbnail_url, headers);
             } else {
-                coverCache.loadFromNetwork(mCover, manga.thumbnail_url, headers);
+                coverCache.loadFromNetwork(cover, manga.thumbnail_url, headers);
             }
+            cover.setTag(manga.thumbnail_url);
         }
-
     }
 
     public void setChapterCount(int count) {
-        mChapters.setText(String.valueOf(count));
+        chapterCount.setText(String.valueOf(count));
     }
 
     public void setFavoriteText(boolean isFavorite) {
         favoriteBtn.setText(!isFavorite ? R.string.add_to_library : R.string.remove_from_library);
     }
 
+    private void fetchMangaFromSource() {
+        setRefreshing(true);
+        getPresenter().fetchMangaFromSource();
+    }
+
+    public void onFetchMangaDone() {
+        setRefreshing(false);
+    }
+
+    public void onFetchMangaError() {
+        setRefreshing(false);
+    }
+
+    private void setRefreshing(boolean value) {
+        swipeRefresh.setRefreshing(value);
+    }
 }

+ 30 - 10
app/src/main/java/eu/kanade/mangafeed/ui/manga/info/MangaInfoPresenter.java

@@ -13,6 +13,8 @@ import eu.kanade.mangafeed.event.ChapterCountEvent;
 import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
 import eu.kanade.mangafeed.util.EventBusHook;
 import rx.Observable;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
 
 public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
 
@@ -24,8 +26,11 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
     protected Source source;
     private int count = -1;
 
+    private boolean isFetching;
+
     private static final int GET_MANGA = 1;
     private static final int GET_CHAPTER_COUNT = 2;
+    private static final int FETCH_MANGA_INFO = 3;
 
     @Override
     protected void onCreate(Bundle savedState) {
@@ -33,23 +38,24 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
 
         restartableLatestCache(GET_MANGA,
                 () -> Observable.just(manga),
-                MangaInfoFragment::setMangaInfo);
+                MangaInfoFragment::onNextManga);
 
         restartableLatestCache(GET_CHAPTER_COUNT,
                 () -> Observable.just(count),
                 MangaInfoFragment::setChapterCount);
-    }
 
-    @Override
-    protected void onTakeView(MangaInfoFragment view) {
-        super.onTakeView(view);
+        restartableFirst(FETCH_MANGA_INFO,
+                this::fetchMangaObs,
+                (view, manga) -> view.onFetchMangaDone(),
+                (view, error) -> view.onFetchMangaError());
+
         registerForStickyEvents();
     }
 
     @Override
-    protected void onDropView() {
+    protected void onDestroy() {
         unregisterForEvents();
-        super.onDropView();
+        super.onDestroy();
     }
 
     @EventBusHook
@@ -67,9 +73,23 @@ public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {
         }
     }
 
-    public void initFavoriteText() {
-        if (getView() != null)
-            getView().setFavoriteText(manga.favorite);
+    public void fetchMangaFromSource() {
+        if (!isFetching) {
+            isFetching = true;
+            start(FETCH_MANGA_INFO);
+        }
+    }
+
+    private Observable<Manga> fetchMangaObs() {
+        return source.pullMangaFromNetwork(manga.url)
+                .flatMap(networkManga -> {
+                    Manga.copyFromNetwork(manga, networkManga);
+                    db.insertManga(manga).executeAsBlocking();
+                    return Observable.just(manga);
+                })
+                .finallyDo(() -> isFetching = false)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread());
     }
 
     public void toggleFavorite() {

+ 213 - 191
app/src/main/res/layout/fragment_manga_info.xml

@@ -3,206 +3,228 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:fitsSystemWindows="true"
     android:orientation="vertical"
     tools:context="eu.kanade.mangafeed.ui.catalogue.CatalogueFragment">
 
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:padding="10dp">
 
-        <RelativeLayout
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:background="@drawable/bkg_shadow_img"
-            android:focusable="false"
-            android:focusableInTouchMode="false"
-            android:gravity="center"
-            android:padding="4dp">
-
-            <ImageView
-                android:id="@+id/manga_cover"
-                android:layout_width="138dp"
-                android:layout_height="190dp"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:scaleType="fitXY"
-                android:visibility="visible" />
-
-        </RelativeLayout>
-
-        <RelativeLayout
-            android:id="@+id/grid_item_description"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:focusable="false"
-            android:focusableInTouchMode="false"
-            android:paddingLeft="15.0dip">
-
-            <TextView
-                android:id="@+id/manga_author_label"
-                style="@style/manga_detail_label"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentLeft="true"
-                android:layout_alignRight="@+id/manga_genres_label"
-                android:layout_marginTop="5dp"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:text="@string/author" />
-
-            <TextView
-                android:id="@+id/manga_author"
-                style="@style/manga_detail_text"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_alignBaseline="@id/manga_author_label"
-                android:layout_toRightOf="@id/manga_author_label"
-                android:ellipsize="end"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:maxLines="1"
-                android:singleLine="true" />
-
-            <TextView
-                android:id="@+id/manga_artist_label"
-                style="@style/manga_detail_label"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentLeft="true"
-                android:layout_alignRight="@id/manga_genres_label"
-                android:layout_below="@id/manga_author_label"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:text="@string/artist" />
-
-            <TextView
-                android:id="@+id/manga_artist"
-                style="@style/manga_detail_text"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_alignBaseline="@id/manga_artist_label"
-                android:layout_toRightOf="@id/manga_artist_label"
-                android:ellipsize="end"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:maxLines="1"
-                android:singleLine="true" />
-
-            <TextView
-                android:id="@+id/manga_chapters_label"
-                style="@style/manga_detail_label"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentLeft="true"
-                android:layout_below="@id/manga_artist_label"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:text="@string/chapters" />
-
-            <TextView
-                android:id="@+id/manga_chapters"
-                style="@style/manga_detail_text"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_alignBaseline="@id/manga_chapters_label"
-                android:layout_toRightOf="@id/manga_chapters_label"
-                android:ellipsize="end"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:maxLines="1"
-                android:singleLine="true" />
-
-            <TextView
-                android:id="@+id/manga_status_label"
-                style="@style/manga_detail_label"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentLeft="true"
-                android:layout_alignRight="@id/manga_genres_label"
-                android:layout_below="@id/manga_chapters_label"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:text="@string/status" />
-
-            <TextView
-                android:id="@+id/manga_status"
-                style="@style/manga_detail_text"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_alignBaseline="@id/manga_status_label"
-                android:layout_toRightOf="@id/manga_chapters_label"
-                android:ellipsize="end"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:maxLines="1"
-                android:singleLine="true" />
-
-            <TextView
-                android:id="@+id/manga_genres_label"
-                style="@style/manga_detail_label"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentLeft="true"
-                android:layout_below="@id/manga_status_label"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:text="@string/genres" />
-
-            <TextView
-                android:id="@+id/manga_genres"
-                style="@style/manga_detail_text"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_below="@id/manga_genres_label"
-                android:focusable="false"
-                android:focusableInTouchMode="false"
-                android:singleLine="false" />
-
-
-        </RelativeLayout>
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:padding="10dp">
-
-        <Button
-            android:id="@+id/action_favorite"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/add_to_library" />
-    </LinearLayout>
-
-    <LinearLayout
+    <!-- It seems I have to wrap everything in SwipeRefreshLayout because it always take the entire height
+         and the description can't be seen.
+         Maybe with Relative layout it's better. We shouldn't put this layout inside the description layout
+         because the description should be scrollable and gestures could conflict with this layout.
+         Leaving it like this for now.
+    -->
+    <android.support.v4.widget.SwipeRefreshLayout
+        android:id="@+id/swipe_refresh"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
         android:orientation="vertical"
-        android:padding="10dp">
+        android:layout_height="match_parent">
 
-        <TextView
-            android:id="@+id/manga_summary_label"
-            style="@style/manga_detail_label"
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:focusable="false"
-            android:focusableInTouchMode="false"
-            android:singleLine="false"
-            android:text="@string/description" />
-
-        <TextView
-            android:id="@+id/manga_summary"
-            style="@style/manga_detail_text"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:focusable="false"
-            android:focusableInTouchMode="false"
-            android:singleLine="false" />
+            android:clickable="true"
+            android:orientation="vertical">
 
-    </LinearLayout>
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dp">
+
+                <RelativeLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:background="@drawable/bkg_shadow_img"
+                    android:focusable="false"
+                    android:focusableInTouchMode="false"
+                    android:gravity="center"
+                    android:padding="4dp">
+
+                    <ImageView
+                        android:id="@+id/manga_cover"
+                        android:layout_width="138dp"
+                        android:layout_height="190dp"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:scaleType="fitXY"
+                        android:visibility="visible" />
+
+                </RelativeLayout>
+
+                <RelativeLayout
+                    android:id="@+id/grid_item_description"
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"
+                    android:focusable="false"
+                    android:focusableInTouchMode="false"
+                    android:paddingLeft="15.0dip">
+
+                    <TextView
+                        android:id="@+id/manga_author_label"
+                        style="@style/manga_detail_label"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_alignParentLeft="true"
+                        android:layout_alignRight="@+id/manga_genres_label"
+                        android:layout_marginTop="5dp"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:text="@string/author" />
+
+                    <TextView
+                        android:id="@+id/manga_author"
+                        style="@style/manga_detail_text"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_alignBaseline="@id/manga_author_label"
+                        android:layout_toRightOf="@id/manga_author_label"
+                        android:ellipsize="end"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:maxLines="1"
+                        android:singleLine="true" />
+
+                    <TextView
+                        android:id="@+id/manga_artist_label"
+                        style="@style/manga_detail_label"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_alignParentLeft="true"
+                        android:layout_alignRight="@id/manga_genres_label"
+                        android:layout_below="@id/manga_author_label"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:text="@string/artist" />
+
+                    <TextView
+                        android:id="@+id/manga_artist"
+                        style="@style/manga_detail_text"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_alignBaseline="@id/manga_artist_label"
+                        android:layout_toRightOf="@id/manga_artist_label"
+                        android:ellipsize="end"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:maxLines="1"
+                        android:singleLine="true" />
+
+                    <TextView
+                        android:id="@+id/manga_chapters_label"
+                        style="@style/manga_detail_label"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_alignParentLeft="true"
+                        android:layout_below="@id/manga_artist_label"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:text="@string/chapters" />
+
+                    <TextView
+                        android:id="@+id/manga_chapters"
+                        style="@style/manga_detail_text"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_alignBaseline="@id/manga_chapters_label"
+                        android:layout_toRightOf="@id/manga_chapters_label"
+                        android:ellipsize="end"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:maxLines="1"
+                        android:singleLine="true" />
+
+                    <TextView
+                        android:id="@+id/manga_status_label"
+                        style="@style/manga_detail_label"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_alignParentLeft="true"
+                        android:layout_alignRight="@id/manga_genres_label"
+                        android:layout_below="@id/manga_chapters_label"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:text="@string/status" />
+
+                    <TextView
+                        android:id="@+id/manga_status"
+                        style="@style/manga_detail_text"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_alignBaseline="@id/manga_status_label"
+                        android:layout_toRightOf="@id/manga_chapters_label"
+                        android:ellipsize="end"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:maxLines="1"
+                        android:singleLine="true" />
+
+                    <TextView
+                        android:id="@+id/manga_genres_label"
+                        style="@style/manga_detail_label"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_alignParentLeft="true"
+                        android:layout_below="@id/manga_status_label"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:text="@string/genres" />
+
+                    <TextView
+                        android:id="@+id/manga_genres"
+                        style="@style/manga_detail_text"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_below="@id/manga_genres_label"
+                        android:focusable="false"
+                        android:focusableInTouchMode="false"
+                        android:singleLine="false" />
+
+
+                </RelativeLayout>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:padding="10dp">
+
+                <Button
+                    android:id="@+id/action_favorite"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/add_to_library" />
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:orientation="vertical"
+                android:padding="10dp">
+
+                <TextView
+                    android:id="@+id/manga_summary_label"
+                    style="@style/manga_detail_label"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:focusable="false"
+                    android:focusableInTouchMode="false"
+                    android:singleLine="false"
+                    android:text="@string/description" />
+
+                <TextView
+                    android:id="@+id/manga_summary"
+                    style="@style/manga_detail_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:focusable="false"
+                    android:focusableInTouchMode="false"
+                    android:singleLine="false" />
+
+            </LinearLayout>
+
+        </LinearLayout>
+
+    </android.support.v4.widget.SwipeRefreshLayout>
 
 </LinearLayout>