Use synthetic view's new caching method

pull/1111/head
inorichi 7 years ago
parent 9ba8d88b07
commit d690d6e0e3

@ -250,3 +250,6 @@ kotlin {
coroutines 'enable' coroutines 'enable'
} }
} }
androidExtensions {
experimental = true
}

@ -6,21 +6,39 @@ import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.ControllerChangeType
import com.bluelinelabs.conductor.RestoreViewOnCreateController import com.bluelinelabs.conductor.RestoreViewOnCreateController
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.*
abstract class BaseController(bundle: Bundle? = null) : RestoreViewOnCreateController(bundle) { abstract class BaseController(bundle: Bundle? = null) : RestoreViewOnCreateController(bundle),
LayoutContainer {
init {
addLifecycleListener(object : LifecycleListener() {
override fun postCreateView(controller: Controller, view: View) {
onViewCreated(view)
}
})
}
override val containerView: View?
get() = view
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View {
val view = inflateView(inflater, container) return inflateView(inflater, container)
onViewCreated(view, savedViewState) }
return view
override fun onDestroyView(view: View) {
super.onDestroyView(view)
clearFindViewByIdCache()
} }
abstract fun inflateView(inflater: LayoutInflater, container: ViewGroup): View abstract fun inflateView(inflater: LayoutInflater, container: ViewGroup): View
open fun onViewCreated(view: View, savedViewState: Bundle?) { } open fun onViewCreated(view: View) { }
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
if (type.isEnter) { if (type.isEnter) {

@ -5,6 +5,8 @@ import android.os.Build
import android.support.v4.content.ContextCompat import android.support.v4.content.ContextCompat
import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
fun Router.popControllerWithTag(tag: String): Boolean { fun Router.popControllerWithTag(tag: String): Boolean {
val controller = getControllerWithTag(tag) val controller = getControllerWithTag(tag)
@ -24,4 +26,10 @@ fun Controller.requestPermissionsSafe(permissions: Array<String>, requestCode: I
} }
} }
} }
} }
fun Controller.withFadeTransaction(): RouterTransaction {
return RouterTransaction.with(this)
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler())
}

@ -30,7 +30,7 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
} }
@CallSuper @CallSuper
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
if (untilDestroySubscriptions.isUnsubscribed) { if (untilDestroySubscriptions.isUnsubscribed) {
untilDestroySubscriptions = CompositeSubscription() untilDestroySubscriptions = CompositeSubscription()
} }

@ -7,8 +7,6 @@ import android.support.v4.widget.DrawerLayout
import android.support.v7.widget.* import android.support.v7.widget.*
import android.view.* import android.view.*
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import com.f2prateek.rx.preferences.Preference import com.f2prateek.rx.preferences.Preference
import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
@ -21,12 +19,13 @@ import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.* import eu.kanade.tachiyomi.util.*
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import eu.kanade.tachiyomi.widget.DrawerSwipeCloseListener import eu.kanade.tachiyomi.widget.DrawerSwipeCloseListener
import kotlinx.android.synthetic.main.catalogue_controller.view.* import kotlinx.android.synthetic.main.catalogue_controller.*
import kotlinx.android.synthetic.main.main_activity.* import kotlinx.android.synthetic.main.main_activity.*
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
@ -112,8 +111,8 @@ open class CatalogueController(bundle: Bundle) :
return inflater.inflate(R.layout.catalogue_controller, container, false) return inflater.inflate(R.layout.catalogue_controller, container, false)
} }
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
// Initialize adapter, scroll listener and recycler views // Initialize adapter, scroll listener and recycler views
adapter = FlexibleAdapter(null, this) adapter = FlexibleAdapter(null, this)
@ -121,11 +120,10 @@ open class CatalogueController(bundle: Bundle) :
navView?.setFilters(presenter.filterItems) navView?.setFilters(presenter.filterItems)
view.progress?.visible() progress?.visible()
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view)
numColumnsSubscription?.unsubscribe() numColumnsSubscription?.unsubscribe()
numColumnsSubscription = null numColumnsSubscription = null
searchViewSubscription?.unsubscribe() searchViewSubscription?.unsubscribe()
@ -133,6 +131,7 @@ open class CatalogueController(bundle: Bundle) :
adapter = null adapter = null
snack = null snack = null
recycler = null recycler = null
super.onDestroyView(view)
} }
override fun createSecondaryDrawer(drawer: DrawerLayout): ViewGroup? { override fun createSecondaryDrawer(drawer: DrawerLayout): ViewGroup? {
@ -172,12 +171,12 @@ open class CatalogueController(bundle: Bundle) :
numColumnsSubscription?.unsubscribe() numColumnsSubscription?.unsubscribe()
var oldPosition = RecyclerView.NO_POSITION var oldPosition = RecyclerView.NO_POSITION
val oldRecycler = view.catalogue_view?.getChildAt(1) val oldRecycler = catalogue_view?.getChildAt(1)
if (oldRecycler is RecyclerView) { if (oldRecycler is RecyclerView) {
oldPosition = (oldRecycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() oldPosition = (oldRecycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
oldRecycler.adapter = null oldRecycler.adapter = null
view.catalogue_view?.removeView(oldRecycler) catalogue_view?.removeView(oldRecycler)
} }
val recycler = if (presenter.isListMode) { val recycler = if (presenter.isListMode) {
@ -187,7 +186,7 @@ open class CatalogueController(bundle: Bundle) :
addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
} }
} else { } else {
(view.catalogue_view.inflate(R.layout.catalogue_recycler_autofit) as AutofitRecyclerView).apply { (catalogue_view.inflate(R.layout.catalogue_recycler_autofit) as AutofitRecyclerView).apply {
numColumnsSubscription = getColumnsPreferenceForCurrentOrientation().asObservable() numColumnsSubscription = getColumnsPreferenceForCurrentOrientation().asObservable()
.doOnNext { spanCount = it } .doOnNext { spanCount = it }
.skip(1) .skip(1)
@ -207,7 +206,7 @@ open class CatalogueController(bundle: Bundle) :
recycler.setHasFixedSize(true) recycler.setHasFixedSize(true)
recycler.adapter = adapter recycler.adapter = adapter
view.catalogue_view.addView(recycler, 1) catalogue_view.addView(recycler, 1)
if (oldPosition != RecyclerView.NO_POSITION) { if (oldPosition != RecyclerView.NO_POSITION) {
recycler.layoutManager.scrollToPosition(oldPosition) recycler.layoutManager.scrollToPosition(oldPosition)
@ -330,7 +329,7 @@ open class CatalogueController(bundle: Bundle) :
val message = if (error is NoResultsException) "No results found" else (error.message ?: "") val message = if (error is NoResultsException) "No results found" else (error.message ?: "")
snack?.dismiss() snack?.dismiss()
snack = view?.catalogue_view?.snack(message, Snackbar.LENGTH_INDEFINITE) { snack = catalogue_view?.snack(message, Snackbar.LENGTH_INDEFINITE) {
setAction(R.string.action_retry) { setAction(R.string.action_retry) {
// If not the first page, show bottom progress bar. // If not the first page, show bottom progress bar.
if (adapter.mainItemCount > 0) { if (adapter.mainItemCount > 0) {
@ -357,7 +356,6 @@ open class CatalogueController(bundle: Bundle) :
* Called by the adapter when scrolled near the bottom. * Called by the adapter when scrolled near the bottom.
*/ */
override fun onLoadMore(lastPosition: Int, currentPage: Int) { override fun onLoadMore(lastPosition: Int, currentPage: Int) {
Timber.e("onLoadMore")
if (presenter.hasNextPage()) { if (presenter.hasNextPage()) {
presenter.requestNext() presenter.requestNext()
} else { } else {
@ -391,7 +389,7 @@ open class CatalogueController(bundle: Bundle) :
setupRecycler(view) setupRecycler(view)
if (!isListMode || !view.context.connectivityManager.isActiveNetworkMetered) { if (!isListMode || !view.context.connectivityManager.isActiveNetworkMetered) {
// Initialize mangas if going to grid view or if over wifi when going to list view // Initialize mangas if going to grid view or if over wifi when going to list view
val mangas = (0..adapter.itemCount-1).mapNotNull { val mangas = (0 until adapter.itemCount).mapNotNull {
(adapter.getItem(it) as? CatalogueItem)?.manga (adapter.getItem(it) as? CatalogueItem)?.manga
} }
presenter.initializeMangas(mangas) presenter.initializeMangas(mangas)
@ -433,7 +431,7 @@ open class CatalogueController(bundle: Bundle) :
* Shows the progress bar. * Shows the progress bar.
*/ */
private fun showProgressBar() { private fun showProgressBar() {
view?.progress?.visible() progress?.visible()
snack?.dismiss() snack?.dismiss()
snack = null snack = null
} }
@ -442,7 +440,7 @@ open class CatalogueController(bundle: Bundle) :
* Hides active progress bars. * Hides active progress bars.
*/ */
private fun hideProgressBar() { private fun hideProgressBar() {
view?.progress?.gone() progress?.gone()
} }
/** /**
@ -453,9 +451,7 @@ open class CatalogueController(bundle: Bundle) :
*/ */
override fun onItemClick(position: Int): Boolean { override fun onItemClick(position: Int): Boolean {
val item = adapter?.getItem(position) as? CatalogueItem ?: return false val item = adapter?.getItem(position) as? CatalogueItem ?: return false
router.pushController(RouterTransaction.with(MangaController(item.manga, true)) router.pushController(MangaController(item.manga, true).withFadeTransaction())
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler()))
return false return false
} }
@ -470,10 +466,11 @@ open class CatalogueController(bundle: Bundle) :
* @param position the position of the element clicked. * @param position the position of the element clicked.
*/ */
override fun onItemLongClick(position: Int) { override fun onItemLongClick(position: Int) {
val activity = activity ?: return
val manga = (adapter?.getItem(position) as? CatalogueItem?)?.manga ?: return val manga = (adapter?.getItem(position) as? CatalogueItem?)?.manga ?: return
if (manga.favorite) { if (manga.favorite) {
MaterialDialog.Builder(activity!!) MaterialDialog.Builder(activity)
.items(resources?.getString(R.string.remove_from_library)) .items(activity.getString(R.string.remove_from_library))
.itemsCallback { _, _, which, _ -> .itemsCallback { _, _, which, _ ->
when (which) { when (which) {
0 -> { 0 -> {

@ -4,15 +4,14 @@ import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.SearchView import android.support.v7.widget.SearchView
import android.view.* import android.view.*
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import kotlinx.android.synthetic.main.catalogue_global_search_controller.view.* import kotlinx.android.synthetic.main.catalogue_global_search_controller.*
/** /**
* This controller shows and manages the different search result in global search. * This controller shows and manages the different search result in global search.
@ -71,9 +70,7 @@ class CatalogueSearchController(private val initialQuery: String? = null) :
*/ */
override fun onMangaClick(manga: Manga) { override fun onMangaClick(manga: Manga) {
// Open MangaController. // Open MangaController.
router.pushController(RouterTransaction.with(MangaController(manga, true)) router.pushController(MangaController(manga, true).withFadeTransaction())
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler()))
} }
/** /**
@ -115,18 +112,15 @@ class CatalogueSearchController(private val initialQuery: String? = null) :
* Called when the view is created * Called when the view is created
* *
* @param view view of controller * @param view view of controller
* @param savedViewState information from previous state.
*/ */
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
adapter = CatalogueSearchAdapter(this) adapter = CatalogueSearchAdapter(this)
with(view) { // Create recycler and set adapter.
// Create recycler and set adapter. recycler.layoutManager = LinearLayoutManager(view.context)
recycler.layoutManager = LinearLayoutManager(context) recycler.adapter = adapter
recycler.adapter = adapter
}
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.catalogue.main package eu.kanade.tachiyomi.ui.catalogue.main
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.SearchView import android.support.v7.widget.SearchView
import android.view.* import android.view.*
@ -16,12 +15,13 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.online.LoginSource import eu.kanade.tachiyomi.source.online.LoginSource
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
import eu.kanade.tachiyomi.ui.latest_updates.LatestUpdatesController import eu.kanade.tachiyomi.ui.latest_updates.LatestUpdatesController
import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController
import eu.kanade.tachiyomi.widget.preference.SourceLoginDialog import eu.kanade.tachiyomi.widget.preference.SourceLoginDialog
import kotlinx.android.synthetic.main.catalogue_main_controller.view.* import kotlinx.android.synthetic.main.catalogue_main_controller.*
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -89,19 +89,16 @@ class CatalogueMainController : NucleusController<CatalogueMainPresenter>(),
* Called when the view is created * Called when the view is created
* *
* @param view view of controller * @param view view of controller
* @param savedViewState information from previous state.
*/ */
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
adapter = CatalogueMainAdapter(this) adapter = CatalogueMainAdapter(this)
with(view) { // Create recycler and set adapter.
// Create recycler and set adapter. recycler.layoutManager = LinearLayoutManager(view.context)
recycler.layoutManager = LinearLayoutManager(context) recycler.adapter = adapter
recycler.adapter = adapter recycler.addItemDecoration(SourceDividerItemDecoration(view.context))
recycler.addItemDecoration(SourceDividerItemDecoration(context))
}
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
@ -165,9 +162,7 @@ class CatalogueMainController : NucleusController<CatalogueMainPresenter>(),
*/ */
private fun openCatalogue(source: CatalogueSource, controller: CatalogueController) { private fun openCatalogue(source: CatalogueSource, controller: CatalogueController) {
preferences.lastUsedCatalogueSource().set(source.id) preferences.lastUsedCatalogueSource().set(source.id)
router.pushController(RouterTransaction.with(controller) router.pushController(controller.withFadeTransaction())
.popChangeHandler(FadeChangeHandler())
.pushChangeHandler(FadeChangeHandler()))
} }
/** /**
@ -192,9 +187,7 @@ class CatalogueMainController : NucleusController<CatalogueMainPresenter>(),
.filter { it.isSubmitted } .filter { it.isSubmitted }
.subscribeUntilDestroy { .subscribeUntilDestroy {
val query = it.queryText().toString() val query = it.queryText().toString()
router.pushController((RouterTransaction.with(CatalogueSearchController(query))) router.pushController(CatalogueSearchController(query).withFadeTransaction())
.popChangeHandler(FadeChangeHandler())
.pushChangeHandler(FadeChangeHandler()))
} }
} }

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.category package eu.kanade.tachiyomi.ui.category
import android.os.Bundle
import android.support.design.widget.Snackbar import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.support.v7.view.ActionMode import android.support.v7.view.ActionMode
@ -15,7 +14,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import kotlinx.android.synthetic.main.categories_controller.view.* import kotlinx.android.synthetic.main.categories_controller.*
/** /**
* Controller to manage the categories for the users' library. * Controller to manage the categories for the users' library.
@ -70,22 +69,19 @@ class CategoryController : NucleusController<CategoryPresenter>(),
* Called after view inflation. Used to initialize the view. * Called after view inflation. Used to initialize the view.
* *
* @param view The view of this controller. * @param view The view of this controller.
* @param savedViewState The saved state of the view.
*/ */
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
with(view) { adapter = CategoryAdapter(this@CategoryController)
adapter = CategoryAdapter(this@CategoryController) recycler.layoutManager = LinearLayoutManager(view.context)
recycler.layoutManager = LinearLayoutManager(context) recycler.setHasFixedSize(true)
recycler.setHasFixedSize(true) recycler.adapter = adapter
recycler.adapter = adapter adapter?.isHandleDragEnabled = true
adapter?.isHandleDragEnabled = true adapter?.isPermanentDelete = false
adapter?.isPermanentDelete = false
fab.clicks().subscribeUntilDestroy {
fab.clicks().subscribeUntilDestroy { CategoryCreateDialog(this@CategoryController).showDialog(router, null)
CategoryCreateDialog(this@CategoryController).showDialog(router, null)
}
} }
} }
@ -95,12 +91,12 @@ class CategoryController : NucleusController<CategoryPresenter>(),
* @param view The view of this controller. * @param view The view of this controller.
*/ */
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view)
// Manually call callback to delete categories if required // Manually call callback to delete categories if required
undoHelper?.onDeleteConfirmed(Snackbar.Callback.DISMISS_EVENT_MANUAL) undoHelper?.onDeleteConfirmed(Snackbar.Callback.DISMISS_EVENT_MANUAL)
undoHelper = null undoHelper = null
actionMode = null actionMode = null
adapter = null adapter = null
super.onDestroyView(view)
} }
/** /**

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.download package eu.kanade.tachiyomi.ui.download
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.view.* import android.view.*
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -8,7 +7,7 @@ import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import kotlinx.android.synthetic.main.download_controller.view.* import kotlinx.android.synthetic.main.download_controller.*
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
@ -52,21 +51,19 @@ class DownloadController : NucleusController<DownloadPresenter>() {
return resources?.getString(R.string.label_download_queue) return resources?.getString(R.string.label_download_queue)
} }
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
// Check if download queue is empty and update information accordingly. // Check if download queue is empty and update information accordingly.
setInformationView() setInformationView()
// Initialize adapter. // Initialize adapter.
adapter = DownloadAdapter() adapter = DownloadAdapter()
with(view) { recycler.adapter = adapter
recycler.adapter = adapter
// Set the layout manager for the recycler and fixed size. // Set the layout manager for the recycler and fixed size.
recycler.layoutManager = LinearLayoutManager(context) recycler.layoutManager = LinearLayoutManager(view.context)
recycler.setHasFixedSize(true) recycler.setHasFixedSize(true)
}
// Suscribe to changes // Suscribe to changes
DownloadService.runningRelay DownloadService.runningRelay
@ -83,12 +80,12 @@ class DownloadController : NucleusController<DownloadPresenter>() {
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view)
for (subscription in progressSubscriptions.values) { for (subscription in progressSubscriptions.values) {
subscription.unsubscribe() subscription.unsubscribe()
} }
progressSubscriptions.clear() progressSubscriptions.clear()
adapter = null adapter = null
super.onDestroyView(view)
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@ -232,20 +229,18 @@ class DownloadController : NucleusController<DownloadPresenter>() {
* @return the holder of the download or null if it's not bound. * @return the holder of the download or null if it's not bound.
*/ */
private fun getHolder(download: Download): DownloadHolder? { private fun getHolder(download: Download): DownloadHolder? {
val recycler = view?.recycler ?: return null return recycler?.findViewHolderForItemId(download.chapter.id!!) as? DownloadHolder
return recycler.findViewHolderForItemId(download.chapter.id!!) as? DownloadHolder
} }
/** /**
* Set information view when queue is empty * Set information view when queue is empty
*/ */
private fun setInformationView() { private fun setInformationView() {
val emptyView = view?.empty_view ?: return
if (presenter.downloadQueue.isEmpty()) { if (presenter.downloadQueue.isEmpty()) {
emptyView.show(R.drawable.ic_file_download_black_128dp, empty_view?.show(R.drawable.ic_file_download_black_128dp,
R.string.information_no_downloads) R.string.information_no_downloads)
} else { } else {
emptyView.hide() empty_view?.hide()
} }
} }

@ -14,8 +14,6 @@ import android.support.v7.widget.SearchView
import android.view.* import android.view.*
import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.ControllerChangeType
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import com.f2prateek.rx.preferences.Preference import com.f2prateek.rx.preferences.Preference
import com.jakewharton.rxbinding.support.v4.view.pageSelections import com.jakewharton.rxbinding.support.v4.view.pageSelections
import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges
@ -30,13 +28,14 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.category.CategoryController import eu.kanade.tachiyomi.ui.category.CategoryController
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.inflate import eu.kanade.tachiyomi.util.inflate
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import eu.kanade.tachiyomi.widget.DrawerSwipeCloseListener import eu.kanade.tachiyomi.widget.DrawerSwipeCloseListener
import kotlinx.android.synthetic.main.library_controller.view.* import kotlinx.android.synthetic.main.library_controller.*
import kotlinx.android.synthetic.main.main_activity.* import kotlinx.android.synthetic.main.main_activity.*
import rx.Subscription import rx.Subscription
import timber.log.Timber import timber.log.Timber
@ -100,14 +99,8 @@ class LibraryController(
private set private set
/** /**
* TabLayout of the categories. * Adapter of the view pager.
*/ */
private val tabs: TabLayout?
get() = activity?.tabs
private val drawer: DrawerLayout?
get() = activity?.drawer
private var adapter: LibraryAdapter? = null private var adapter: LibraryAdapter? = null
/** /**
@ -141,43 +134,41 @@ class LibraryController(
return inflater.inflate(R.layout.library_controller, container, false) return inflater.inflate(R.layout.library_controller, container, false)
} }
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
adapter = LibraryAdapter(this) adapter = LibraryAdapter(this)
with(view) { view_pager.adapter = adapter
view_pager.adapter = adapter view_pager.pageSelections().skip(1).subscribeUntilDestroy {
view_pager.pageSelections().skip(1).subscribeUntilDestroy { preferences.lastUsedCategory().set(it)
preferences.lastUsedCategory().set(it) activeCategory = it
activeCategory = it }
}
getColumnsPreferenceForCurrentOrientation().asObservable() getColumnsPreferenceForCurrentOrientation().asObservable()
.doOnNext { mangaPerRow = it } .doOnNext { mangaPerRow = it }
.skip(1) .skip(1)
// Set again the adapter to recalculate the covers height // Set again the adapter to recalculate the covers height
.subscribeUntilDestroy { reattachAdapter() } .subscribeUntilDestroy { reattachAdapter() }
if (selectedMangas.isNotEmpty()) { if (selectedMangas.isNotEmpty()) {
createActionModeIfNeeded() createActionModeIfNeeded()
}
} }
} }
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type) super.onChangeStarted(handler, type)
if (type.isEnter) { if (type.isEnter) {
activity?.tabs?.setupWithViewPager(view?.view_pager) activity?.tabs?.setupWithViewPager(view_pager)
presenter.subscribeLibrary() presenter.subscribeLibrary()
} }
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view)
adapter = null adapter = null
actionMode = null actionMode = null
tabsVisibilitySubscription?.unsubscribe() tabsVisibilitySubscription?.unsubscribe()
tabsVisibilitySubscription = null tabsVisibilitySubscription = null
super.onDestroyView(view)
} }
override fun createSecondaryDrawer(drawer: DrawerLayout): ViewGroup { override fun createSecondaryDrawer(drawer: DrawerLayout): ViewGroup {
@ -233,14 +224,14 @@ class LibraryController(
// Show empty view if needed // Show empty view if needed
if (mangaMap.isNotEmpty()) { if (mangaMap.isNotEmpty()) {
view.empty_view.hide() empty_view.hide()
} else { } else {
view.empty_view.show(R.drawable.ic_book_black_128dp, R.string.information_empty_library) empty_view.show(R.drawable.ic_book_black_128dp, R.string.information_empty_library)
} }
// Get the current active category. // Get the current active category.
val activeCat = if (adapter.categories.isNotEmpty()) val activeCat = if (adapter.categories.isNotEmpty())
view.view_pager.currentItem view_pager.currentItem
else else
activeCategory activeCategory
@ -248,14 +239,14 @@ class LibraryController(
adapter.categories = categories adapter.categories = categories
// Restore active category. // Restore active category.
view.view_pager.setCurrentItem(activeCat, false) view_pager.setCurrentItem(activeCat, false)
tabsVisibilityRelay.call(categories.size > 1) tabsVisibilityRelay.call(categories.size > 1)
// Delay the scroll position to allow the view to be properly measured. // Delay the scroll position to allow the view to be properly measured.
view.post { view.post {
if (isAttached) { if (isAttached) {
tabs?.setScrollPosition(view.view_pager.currentItem, 0f, true) activity?.tabs?.setScrollPosition(view_pager.currentItem, 0f, true)
} }
} }
@ -298,14 +289,13 @@ class LibraryController(
* Reattaches the adapter to the view pager to recreate fragments * Reattaches the adapter to the view pager to recreate fragments
*/ */
private fun reattachAdapter() { private fun reattachAdapter() {
val pager = view?.view_pager ?: return
val adapter = adapter ?: return val adapter = adapter ?: return
val position = pager.currentItem val position = view_pager.currentItem
adapter.recycle = false adapter.recycle = false
pager.adapter = adapter view_pager.adapter = adapter
pager.currentItem = position view_pager.currentItem = position
adapter.recycle = true adapter.recycle = true
} }
@ -331,7 +321,7 @@ class LibraryController(
val searchItem = menu.findItem(R.id.action_search) val searchItem = menu.findItem(R.id.action_search)
val searchView = searchItem.actionView as SearchView val searchView = searchItem.actionView as SearchView
if (!query.isNullOrEmpty()) { if (!query.isEmpty()) {
searchItem.expandActionView() searchItem.expandActionView()
searchView.setQuery(query, true) searchView.setQuery(query, true)
searchView.clearFocus() searchView.clearFocus()
@ -361,15 +351,13 @@ class LibraryController(
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.action_filter -> { R.id.action_filter -> {
navView?.let { drawer?.openDrawer(Gravity.END) } navView?.let { activity?.drawer?.openDrawer(Gravity.END) }
} }
R.id.action_update_library -> { R.id.action_update_library -> {
activity?.let { LibraryUpdateService.start(it) } activity?.let { LibraryUpdateService.start(it) }
} }
R.id.action_edit_categories -> { R.id.action_edit_categories -> {
router.pushController(RouterTransaction.with(CategoryController()) router.pushController(CategoryController().withFadeTransaction())
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler()))
} }
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }
@ -425,9 +413,7 @@ class LibraryController(
// Notify the presenter a manga is being opened. // Notify the presenter a manga is being opened.
presenter.onOpenManga() presenter.onOpenManga()
router.pushController(RouterTransaction.with(MangaController(manga)) router.pushController(MangaController(manga).withFadeTransaction())
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler()))
} }
/** /**
@ -462,11 +448,11 @@ class LibraryController(
.toTypedArray() .toTypedArray()
ChangeMangaCategoriesDialog(this, mangas, categories, commonCategoriesIndexes) ChangeMangaCategoriesDialog(this, mangas, categories, commonCategoriesIndexes)
.showDialog(router, null) .showDialog(router)
} }
private fun showDeleteMangaDialog() { private fun showDeleteMangaDialog() {
DeleteLibraryMangasDialog(this, selectedMangas.toList()).showDialog(router, null) DeleteLibraryMangasDialog(this, selectedMangas.toList()).showDialog(router)
} }
override fun updateCategoriesForMangas(mangas: List<Manga>, categories: List<Category>) { override fun updateCategoriesForMangas(mangas: List<Manga>, categories: List<Category>) {
@ -481,8 +467,6 @@ class LibraryController(
/** /**
* Changes the cover for the selected manga. * Changes the cover for the selected manga.
*
* @param mangas a list of selected manga.
*/ */
private fun changeSelectedCover() { private fun changeSelectedCover() {
val manga = selectedMangas.firstOrNull() ?: return val manga = selectedMangas.firstOrNull() ?: return

@ -14,10 +14,7 @@ import eu.kanade.tachiyomi.Migrations
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.*
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.catalogue.main.CatalogueMainController import eu.kanade.tachiyomi.ui.catalogue.main.CatalogueMainController
import eu.kanade.tachiyomi.ui.download.DownloadController import eu.kanade.tachiyomi.ui.download.DownloadController
import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.library.LibraryController
@ -85,14 +82,11 @@ class MainActivity : BaseActivity() {
R.id.nav_drawer_recently_read -> setRoot(RecentlyReadController(), id) R.id.nav_drawer_recently_read -> setRoot(RecentlyReadController(), id)
R.id.nav_drawer_catalogues -> setRoot(CatalogueMainController(), id) R.id.nav_drawer_catalogues -> setRoot(CatalogueMainController(), id)
R.id.nav_drawer_downloads -> { R.id.nav_drawer_downloads -> {
router.pushController(RouterTransaction.with(DownloadController()) router.pushController(DownloadController().withFadeTransaction())
.pushChangeHandler(FadeChangeHandler()) }
.popChangeHandler(FadeChangeHandler())) R.id.nav_drawer_settings -> {
router.pushController(SettingsMainController().withFadeTransaction())
} }
R.id.nav_drawer_settings ->
router.pushController(RouterTransaction.with(SettingsMainController())
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler()))
} }
} }
drawer.closeDrawer(GravityCompat.START) drawer.closeDrawer(GravityCompat.START)
@ -189,10 +183,7 @@ class MainActivity : BaseActivity() {
} }
private fun setRoot(controller: Controller, id: Int) { private fun setRoot(controller: Controller, id: Int) {
router.setRoot(RouterTransaction.with(controller) router.setRoot(controller.withFadeTransaction().tag(id.toString()))
.popChangeHandler(FadeChangeHandler())
.pushChangeHandler(FadeChangeHandler())
.tag(id.toString()))
} }
private fun syncActivityViewWithController(to: Controller?, from: Controller? = null) { private fun syncActivityViewWithController(to: Controller?, from: Controller? = null) {

@ -1,8 +1,6 @@
package eu.kanade.tachiyomi.ui.manga package eu.kanade.tachiyomi.ui.manga
import android.Manifest.permission.READ_EXTERNAL_STORAGE
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.support.design.widget.TabLayout import android.support.design.widget.TabLayout
import android.support.graphics.drawable.VectorDrawableCompat import android.support.graphics.drawable.VectorDrawableCompat
@ -32,7 +30,7 @@ import eu.kanade.tachiyomi.ui.manga.info.MangaInfoController
import eu.kanade.tachiyomi.ui.manga.track.TrackController import eu.kanade.tachiyomi.ui.manga.track.TrackController
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import kotlinx.android.synthetic.main.main_activity.* import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.android.synthetic.main.manga_controller.view.* import kotlinx.android.synthetic.main.manga_controller.*
import rx.Subscription import rx.Subscription
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -81,21 +79,19 @@ class MangaController : RxController, TabbedController {
return inflater.inflate(R.layout.manga_controller, container, false) return inflater.inflate(R.layout.manga_controller, container, false)
} }
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
if (manga == null || source == null) return if (manga == null || source == null) return
requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301) requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301)
with(view) { adapter = MangaDetailAdapter()
adapter = MangaDetailAdapter() view_pager.offscreenPageLimit = 3
view_pager.offscreenPageLimit = 3 view_pager.adapter = adapter
view_pager.adapter = adapter
if (!fromCatalogue) if (!fromCatalogue)
view_pager.currentItem = CHAPTERS_CONTROLLER view_pager.currentItem = CHAPTERS_CONTROLLER
}
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
@ -106,7 +102,7 @@ class MangaController : RxController, TabbedController {
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type) super.onChangeStarted(handler, type)
if (type.isEnter) { if (type.isEnter) {
activity?.tabs?.setupWithViewPager(view?.view_pager) activity?.tabs?.setupWithViewPager(view_pager)
trackingIconSubscription = trackingIconRelay.subscribe { setTrackingIconInternal(it) } trackingIconSubscription = trackingIconRelay.subscribe { setTrackingIconInternal(it) }
} }
} }

@ -4,7 +4,6 @@ import android.animation.Animator
import android.animation.AnimatorListenerAdapter import android.animation.AnimatorListenerAdapter
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle
import android.support.design.widget.Snackbar import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.support.v7.view.ActionMode import android.support.v7.view.ActionMode
@ -26,7 +25,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.getCoordinates import eu.kanade.tachiyomi.util.getCoordinates
import eu.kanade.tachiyomi.util.snack import eu.kanade.tachiyomi.util.snack
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import kotlinx.android.synthetic.main.chapters_controller.view.* import kotlinx.android.synthetic.main.chapters_controller.*
import timber.log.Timber import timber.log.Timber
class ChaptersController : NucleusController<ChaptersPresenter>(), class ChaptersController : NucleusController<ChaptersPresenter>(),
@ -69,57 +68,55 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
return inflater.inflate(R.layout.chapters_controller, container, false) return inflater.inflate(R.layout.chapters_controller, container, false)
} }
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
// Init RecyclerView and adapter // Init RecyclerView and adapter
adapter = ChaptersAdapter(this, view.context) adapter = ChaptersAdapter(this, view.context)
with(view) { recycler.adapter = adapter
recycler.adapter = adapter recycler.layoutManager = LinearLayoutManager(view.context)
recycler.layoutManager = LinearLayoutManager(context) recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
recycler.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) recycler.setHasFixedSize(true)
recycler.setHasFixedSize(true) adapter?.fastScroller = fast_scroller
adapter?.fastScroller = view.fast_scroller
swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
fab.clicks().subscribeUntilDestroy {
fab.clicks().subscribeUntilDestroy { val item = presenter.getNextUnreadChapter()
val item = presenter.getNextUnreadChapter() if (item != null) {
if (item != null) { // Create animation listener
// Create animation listener val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) {
override fun onAnimationStart(animation: Animator?) { openChapter(item.chapter, true)
openChapter(item.chapter, true)
}
} }
}
// Get coordinates and start animation // Get coordinates and start animation
val coordinates = fab.getCoordinates() val coordinates = fab.getCoordinates()
if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) { if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) {
openChapter(item.chapter) openChapter(item.chapter)
}
} else {
context.toast(R.string.no_next_chapter)
} }
} else {
view.context.toast(R.string.no_next_chapter)
} }
} }
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view)
adapter = null adapter = null
actionMode = null actionMode = null
super.onDestroyView(view)
} }
override fun onActivityResumed(activity: Activity) { override fun onActivityResumed(activity: Activity) {
val view = view ?: return if (view == null) return
// Check if animation view is visible // Check if animation view is visible
if (view.reveal_view.visibility == View.VISIBLE) { if (reveal_view.visibility == View.VISIBLE) {
// Show the unReveal effect // Show the unReveal effect
val coordinates = view.fab.getCoordinates() val coordinates = fab.getCoordinates()
view.reveal_view.hideRevealEffect(coordinates.x, coordinates.y, 1920) reveal_view.hideRevealEffect(coordinates.x, coordinates.y, 1920)
} }
super.onActivityResumed(activity) super.onActivityResumed(activity)
} }
@ -213,16 +210,16 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
} }
fun fetchChaptersFromSource() { fun fetchChaptersFromSource() {
view?.swipe_refresh?.isRefreshing = true swipe_refresh?.isRefreshing = true
presenter.fetchChaptersFromSource() presenter.fetchChaptersFromSource()
} }
fun onFetchChaptersDone() { fun onFetchChaptersDone() {
view?.swipe_refresh?.isRefreshing = false swipe_refresh?.isRefreshing = false
} }
fun onFetchChaptersError(error: Throwable) { fun onFetchChaptersError(error: Throwable) {
view?.swipe_refresh?.isRefreshing = false swipe_refresh?.isRefreshing = false
activity?.toast(error.message) activity?.toast(error.message)
} }
@ -231,7 +228,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
} }
private fun getHolder(chapter: Chapter): ChapterHolder? { private fun getHolder(chapter: Chapter): ChapterHolder? {
return view?.recycler?.findViewHolderForItemId(chapter.id!!) as? ChapterHolder return recycler?.findViewHolderForItemId(chapter.id!!) as? ChapterHolder
} }
fun openChapter(chapter: Chapter, hasAnimation: Boolean = false) { fun openChapter(chapter: Chapter, hasAnimation: Boolean = false) {
@ -365,7 +362,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
presenter.downloadChapters(chapters) presenter.downloadChapters(chapters)
if (view != null && !presenter.manga.favorite) { if (view != null && !presenter.manga.favorite) {
view.recycler?.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) { recycler?.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) {
setAction(R.string.action_add) { setAction(R.string.action_add) {
presenter.addToLibrary() presenter.addToLibrary()
} }

@ -39,7 +39,7 @@ import eu.kanade.tachiyomi.util.snack
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import jp.wasabeef.glide.transformations.CropSquareTransformation import jp.wasabeef.glide.transformations.CropSquareTransformation
import jp.wasabeef.glide.transformations.MaskTransformation import jp.wasabeef.glide.transformations.MaskTransformation
import kotlinx.android.synthetic.main.manga_info_controller.view.* import kotlinx.android.synthetic.main.manga_info_controller.*
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.text.DecimalFormat import java.text.DecimalFormat
@ -71,17 +71,14 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
return inflater.inflate(R.layout.manga_info_controller, container, false) return inflater.inflate(R.layout.manga_info_controller, container, false)
} }
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
with(view) { // Set onclickListener to toggle favorite when FAB clicked.
// Set onclickListener to toggle favorite when FAB clicked. fab_favorite.clicks().subscribeUntilDestroy { onFabClick() }
fab_favorite.clicks().subscribeUntilDestroy { onFabClick() }
// Set SwipeRefresh to refresh manga data.
swipe_refresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() }
}
// Set SwipeRefresh to refresh manga data.
swipe_refresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() }
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@ -124,50 +121,49 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
*/ */
private fun setMangaInfo(manga: Manga, source: Source?) { private fun setMangaInfo(manga: Manga, source: Source?) {
val view = view ?: return val view = view ?: return
with(view) {
// 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 genres TextView.
manga_genres.text = manga.genre
// Update status TextView. // Update artist TextView.
manga_status.setText(when (manga.status) { manga_artist.text = manga.artist
SManga.ONGOING -> R.string.ongoing
SManga.COMPLETED -> R.string.completed
SManga.LICENSED -> R.string.licensed
else -> R.string.unknown
})
// Update description TextView. // Update author TextView.
manga_summary.text = manga.description manga_author.text = manga.author
// Set the favorite drawable to the correct one. // If manga source is known update source TextView.
setFavoriteDrawable(manga.favorite) if (source != null) {
manga_source.text = source.toString()
}
// Set cover if it wasn't already. // Update genres TextView.
if (manga_cover.drawable == null && !manga.thumbnail_url.isNullOrEmpty()) { manga_genres.text = manga.genre
GlideApp.with(context)
// Update status TextView.
manga_status.setText(when (manga.status) {
SManga.ONGOING -> R.string.ongoing
SManga.COMPLETED -> R.string.completed
SManga.LICENSED -> R.string.licensed
else -> R.string.unknown
})
// Update description TextView.
manga_summary.text = manga.description
// Set the favorite drawable to the correct one.
setFavoriteDrawable(manga.favorite)
// Set cover if it wasn't already.
if (manga_cover.drawable == null && !manga.thumbnail_url.isNullOrEmpty()) {
GlideApp.with(view.context)
.load(manga)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerCrop()
.into(manga_cover)
if (backdrop != null) {
GlideApp.with(view.context)
.load(manga) .load(manga)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerCrop() .centerCrop()
.into(manga_cover) .into(backdrop)
if (backdrop != null) {
GlideApp.with(context)
.load(manga)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerCrop()
.into(backdrop)
}
} }
} }
} }
@ -178,7 +174,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
* @param count number of chapters. * @param count number of chapters.
*/ */
fun setChapterCount(count: Float) { fun setChapterCount(count: Float) {
view?.manga_chapters?.text = DecimalFormat("#.#").format(count) manga_chapters?.text = DecimalFormat("#.#").format(count)
} }
/** /**
@ -243,7 +239,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
private fun setFavoriteDrawable(isFavorite: Boolean) { private fun setFavoriteDrawable(isFavorite: Boolean) {
// Set the Favorite drawable to the correct one. // Set the Favorite drawable to the correct one.
// Border drawable if false, filled drawable if true. // Border drawable if false, filled drawable if true.
view?.fab_favorite?.setImageResource(if (isFavorite) fab_favorite?.setImageResource(if (isFavorite)
R.drawable.ic_bookmark_white_24dp R.drawable.ic_bookmark_white_24dp
else else
R.drawable.ic_bookmark_border_white_24dp) R.drawable.ic_bookmark_border_white_24dp)
@ -279,7 +275,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
* @param value whether it should be refreshing or not. * @param value whether it should be refreshing or not.
*/ */
private fun setRefreshing(value: Boolean) { private fun setRefreshing(value: Boolean) {
view?.swipe_refresh?.isRefreshing = value swipe_refresh?.isRefreshing = value
} }
/** /**

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.manga.track package eu.kanade.tachiyomi.ui.manga.track
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -11,7 +10,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import kotlinx.android.synthetic.main.track_controller.view.* import kotlinx.android.synthetic.main.track_controller.*
class TrackController : NucleusController<TrackPresenter>(), class TrackController : NucleusController<TrackPresenter>(),
TrackAdapter.OnRowClickListener, TrackAdapter.OnRowClickListener,
@ -35,8 +34,8 @@ class TrackController : NucleusController<TrackPresenter>(),
return inflater.inflate(R.layout.track_controller, container, false) return inflater.inflate(R.layout.track_controller, container, false)
} }
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
adapter = TrackAdapter(this) adapter = TrackAdapter(this)
with(view) { with(view) {
@ -48,14 +47,14 @@ class TrackController : NucleusController<TrackPresenter>(),
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view)
adapter = null adapter = null
super.onDestroyView(view)
} }
fun onNextTrackings(trackings: List<TrackItem>) { fun onNextTrackings(trackings: List<TrackItem>) {
val atLeastOneLink = trackings.any { it.track != null } val atLeastOneLink = trackings.any { it.track != null }
adapter?.items = trackings adapter?.items = trackings
view?.swipe_refresh?.isEnabled = atLeastOneLink swipe_refresh?.isEnabled = atLeastOneLink
(parentController as? MangaController)?.setTrackingIcon(atLeastOneLink) (parentController as? MangaController)?.setTrackingIcon(atLeastOneLink)
} }
@ -73,11 +72,11 @@ class TrackController : NucleusController<TrackPresenter>(),
} }
fun onRefreshDone() { fun onRefreshDone() {
view?.swipe_refresh?.isRefreshing = false swipe_refresh?.isRefreshing = false
} }
fun onRefreshError(error: Throwable) { fun onRefreshError(error: Throwable) {
view?.swipe_refresh?.isRefreshing = false swipe_refresh?.isRefreshing = false
activity?.toast(error.message) activity?.toast(error.message)
} }
@ -109,17 +108,17 @@ class TrackController : NucleusController<TrackPresenter>(),
override fun setStatus(item: TrackItem, selection: Int) { override fun setStatus(item: TrackItem, selection: Int) {
presenter.setStatus(item, selection) presenter.setStatus(item, selection)
view?.swipe_refresh?.isRefreshing = true swipe_refresh?.isRefreshing = true
} }
override fun setScore(item: TrackItem, score: Int) { override fun setScore(item: TrackItem, score: Int) {
presenter.setScore(item, score) presenter.setScore(item, score)
view?.swipe_refresh?.isRefreshing = true swipe_refresh?.isRefreshing = true
} }
override fun setChaptersRead(item: TrackItem, chaptersRead: Int) { override fun setChaptersRead(item: TrackItem, chaptersRead: Int) {
presenter.setLastChapterRead(item, chaptersRead) presenter.setLastChapterRead(item, chaptersRead)
view?.swipe_refresh?.isRefreshing = true swipe_refresh?.isRefreshing = true
} }
private companion object { private companion object {

@ -1,13 +1,10 @@
package eu.kanade.tachiyomi.ui.recent_updates package eu.kanade.tachiyomi.ui.recent_updates
import android.os.Bundle
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.support.v7.view.ActionMode import android.support.v7.view.ActionMode
import android.support.v7.widget.DividerItemDecoration import android.support.v7.widget.DividerItemDecoration
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.view.* import android.view.*
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import com.jakewharton.rxbinding.support.v4.widget.refreshes import com.jakewharton.rxbinding.support.v4.widget.refreshes
import com.jakewharton.rxbinding.support.v7.widget.scrollStateChanges import com.jakewharton.rxbinding.support.v7.widget.scrollStateChanges
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
@ -19,10 +16,11 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import kotlinx.android.synthetic.main.recent_chapters_controller.view.* import kotlinx.android.synthetic.main.recent_chapters_controller.*
import timber.log.Timber import timber.log.Timber
/** /**
@ -65,42 +63,39 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
/** /**
* Called when view is created * Called when view is created
* @param view created view * @param view created view
* @param savedViewState status of saved sate
*/ */
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
with(view) { // Init RecyclerView and adapter
// Init RecyclerView and adapter val layoutManager = LinearLayoutManager(view.context)
val layoutManager = LinearLayoutManager(context) recycler.layoutManager = layoutManager
recycler.layoutManager = layoutManager recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
recycler.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) recycler.setHasFixedSize(true)
recycler.setHasFixedSize(true) adapter = RecentChaptersAdapter(this@RecentChaptersController)
adapter = RecentChaptersAdapter(this@RecentChaptersController) recycler.adapter = adapter
recycler.adapter = adapter
recycler.scrollStateChanges().subscribeUntilDestroy {
recycler.scrollStateChanges().subscribeUntilDestroy { // Disable swipe refresh when view is not at the top
// Disable swipe refresh when view is not at the top val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition() swipe_refresh.isEnabled = firstPos <= 0
swipe_refresh.isEnabled = firstPos <= 0 }
}
swipe_refresh.setDistanceToTriggerSync((2 * 64 * resources.displayMetrics.density).toInt()) swipe_refresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
swipe_refresh.refreshes().subscribeUntilDestroy { swipe_refresh.refreshes().subscribeUntilDestroy {
if (!LibraryUpdateService.isRunning(context)) { if (!LibraryUpdateService.isRunning(view.context)) {
LibraryUpdateService.start(context) LibraryUpdateService.start(view.context)
context.toast(R.string.action_update_library) view.context.toast(R.string.action_update_library)
}
// It can be a very long operation, so we disable swipe refresh and show a toast.
swipe_refresh.isRefreshing = false
} }
// It can be a very long operation, so we disable swipe refresh and show a toast.
swipe_refresh.isRefreshing = false
} }
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view)
adapter = null adapter = null
actionMode = null actionMode = null
super.onDestroyView(view)
} }
/** /**
@ -180,11 +175,10 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
} }
override fun onUpdateEmptyView(size: Int) { override fun onUpdateEmptyView(size: Int) {
val emptyView = view?.empty_view ?: return
if (size > 0) { if (size > 0) {
emptyView.hide() empty_view?.hide()
} else { } else {
emptyView.show(R.drawable.ic_update_black_128dp, R.string.information_no_recent) empty_view?.show(R.drawable.ic_update_black_128dp, R.string.information_no_recent)
} }
} }
@ -201,7 +195,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
* @param download [Download] object containing download progress. * @param download [Download] object containing download progress.
*/ */
private fun getHolder(download: Download): RecentChapterHolder? { private fun getHolder(download: Download): RecentChapterHolder? {
return view?.recycler?.findViewHolderForItemId(download.chapter.id!!) as? RecentChapterHolder return recycler?.findViewHolderForItemId(download.chapter.id!!) as? RecentChapterHolder
} }
/** /**
@ -260,9 +254,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
} }
fun openManga(chapter: RecentChapterItem) { fun openManga(chapter: RecentChapterItem) {
router.pushController(RouterTransaction.with(MangaController(chapter.manga)) router.pushController(MangaController(chapter.manga).withFadeTransaction())
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler()))
} }
/** /**

@ -1,21 +1,19 @@
package eu.kanade.tachiyomi.ui.recently_read package eu.kanade.tachiyomi.ui.recently_read
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.History import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import kotlinx.android.synthetic.main.recently_read_controller.view.* import kotlinx.android.synthetic.main.recently_read_controller.*
/** /**
* Fragment that shows recently read manga. * Fragment that shows recently read manga.
@ -51,23 +49,20 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
* Called when view is created * Called when view is created
* *
* @param view created view * @param view created view
* @param savedViewState saved state of the view
*/ */
override fun onViewCreated(view: View, savedViewState: Bundle?) { override fun onViewCreated(view: View) {
super.onViewCreated(view, savedViewState) super.onViewCreated(view)
with(view) { // Initialize adapter
// Initialize adapter recycler.layoutManager = LinearLayoutManager(view.context)
recycler.layoutManager = LinearLayoutManager(context) adapter = RecentlyReadAdapter(this@RecentlyReadController)
adapter = RecentlyReadAdapter(this@RecentlyReadController) recycler.setHasFixedSize(true)
recycler.setHasFixedSize(true) recycler.adapter = adapter
recycler.adapter = adapter
}
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view)
adapter = null adapter = null
super.onDestroyView(view)
} }
/** /**
@ -80,11 +75,10 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
} }
override fun onUpdateEmptyView(size: Int) { override fun onUpdateEmptyView(size: Int) {
val emptyView = view?.empty_view ?: return
if (size > 0) { if (size > 0) {
emptyView.hide() empty_view.hide()
} else { } else {
emptyView.show(R.drawable.ic_glasses_black_128dp, R.string.information_no_recent_manga) empty_view.show(R.drawable.ic_glasses_black_128dp, R.string.information_no_recent_manga)
} }
} }
@ -108,9 +102,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
override fun onCoverClick(position: Int) { override fun onCoverClick(position: Int) {
val manga = adapter?.getItem(position)?.mch?.manga ?: return val manga = adapter?.getItem(position)?.mch?.manga ?: return
router.pushController(RouterTransaction.with(MangaController(manga)) router.pushController(MangaController(manga).withFadeTransaction())
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler()))
} }
override fun removeHistory(manga: Manga, history: History, all: Boolean) { override fun removeHistory(manga: Manga, history: History, all: Boolean) {

@ -1,9 +1,8 @@
package eu.kanade.tachiyomi.ui.setting package eu.kanade.tachiyomi.ui.setting
import android.support.v7.preference.PreferenceScreen import android.support.v7.preference.PreferenceScreen
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.util.getResourceColor import eu.kanade.tachiyomi.util.getResourceColor
class SettingsMainController : SettingsController() { class SettingsMainController : SettingsController() {
@ -57,8 +56,6 @@ class SettingsMainController : SettingsController() {
} }
private fun navigateTo(controller: SettingsController) { private fun navigateTo(controller: SettingsController) {
router.pushController(RouterTransaction.with(controller) router.pushController(controller.withFadeTransaction())
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler()))
} }
} }
Loading…
Cancel
Save