Преглед на файлове

Use synthetic view's new caching method

inorichi преди 7 години
родител
ревизия
d690d6e0e3
променени са 18 файла, в които са добавени 282 реда и са изтрити 334 реда
  1. 3 0
      app/build.gradle
  2. 23 5
      app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt
  3. 9 1
      app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ConductorExtensions.kt
  4. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/RxController.kt
  5. 18 21
      app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt
  6. 8 14
      app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt
  7. 10 17
      app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/main/CatalogueMainController.kt
  8. 14 18
      app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt
  9. 11 16
      app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt
  10. 33 49
      app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
  11. 6 15
      app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
  12. 9 13
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
  13. 35 38
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt
  14. 46 50
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt
  15. 10 11
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt
  16. 30 38
      app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt
  17. 14 22
      app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadController.kt
  18. 2 5
      app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt

+ 3 - 0
app/build.gradle

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

+ 23 - 5
app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt

@@ -6,21 +6,39 @@ import android.view.LayoutInflater
 import android.view.MenuItem
 import android.view.View
 import android.view.ViewGroup
+import com.bluelinelabs.conductor.Controller
 import com.bluelinelabs.conductor.ControllerChangeHandler
 import com.bluelinelabs.conductor.ControllerChangeType
 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 {
-        val view = inflateView(inflater, container)
-        onViewCreated(view, savedViewState)
-        return view
+        return inflateView(inflater, container)
+    }
+
+    override fun onDestroyView(view: View) {
+        super.onDestroyView(view)
+        clearFindViewByIdCache()
     }
 
     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) {
         if (type.isEnter) {

+ 9 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ConductorExtensions.kt

@@ -5,6 +5,8 @@ import android.os.Build
 import android.support.v4.content.ContextCompat
 import com.bluelinelabs.conductor.Controller
 import com.bluelinelabs.conductor.Router
+import com.bluelinelabs.conductor.RouterTransaction
+import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
 
 fun Router.popControllerWithTag(tag: String): Boolean {
     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())
+}

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/RxController.kt

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

+ 18 - 21
app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt

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

+ 8 - 14
app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt

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

+ 10 - 17
app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/main/CatalogueMainController.kt

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

+ 14 - 18
app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt

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

+ 11 - 16
app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt

@@ -1,6 +1,5 @@
 package eu.kanade.tachiyomi.ui.download
 
-import android.os.Bundle
 import android.support.v7.widget.LinearLayoutManager
 import android.view.*
 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.source.model.Page
 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.Subscription
 import rx.android.schedulers.AndroidSchedulers
@@ -52,21 +51,19 @@ class DownloadController : NucleusController<DownloadPresenter>() {
         return resources?.getString(R.string.label_download_queue)
     }
 
-    override fun onViewCreated(view: View, savedViewState: Bundle?) {
-        super.onViewCreated(view, savedViewState)
+    override fun onViewCreated(view: View) {
+        super.onViewCreated(view)
 
         // Check if download queue is empty and update information accordingly.
         setInformationView()
 
         // Initialize adapter.
         adapter = DownloadAdapter()
-        with(view) {
-            recycler.adapter = adapter
+        recycler.adapter = adapter
 
-            // Set the layout manager for the recycler and fixed size.
-            recycler.layoutManager = LinearLayoutManager(context)
-            recycler.setHasFixedSize(true)
-        }
+        // Set the layout manager for the recycler and fixed size.
+        recycler.layoutManager = LinearLayoutManager(view.context)
+        recycler.setHasFixedSize(true)
 
         // Suscribe to changes
         DownloadService.runningRelay
@@ -83,12 +80,12 @@ class DownloadController : NucleusController<DownloadPresenter>() {
     }
 
     override fun onDestroyView(view: View) {
-        super.onDestroyView(view)
         for (subscription in progressSubscriptions.values) {
             subscription.unsubscribe()
         }
         progressSubscriptions.clear()
         adapter = null
+        super.onDestroyView(view)
     }
 
     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.
      */
     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
      */
     private fun setInformationView() {
-        val emptyView = view?.empty_view ?: return
         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)
         } else {
-            emptyView.hide()
+            empty_view?.hide()
         }
     }
 

+ 33 - 49
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt

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

+ 6 - 15
app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt

@@ -14,10 +14,7 @@ import eu.kanade.tachiyomi.Migrations
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
-import eu.kanade.tachiyomi.ui.base.controller.DialogController
-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.base.controller.*
 import eu.kanade.tachiyomi.ui.catalogue.main.CatalogueMainController
 import eu.kanade.tachiyomi.ui.download.DownloadController
 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_catalogues -> setRoot(CatalogueMainController(), id)
                     R.id.nav_drawer_downloads -> {
-                        router.pushController(RouterTransaction.with(DownloadController())
-                                .pushChangeHandler(FadeChangeHandler())
-                                .popChangeHandler(FadeChangeHandler()))
+                        router.pushController(DownloadController().withFadeTransaction())
+                    }
+                    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)
@@ -189,10 +183,7 @@ class MainActivity : BaseActivity() {
     }
 
     private fun setRoot(controller: Controller, id: Int) {
-        router.setRoot(RouterTransaction.with(controller)
-                .popChangeHandler(FadeChangeHandler())
-                .pushChangeHandler(FadeChangeHandler())
-                .tag(id.toString()))
+        router.setRoot(controller.withFadeTransaction().tag(id.toString()))
     }
 
     private fun syncActivityViewWithController(to: Controller?, from: Controller? = null) {

+ 9 - 13
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt

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

+ 35 - 38
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt

@@ -4,7 +4,6 @@ import android.animation.Animator
 import android.animation.AnimatorListenerAdapter
 import android.app.Activity
 import android.content.Intent
-import android.os.Bundle
 import android.support.design.widget.Snackbar
 import android.support.v7.app.AppCompatActivity
 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.snack
 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
 
 class ChaptersController : NucleusController<ChaptersPresenter>(),
@@ -69,57 +68,55 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
         return inflater.inflate(R.layout.chapters_controller, container, false)
     }
 
-    override fun onViewCreated(view: View, savedViewState: Bundle?) {
-        super.onViewCreated(view, savedViewState)
+    override fun onViewCreated(view: View) {
+        super.onViewCreated(view)
 
         // Init RecyclerView and adapter
         adapter = ChaptersAdapter(this, view.context)
 
-        with(view) {
-            recycler.adapter = adapter
-            recycler.layoutManager = LinearLayoutManager(context)
-            recycler.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
-            recycler.setHasFixedSize(true)
-            adapter?.fastScroller = view.fast_scroller
-
-            swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
-
-            fab.clicks().subscribeUntilDestroy {
-                val item = presenter.getNextUnreadChapter()
-                if (item != null) {
-                    // Create animation listener
-                    val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
-                        override fun onAnimationStart(animation: Animator?) {
-                            openChapter(item.chapter, true)
-                        }
+        recycler.adapter = adapter
+        recycler.layoutManager = LinearLayoutManager(view.context)
+        recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
+        recycler.setHasFixedSize(true)
+        adapter?.fastScroller = fast_scroller
+
+        swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
+
+        fab.clicks().subscribeUntilDestroy {
+            val item = presenter.getNextUnreadChapter()
+            if (item != null) {
+                // Create animation listener
+                val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
+                    override fun onAnimationStart(animation: Animator?) {
+                        openChapter(item.chapter, true)
                     }
+                }
 
-                    // Get coordinates and start animation
-                    val coordinates = fab.getCoordinates()
-                    if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) {
-                        openChapter(item.chapter)
-                    }
-                } else {
-                    context.toast(R.string.no_next_chapter)
+                // Get coordinates and start animation
+                val coordinates = fab.getCoordinates()
+                if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) {
+                    openChapter(item.chapter)
                 }
+            } else {
+                view.context.toast(R.string.no_next_chapter)
             }
         }
     }
 
     override fun onDestroyView(view: View) {
-        super.onDestroyView(view)
         adapter = null
         actionMode = null
+        super.onDestroyView(view)
     }
 
     override fun onActivityResumed(activity: Activity) {
-        val view = view ?: return
+        if (view == null) return
 
         // Check if animation view is visible
-        if (view.reveal_view.visibility == View.VISIBLE) {
+        if (reveal_view.visibility == View.VISIBLE) {
             // Show the unReveal effect
-            val coordinates = view.fab.getCoordinates()
-            view.reveal_view.hideRevealEffect(coordinates.x, coordinates.y, 1920)
+            val coordinates = fab.getCoordinates()
+            reveal_view.hideRevealEffect(coordinates.x, coordinates.y, 1920)
         }
         super.onActivityResumed(activity)
     }
@@ -213,16 +210,16 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
     }
 
     fun fetchChaptersFromSource() {
-        view?.swipe_refresh?.isRefreshing = true
+        swipe_refresh?.isRefreshing = true
         presenter.fetchChaptersFromSource()
     }
 
     fun onFetchChaptersDone() {
-        view?.swipe_refresh?.isRefreshing = false
+        swipe_refresh?.isRefreshing = false
     }
 
     fun onFetchChaptersError(error: Throwable) {
-        view?.swipe_refresh?.isRefreshing = false
+        swipe_refresh?.isRefreshing = false
         activity?.toast(error.message)
     }
 
@@ -231,7 +228,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
     }
 
     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) {
@@ -365,7 +362,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
         destroyActionModeIfNeeded()
         presenter.downloadChapters(chapters)
         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) {
                     presenter.addToLibrary()
                 }

+ 46 - 50
app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt

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

+ 10 - 11
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt

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

+ 30 - 38
app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt

@@ -1,13 +1,10 @@
 package eu.kanade.tachiyomi.ui.recent_updates
 
-import android.os.Bundle
 import android.support.v7.app.AppCompatActivity
 import android.support.v7.view.ActionMode
 import android.support.v7.widget.DividerItemDecoration
 import android.support.v7.widget.LinearLayoutManager
 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.v7.widget.scrollStateChanges
 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.NucleusController
 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.reader.ReaderActivity
 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
 
 /**
@@ -65,42 +63,39 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
     /**
      * Called when view is created
      * @param view created view
-     * @param savedViewState status of saved sate
      */
-    override fun onViewCreated(view: View, savedViewState: Bundle?) {
-        super.onViewCreated(view, savedViewState)
-
-        with(view) {
-            // Init RecyclerView and adapter
-            val layoutManager = LinearLayoutManager(context)
-            recycler.layoutManager = layoutManager
-            recycler.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
-            recycler.setHasFixedSize(true)
-            adapter = RecentChaptersAdapter(this@RecentChaptersController)
-            recycler.adapter = adapter
-
-            recycler.scrollStateChanges().subscribeUntilDestroy {
-                // Disable swipe refresh when view is not at the top
-                val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
-                swipe_refresh.isEnabled = firstPos <= 0
-            }
+    override fun onViewCreated(view: View) {
+        super.onViewCreated(view)
+
+        // Init RecyclerView and adapter
+        val layoutManager = LinearLayoutManager(view.context)
+        recycler.layoutManager = layoutManager
+        recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
+        recycler.setHasFixedSize(true)
+        adapter = RecentChaptersAdapter(this@RecentChaptersController)
+        recycler.adapter = adapter
+
+        recycler.scrollStateChanges().subscribeUntilDestroy {
+            // Disable swipe refresh when view is not at the top
+            val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
+            swipe_refresh.isEnabled = firstPos <= 0
+        }
 
-            swipe_refresh.setDistanceToTriggerSync((2 * 64 * resources.displayMetrics.density).toInt())
-            swipe_refresh.refreshes().subscribeUntilDestroy {
-                if (!LibraryUpdateService.isRunning(context)) {
-                    LibraryUpdateService.start(context)
-                    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
+        swipe_refresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
+        swipe_refresh.refreshes().subscribeUntilDestroy {
+            if (!LibraryUpdateService.isRunning(view.context)) {
+                LibraryUpdateService.start(view.context)
+                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
         }
     }
 
     override fun onDestroyView(view: View) {
-        super.onDestroyView(view)
         adapter = null
         actionMode = null
+        super.onDestroyView(view)
     }
 
     /**
@@ -180,11 +175,10 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
     }
 
     override fun onUpdateEmptyView(size: Int) {
-        val emptyView = view?.empty_view ?: return
         if (size > 0) {
-            emptyView.hide()
+            empty_view?.hide()
         } 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.
      */
     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) {
-        router.pushController(RouterTransaction.with(MangaController(chapter.manga))
-                .pushChangeHandler(FadeChangeHandler())
-                .popChangeHandler(FadeChangeHandler()))
+        router.pushController(MangaController(chapter.manga).withFadeTransaction())
     }
 
     /**

+ 14 - 22
app/src/main/java/eu/kanade/tachiyomi/ui/recently_read/RecentlyReadController.kt

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

+ 2 - 5
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsMainController.kt

@@ -1,9 +1,8 @@
 package eu.kanade.tachiyomi.ui.setting
 
 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.ui.base.controller.withFadeTransaction
 import eu.kanade.tachiyomi.util.getResourceColor
 
 class SettingsMainController : SettingsController() {
@@ -57,8 +56,6 @@ class SettingsMainController : SettingsController() {
     }
 
     private fun navigateTo(controller: SettingsController) {
-        router.pushController(RouterTransaction.with(controller)
-                .pushChangeHandler(FadeChangeHandler())
-                .popChangeHandler(FadeChangeHandler()))
+        router.pushController(controller.withFadeTransaction())
     }
 }