diff --git a/app/build.gradle b/app/build.gradle index d42065f09..a144e78d7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -57,6 +57,10 @@ android { } } + viewBinding { + enabled = true + } + buildTypes { debug { versionNameSuffix "-${getCommitCount()}" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt index d13918387..6413549b1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt @@ -20,9 +20,6 @@ import uy.kohesive.injekt.injectLazy */ class DownloadProvider(private val context: Context) { - /** - * Preferences helper. - */ private val preferences: PreferencesHelper by injectLazy() /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt index 5b6a5471b..ba37783f1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt @@ -63,14 +63,8 @@ class DownloadService : Service() { } } - /** - * Download manager. - */ private val downloadManager: DownloadManager by injectLazy() - /** - * Preferences helper. - */ private val preferences: PreferencesHelper by injectLazy() /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/holder/BaseFlexibleViewHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/holder/BaseFlexibleViewHolder.kt index c4953b85d..e85cb7709 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/holder/BaseFlexibleViewHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/holder/BaseFlexibleViewHolder.kt @@ -9,8 +9,7 @@ abstract class BaseFlexibleViewHolder( view: View, adapter: FlexibleAdapter<*>, stickyHeader: Boolean = false -) : - FlexibleViewHolder(view, adapter, stickyHeader), LayoutContainer { +) : FlexibleViewHolder(view, adapter, stickyHeader), LayoutContainer { override val containerView: View? get() = itemView diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt index e3280d7b5..f12a42674 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt @@ -20,6 +20,7 @@ import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.databinding.CatalogueMainControllerBinding import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.ui.base.controller.NucleusController @@ -30,8 +31,6 @@ import eu.kanade.tachiyomi.ui.catalogue.browse.BrowseCatalogueController import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController import eu.kanade.tachiyomi.ui.catalogue.latest.LatestUpdatesController import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController -import kotlinx.android.synthetic.main.catalogue_main_controller.fast_scroller -import kotlinx.android.synthetic.main.catalogue_main_controller.recycler import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -48,9 +47,6 @@ class CatalogueController : NucleusController(), CatalogueAdapter.OnBrowseClickListener, CatalogueAdapter.OnLatestClickListener { - /** - * Application preferences. - */ private val preferences: PreferencesHelper = Injekt.get() /** @@ -58,9 +54,8 @@ class CatalogueController : NucleusController(), */ private var adapter: CatalogueAdapter? = null - /** - * Called when controller is initialized. - */ + private lateinit var binding: CatalogueMainControllerBinding + init { // Enable the option menu setHasOptionsMenu(true) @@ -92,7 +87,8 @@ class CatalogueController : NucleusController(), * @return inflated view. */ override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.catalogue_main_controller, container, false) + binding = CatalogueMainControllerBinding.inflate(inflater) + return binding.root } /** @@ -106,10 +102,10 @@ class CatalogueController : NucleusController(), adapter = CatalogueAdapter(this) // Create recycler and set adapter. - recycler.layoutManager = LinearLayoutManager(view.context) - recycler.adapter = adapter - recycler.addItemDecoration(SourceDividerItemDecoration(view.context)) - adapter?.fastScroller = fast_scroller + binding.recycler.layoutManager = LinearLayoutManager(view.context) + binding.recycler.adapter = adapter + binding.recycler.addItemDecoration(SourceDividerItemDecoration(view.context)) + adapter?.fastScroller = binding.fastScroller requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 73ec41174..4f5b5e944 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.databinding.CatalogueControllerBinding import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.online.HttpSource @@ -43,9 +44,6 @@ import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.EmptyView import java.util.concurrent.TimeUnit -import kotlinx.android.synthetic.main.catalogue_controller.catalogue_view -import kotlinx.android.synthetic.main.catalogue_controller.empty_view -import kotlinx.android.synthetic.main.catalogue_controller.progress import kotlinx.android.synthetic.main.main_activity.drawer import rx.Observable import rx.Subscription @@ -68,9 +66,6 @@ open class BrowseCatalogueController(bundle: Bundle) : putLong(SOURCE_ID_KEY, source.id) }) - /** - * Preferences helper. - */ private val preferences: PreferencesHelper by injectLazy() /** @@ -108,6 +103,8 @@ open class BrowseCatalogueController(bundle: Bundle) : */ private var progressItem: ProgressItem? = null + private lateinit var binding: CatalogueControllerBinding + init { setHasOptionsMenu(true) } @@ -121,7 +118,8 @@ open class BrowseCatalogueController(bundle: Bundle) : } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.catalogue_controller, container, false) + binding = CatalogueControllerBinding.inflate(inflater) + return binding.root } override fun onViewCreated(view: View) { @@ -133,7 +131,7 @@ open class BrowseCatalogueController(bundle: Bundle) : navView?.setFilters(presenter.filterItems) - progress?.visible() + binding.progress.visible() } override fun onDestroyView(view: View) { @@ -180,12 +178,12 @@ open class BrowseCatalogueController(bundle: Bundle) : numColumnsSubscription?.unsubscribe() var oldPosition = RecyclerView.NO_POSITION - val oldRecycler = catalogue_view?.getChildAt(1) + val oldRecycler = binding.catalogueView.getChildAt(1) if (oldRecycler is RecyclerView) { oldPosition = (oldRecycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() oldRecycler.adapter = null - catalogue_view?.removeView(oldRecycler) + binding.catalogueView.removeView(oldRecycler) } val recycler = if (presenter.isListMode) { @@ -196,7 +194,7 @@ open class BrowseCatalogueController(bundle: Bundle) : addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) } } else { - (catalogue_view.inflate(R.layout.catalogue_recycler_autofit) as AutofitRecyclerView).apply { + (binding.catalogueView.inflate(R.layout.catalogue_recycler_autofit) as AutofitRecyclerView).apply { numColumnsSubscription = getColumnsPreferenceForCurrentOrientation().asObservable() .doOnNext { spanCount = it } .skip(1) @@ -216,7 +214,7 @@ open class BrowseCatalogueController(bundle: Bundle) : recycler.setHasFixedSize(true) recycler.adapter = adapter - catalogue_view.addView(recycler, 1) + binding.catalogueView.addView(recycler, 1) if (oldPosition != RecyclerView.NO_POSITION) { recycler.layoutManager?.scrollToPosition(oldPosition) @@ -353,45 +351,43 @@ open class BrowseCatalogueController(bundle: Bundle) : snack?.dismiss() - if (catalogue_view != null) { - val message = getErrorMessage(error) - val retryAction = View.OnClickListener { + val message = getErrorMessage(error) + val retryAction = View.OnClickListener { - // If not the first page, show bottom progress bar. - if (adapter.mainItemCount > 0 && progressItem != null) { - adapter.addScrollableFooterWithDelay(progressItem!!, 0, true) - } else { - showProgressBar() + // If not the first page, show bottom progress bar. + if (adapter.mainItemCount > 0 && progressItem != null) { + adapter.addScrollableFooterWithDelay(progressItem!!, 0, true) + } else { + showProgressBar() + } + presenter.requestNext() + } + + if (adapter.isEmpty) { + val actions = mutableListOf(EmptyView.Action(R.string.action_retry, retryAction)) + if (presenter.source is HttpSource) { + val openInWebViewAction = View.OnClickListener { + openInWebView() } - presenter.requestNext() + actions += EmptyView.Action(R.string.action_open_in_web_view, openInWebViewAction) } - if (adapter.isEmpty) { - val actions = mutableListOf(EmptyView.Action(R.string.action_retry, retryAction)) - if (presenter.source is HttpSource) { - val openInWebViewAction = View.OnClickListener { - openInWebView() - } - actions += EmptyView.Action(R.string.action_open_in_web_view, openInWebViewAction) - } - - empty_view.show(message, actions) - } else { - snack = catalogue_view.snack(message, Snackbar.LENGTH_INDEFINITE) { - setAction(R.string.action_retry, retryAction) - } + binding.emptyView.show(message, actions) + } else { + snack = binding.catalogueView.snack(message, Snackbar.LENGTH_INDEFINITE) { + setAction(R.string.action_retry, retryAction) } } } private fun getErrorMessage(error: Throwable): String { if (error is NoResultsException) { - return catalogue_view.context.getString(R.string.no_results_found) + return binding.catalogueView.context.getString(R.string.no_results_found) } return when { error.message == null -> "" - error.message!!.startsWith("HTTP error") -> "${error.message}: ${catalogue_view.context.getString(R.string.http_error_hint)}" + error.message!!.startsWith("HTTP error") -> "${error.message}: ${binding.catalogueView.context.getString(R.string.http_error_hint)}" else -> error.message!! } } @@ -484,7 +480,7 @@ open class BrowseCatalogueController(bundle: Bundle) : * Shows the progress bar. */ private fun showProgressBar() { - progress?.visible() + binding.progress.visible() snack?.dismiss() snack = null } @@ -493,8 +489,8 @@ open class BrowseCatalogueController(bundle: Bundle) : * Hides active progress bars. */ private fun hideProgressBar() { - empty_view.hide() - progress?.gone() + binding.emptyView.hide() + binding.progress.gone() } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt index 61abba261..87279497e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt @@ -12,11 +12,11 @@ import androidx.recyclerview.widget.LinearLayoutManager 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.databinding.CatalogueGlobalSearchControllerBinding 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.recycler /** * This controller shows and manages the different search result in global search. @@ -34,6 +34,8 @@ open class CatalogueSearchController( */ protected var adapter: CatalogueSearchAdapter? = null + private lateinit var binding: CatalogueGlobalSearchControllerBinding + /** * Called when controller is initialized. */ @@ -48,8 +50,9 @@ open class CatalogueSearchController( * @param container containing parent views. * @return inflated view */ - override fun inflateView(inflater: LayoutInflater, container: ViewGroup): android.view.View { - return inflater.inflate(R.layout.catalogue_global_search_controller, container, false) + override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { + binding = CatalogueGlobalSearchControllerBinding.inflate(inflater) + return binding.root } /** @@ -136,8 +139,8 @@ open class CatalogueSearchController( adapter = CatalogueSearchAdapter(this) // Create recycler and set adapter. - recycler.layoutManager = LinearLayoutManager(view.context) - recycler.adapter = adapter + binding.recycler.layoutManager = LinearLayoutManager(view.context) + binding.recycler.adapter = adapter } override fun onDestroyView(view: View) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt index 55591726e..ffe270673 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt @@ -16,11 +16,9 @@ import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.helpers.UndoHelper import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Category +import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.util.system.toast -import kotlinx.android.synthetic.main.categories_controller.empty_view -import kotlinx.android.synthetic.main.categories_controller.fab -import kotlinx.android.synthetic.main.categories_controller.recycler /** * Controller to manage the categories for the users' library. @@ -49,6 +47,8 @@ class CategoryController : NucleusController(), */ private var undoHelper: UndoHelper? = null + private lateinit var binding: CategoriesControllerBinding + /** * Creates the presenter for this controller. Not to be manually called. */ @@ -68,7 +68,8 @@ class CategoryController : NucleusController(), * @param container The parent view for this one. */ override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.categories_controller, container, false) + binding = CategoriesControllerBinding.inflate(inflater) + return binding.root } /** @@ -80,13 +81,13 @@ class CategoryController : NucleusController(), super.onViewCreated(view) adapter = CategoryAdapter(this@CategoryController) - recycler.layoutManager = LinearLayoutManager(view.context) - recycler.setHasFixedSize(true) - recycler.adapter = adapter + binding.recycler.layoutManager = LinearLayoutManager(view.context) + binding.recycler.setHasFixedSize(true) + binding.recycler.adapter = adapter adapter?.isHandleDragEnabled = true adapter?.isPermanentDelete = false - fab.clicks().subscribeUntilDestroy { + binding.fab.clicks().subscribeUntilDestroy { CategoryCreateDialog(this@CategoryController).showDialog(router, null) } } @@ -114,13 +115,13 @@ class CategoryController : NucleusController(), actionMode?.finish() adapter?.updateDataSet(categories) if (categories.isNotEmpty()) { - empty_view.hide() + binding.emptyView.hide() val selected = categories.filter { it.isSelected } if (selected.isNotEmpty()) { selected.forEach { onItemLongClick(categories.indexOf(it)) } } } else { - empty_view.show(R.string.information_empty_category) + binding.emptyView.show(R.string.information_empty_category) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt index ddf548c33..612692f59 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt @@ -10,12 +10,11 @@ import androidx.recyclerview.widget.LinearLayoutManager import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.model.Download +import eu.kanade.tachiyomi.databinding.DownloadControllerBinding import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.ui.base.controller.NucleusController import java.util.HashMap import java.util.concurrent.TimeUnit -import kotlinx.android.synthetic.main.download_controller.empty_view -import kotlinx.android.synthetic.main.download_controller.recycler import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers @@ -42,12 +41,15 @@ class DownloadController : NucleusController(), */ private var isRunning: Boolean = false + private lateinit var binding: DownloadControllerBinding + init { setHasOptionsMenu(true) } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.download_controller, container, false) + binding = DownloadControllerBinding.inflate(inflater) + return binding.root } override fun createPresenter(): DownloadPresenter { @@ -66,12 +68,12 @@ class DownloadController : NucleusController(), // Initialize adapter. adapter = DownloadAdapter(this@DownloadController) - recycler.adapter = adapter + binding.recycler.adapter = adapter adapter?.isHandleDragEnabled = true // Set the layout manager for the recycler and fixed size. - recycler.layoutManager = LinearLayoutManager(view.context) - recycler.setHasFixedSize(true) + binding.recycler.layoutManager = LinearLayoutManager(view.context) + binding.recycler.setHasFixedSize(true) // Subscribe to changes DownloadService.runningRelay @@ -242,7 +244,7 @@ class DownloadController : NucleusController(), * @return the holder of the download or null if it's not bound. */ private fun getHolder(download: Download): DownloadHolder? { - return recycler?.findViewHolderForItemId(download.chapter.id!!) as? DownloadHolder + return binding.recycler.findViewHolderForItemId(download.chapter.id!!) as? DownloadHolder } /** @@ -250,9 +252,9 @@ class DownloadController : NucleusController(), */ private fun setInformationView() { if (presenter.downloadQueue.isEmpty()) { - empty_view?.show(R.string.information_no_downloads) + binding.emptyView.show(R.string.information_no_downloads) } else { - empty_view?.hide() + binding.emptyView.hide() } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt index f316bc33c..ede78ab3b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt @@ -19,11 +19,11 @@ import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.databinding.ExtensionControllerBinding import eu.kanade.tachiyomi.extension.ExtensionUpdateJob import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction -import kotlinx.android.synthetic.main.extension_controller.* import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -47,6 +47,8 @@ open class ExtensionController : NucleusController(), private var query = "" + private lateinit var binding: ExtensionControllerBinding + init { setHasOptionsMenu(true) } @@ -60,24 +62,25 @@ open class ExtensionController : NucleusController(), } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.extension_controller, container, false) + binding = ExtensionControllerBinding.inflate(inflater) + return binding.root } override fun onViewCreated(view: View) { super.onViewCreated(view) - ext_swipe_refresh.isRefreshing = true - ext_swipe_refresh.refreshes().subscribeUntilDestroy { + binding.extSwipeRefresh.isRefreshing = true + binding.extSwipeRefresh.refreshes().subscribeUntilDestroy { presenter.findAvailableExtensions() } // Initialize adapter, scroll listener and recycler views adapter = ExtensionAdapter(this) // Create recycler and set adapter. - ext_recycler.layoutManager = LinearLayoutManager(view.context) - ext_recycler.adapter = adapter - ext_recycler.addItemDecoration(ExtensionDividerItemDecoration(view.context)) - adapter?.fastScroller = fast_scroller + binding.extRecycler.layoutManager = LinearLayoutManager(view.context) + binding.extRecycler.adapter = adapter + binding.extRecycler.addItemDecoration(ExtensionDividerItemDecoration(view.context)) + adapter?.fastScroller = binding.fastScroller } override fun onDestroyView(view: View) { @@ -184,7 +187,7 @@ open class ExtensionController : NucleusController(), } fun setExtensions(extensions: List) { - ext_swipe_refresh?.isRefreshing = false + binding.extSwipeRefresh.isRefreshing = false this.extensions = extensions drawExtensions() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt index 124874370..c7b122add 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt @@ -26,21 +26,13 @@ import com.jakewharton.rxbinding.view.clicks import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.EmptyPreferenceDataStore import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore +import eu.kanade.tachiyomi.databinding.ExtensionDetailControllerBinding import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.util.preference.preferenceCategory import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.view.visible -import kotlinx.android.synthetic.main.extension_detail_controller.extension_icon -import kotlinx.android.synthetic.main.extension_detail_controller.extension_lang -import kotlinx.android.synthetic.main.extension_detail_controller.extension_obsolete -import kotlinx.android.synthetic.main.extension_detail_controller.extension_pkg -import kotlinx.android.synthetic.main.extension_detail_controller.extension_prefs_empty_view -import kotlinx.android.synthetic.main.extension_detail_controller.extension_prefs_recycler -import kotlinx.android.synthetic.main.extension_detail_controller.extension_title -import kotlinx.android.synthetic.main.extension_detail_controller.extension_uninstall_button -import kotlinx.android.synthetic.main.extension_detail_controller.extension_version @SuppressLint("RestrictedApi") class ExtensionDetailsController(bundle: Bundle? = null) : @@ -52,14 +44,16 @@ class ExtensionDetailsController(bundle: Bundle? = null) : private var preferenceScreen: PreferenceScreen? = null + private lateinit var binding: ExtensionDetailControllerBinding + constructor(pkgName: String) : this(Bundle().apply { putString(PKGNAME_KEY, pkgName) }) override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { val themedInflater = inflater.cloneInContext(getPreferenceThemeContext()) - - return themedInflater.inflate(R.layout.extension_detail_controller, container, false) + binding = ExtensionDetailControllerBinding.inflate(themedInflater) + return binding.root } override fun createPresenter(): ExtensionDetailsPresenter { @@ -77,17 +71,17 @@ class ExtensionDetailsController(bundle: Bundle? = null) : val extension = presenter.extension ?: return val context = view.context - extension_title.text = extension.name - extension_version.text = context.getString(R.string.ext_version_info, extension.versionName) - extension_lang.text = context.getString(R.string.ext_language_info, LocaleHelper.getDisplayName(extension.lang, context)) - extension_pkg.text = extension.pkgName - extension.getApplicationIcon(context)?.let { extension_icon.setImageDrawable(it) } - extension_uninstall_button.clicks().subscribeUntilDestroy { + binding.extensionTitle.text = extension.name + binding.extensionVersion.text = context.getString(R.string.ext_version_info, extension.versionName) + binding.extensionLang.text = context.getString(R.string.ext_language_info, LocaleHelper.getDisplayName(extension.lang, context)) + binding.extensionPkg.text = extension.pkgName + extension.getApplicationIcon(context)?.let { binding.extensionIcon.setImageDrawable(it) } + binding.extensionUninstallButton.clicks().subscribeUntilDestroy { presenter.uninstallExtension() } if (extension.isObsolete) { - extension_obsolete.visible() + binding.extensionObsolete.visible() } val themedContext by lazy { getPreferenceThemeContext() } @@ -107,12 +101,12 @@ class ExtensionDetailsController(bundle: Bundle? = null) : manager.setPreferences(screen) - extension_prefs_recycler.layoutManager = LinearLayoutManager(context) - extension_prefs_recycler.adapter = PreferenceGroupAdapter(screen) - extension_prefs_recycler.addItemDecoration(DividerItemDecoration(context, VERTICAL)) + binding.extensionPrefsRecycler.layoutManager = LinearLayoutManager(context) + binding.extensionPrefsRecycler.adapter = PreferenceGroupAdapter(screen) + binding.extensionPrefsRecycler.addItemDecoration(DividerItemDecoration(context, VERTICAL)) if (screen.preferenceCount == 0) { - extension_prefs_empty_view.show(R.string.ext_empty_preferences) + binding.extensionPrefsEmptyView.show(R.string.ext_empty_preferences) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 8ac2e31b0..541ecee19 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -29,6 +29,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.databinding.LibraryControllerBinding import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.TabbedController @@ -38,9 +39,6 @@ import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.toast import java.io.IOException -import kotlinx.android.synthetic.main.library_controller.action_toolbar -import kotlinx.android.synthetic.main.library_controller.empty_view -import kotlinx.android.synthetic.main.library_controller.library_pager import kotlinx.android.synthetic.main.main_activity.tabs import rx.Subscription import timber.log.Timber @@ -127,6 +125,8 @@ class LibraryController( private var searchViewSubscription: Subscription? = null + private lateinit var binding: LibraryControllerBinding + init { setHasOptionsMenu(true) retainViewMode = RetainViewMode.RETAIN_DETACH @@ -141,15 +141,16 @@ class LibraryController( } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.library_controller, container, false) + binding = LibraryControllerBinding.inflate(inflater) + return binding.root } override fun onViewCreated(view: View) { super.onViewCreated(view) adapter = LibraryAdapter(this) - library_pager.adapter = adapter - library_pager.pageSelections().skip(1).subscribeUntilDestroy { + binding.libraryPager.adapter = adapter + binding.libraryPager.pageSelections().skip(1).subscribeUntilDestroy { preferences.lastUsedCategory().set(it) activeCategory = it } @@ -177,14 +178,14 @@ class LibraryController( override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { super.onChangeStarted(handler, type) if (type.isEnter) { - activity?.tabs?.setupWithViewPager(library_pager) + activity?.tabs?.setupWithViewPager(binding.libraryPager) presenter.subscribeLibrary() } } override fun onDestroyView(view: View) { destroyActionModeIfNeeded() - action_toolbar.destroy() + binding.actionToolbar.destroy() adapter?.onDestroy() adapter = null settingsSheet = null @@ -224,14 +225,14 @@ class LibraryController( // Show empty view if needed if (mangaMap.isNotEmpty()) { - empty_view.hide() + binding.emptyView.hide() } else { - empty_view.show(R.string.information_empty_library) + binding.emptyView.show(R.string.information_empty_library) } // Get the current active category. val activeCat = if (adapter.categories.isNotEmpty()) - library_pager.currentItem + binding.libraryPager.currentItem else activeCategory @@ -239,14 +240,14 @@ class LibraryController( adapter.categories = categories // Restore active category. - library_pager.setCurrentItem(activeCat, false) + binding.libraryPager.setCurrentItem(activeCat, false) tabsVisibilityRelay.call(categories.size > 1) // Delay the scroll position to allow the view to be properly measured. view.post { if (isAttached) { - activity?.tabs?.setScrollPosition(library_pager.currentItem, 0f, true) + activity?.tabs?.setScrollPosition(binding.libraryPager.currentItem, 0f, true) } } @@ -291,11 +292,11 @@ class LibraryController( private fun reattachAdapter() { val adapter = adapter ?: return - val position = library_pager.currentItem + val position = binding.libraryPager.currentItem adapter.recycle = false - library_pager.adapter = adapter - library_pager.currentItem = position + binding.libraryPager.adapter = adapter + binding.libraryPager.currentItem = position adapter.recycle = true } @@ -305,7 +306,7 @@ class LibraryController( fun createActionModeIfNeeded() { if (actionMode == null) { actionMode = (activity as AppCompatActivity).startSupportActionMode(this) - action_toolbar.show( + binding.actionToolbar.show( actionMode!!, R.menu.library_selection ) { onActionItemClicked(actionMode!!, it!!) } @@ -398,7 +399,7 @@ class LibraryController( } else { mode.title = count.toString() - action_toolbar.findItem(R.id.action_edit_cover)?.isVisible = count == 1 + binding.actionToolbar.findItem(R.id.action_edit_cover)?.isVisible = count == 1 } return false } @@ -419,7 +420,7 @@ class LibraryController( } override fun onDestroyActionMode(mode: ActionMode?) { - action_toolbar.hide() + binding.actionToolbar.hide() // Clear all the manga selections and notify child views. selectedMangas.clear() selectionRelay.call(LibrarySelectionEvent.Cleared()) @@ -515,13 +516,13 @@ class LibraryController( } private fun selectAllCategoryManga() { - adapter?.categories?.getOrNull(library_pager.currentItem)?.id?.let { + adapter?.categories?.getOrNull(binding.libraryPager.currentItem)?.id?.let { selectAllRelay.call(it) } } private fun selectInverseCategoryManga() { - adapter?.categories?.getOrNull(library_pager.currentItem)?.id?.let { + adapter?.categories?.getOrNull(binding.libraryPager.currentItem)?.id?.let { selectInverseRelay.call(it) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt index ea5ff57df..e30816084 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt @@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.track.TrackManager +import eu.kanade.tachiyomi.databinding.MangaControllerBinding import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.ui.base.controller.RxController @@ -29,7 +30,6 @@ import eu.kanade.tachiyomi.ui.manga.track.TrackController import eu.kanade.tachiyomi.util.system.toast import java.util.Date import kotlinx.android.synthetic.main.main_activity.tabs -import kotlinx.android.synthetic.main.manga_controller.manga_pager import rx.Subscription import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -68,6 +68,8 @@ class MangaController : RxController, TabbedController { val mangaFavoriteRelay: PublishRelay = PublishRelay.create() + private lateinit var binding: MangaControllerBinding + private val trackingIconRelay: BehaviorRelay = BehaviorRelay.create() private var trackingIconSubscription: Subscription? = null @@ -77,7 +79,8 @@ class MangaController : RxController, TabbedController { } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.manga_controller, container, false) + binding = MangaControllerBinding.inflate(inflater) + return binding.root } override fun onViewCreated(view: View) { @@ -88,11 +91,11 @@ class MangaController : RxController, TabbedController { requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301) adapter = MangaDetailAdapter() - manga_pager.offscreenPageLimit = 3 - manga_pager.adapter = adapter + binding.mangaPager.offscreenPageLimit = 3 + binding.mangaPager.adapter = adapter if (!fromCatalogue) - manga_pager.currentItem = CHAPTERS_CONTROLLER + binding.mangaPager.currentItem = CHAPTERS_CONTROLLER } override fun onDestroyView(view: View) { @@ -103,7 +106,7 @@ class MangaController : RxController, TabbedController { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { super.onChangeStarted(handler, type) if (type.isEnter) { - activity?.tabs?.setupWithViewPager(manga_pager) + activity?.tabs?.setupWithViewPager(binding.mangaPager) trackingIconSubscription = trackingIconRelay.subscribe { setTrackingIconInternal(it) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt index fe6742581..4b49830d7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt @@ -24,6 +24,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download +import eu.kanade.tachiyomi.databinding.ChaptersControllerBinding import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag import eu.kanade.tachiyomi.ui.manga.MangaController @@ -32,12 +33,6 @@ import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.view.getCoordinates import eu.kanade.tachiyomi.util.view.snack -import kotlinx.android.synthetic.main.chapters_controller.action_toolbar -import kotlinx.android.synthetic.main.chapters_controller.fab -import kotlinx.android.synthetic.main.chapters_controller.fast_scroller -import kotlinx.android.synthetic.main.chapters_controller.recycler -import kotlinx.android.synthetic.main.chapters_controller.reveal_view -import kotlinx.android.synthetic.main.chapters_controller.swipe_refresh import timber.log.Timber class ChaptersController : NucleusController(), @@ -64,6 +59,8 @@ class ChaptersController : NucleusController(), private var lastClickPosition = -1 + private lateinit var binding: ChaptersControllerBinding + init { setHasOptionsMenu(true) setOptionsMenuHidden(true) @@ -76,7 +73,8 @@ class ChaptersController : NucleusController(), } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.chapters_controller, container, false) + binding = ChaptersControllerBinding.inflate(inflater) + return binding.root } override fun onViewCreated(view: View) { @@ -85,15 +83,15 @@ class ChaptersController : NucleusController(), // Init RecyclerView and adapter adapter = ChaptersAdapter(this, view.context) - recycler.adapter = adapter - recycler.layoutManager = LinearLayoutManager(view.context) - recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL)) - recycler.setHasFixedSize(true) - adapter?.fastScroller = fast_scroller + binding.recycler.adapter = adapter + binding.recycler.layoutManager = LinearLayoutManager(view.context) + binding.recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL)) + binding.recycler.setHasFixedSize(true) + adapter?.fastScroller = binding.fastScroller - swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() } + binding.swipeRefresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() } - fab.clicks().subscribeUntilDestroy { + binding.fab.clicks().subscribeUntilDestroy { val item = presenter.getNextUnreadChapter() if (item != null) { // Create animation listener @@ -104,8 +102,8 @@ class ChaptersController : NucleusController(), } // Get coordinates and start animation - val coordinates = fab.getCoordinates() - if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) { + val coordinates = binding.fab.getCoordinates() + if (!binding.revealView.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) { openChapter(item.chapter) } } else { @@ -116,7 +114,7 @@ class ChaptersController : NucleusController(), override fun onDestroyView(view: View) { destroyActionModeIfNeeded() - action_toolbar.destroy() + binding.actionToolbar.destroy() adapter = null super.onDestroyView(view) } @@ -125,10 +123,10 @@ class ChaptersController : NucleusController(), if (view == null) return // Check if animation view is visible - if (reveal_view.visibility == View.VISIBLE) { - // Show the unReveal effect - val coordinates = fab.getCoordinates() - reveal_view.hideRevealEffect(coordinates.x, coordinates.y, 1920) + if (binding.revealView.visibility == View.VISIBLE) { + // Show the unreveal effect + val coordinates = binding.fab.getCoordinates() + binding.revealView.hideRevealEffect(coordinates.x, coordinates.y, 1920) } super.onActivityResumed(activity) } @@ -267,16 +265,16 @@ class ChaptersController : NucleusController(), } private fun fetchChaptersFromSource() { - swipe_refresh?.isRefreshing = true + binding.swipeRefresh.isRefreshing = true presenter.fetchChaptersFromSource() } fun onFetchChaptersDone() { - swipe_refresh?.isRefreshing = false + binding.swipeRefresh.isRefreshing = false } fun onFetchChaptersError(error: Throwable) { - swipe_refresh?.isRefreshing = false + binding.swipeRefresh.isRefreshing = false activity?.toast(error.message) } @@ -285,7 +283,7 @@ class ChaptersController : NucleusController(), } private fun getHolder(chapter: Chapter): ChapterHolder? { - return recycler?.findViewHolderForItemId(chapter.id!!) as? ChapterHolder + return binding.recycler.findViewHolderForItemId(chapter.id!!) as? ChapterHolder } fun openChapter(chapter: Chapter, hasAnimation: Boolean = false) { @@ -357,7 +355,7 @@ class ChaptersController : NucleusController(), private fun createActionModeIfNeeded() { if (actionMode == null) { actionMode = (activity as? AppCompatActivity)?.startSupportActionMode(this) - action_toolbar.show( + binding.actionToolbar.show( actionMode!!, R.menu.chapter_selection ) { onActionItemClicked(actionMode!!, it!!) } @@ -384,15 +382,15 @@ class ChaptersController : NucleusController(), mode.title = count.toString() val chapters = getSelectedChapters() - action_toolbar.findItem(R.id.action_download)?.isVisible = chapters.any { !it.isDownloaded } - action_toolbar.findItem(R.id.action_delete)?.isVisible = chapters.any { it.isDownloaded } - action_toolbar.findItem(R.id.action_bookmark)?.isVisible = chapters.any { !it.chapter.bookmark } - action_toolbar.findItem(R.id.action_remove_bookmark)?.isVisible = chapters.all { it.chapter.bookmark } - action_toolbar.findItem(R.id.action_mark_as_read)?.isVisible = chapters.any { !it.chapter.read } - action_toolbar.findItem(R.id.action_mark_as_unread)?.isVisible = chapters.all { it.chapter.read } + binding.actionToolbar.findItem(R.id.action_download)?.isVisible = chapters.any { !it.isDownloaded } + binding.actionToolbar.findItem(R.id.action_delete)?.isVisible = chapters.any { it.isDownloaded } + binding.actionToolbar.findItem(R.id.action_bookmark)?.isVisible = chapters.any { !it.chapter.bookmark } + binding.actionToolbar.findItem(R.id.action_remove_bookmark)?.isVisible = chapters.all { it.chapter.bookmark } + binding.actionToolbar.findItem(R.id.action_mark_as_read)?.isVisible = chapters.any { !it.chapter.read } + binding.actionToolbar.findItem(R.id.action_mark_as_unread)?.isVisible = chapters.all { it.chapter.read } // Hide FAB to avoid interfering with the bottom action toolbar - fab.hide() + binding.fab.hide() } return false } @@ -414,13 +412,13 @@ class ChaptersController : NucleusController(), } override fun onDestroyActionMode(mode: ActionMode) { - action_toolbar.hide() + binding.actionToolbar.hide() adapter?.mode = SelectableAdapter.Mode.SINGLE adapter?.clearSelection() selectedItems.clear() actionMode = null - fab.show() + binding.fab.show() } override fun onDetach(view: View) { @@ -461,7 +459,7 @@ class ChaptersController : NucleusController(), val view = view presenter.downloadChapters(chapters) if (view != null && !presenter.manga.favorite) { - recycler?.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) { + binding.recycler.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) { setAction(R.string.action_add) { presenter.addToLibrary() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index bf133980f..ac98197d6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -36,6 +36,7 @@ import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.databinding.MangaInfoControllerBinding import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.model.SManga @@ -57,20 +58,6 @@ import java.text.DateFormat import java.text.DecimalFormat import java.util.Date import jp.wasabeef.glide.transformations.CropSquareTransformation -import kotlinx.android.synthetic.main.manga_info_controller.backdrop -import kotlinx.android.synthetic.main.manga_info_controller.fab_favorite -import kotlinx.android.synthetic.main.manga_info_controller.manga_artist -import kotlinx.android.synthetic.main.manga_info_controller.manga_artist_label -import kotlinx.android.synthetic.main.manga_info_controller.manga_author -import kotlinx.android.synthetic.main.manga_info_controller.manga_chapters -import kotlinx.android.synthetic.main.manga_info_controller.manga_cover -import kotlinx.android.synthetic.main.manga_info_controller.manga_full_title -import kotlinx.android.synthetic.main.manga_info_controller.manga_genres_tags -import kotlinx.android.synthetic.main.manga_info_controller.manga_last_update -import kotlinx.android.synthetic.main.manga_info_controller.manga_source -import kotlinx.android.synthetic.main.manga_info_controller.manga_status -import kotlinx.android.synthetic.main.manga_info_controller.manga_summary -import kotlinx.android.synthetic.main.manga_info_controller.swipe_refresh import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy @@ -83,15 +70,14 @@ import uy.kohesive.injekt.injectLazy class MangaInfoController : NucleusController(), ChangeMangaCategoriesDialog.Listener { - /** - * Preferences helper. - */ private val preferences: PreferencesHelper by injectLazy() private val dateFormat: DateFormat by lazy { preferences.dateFormat().getOrDefault() } + private lateinit var binding: MangaInfoControllerBinding + init { setHasOptionsMenu(true) setOptionsMenuHidden(true) @@ -104,50 +90,51 @@ class MangaInfoController : NucleusController(), } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.manga_info_controller, container, false) + binding = MangaInfoControllerBinding.inflate(inflater) + return binding.root } override fun onViewCreated(view: View) { super.onViewCreated(view) // Set onclickListener to toggle favorite when FAB clicked. - fab_favorite.clicks().subscribeUntilDestroy { onFabClick() } + binding.fabFavorite.clicks().subscribeUntilDestroy { onFabClick() } // Set onLongClickListener to manage categories when FAB is clicked. - fab_favorite.longClicks().subscribeUntilDestroy { onFabLongClick() } + binding.fabFavorite.longClicks().subscribeUntilDestroy { onFabLongClick() } // Set SwipeRefresh to refresh manga data. - swipe_refresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() } + binding.swipeRefresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() } - manga_full_title.longClicks().subscribeUntilDestroy { - copyToClipboard(view.context.getString(R.string.title), manga_full_title.text.toString()) + binding.mangaFullTitle.longClicks().subscribeUntilDestroy { + copyToClipboard(view.context.getString(R.string.title), binding.mangaFullTitle.text.toString()) } - manga_full_title.clicks().subscribeUntilDestroy { - performGlobalSearch(manga_full_title.text.toString()) + binding.mangaFullTitle.clicks().subscribeUntilDestroy { + performGlobalSearch(binding.mangaFullTitle.text.toString()) } - manga_artist.longClicks().subscribeUntilDestroy { - copyToClipboard(manga_artist_label.text.toString(), manga_artist.text.toString()) + binding.mangaArtist.longClicks().subscribeUntilDestroy { + copyToClipboard(binding.mangaArtistLabel.text.toString(), binding.mangaArtist.text.toString()) } - manga_artist.clicks().subscribeUntilDestroy { - performGlobalSearch(manga_artist.text.toString()) + binding.mangaArtist.clicks().subscribeUntilDestroy { + performGlobalSearch(binding.mangaArtist.text.toString()) } - manga_author.longClicks().subscribeUntilDestroy { - copyToClipboard(manga_author.text.toString(), manga_author.text.toString()) + binding.mangaAuthor.longClicks().subscribeUntilDestroy { + copyToClipboard(binding.mangaAuthor.text.toString(), binding.mangaAuthor.text.toString()) } - manga_author.clicks().subscribeUntilDestroy { - performGlobalSearch(manga_author.text.toString()) + binding.mangaAuthor.clicks().subscribeUntilDestroy { + performGlobalSearch(binding.mangaAuthor.text.toString()) } - manga_summary.longClicks().subscribeUntilDestroy { - copyToClipboard(view.context.getString(R.string.description), manga_summary.text.toString()) + binding.mangaSummary.longClicks().subscribeUntilDestroy { + copyToClipboard(view.context.getString(R.string.description), binding.mangaSummary.text.toString()) } - manga_cover.longClicks().subscribeUntilDestroy { + binding.mangaCover.longClicks().subscribeUntilDestroy { copyToClipboard(view.context.getString(R.string.title), presenter.manga.title) } } @@ -197,21 +184,21 @@ class MangaInfoController : NucleusController(), val view = view ?: return // update full title TextView. - manga_full_title.text = if (manga.title.isBlank()) { + binding.mangaFullTitle.text = if (manga.title.isBlank()) { view.context.getString(R.string.unknown) } else { manga.title } // Update artist TextView. - manga_artist.text = if (manga.artist.isNullOrBlank()) { + binding.mangaArtist.text = if (manga.artist.isNullOrBlank()) { view.context.getString(R.string.unknown) } else { manga.artist } // Update author TextView. - manga_author.text = if (manga.author.isNullOrBlank()) { + binding.mangaAuthor.text = if (manga.author.isNullOrBlank()) { view.context.getString(R.string.unknown) } else { manga.author @@ -219,7 +206,7 @@ class MangaInfoController : NucleusController(), // If manga source is known update source TextView. val mangaSource = source?.toString() - with(manga_source) { + with(binding.mangaSource) { if (mangaSource != null) { text = mangaSource setOnClickListener { @@ -233,7 +220,7 @@ class MangaInfoController : NucleusController(), // Update genres list if (!manga.genre.isNullOrBlank()) { - manga_genres_tags.removeAllViews() + binding.mangaGenresTags.removeAllViews() manga.genre?.split(", ")?.forEach { genre -> val chip = Chip(view.context).apply { @@ -241,19 +228,19 @@ class MangaInfoController : NucleusController(), setOnClickListener { performSearch(genre) } } - manga_genres_tags.addView(chip) + binding.mangaGenresTags.addView(chip) } } // Update description TextView. - manga_summary.text = if (manga.description.isNullOrBlank()) { + binding.mangaSummary.text = if (manga.description.isNullOrBlank()) { view.context.getString(R.string.unknown) } else { manga.description } // Update status TextView. - manga_status.setText(when (manga.status) { + binding.mangaStatus.setText(when (manga.status) { SManga.ONGOING -> R.string.ongoing SManga.COMPLETED -> R.string.completed SManga.LICENSED -> R.string.licensed @@ -264,19 +251,19 @@ class MangaInfoController : NucleusController(), setFavoriteDrawable(manga.favorite) // Set cover if it wasn't already. - if (manga_cover.drawable == null && !manga.thumbnail_url.isNullOrEmpty()) { + if (binding.mangaCover.drawable == null && !manga.thumbnail_url.isNullOrEmpty()) { GlideApp.with(view.context) .load(manga) .diskCacheStrategy(DiskCacheStrategy.RESOURCE) .centerCrop() - .into(manga_cover) + .into(binding.mangaCover) - if (backdrop != null) { + if (binding.backdrop != null) { GlideApp.with(view.context) .load(manga) .diskCacheStrategy(DiskCacheStrategy.RESOURCE) .centerCrop() - .into(backdrop) + .into(binding.backdrop!!) } } } @@ -288,17 +275,17 @@ class MangaInfoController : NucleusController(), */ fun setChapterCount(count: Float) { if (count > 0f) { - manga_chapters?.text = DecimalFormat("#.#").format(count) + binding.mangaChapters.text = DecimalFormat("#.#").format(count) } else { - manga_chapters?.text = resources?.getString(R.string.unknown) + binding.mangaChapters.text = resources?.getString(R.string.unknown) } } fun setLastUpdateDate(date: Date) { if (date.time != 0L) { - manga_last_update?.text = dateFormat.format(date) + binding.mangaLastUpdate.text = dateFormat.format(date) } else { - manga_last_update?.text = resources?.getString(R.string.unknown) + binding.mangaLastUpdate.text = resources?.getString(R.string.unknown) } } @@ -359,7 +346,7 @@ class MangaInfoController : NucleusController(), private fun setFavoriteDrawable(isFavorite: Boolean) { // Set the Favorite drawable to the correct one. // Border drawable if false, filled drawable if true. - fab_favorite?.setImageResource(if (isFavorite) + binding.fabFavorite.setImageResource(if (isFavorite) R.drawable.ic_bookmark_24dp else R.drawable.ic_add_to_library_24dp) @@ -395,7 +382,7 @@ class MangaInfoController : NucleusController(), * @param value whether it should be refreshing or not. */ private fun setRefreshing(value: Boolean) { - swipe_refresh?.isRefreshing = value + binding.swipeRefresh.isRefreshing = value } private fun onFabClick() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt index 25400350d..1637376fb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt @@ -9,11 +9,10 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.jakewharton.rxbinding.support.v4.widget.refreshes import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.track.model.TrackSearch +import eu.kanade.tachiyomi.databinding.TrackControllerBinding import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.util.system.toast -import kotlinx.android.synthetic.main.track_controller.swipe_refresh -import kotlinx.android.synthetic.main.track_controller.track_recycler import timber.log.Timber class TrackController : NucleusController(), @@ -24,6 +23,8 @@ class TrackController : NucleusController(), private var adapter: TrackAdapter? = null + private lateinit var binding: TrackControllerBinding + init { // There's no menu, but this avoids a bug when coming from the catalogue, where the menu // disappears if the searchview is expanded @@ -35,19 +36,18 @@ class TrackController : NucleusController(), } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.track_controller, container, false) + binding = TrackControllerBinding.inflate(inflater) + return binding.root } override fun onViewCreated(view: View) { super.onViewCreated(view) adapter = TrackAdapter(this) - with(view) { - track_recycler.layoutManager = LinearLayoutManager(context) - track_recycler.adapter = adapter - swipe_refresh.isEnabled = false - swipe_refresh.refreshes().subscribeUntilDestroy { presenter.refresh() } - } + binding.trackRecycler.layoutManager = LinearLayoutManager(view.context) + binding.trackRecycler.adapter = adapter + binding.swipeRefresh.isEnabled = false + binding.swipeRefresh.refreshes().subscribeUntilDestroy { presenter.refresh() } } override fun onDestroyView(view: View) { @@ -58,7 +58,7 @@ class TrackController : NucleusController(), fun onNextTrackings(trackings: List) { val atLeastOneLink = trackings.any { it.track != null } adapter?.items = trackings - swipe_refresh?.isEnabled = atLeastOneLink + binding.swipeRefresh.isEnabled = atLeastOneLink (parentController as? MangaController)?.setTrackingIcon(atLeastOneLink) } @@ -77,11 +77,11 @@ class TrackController : NucleusController(), } fun onRefreshDone() { - swipe_refresh?.isRefreshing = false + binding.swipeRefresh.isRefreshing = false } fun onRefreshError(error: Throwable) { - swipe_refresh?.isRefreshing = false + binding.swipeRefresh.isRefreshing = false activity?.toast(error.message) } @@ -123,17 +123,17 @@ class TrackController : NucleusController(), override fun setStatus(item: TrackItem, selection: Int) { presenter.setStatus(item, selection) - swipe_refresh?.isRefreshing = true + binding.swipeRefresh.isRefreshing = true } override fun setScore(item: TrackItem, score: Int) { presenter.setScore(item, score) - swipe_refresh?.isRefreshing = true + binding.swipeRefresh.isRefreshing = true } override fun setChaptersRead(item: TrackItem, chaptersRead: Int) { presenter.setLastChapterRead(item, chaptersRead) - swipe_refresh?.isRefreshing = true + binding.swipeRefresh.isRefreshing = true } private companion object { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt index ab78eda3e..f4c8c6811 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt @@ -7,9 +7,9 @@ import androidx.recyclerview.widget.LinearLayoutManager import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.items.IFlexible import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.databinding.MigrationControllerBinding import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction -import kotlinx.android.synthetic.main.migration_controller.migration_recycler class MigrationController : NucleusController(), FlexibleAdapter.OnItemClickListener, @@ -23,20 +23,23 @@ class MigrationController : NucleusController(), setTitle() } + private lateinit var binding: MigrationControllerBinding + override fun createPresenter(): MigrationPresenter { return MigrationPresenter() } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.migration_controller, container, false) + binding = MigrationControllerBinding.inflate(inflater) + return binding.root } override fun onViewCreated(view: View) { super.onViewCreated(view) adapter = FlexibleAdapter(null, this) - migration_recycler.layoutManager = LinearLayoutManager(view.context) - migration_recycler.adapter = adapter + binding.migrationRecycler.layoutManager = LinearLayoutManager(view.context) + binding.migrationRecycler.adapter = adapter } override fun onDestroyView(view: View) { @@ -62,14 +65,14 @@ class MigrationController : NucleusController(), title = resources?.getString(R.string.label_migration) if (adapter !is SourceAdapter) { adapter = SourceAdapter(this) - migration_recycler.adapter = adapter + binding.migrationRecycler.adapter = adapter } adapter?.updateDataSet(state.sourcesWithManga) } else { title = state.selectedSource.toString() if (adapter !is MangaAdapter) { adapter = MangaAdapter(this) - migration_recycler.adapter = adapter + binding.migrationRecycler.adapter = adapter } adapter?.updateDataSet(state.mangaForSource) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 39aaa6909..9263fbcf8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -84,9 +84,6 @@ import uy.kohesive.injekt.injectLazy @RequiresPresenter(ReaderPresenter::class) class ReaderActivity : BaseRxActivity() { - /** - * Preferences helper. - */ private val preferences by injectLazy() /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt index 3978015bb..bf7318791 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt @@ -38,9 +38,6 @@ import uy.kohesive.injekt.injectLazy */ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDialog(activity) { - /** - * Preferences helper. - */ private val preferences by injectLazy() init { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryController.kt index 06989eec3..99701a95a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryController.kt @@ -8,6 +8,7 @@ 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.databinding.HistoryControllerBinding import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.RootController @@ -15,8 +16,6 @@ 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.system.toast -import kotlinx.android.synthetic.main.history_controller.empty_view -import kotlinx.android.synthetic.main.history_controller.recycler /** * Fragment that shows recently read manga. @@ -38,6 +37,8 @@ class HistoryController : NucleusController(), var adapter: HistoryAdapter? = null private set + private lateinit var binding: HistoryControllerBinding + override fun getTitle(): String? { return resources?.getString(R.string.label_recent_manga) } @@ -47,7 +48,8 @@ class HistoryController : NucleusController(), } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.history_controller, container, false) + binding = HistoryControllerBinding.inflate(inflater) + return binding.root } /** @@ -59,10 +61,10 @@ class HistoryController : NucleusController(), super.onViewCreated(view) // Initialize adapter - recycler.layoutManager = LinearLayoutManager(view.context) + binding.recycler.layoutManager = LinearLayoutManager(view.context) adapter = HistoryAdapter(this@HistoryController) - recycler.setHasFixedSize(true) - recycler.adapter = adapter + binding.recycler.setHasFixedSize(true) + binding.recycler.adapter = adapter } override fun onDestroyView(view: View) { @@ -81,9 +83,9 @@ class HistoryController : NucleusController(), override fun onUpdateEmptyView(size: Int) { if (size > 0) { - empty_view.hide() + binding.emptyView.hide() } else { - empty_view.show(R.string.information_no_recent_manga) + binding.emptyView.show(R.string.information_no_recent_manga) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt index 2494381b4..bc0535e04 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt @@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.notification.Notifications +import eu.kanade.tachiyomi.databinding.UpdatesControllerBinding import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.RootController @@ -28,10 +29,6 @@ import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.util.system.notificationManager import eu.kanade.tachiyomi.util.system.toast -import kotlinx.android.synthetic.main.updates_controller.action_toolbar -import kotlinx.android.synthetic.main.updates_controller.empty_view -import kotlinx.android.synthetic.main.updates_controller.recycler -import kotlinx.android.synthetic.main.updates_controller.swipe_refresh import timber.log.Timber /** @@ -60,6 +57,8 @@ class UpdatesController : NucleusController(), var adapter: UpdatesAdapter? = null private set + private lateinit var binding: UpdatesControllerBinding + init { setHasOptionsMenu(true) } @@ -73,7 +72,8 @@ class UpdatesController : NucleusController(), } override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { - return inflater.inflate(R.layout.updates_controller, container, false) + binding = UpdatesControllerBinding.inflate(inflater) + return binding.root } /** @@ -83,32 +83,33 @@ class UpdatesController : NucleusController(), override fun onViewCreated(view: View) { super.onViewCreated(view) view.context.notificationManager.cancel(Notifications.ID_NEW_CHAPTERS) + // Init RecyclerView and adapter val layoutManager = LinearLayoutManager(view.context) - recycler.layoutManager = layoutManager - recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL)) - recycler.setHasFixedSize(true) + binding.recycler.layoutManager = layoutManager + binding.recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL)) + binding.recycler.setHasFixedSize(true) adapter = UpdatesAdapter(this@UpdatesController) - recycler.adapter = adapter + binding.recycler.adapter = adapter - recycler.scrollStateChanges().subscribeUntilDestroy { + binding.recycler.scrollStateChanges().subscribeUntilDestroy { // Disable swipe refresh when view is not at the top val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition() - swipe_refresh.isEnabled = firstPos <= 0 + binding.swipeRefresh.isEnabled = firstPos <= 0 } - swipe_refresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt()) - swipe_refresh.refreshes().subscribeUntilDestroy { + binding.swipeRefresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt()) + binding.swipeRefresh.refreshes().subscribeUntilDestroy { updateLibrary() // It can be a very long operation, so we disable swipe refresh and show a toast. - swipe_refresh.isRefreshing = false + binding.swipeRefresh.isRefreshing = false } } override fun onDestroyView(view: View) { destroyActionModeIfNeeded() - action_toolbar.destroy() + binding.actionToolbar.destroy() adapter = null super.onDestroyView(view) } @@ -167,7 +168,7 @@ class UpdatesController : NucleusController(), override fun onItemLongClick(position: Int) { if (actionMode == null) { actionMode = (activity as AppCompatActivity).startSupportActionMode(this) - action_toolbar.show( + binding.actionToolbar.show( actionMode!!, R.menu.updates_chapter_selection ) { onActionItemClicked(actionMode!!, it!!) } @@ -215,9 +216,9 @@ class UpdatesController : NucleusController(), override fun onUpdateEmptyView(size: Int) { if (size > 0) { - empty_view?.hide() + binding.emptyView.hide() } else { - empty_view?.show(R.string.information_no_recent) + binding.emptyView.show(R.string.information_no_recent) } } @@ -234,7 +235,7 @@ class UpdatesController : NucleusController(), * @param download [Download] object containing download progress. */ private fun getHolder(download: Download): UpdatesHolder? { - return recycler?.findViewHolderForItemId(download.chapter.id!!) as? UpdatesHolder + return binding.recycler.findViewHolderForItemId(download.chapter.id!!) as? UpdatesHolder } /** @@ -321,10 +322,10 @@ class UpdatesController : NucleusController(), mode.title = count.toString() val chapters = getSelectedChapters() - action_toolbar.findItem(R.id.action_download)?.isVisible = chapters.any { !it.isDownloaded } - action_toolbar.findItem(R.id.action_delete)?.isVisible = chapters.any { it.isDownloaded } - action_toolbar.findItem(R.id.action_mark_as_read)?.isVisible = chapters.any { !it.chapter.read } - action_toolbar.findItem(R.id.action_mark_as_unread)?.isVisible = chapters.all { it.chapter.read } + binding.actionToolbar.findItem(R.id.action_download)?.isVisible = chapters.any { !it.isDownloaded } + binding.actionToolbar.findItem(R.id.action_delete)?.isVisible = chapters.any { it.isDownloaded } + binding.actionToolbar.findItem(R.id.action_mark_as_read)?.isVisible = chapters.any { !it.chapter.read } + binding.actionToolbar.findItem(R.id.action_mark_as_unread)?.isVisible = chapters.all { it.chapter.read } } return false @@ -354,7 +355,7 @@ class UpdatesController : NucleusController(), * @param mode the ActionMode object */ override fun onDestroyActionMode(mode: ActionMode?) { - action_toolbar.hide() + binding.actionToolbar.hide() adapter?.mode = SelectableAdapter.Mode.IDLE adapter?.clearSelection() actionMode = null diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt index d0508cb8b..730b09dcf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt @@ -16,14 +16,8 @@ import uy.kohesive.injekt.injectLazy @Suppress("DEPRECATION") object LocaleHelper { - /** - * Preferences helper. - */ private val preferences: PreferencesHelper by injectLazy() - /** - * The system's locale. - */ private var systemLocale: Locale? = null /**