Information Page Improvements (click to search, copy to clipboard, etc) (#1139)

* adds long click to copy details per inorichi/tachiyomi#1127

* Added the latest update date for inorichi/tachiyomi#1098 and possible fix for inorichi/tachiyomi#1141

* cleanup some mistakes I left

* adds modifications to full name display for inorichi/tachiyomi#1141 and click to search on various information pieces for inorichi/tachiyomi#860

* This modifies how the full title shows up in the info pages and also properly ellipsizes the titles in the catalogue/library list views

* Changes full title layout in horizontal mode

* Adds the tags in using AndroidTagGroup library

* reverting the sdk version in the gradle build

* code cleanup

* added back status update
This commit is contained in:
Josh 2018-01-18 12:15:33 -06:00 committed by inorichi
parent fae36aebf4
commit 34d21c1de3
13 changed files with 321 additions and 103 deletions

View file

@ -202,6 +202,7 @@ dependencies {
implementation 'me.zhanghai.android.systemuihelper:library:1.0.0'
implementation 'com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.0.4'
implementation 'com.github.mthli:Slice:v1.2'
implementation 'me.gujun.android.taggroup:library:1.4@aar'
// Conductor
implementation "com.bluelinelabs:conductor:2.1.4"

View file

@ -185,10 +185,11 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
// Create query listener which opens the global search view.
searchView.queryTextChangeEvents()
.filter { it.isSubmitted }
.subscribeUntilDestroy {
val query = it.queryText().toString()
router.pushController(CatalogueSearchController(query).withFadeTransaction())
}
.subscribeUntilDestroy { performGlobalSearch(it.queryText().toString()) }
}
fun performGlobalSearch(query: String){
router.pushController(CatalogueSearchController(query).withFadeTransaction())
}
/**

View file

@ -21,10 +21,8 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.controller.RouterPagerAdapter
import eu.kanade.tachiyomi.ui.base.controller.RxController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.base.controller.requestPermissionsSafe
import eu.kanade.tachiyomi.ui.base.controller.*
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersController
import eu.kanade.tachiyomi.ui.manga.info.MangaInfoController
import eu.kanade.tachiyomi.ui.manga.track.TrackController
@ -34,6 +32,7 @@ import kotlinx.android.synthetic.main.manga_controller.*
import rx.Subscription
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.*
class MangaController : RxController, TabbedController {
@ -63,6 +62,8 @@ class MangaController : RxController, TabbedController {
val fromCatalogue = args.getBoolean(FROM_CATALOGUE_EXTRA, false)
val lastUpdateRelay: BehaviorRelay<Date> = BehaviorRelay.create()
val chapterCountRelay: BehaviorRelay<Float> = BehaviorRelay.create()
val mangaFavoriteRelay: PublishRelay<Boolean> = PublishRelay.create()
@ -188,4 +189,5 @@ class MangaController : RxController, TabbedController {
.apply { isAccessible = true }
}
}

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.manga.chapter
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.support.design.widget.Snackbar
@ -61,7 +62,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
override fun createPresenter(): ChaptersPresenter {
val ctrl = parentController as MangaController
return ChaptersPresenter(ctrl.manga!!, ctrl.source!!,
ctrl.chapterCountRelay, ctrl.mangaFavoriteRelay)
ctrl.chapterCountRelay, ctrl.lastUpdateRelay, ctrl.mangaFavoriteRelay)
}
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
@ -292,6 +293,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
return true
}
@SuppressLint("StringFormatInvalid")
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
val count = adapter?.selectedItemCount ?: 0
if (count == 0) {

View file

@ -20,6 +20,7 @@ import rx.schedulers.Schedulers
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.*
/**
* Presenter of [ChaptersController].
@ -28,6 +29,7 @@ class ChaptersPresenter(
val manga: Manga,
val source: Source,
private val chapterCountRelay: BehaviorRelay<Float>,
private val lastUpdateRelay: BehaviorRelay<Date>,
private val mangaFavoriteRelay: PublishRelay<Boolean>,
val preferences: PreferencesHelper = Injekt.get(),
private val db: DatabaseHelper = Injekt.get(),
@ -91,6 +93,11 @@ class ChaptersPresenter(
// Emit the number of chapters to the info tab.
chapterCountRelay.call(chapters.maxBy { it.chapter_number }?.chapter_number
?: 0f)
// Emit the upload date of the most recent chapter
lastUpdateRelay.call(Date(chapters.maxBy { it.date_upload }?.date_upload
?: 0))
}
.subscribe { chaptersRelay.call(it) })
}

View file

@ -2,8 +2,12 @@ package eu.kanade.tachiyomi.ui.manga.info
import android.app.Dialog
import android.app.PendingIntent
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
@ -13,6 +17,7 @@ import android.support.v4.content.pm.ShortcutInfoCompat
import android.support.v4.content.pm.ShortcutManagerCompat
import android.support.v4.graphics.drawable.IconCompat
import android.view.*
import android.widget.Toast
import com.afollestad.materialdialogs.MaterialDialog
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
@ -20,6 +25,7 @@ import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
import com.jakewharton.rxbinding.support.v4.widget.refreshes
import com.jakewharton.rxbinding.view.clicks
import com.jakewharton.rxbinding.view.longClicks
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
@ -31,17 +37,22 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.getResourceColor
import eu.kanade.tachiyomi.util.snack
import eu.kanade.tachiyomi.util.toast
import eu.kanade.tachiyomi.util.truncateCenter
import jp.wasabeef.glide.transformations.CropSquareTransformation
import jp.wasabeef.glide.transformations.MaskTransformation
import kotlinx.android.synthetic.main.manga_info_controller.*
import uy.kohesive.injekt.injectLazy
import java.text.DateFormat
import java.text.DecimalFormat
import java.util.*
/**
* Fragment that shows manga information.
@ -64,7 +75,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
override fun createPresenter(): MangaInfoPresenter {
val ctrl = parentController as MangaController
return MangaInfoPresenter(ctrl.manga!!, ctrl.source!!,
ctrl.chapterCountRelay, ctrl.mangaFavoriteRelay)
ctrl.chapterCountRelay, ctrl.lastUpdateRelay, ctrl.mangaFavoriteRelay)
}
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
@ -79,6 +90,41 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
// Set SwipeRefresh to refresh manga data.
swipe_refresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() }
manga_full_title.longClicks().subscribeUntilDestroy{
copyToClipboard(view.context.getString(R.string.title), manga_full_title.text.toString())
}
manga_full_title.clicks().subscribeUntilDestroy {
performGlobalSearch(manga_full_title.text.toString())
}
manga_artist.longClicks().subscribeUntilDestroy {
copyToClipboard(manga_artist_label.text.toString(), manga_artist.text.toString())
}
manga_artist.clicks().subscribeUntilDestroy {
performGlobalSearch(manga_artist.text.toString())
}
manga_author.longClicks().subscribeUntilDestroy {
copyToClipboard(manga_author.text.toString(), manga_author.text.toString())
}
manga_author.clicks().subscribeUntilDestroy {
performGlobalSearch(manga_author.text.toString())
}
manga_summary.longClicks().subscribeUntilDestroy {
copyToClipboard(view.context.getString(R.string.description), manga_summary.text.toString())
}
manga_genres_tags.setOnTagClickListener { tag -> performGlobalSearch(tag) }
manga_cover.longClicks().subscribeUntilDestroy {
copyToClipboard(view.context.getString(R.string.title), presenter.manga.title)
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@ -107,6 +153,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
if (manga.initialized) {
// Update view.
setMangaInfo(manga, source)
} else {
// Initialize manga.
fetchMangaFromSource()
@ -122,19 +169,45 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
private fun setMangaInfo(manga: Manga, source: Source?) {
val view = view ?: return
// Update artist TextView.
manga_artist.text = manga.artist
// Update author TextView.
manga_author.text = manga.author
// If manga source is known update source TextView.
if (source != null) {
manga_source.text = source.toString()
//update full title TextView.
manga_full_title.text = if (manga.title.isBlank()) {
view.context.getString(R.string.unknown)
} else {
manga.title
}
// Update genres TextView.
manga_genres.text = manga.genre
// Update artist TextView.
manga_artist.text = if (manga.artist.isNullOrBlank()) {
view.context.getString(R.string.unknown)
} else {
manga.artist
}
// Update author TextView.
manga_author.text = if (manga.author.isNullOrBlank()) {
view.context.getString(R.string.unknown)
} else {
manga.author
}
// If manga source is known update source TextView.
manga_source.text = if(source == null) {
view.context.getString(R.string.unknown)
} else {
source.toString()
}
// Update genres list
if(manga.genre.isNullOrBlank().not()){
manga_genres_tags.setTags(manga.genre?.split(", "))
}
// Update description TextView.
manga_summary.text = if (manga.description.isNullOrBlank()) {
view.context.getString(R.string.unknown)
} else {
manga.description
}
// Update status TextView.
manga_status.setText(when (manga.status) {
@ -144,9 +217,6 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
else -> R.string.unknown
})
// Update description TextView.
manga_summary.text = manga.description
// Set the favorite drawable to the correct one.
setFavoriteDrawable(manga.favorite)
@ -168,6 +238,11 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
}
}
override fun onDestroyView(view: View) {
manga_genres_tags.setOnTagClickListener(null)
super.onDestroyView(view)
}
/**
* Update chapter count TextView.
*
@ -177,6 +252,10 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
manga_chapters?.text = DecimalFormat("#.#").format(count)
}
fun setLastUpdateDate(date: Date){
manga_last_update?.text = DateFormat.getDateInstance(DateFormat.SHORT).format(date)
}
/**
* Toggles the favorite status and asks for confirmation to delete downloaded chapters.
*/
@ -380,6 +459,35 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
})
}
/**
* Copies a string to clipboard
*
* @param label Label to show to the user describing the content
* @param content the actual text to copy to the board
*/
private fun copyToClipboard(label: String, content: String){
if(content.isBlank()) return
val activity = activity ?: return
val view = view ?: return
val clipboard = activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboard.primaryClip = ClipData.newPlainText(label, content)
activity.toast( view.context.getString(R.string.copied_to_clipboard, content.truncateCenter(20)),
Toast.LENGTH_SHORT)
}
/**
* Perform a global search using the provided query.
*
* @param query the search query to pass to the search controller
*/
fun performGlobalSearch(query: String){
val router = parentController?.router ?: return
router.pushController(CatalogueSearchController(query).withFadeTransaction())
}
/**
* Create shortcut using ShortcutManager.
*

View file

@ -18,6 +18,7 @@ import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.*
/**
* Presenter of MangaInfoFragment.
@ -28,6 +29,7 @@ class MangaInfoPresenter(
val manga: Manga,
val source: Source,
private val chapterCountRelay: BehaviorRelay<Float>,
private val lastUpdateRelay: BehaviorRelay<Date>,
private val mangaFavoriteRelay: PublishRelay<Boolean>,
private val db: DatabaseHelper = Injekt.get(),
private val downloadManager: DownloadManager = Injekt.get(),
@ -37,7 +39,7 @@ class MangaInfoPresenter(
/**
* Subscription to send the manga to the view.
*/
private var viewMangaSubcription: Subscription? = null
private var viewMangaSubscription: Subscription? = null
/**
* Subscription to update the manga from the source.
@ -56,14 +58,18 @@ class MangaInfoPresenter(
mangaFavoriteRelay.observeOn(AndroidSchedulers.mainThread())
.subscribe { setFavorite(it) }
.apply { add(this) }
//update last update date
lastUpdateRelay.observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache(MangaInfoController::setLastUpdateDate)
}
/**
* Sends the active manga to the view.
*/
fun sendMangaToView() {
viewMangaSubcription?.let { remove(it) }
viewMangaSubcription = Observable.just(manga)
viewMangaSubscription?.let { remove(it) }
viewMangaSubscription = Observable.just(manga)
.subscribeLatestCache({ view, manga -> view.onNextManga(manga, source) })
}

View file

@ -1,5 +1,7 @@
package eu.kanade.tachiyomi.util
import java.lang.Math.floor
/**
* Replaces the given string to have at most [count] characters using [replacement] at its end.
* If [replacement] is longer than [count] an exception will be thrown when `length > count`.
@ -11,3 +13,16 @@ fun String.chop(count: Int, replacement: String = "..."): String {
this
}
/**
* Replaces the given string to have at most [count] characters using [replacement] near the center.
* If [replacement] is longer than [count] an exception will be thrown when `length > count`.
*/
fun String.truncateCenter(count: Int, replacement: String = "..."): String{
if(length <= count)
return this
val pieceLength:Int = floor((count - replacement.length).div(2.0)).toInt()
return "${ take(pieceLength) }$replacement${ takeLast(pieceLength) }"
}

View file

@ -59,6 +59,18 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="@string/manga_info_full_title_label"
android:id="@+id/manga_full_title"
style="@style/TextAppearance.Medium.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textIsSelectable="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/manga_author_label"
style="@style/TextAppearance.Medium.Body2"
@ -66,7 +78,7 @@
android:layout_height="wrap_content"
android:text="@string/manga_info_author_label"
android:textIsSelectable="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@+id/manga_full_title"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
@ -131,6 +143,30 @@
app:layout_constraintRight_toRightOf="parent"
android:layout_marginStart="8dp"/>
<TextView
android:id="@+id/manga_last_update_label"
style="@style/TextAppearance.Medium.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/manga_info_latest_data_label"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_chapters_label"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/manga_last_update"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:ellipsize="end"
android:maxLines="1"
android:textIsSelectable="false"
app:layout_constraintBaseline_toBaselineOf="@+id/manga_last_update_label"
app:layout_constraintLeft_toRightOf="@+id/manga_last_update_label"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginStart="8dp"/>
<TextView
android:id="@+id/manga_status_label"
style="@style/TextAppearance.Medium.Body2"
@ -138,7 +174,7 @@
android:layout_height="wrap_content"
android:text="@string/manga_info_status_label"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_chapters_label"
app:layout_constraintTop_toBottomOf="@+id/manga_last_update_label"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
@ -179,26 +215,6 @@
app:layout_constraintRight_toRightOf="parent"
android:layout_marginStart="8dp"/>
<TextView
android:id="@+id/manga_genres_label"
style="@style/TextAppearance.Medium.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/manga_info_genres_label"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_source_label"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/manga_genres"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_genres_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/manga_summary_label"
style="@style/TextAppearance.Medium.Body2"
@ -206,7 +222,7 @@
android:layout_height="wrap_content"
android:text="@string/description"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_genres"
app:layout_constraintTop_toBottomOf="@+id/manga_source"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
@ -220,6 +236,22 @@
app:layout_constraintRight_toRightOf="parent"
android:layout_marginRight="64dp"/>
<me.gujun.android.taggroup.TagGroup
android:id="@+id/manga_genres_tags"
style="@style/TagGroup"
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/manga_summary"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:atg_borderStrokeWidth="1dp"
app:atg_backgroundColor="@android:color/transparent"
app:atg_borderColor="@color/md_blue_A400"
app:atg_textColor="@color/md_blue_A400"
android:layout_marginRight="64dp"/>
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>

View file

@ -21,10 +21,11 @@
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:layout_marginLeft="8dp"/>
<TextView
android:id="@+id/title"
style="@style/TextAppearance.Regular.SubHeading"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
@ -41,6 +42,28 @@
app:layout_constraintVertical_bias="0.523"
app:layout_constraintHorizontal_bias="0.007"/>
<TextView
android:id="@+id/local_text"
style="@style/TextAppearance.Regular.Caption.Light"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/md_teal_500"
android:paddingBottom="1dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="1dp"
android:layout_centerVertical="true"
android:maxLines="1"
android:text="@string/local_source_badge"
android:visibility="gone"
tools:visibility="visible"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toLeftOf="@+id/unread_text"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"/>
<TextView
android:id="@+id/unread_text"
style="@style/TextAppearance.Regular.Caption.Light"
@ -58,6 +81,7 @@
tools:text="130"
tools:visibility="visible"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@+id/download_text"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"
@ -81,32 +105,11 @@
tools:text="122"
tools:visibility="visible"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toLeftOf="@+id/unread_text"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"/>
<TextView
android:id="@+id/local_text"
style="@style/TextAppearance.Regular.Caption.Light"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/md_teal_500"
android:paddingBottom="1dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="1dp"
android:layout_centerVertical="true"
android:maxLines="1"
android:text="@string/local_source_badge"
android:visibility="gone"
tools:visibility="visible"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toLeftOf="@+id/download_text"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"/>
</android.support.constraint.ConstraintLayout>

View file

@ -41,10 +41,10 @@
android:layout_height="wrap_content"
tools:text="22/02/2016"
android:ellipsize="marquee"
android:maxLines="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginLeft="16dp"/>
android:layout_marginLeft="16dp"
android:singleLine="true" />
<TextView
android:id="@+id/chapter_pages"
@ -53,10 +53,10 @@
android:layout_height="wrap_content"
tools:text="Pages: 45"
android:ellipsize="marquee"
android:maxLines="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
app:layout_constraintLeft_toLeftOf="parent"
android:singleLine="true" />
<ImageView
android:id="@+id/chapter_menu"

View file

@ -83,6 +83,16 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="@string/manga_info_full_title_label"
android:id="@+id/manga_full_title"
style="@style/TextAppearance.Medium.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:textIsSelectable="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/manga_author_label"
style="@style/TextAppearance.Medium.Body2"
@ -90,9 +100,11 @@
android:layout_height="wrap_content"
android:text="@string/manga_info_author_label"
android:textIsSelectable="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@+id/manga_full_title"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/manga_author"
style="@style/TextAppearance.Regular.Body1.Secondary"
@ -152,6 +164,29 @@
app:layout_constraintLeft_toRightOf="@+id/manga_chapters_label"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/manga_last_update_label"
style="@style/TextAppearance.Medium.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/manga_info_latest_data_label"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_chapters_label"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/manga_last_update"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:ellipsize="end"
android:maxLines="1"
android:textIsSelectable="false"
app:layout_constraintBaseline_toBaselineOf="@+id/manga_last_update_label"
app:layout_constraintLeft_toRightOf="@+id/manga_last_update_label"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/manga_status_label"
style="@style/TextAppearance.Medium.Body2"
@ -159,7 +194,7 @@
android:layout_height="wrap_content"
android:text="@string/manga_info_status_label"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_chapters_label"
app:layout_constraintTop_toBottomOf="@+id/manga_last_update_label"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
@ -198,26 +233,6 @@
app:layout_constraintLeft_toRightOf="@+id/manga_source_label"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/manga_genres_label"
style="@style/TextAppearance.Medium.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/manga_info_genres_label"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_source_label"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/manga_genres"
style="@style/TextAppearance.Regular.Body1.Secondary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textIsSelectable="false"
app:layout_constraintTop_toBottomOf="@+id/manga_genres_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>
@ -225,17 +240,16 @@
<android.support.v4.widget.NestedScrollView
android:id="@+id/description_scrollview"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline">
app:layout_constraintTop_toBottomOf="@+id/guideline">
<LinearLayout
android:layout_width="match_parent"
@ -261,6 +275,29 @@
</android.support.v4.widget.NestedScrollView>
<me.gujun.android.taggroup.TagGroup
android:id="@+id/manga_genres_tags"
style="@style/TagGroup"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="16dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/description_scrollview"
app:layout_constraintBottom_toBottomOf="parent"
app:atg_borderStrokeWidth="1dp"
app:atg_backgroundColor="@android:color/transparent"
app:atg_borderColor="@color/md_blue_A400"
app:atg_textColor="@color/md_blue_A400"
/>
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.SwipeRefreshLayout>

View file

@ -300,12 +300,14 @@
<string name="unknown">Unknown</string>
<string name="licensed">Licensed</string>
<string name="remove_from_library">Remove from library</string>
<string name="manga_info_full_title_label">Title</string>
<string name="manga_added_library">Added to library</string>
<string name="manga_removed_library">Removed from library</string>
<string name="manga_info_author_label">Author</string>
<string name="manga_info_artist_label">Artist</string>
<string name="manga_info_chapters_label">Chapters</string>
<string name="manga_info_last_chapter_label">Last chapter</string>
<string name="manga_info_latest_data_label">Updated</string>
<string name="manga_info_status_label">Status</string>
<string name="manga_info_source_label">Source</string>
<string name="manga_info_genres_label">Genres</string>
@ -319,6 +321,7 @@
<string name="icon_shape">Icon shape</string>
<string name="icon_creation_fail">Failed to create shortcut!</string>
<string name="delete_downloads_for_manga">Delete downloaded chapters?</string>
<string name="copied_to_clipboard">%1$s copied to clipboard</string>
<!-- Manga chapters fragment -->
<string name="manga_chapters_tab">Chapters</string>
@ -457,4 +460,5 @@
<string name="channel_common">Common</string>
<string name="channel_library">Library</string>
<string name="channel_downloader">Downloader</string>
</resources>