mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	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:
		@@ -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())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -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 }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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) })
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -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) })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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) }"
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user