@ -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 full title TextView.
manga _full _title . text = if ( manga . title . isBlank ( ) ) {
view . context . getString ( R . string . unknown )
} else {
manga . title
}
// Update artist TextView.
manga _artist . text = manga . artist
manga _artist . text = if ( manga . artist . isNullOrBlank ( ) ) {
view . context . getString ( R . string . unknown )
} else {
manga . artist
}
// Update author TextView.
manga _author . text = manga . author
manga _author . text = if ( manga . author . isNullOrBlank ( ) ) {
view . context . getString ( R . string . unknown )
} else {
manga . author
}
// If manga source is known update source TextView.
if ( source != null ) {
manga _source . text = source . toString ( )
manga _source . text = if ( source == null ) {
view . context . getString ( R . string . unknown )
} else {
source . toString ( )
}
// Update genres TextView.
manga _genres . text = manga . genre
// 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 .
*