From 75b3ea0bc93eb64cf9b6dc9f1a0173925e620640 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Tue, 1 Dec 2020 07:45:11 +0200 Subject: [PATCH] Migrate to ViewBinding --- app/build.gradle | 15 +-- .../kotatsu/base/domain/MangaUtils.kt | 1 - .../kotatsu/base/ui/AlertDialogFragment.kt | 30 +++-- .../koitharu/kotatsu/base/ui/BaseActivity.kt | 14 ++- .../kotatsu/base/ui/BaseBottomSheet.kt | 22 +++- .../koitharu/kotatsu/base/ui/BaseFragment.kt | 34 ++++-- .../kotatsu/base/ui/BaseFullscreenActivity.kt | 3 +- .../base/ui/dialog/CheckBoxAlertDialog.kt | 17 +-- .../base/ui/dialog/StorageSelectDialog.kt | 8 +- .../kotatsu/base/ui/dialog/TextInputDialog.kt | 24 ++-- .../kotatsu/base/ui/list/BaseViewHolder.kt | 15 +-- .../kotatsu/base/ui/list/ProgressBarHolder.kt | 34 ------ .../kotatsu/browser/BrowserActivity.kt | 27 ++-- .../browser/cloudflare/CloudFlareDialog.kt | 28 +++-- .../kotatsu/core/github/AppVersion.kt | 2 +- .../koitharu/kotatsu/core/github/VersionId.kt | 2 - .../kotatsu/core/model/FavouriteCategory.kt | 2 +- .../org/koitharu/kotatsu/core/model/Manga.kt | 2 +- .../kotatsu/core/model/MangaChapter.kt | 2 +- .../kotatsu/core/model/MangaFilter.kt | 2 +- .../kotatsu/core/model/MangaHistory.kt | 2 +- .../koitharu/kotatsu/core/model/MangaPage.kt | 2 +- .../kotatsu/core/model/MangaSource.kt | 2 +- .../koitharu/kotatsu/core/model/MangaTag.kt | 2 +- .../kotatsu/core/model/MangaTracking.kt | 2 +- .../kotatsu/core/model/TrackingLogItem.kt | 2 +- .../network/cookies/PersistentCookieJar.kt | 2 - .../cookies/cache/IdentifiableCookie.kt | 1 - .../cookies/persistence/SerializableCookie.kt | 2 - .../kotatsu/core/prefs/SourceSettings.kt | 1 - .../koitharu/kotatsu/core/ui/CrashActivity.kt | 17 +-- .../koitharu/kotatsu/details/DetailsModule.kt | 2 +- .../kotatsu/details/ui/ChaptersFragment.kt | 27 ++-- .../kotatsu/details/ui/DetailsActivity.kt | 24 ++-- .../kotatsu/details/ui/DetailsFragment.kt | 115 ++++++++++-------- .../details/ui/adapter/ChapterListItemAD.kt | 28 +++-- .../kotatsu/download/DownloadNotification.kt | 1 - .../kotatsu/download/DownloadService.kt | 4 +- .../kotatsu/favourites/FavouritesModule.kt | 2 +- .../ui/FavouritesContainerFragment.kt | 27 ++-- .../ui/categories/CategoriesActivity.kt | 25 ++-- .../favourites/ui/categories/CategoryAD.kt | 15 +-- .../select/FavouriteCategoriesDialog.kt | 17 ++- .../select/adapter/MangaCaegoryAD.kt | 15 +-- .../ui/list/FavouritesListFragment.kt | 7 +- .../koitharu/kotatsu/history/HistoryModule.kt | 2 +- .../kotatsu/history/ui/HistoryListFragment.kt | 12 +- .../kotatsu/list/ui/ListModeSelectDialog.kt | 25 ++-- .../kotatsu/list/ui/MangaListFragment.kt | 102 +++++++++------- .../kotatsu/list/ui/MangaListSheet.kt | 73 ++++++----- .../list/ui/adapter/MangaGridItemAD.kt | 14 ++- .../ui/adapter/MangaListDetailedItemAD.kt | 20 +-- .../list/ui/adapter/MangaListItemAD.kt | 16 +-- .../kotatsu/list/ui/filter/FilterAdapter.kt | 4 +- .../list/ui/filter/FilterSortHolder.kt | 12 +- .../kotatsu/list/ui/filter/FilterTagHolder.kt | 11 +- .../org/koitharu/kotatsu/local/LocalModule.kt | 2 +- .../kotatsu/local/ui/LocalListFragment.kt | 15 +-- .../org/koitharu/kotatsu/main/MainModule.kt | 2 +- .../koitharu/kotatsu/main/ui/MainActivity.kt | 56 +++++---- .../main/ui/protect/ProtectActivity.kt | 23 ++-- .../koitharu/kotatsu/reader/ReaderModule.kt | 2 +- .../kotatsu/reader/ui/ChaptersDialog.kt | 15 ++- .../kotatsu/reader/ui/ReaderActivity.kt | 59 ++++----- .../kotatsu/reader/ui/ReaderConfigDialog.kt | 25 ++-- .../koitharu/kotatsu/reader/ui/ReaderState.kt | 2 +- .../reader/ui/SimpleSettingsActivity.kt | 5 +- .../kotatsu/reader/ui/base/AbstractReader.kt | 24 ++-- .../reader/ui/base/BaseReaderAdapter.kt | 10 +- .../kotatsu/reader/ui/base/ReaderPage.kt | 2 +- .../reader/ui/reversed/ReversedPageHolder.kt | 65 +++++----- .../ui/reversed/ReversedPagesAdapter.kt | 2 +- .../ui/reversed/ReversedReaderFragment.kt | 42 ++++--- .../kotatsu/reader/ui/standard/PageHolder.kt | 66 +++++----- .../reader/ui/standard/PagerReaderFragment.kt | 38 +++--- .../ui/thumbnails/PageThumbnailHolder.kt | 58 --------- .../ui/thumbnails/PagesThumbnailsSheet.kt | 52 ++++---- .../ui/thumbnails/adapter/PageThumbnailAD.kt | 18 +-- .../kotatsu/reader/ui/wetoon/WebtoonHolder.kt | 58 +++++---- .../reader/ui/wetoon/WebtoonReaderFragment.kt | 40 +++--- .../kotatsu/remotelist/RemoteListModule.kt | 2 +- .../remotelist/ui/RemoteListFragment.kt | 2 +- .../koitharu/kotatsu/search/SearchModule.kt | 2 +- .../kotatsu/search/ui/MangaSearchSheet.kt | 2 +- .../kotatsu/search/ui/SearchActivity.kt | 30 ++--- .../kotatsu/search/ui/SearchFragment.kt | 2 +- .../kotatsu/search/ui/SearchHelper.kt | 1 - .../search/ui/global/GlobalSearchActivity.kt | 5 +- .../search/ui/global/GlobalSearchFragment.kt | 2 +- .../kotatsu/settings/SettingsActivity.kt | 5 +- .../kotatsu/settings/SettingsModule.kt | 2 +- .../settings/backup/BackupDialogFragment.kt | 19 ++- .../settings/backup/BackupSettingsFragment.kt | 3 +- .../settings/backup/RestoreDialogFragment.kt | 19 ++- .../settings/sources/SourceViewHolder.kt | 12 +- .../settings/sources/SourcesAdapter.kt | 7 +- .../sources/SourcesSettingsFragment.kt | 21 +++- .../koitharu/kotatsu/tracker/TrackerModule.kt | 2 +- .../kotatsu/tracker/ui/FeedFragment.kt | 83 +++++++------ .../kotatsu/tracker/ui/adapter/FeedItemAD.kt | 18 +-- .../koitharu/kotatsu/utils/FileSizeUtils.kt | 3 - .../kotatsu/utils/MediaStoreCompat.kt | 1 - .../kotatsu/utils/progress/Progress.kt | 2 +- .../kotatsu/widget/AppWidgetModule.kt | 2 +- .../widget/shelf/ShelfConfigActivity.kt | 18 +-- .../shelf/adapter/CategorySelectItemAD.kt | 14 ++- .../main/res/layout/fragment_cloudflare.xml | 5 +- ...agment_tracklogs.xml => fragment_feed.xml} | 0 108 files changed, 1004 insertions(+), 880 deletions(-) delete mode 100644 app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarHolder.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PageThumbnailHolder.kt rename app/src/main/res/layout/{fragment_tracklogs.xml => fragment_feed.xml} (100%) diff --git a/app/build.gradle b/app/build.gradle index 5c8844638..c4a70b3b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,9 +1,8 @@ plugins { id 'com.android.application' id 'kotlin-android' - id 'kotlin-android-extensions' id 'kotlin-kapt' - // TODO id 'kotlin-parcelize' + id 'kotlin-parcelize' } def gitCommits = 'git rev-list --count HEAD'.execute([], rootDir).text.trim().toInteger() @@ -40,6 +39,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + buildFeatures { + viewBinding true + } lintOptions { disable 'MissingTranslation' abortOnError false @@ -49,9 +51,6 @@ android { unitTests.returnDefaultValues = true } } -androidExtensions { - experimental = true -} tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { kotlinOptions { jvmTarget = JavaVersion.VERSION_1_8.toString() @@ -73,13 +72,15 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-beta01' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0-beta01' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0-beta01' + implementation 'androidx.lifecycle:lifecycle-service:2.3.0-beta01' + implementation 'androidx.lifecycle:lifecycle-process:2.3.0-beta01' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha06' implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01' implementation 'androidx.preference:preference-ktx:1.1.1' implementation 'androidx.work:work-runtime-ktx:2.4.0' - implementation 'com.google.android.material:material:1.3.0-alpha03' + implementation 'com.google.android.material:material:1.3.0-alpha04' //noinspection LifecycleAnnotationProcessorWithJava8 kapt 'androidx.lifecycle:lifecycle-compiler:2.3.0-beta01' @@ -92,7 +93,7 @@ dependencies { implementation 'org.jsoup:jsoup:1.13.1' implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl:4.3.0' - implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl-layoutcontainer:4.3.0' + implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:4.3.0' implementation 'org.koin:koin-android:2.2.0' implementation 'org.koin:koin-android-viewmodel:2.2.0' diff --git a/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt index cce8023f2..03559794d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt @@ -53,7 +53,6 @@ object MangaUtils : KoinComponent { } } - @JvmStatic private fun getBitmapSize(input: InputStream?): Size { val options = BitmapFactory.Options().apply { inJustDecodeBounds = true diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/AlertDialogFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/AlertDialogFragment.kt index 08f80ed88..c241c0b51 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/AlertDialogFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/AlertDialogFragment.kt @@ -2,39 +2,43 @@ package org.koitharu.kotatsu.base.ui import android.app.Dialog import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.annotation.CallSuper -import androidx.annotation.LayoutRes import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment +import androidx.viewbinding.ViewBinding -abstract class AlertDialogFragment( - @LayoutRes private val layoutResId: Int -) : DialogFragment() { +abstract class AlertDialogFragment : DialogFragment() { - private var rootView: View? = null + private var viewBinding: B? = null + + protected val binding: B + get() = checkNotNull(viewBinding) final override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val view = activity?.layoutInflater?.inflate(layoutResId, null) - rootView = view - if (view != null) { - onViewCreated(view, savedInstanceState) - } + val inflater = activity?.layoutInflater ?: LayoutInflater.from(requireContext()) + val binding = onInflateView(inflater, null) + viewBinding = binding + onViewCreated(binding.root, savedInstanceState) return AlertDialog.Builder(requireContext(), theme) - .setView(view) + .setView(binding.root) .also(::onBuildDialog) .create() } @CallSuper override fun onDestroyView() { - rootView = null + viewBinding = null super.onDestroyView() } final override fun getView(): View? { - return rootView + return viewBinding?.root } open fun onBuildDialog(builder: AlertDialog.Builder) = Unit + + protected abstract fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): B } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt index 535cfaf86..e8719eb19 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt @@ -7,12 +7,16 @@ import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.core.app.ActivityCompat +import androidx.viewbinding.ViewBinding import org.koin.android.ext.android.get import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings -abstract class BaseActivity : AppCompatActivity() { +abstract class BaseActivity : AppCompatActivity() { + + protected lateinit var binding: B + private set override fun onCreate(savedInstanceState: Bundle?) { if (get().isAmoledTheme) { @@ -21,16 +25,24 @@ abstract class BaseActivity : AppCompatActivity() { super.onCreate(savedInstanceState) } + @Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR) override fun setContentView(layoutResID: Int) { super.setContentView(layoutResID) setupToolbar() } + @Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR) override fun setContentView(view: View?) { super.setContentView(view) setupToolbar() } + protected fun setContentView(binding: B) { + this.binding = binding + super.setContentView(binding.root) + (binding.root.findViewById(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar) + } + private fun setupToolbar() { (findViewById(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar) } diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt index 81eaeb5b7..4d9d55049 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt @@ -5,23 +5,39 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.annotation.LayoutRes import androidx.appcompat.app.AppCompatDialog +import androidx.viewbinding.ViewBinding import com.google.android.material.bottomsheet.BottomSheetDialogFragment import org.koitharu.kotatsu.utils.UiUtils -abstract class BaseBottomSheet(@LayoutRes private val layoutResId: Int) : +abstract class BaseBottomSheet : BottomSheetDialogFragment() { + private var viewBinding: B? = null + + protected val binding: B + get() = checkNotNull(viewBinding) + final override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? = inflater.inflate(layoutResId, container, false) + ): View { + val binding = onInflateView(inflater, container) + viewBinding = binding + return binding.root + } + + override fun onDestroyView() { + viewBinding = null + super.onDestroyView() + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return if (UiUtils.isTablet(requireContext())) { AppCompatDialog(context, theme) } else super.onCreateDialog(savedInstanceState) } + + protected abstract fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): B } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt index 398f85cf8..a70c514fd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt @@ -1,19 +1,39 @@ package org.koitharu.kotatsu.base.ui import android.content.Context -import androidx.annotation.LayoutRes +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import androidx.fragment.app.Fragment -import coil.ImageLoader -import org.koin.android.ext.android.inject +import androidx.viewbinding.ViewBinding -abstract class BaseFragment( - @LayoutRes contentLayoutId: Int -) : Fragment(contentLayoutId) { +abstract class BaseFragment : Fragment() { - protected val coil by inject() + private var viewBinding: B? = null + + protected val binding: B + get() = checkNotNull(viewBinding) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val binding = onInflateView(inflater, container) + viewBinding = binding + return binding.root + } + + override fun onDestroyView() { + viewBinding = null + super.onDestroyView() + } open fun getTitle(): CharSequence? = null + protected abstract fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): B + override fun onAttach(context: Context) { super.onAttach(context) getTitle()?.let { diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt index 481e54318..c84852181 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt @@ -5,9 +5,10 @@ import android.os.Build import android.os.Bundle import android.view.View import android.view.WindowManager +import androidx.viewbinding.ViewBinding -abstract class BaseFullscreenActivity : BaseActivity() { +abstract class BaseFullscreenActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/CheckBoxAlertDialog.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/CheckBoxAlertDialog.kt index ec9ad0567..ef059eff7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/CheckBoxAlertDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/CheckBoxAlertDialog.kt @@ -1,14 +1,12 @@ package org.koitharu.kotatsu.base.ui.dialog -import android.annotation.SuppressLint import android.content.Context import android.content.DialogInterface import android.view.LayoutInflater import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog -import com.google.android.material.checkbox.MaterialCheckBox -import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.databinding.DialogCheckboxBinding class CheckBoxAlertDialog private constructor(private val delegate: AlertDialog) : DialogInterface by delegate { @@ -17,13 +15,10 @@ class CheckBoxAlertDialog private constructor(private val delegate: AlertDialog) class Builder(context: Context) { - @SuppressLint("InflateParams") - private val view = LayoutInflater.from(context) - .inflate(R.layout.dialog_checkbox, null, false) - private val checkBox = view.findViewById(android.R.id.checkbox) + private val binding = DialogCheckboxBinding.inflate(LayoutInflater.from(context)) private val delegate = AlertDialog.Builder(context) - .setView(view) + .setView(binding.root) fun setTitle(@StringRes titleResId: Int): Builder { delegate.setTitle(titleResId) @@ -46,12 +41,12 @@ class CheckBoxAlertDialog private constructor(private val delegate: AlertDialog) } fun setCheckBoxText(@StringRes textId: Int): Builder { - checkBox.setText(textId) + binding.checkbox.setText(textId) return this } fun setCheckBoxChecked(isChecked: Boolean): Builder { - checkBox.isChecked = isChecked + binding.checkbox.isChecked = isChecked return this } @@ -65,7 +60,7 @@ class CheckBoxAlertDialog private constructor(private val delegate: AlertDialog) listener: (DialogInterface, Boolean) -> Unit ): Builder { delegate.setPositiveButton(textId) { dialog, _ -> - listener(dialog, checkBox.isChecked) + listener(dialog, binding.checkbox.isChecked) } return this } diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt index ae66acca8..5b843358f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt @@ -7,8 +7,8 @@ import android.view.ViewGroup import android.widget.BaseAdapter import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.item_storage.view.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.databinding.ItemStorageBinding import org.koitharu.kotatsu.local.domain.LocalMangaRepository import org.koitharu.kotatsu.utils.ext.getStorageName import org.koitharu.kotatsu.utils.ext.inflate @@ -64,8 +64,9 @@ class StorageSelectDialog private constructor(private val delegate: AlertDialog) override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val view = convertView ?: parent.inflate(R.layout.item_storage) val item = volumes[position] - view.textView_title.text = item.second - view.textView_subtitle.text = item.first.path + val binding = ItemStorageBinding.bind(view) + binding.textViewTitle.text = item.second + binding.textViewSubtitle.text = item.first.path return view } @@ -84,7 +85,6 @@ class StorageSelectDialog private constructor(private val delegate: AlertDialog) private companion object { - @JvmStatic fun getAvailableVolumes(context: Context): List> { return LocalMangaRepository.getAvailableStorageDirs(context).map { it to it.getStorageName(context) diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/TextInputDialog.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/TextInputDialog.kt index 159c52786..73a3f8d4c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/TextInputDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/TextInputDialog.kt @@ -1,14 +1,12 @@ package org.koitharu.kotatsu.base.ui.dialog -import android.annotation.SuppressLint import android.content.Context import android.content.DialogInterface import android.text.InputFilter import android.view.LayoutInflater import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.dialog_input.view.* -import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.databinding.DialogInputBinding class TextInputDialog private constructor( private val delegate: AlertDialog @@ -18,12 +16,10 @@ class TextInputDialog private constructor( class Builder(context: Context) { - @SuppressLint("InflateParams") - private val view = LayoutInflater.from(context) - .inflate(R.layout.dialog_input, null, false) + private val binding = DialogInputBinding.inflate(LayoutInflater.from(context)) private val delegate = AlertDialog.Builder(context) - .setView(view) + .setView(binding.root) fun setTitle(@StringRes titleResId: Int): Builder { delegate.setTitle(titleResId) @@ -36,29 +32,29 @@ class TextInputDialog private constructor( } fun setHint(@StringRes hintResId: Int): Builder { - view.inputLayout.hint = view.context.getString(hintResId) + binding.inputLayout.hint = binding.root.context.getString(hintResId) return this } fun setMaxLength(maxLength: Int, strict: Boolean): Builder { - with(view.inputLayout) { + with(binding.inputLayout) { counterMaxLength = maxLength isCounterEnabled = maxLength > 0 } if (strict && maxLength > 0) { - view.inputEdit.filters += InputFilter.LengthFilter(maxLength) + binding.inputEdit.filters += InputFilter.LengthFilter(maxLength) } return this } fun setInputType(inputType: Int): Builder { - view.inputEdit.inputType = inputType + binding.inputEdit.inputType = inputType return this } fun setText(text: String): Builder { - view.inputEdit.setText(text) - view.inputEdit.setSelection(text.length) + binding.inputEdit.setText(text) + binding.inputEdit.setSelection(text.length) return this } @@ -67,7 +63,7 @@ class TextInputDialog private constructor( listener: (DialogInterface, String) -> Unit ): Builder { delegate.setPositiveButton(textId) { dialog, _ -> - listener(dialog, view.inputEdit.text?.toString().orEmpty()) + listener(dialog, binding.inputEdit.text.toString().orEmpty()) } return this } diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseViewHolder.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseViewHolder.kt index 0d4b629a5..cdbbd00d5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseViewHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseViewHolder.kt @@ -1,20 +1,11 @@ package org.koitharu.kotatsu.base.ui.list -import android.view.View -import android.view.ViewGroup -import androidx.annotation.LayoutRes import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.extensions.LayoutContainer +import androidx.viewbinding.ViewBinding import org.koin.core.component.KoinComponent -import org.koitharu.kotatsu.utils.ext.inflate -abstract class BaseViewHolder protected constructor(view: View) : - RecyclerView.ViewHolder(view), LayoutContainer, KoinComponent { - - constructor(parent: ViewGroup, @LayoutRes resId: Int) : this(parent.inflate(resId)) - - override val containerView: View? - get() = itemView +abstract class BaseViewHolder protected constructor(val binding: B) : + RecyclerView.ViewHolder(binding.root), KoinComponent { var boundData: T? = null private set diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarHolder.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarHolder.kt deleted file mode 100644 index bb940b180..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarHolder.kt +++ /dev/null @@ -1,34 +0,0 @@ -package org.koitharu.kotatsu.base.ui.list - -import android.view.View -import android.view.ViewGroup -import kotlinx.android.synthetic.main.item_progress.* -import org.koitharu.kotatsu.R - -class ProgressBarHolder(parent: ViewGroup) : - BaseViewHolder(parent, R.layout.item_progress) { - - private var pendingVisibility: Int = View.GONE - private val action = Runnable { - progressBar?.visibility = pendingVisibility - pendingVisibility = View.GONE - } - - override fun onBind(data: Boolean, extra: Unit) { - val visibility = if (data) { - View.VISIBLE - } else { - View.INVISIBLE - } - if (visibility != progressBar.visibility && visibility != pendingVisibility) { - progressBar.removeCallbacks(action) - pendingVisibility = visibility - progressBar.postDelayed(action, 400) - } - } - - override fun onRecycled() { - progressBar.removeCallbacks(action) - super.onRecycled() - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt index 5ee23f338..0839ef204 100644 --- a/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt @@ -9,29 +9,29 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.core.view.isVisible -import kotlinx.android.synthetic.main.activity_browser.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity +import org.koitharu.kotatsu.databinding.ActivityBrowserBinding @SuppressLint("SetJavaScriptEnabled") -class BrowserActivity : BaseActivity(), BrowserCallback { +class BrowserActivity : BaseActivity(), BrowserCallback { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_browser) + setContentView(ActivityBrowserBinding.inflate(layoutInflater)) supportActionBar?.run { setDisplayHomeAsUpEnabled(true) setHomeAsUpIndicator(R.drawable.ic_cross) } - with(webView.settings) { + with(binding.webView.settings) { javaScriptEnabled = true } - webView.webViewClient = BrowserClient(this) + binding.webView.webViewClient = BrowserClient(this) val url = intent?.dataString if (url.isNullOrEmpty()) { finishAfterTransition() } else { - webView.loadUrl(url) + binding.webView.loadUrl(url) } } @@ -42,13 +42,13 @@ class BrowserActivity : BaseActivity(), BrowserCallback { override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { android.R.id.home -> { - webView.stopLoading() + binding.webView.stopLoading() finishAfterTransition() true } R.id.action_browser -> { val intent = Intent(Intent.ACTION_VIEW) - intent.data = Uri.parse(webView.url) + intent.data = Uri.parse(binding.webView.url) try { startActivity(Intent.createChooser(intent, item.title)) } catch (_: ActivityNotFoundException) { @@ -59,25 +59,25 @@ class BrowserActivity : BaseActivity(), BrowserCallback { } override fun onBackPressed() { - if (webView.canGoBack()) { - webView.goBack() + if (binding.webView.canGoBack()) { + binding.webView.goBack() } else { super.onBackPressed() } } override fun onPause() { - webView.onPause() + binding.webView.onPause() super.onPause() } override fun onResume() { super.onResume() - webView.onResume() + binding.webView.onResume() } override fun onLoadingStateChanged(isLoading: Boolean) { - progressBar.isVisible = isLoading + binding.progressBar.isVisible = isLoading } override fun onTitleChanged(title: CharSequence, subtitle: CharSequence?) { @@ -87,7 +87,6 @@ class BrowserActivity : BaseActivity(), BrowserCallback { companion object { - @JvmStatic fun newIntent(context: Context, url: String) = Intent(context, BrowserActivity::class.java) .setData(Uri.parse(url)) } diff --git a/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareDialog.kt b/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareDialog.kt index e34ef8ff1..a3464e778 100644 --- a/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareDialog.kt @@ -2,44 +2,50 @@ package org.koitharu.kotatsu.browser.cloudflare import android.annotation.SuppressLint import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.webkit.CookieManager import android.webkit.WebSettings import androidx.appcompat.app.AlertDialog import androidx.core.view.isInvisible import androidx.swiperefreshlayout.widget.SwipeRefreshLayout -import kotlinx.android.synthetic.main.fragment_cloudflare.* -import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.core.network.UserAgentInterceptor +import org.koitharu.kotatsu.databinding.FragmentCloudflareBinding import org.koitharu.kotatsu.utils.ext.stringArgument import org.koitharu.kotatsu.utils.ext.withArgs -class CloudFlareDialog : AlertDialogFragment(R.layout.fragment_cloudflare), CloudFlareCallback { +class CloudFlareDialog : AlertDialogFragment(), CloudFlareCallback { private val url by stringArgument(ARG_URL) + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentCloudflareBinding.inflate(inflater, container, false) + @SuppressLint("SetJavaScriptEnabled") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - with(webView.settings) { + with(binding.webView.settings) { javaScriptEnabled = true cacheMode = WebSettings.LOAD_DEFAULT domStorageEnabled = true databaseEnabled = true userAgentString = UserAgentInterceptor.userAgent } - webView.webViewClient = CloudFlareClient(this, url.orEmpty()) - CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true) + binding.webView.webViewClient = CloudFlareClient(this, url.orEmpty()) + CookieManager.getInstance().setAcceptThirdPartyCookies(binding.webView, true) if (url.isNullOrEmpty()) { dismissAllowingStateLoss() } else { - webView.loadUrl(url.orEmpty()) + binding.webView.loadUrl(url.orEmpty()) } } override fun onDestroyView() { - webView.stopLoading() + binding.webView.stopLoading() super.onDestroyView() } @@ -49,16 +55,16 @@ class CloudFlareDialog : AlertDialogFragment(R.layout.fragment_cloudflare), Clou override fun onResume() { super.onResume() - webView.onResume() + binding.webView.onResume() } override fun onPause() { - webView.onPause() + binding.webView.onPause() super.onPause() } override fun onPageLoaded() { - progressBar?.isInvisible = true + binding.progressBar.isInvisible = true } override fun onCheckPassed() { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/github/AppVersion.kt b/app/src/main/java/org/koitharu/kotatsu/core/github/AppVersion.kt index c5961a543..ff6babc95 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/github/AppVersion.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/github/AppVersion.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.github import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class AppVersion( diff --git a/app/src/main/java/org/koitharu/kotatsu/core/github/VersionId.kt b/app/src/main/java/org/koitharu/kotatsu/core/github/VersionId.kt index f66dd6381..758dd5f46 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/github/VersionId.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/github/VersionId.kt @@ -32,7 +32,6 @@ data class VersionId( companion object { - @JvmStatic private fun variantWeight(variantType: String) = when (variantType.toLowerCase(Locale.ROOT)) { "a", "alpha" -> 1 @@ -42,7 +41,6 @@ data class VersionId( else -> 0 } - @JvmStatic fun parse(versionName: String): VersionId { val parts = versionName.substringBeforeLast('-').split('.') val variant = versionName.substringAfterLast('-', "") diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/FavouriteCategory.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/FavouriteCategory.kt index 3b69d6c51..5eedf24b8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/FavouriteCategory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/FavouriteCategory.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import java.util.* @Parcelize diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/Manga.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/Manga.kt index 5ef07fe09..b550fdd92 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/Manga.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/Manga.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class Manga( diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaChapter.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaChapter.kt index b97e2bd94..62c27c781 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaChapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaChapter.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class MangaChapter( diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaFilter.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaFilter.kt index 012ded842..68a3b5174 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaFilter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaFilter.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class MangaFilter( diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaHistory.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaHistory.kt index 252fa7d66..eaf04e6c7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaHistory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaHistory.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import java.util.* @Parcelize diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaPage.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaPage.kt index 8fc7fd6d9..8d4a9f7e5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaPage.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaPage.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class MangaPage( diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt index 2e430a652..802485e18 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.koin.core.context.GlobalContext import org.koin.core.error.NoBeanDefFoundException import org.koin.core.qualifier.named diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTag.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTag.kt index aaa871d44..be5aa63d2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTag.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTag.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class MangaTag( diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTracking.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTracking.kt index 7a3841c36..c336599cc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTracking.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTracking.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import java.util.* @Parcelize diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/TrackingLogItem.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/TrackingLogItem.kt index de7adaaa7..ccb69b081 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/TrackingLogItem.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/TrackingLogItem.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import java.util.* @Parcelize diff --git a/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/PersistentCookieJar.kt b/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/PersistentCookieJar.kt index 437a54467..5a61f4c6c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/PersistentCookieJar.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/PersistentCookieJar.kt @@ -73,7 +73,6 @@ class PersistentCookieJar( private companion object { - @JvmStatic fun filterPersistentCookies(cookies: List): List { val persistentCookies: MutableList = ArrayList() for (cookie in cookies) { @@ -84,7 +83,6 @@ class PersistentCookieJar( return persistentCookies } - @JvmStatic fun isCookieExpired(cookie: Cookie): Boolean { return cookie.expiresAt < System.currentTimeMillis() } diff --git a/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/cache/IdentifiableCookie.kt b/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/cache/IdentifiableCookie.kt index 374697c74..0bffe0b09 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/cache/IdentifiableCookie.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/cache/IdentifiableCookie.kt @@ -47,7 +47,6 @@ internal class IdentifiableCookie(val cookie: Cookie) { companion object { - @JvmStatic fun decorateAll(cookies: Collection): List { val identifiableCookies: MutableList = ArrayList(cookies.size) for (cookie in cookies) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/persistence/SerializableCookie.kt b/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/persistence/SerializableCookie.kt index 2feea3450..529313d92 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/persistence/SerializableCookie.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/network/cookies/persistence/SerializableCookie.kt @@ -117,7 +117,6 @@ class SerializableCookie : Serializable { * @param bytes byte array to be converted * @return string containing hex values */ - @JvmStatic private fun byteArrayToHexString(bytes: ByteArray): String { val sb = StringBuilder(bytes.size * 2) for (element in bytes) { @@ -136,7 +135,6 @@ class SerializableCookie : Serializable { * @param hexString string of hex-encoded values * @return decoded byte array */ - @JvmStatic private fun hexStringToByteArray(hexString: String): ByteArray { val len = hexString.length val data = ByteArray(len / 2) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/SourceSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/SourceSettings.kt index 4cc17b280..6ee3d0747 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/SourceSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/SourceSettings.kt @@ -22,7 +22,6 @@ interface SourceSettings { companion object { - @JvmStatic operator fun invoke(context: Context, source: MangaSource): SourceSettings = PrefSourceSettings(context, source) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/ui/CrashActivity.kt b/app/src/main/java/org/koitharu/kotatsu/core/ui/CrashActivity.kt index d68e6ae00..5d7ecda66 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/ui/CrashActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/ui/CrashActivity.kt @@ -8,20 +8,23 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.view.View -import kotlinx.android.synthetic.main.activity_crash.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.databinding.ActivityCrashBinding import org.koitharu.kotatsu.main.ui.MainActivity import org.koitharu.kotatsu.utils.ShareHelper class CrashActivity : Activity(), View.OnClickListener { + private lateinit var binding: ActivityCrashBinding + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_crash) - textView.text = intent.getStringExtra(Intent.EXTRA_TEXT) - button_close.setOnClickListener(this) - button_restart.setOnClickListener(this) - button_report.setOnClickListener(this) + binding = ActivityCrashBinding.inflate(layoutInflater) + setContentView(binding.root) + binding.textView.text = intent.getStringExtra(Intent.EXTRA_TEXT) + binding.buttonClose.setOnClickListener(this) + binding.buttonRestart.setOnClickListener(this) + binding.buttonReport.setOnClickListener(this) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { @@ -32,7 +35,7 @@ class CrashActivity : Activity(), View.OnClickListener { override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_share -> { - ShareHelper.shareText(this, textView.text?.toString() ?: return false) + ShareHelper.shareText(this, binding.textView.text.toString() ?: return false) } else -> return super.onOptionsItemSelected(item) } diff --git a/app/src/main/java/org/koitharu/kotatsu/details/DetailsModule.kt b/app/src/main/java/org/koitharu/kotatsu/details/DetailsModule.kt index 815358e2c..176b50785 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/DetailsModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/DetailsModule.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.details -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.base.domain.MangaIntent import org.koitharu.kotatsu.details.ui.DetailsViewModel diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index 789853318..d6310eae6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -2,28 +2,26 @@ package org.koitharu.kotatsu.details.ui import android.app.ActivityOptions import android.os.Bundle -import android.view.Menu -import android.view.MenuItem -import android.view.View +import android.view.* import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.view.ActionMode import androidx.core.view.isVisible import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.fragment_chapters.* -import org.koin.android.viewmodel.ext.android.sharedViewModel +import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.databinding.FragmentChaptersBinding import org.koitharu.kotatsu.details.ui.adapter.ChaptersAdapter import org.koitharu.kotatsu.details.ui.adapter.ChaptersSelectionDecoration import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.download.DownloadService import org.koitharu.kotatsu.reader.ui.ReaderActivity -class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), +class ChaptersFragment : BaseFragment(), OnListItemClickListener, ActionMode.Callback { private val viewModel by sharedViewModel() @@ -32,11 +30,16 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), private var actionMode: ActionMode? = null private var selectionDecoration: ChaptersSelectionDecoration? = null + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentChaptersBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) chaptersAdapter = ChaptersAdapter(this) selectionDecoration = ChaptersSelectionDecoration(view.context) - with(recyclerView_chapters) { + with(binding.recyclerViewChapters) { addItemDecoration(DividerItemDecoration(view.context, RecyclerView.VERTICAL)) addItemDecoration(selectionDecoration!!) setHasFixedSize(true) @@ -58,7 +61,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), } private fun onLoadingStateChanged(isLoading: Boolean) { - progressBar.isVisible = isLoading + binding.progressBar.isVisible = isLoading } override fun onItemClick(item: MangaChapter, view: View) { @@ -68,7 +71,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), actionMode?.finish() } else { actionMode?.invalidate() - recyclerView_chapters.invalidateItemDecorations() + binding.recyclerViewChapters.invalidateItemDecorations() } return } @@ -94,7 +97,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), } return actionMode?.also { selectionDecoration?.setItemIsChecked(item.id, true) - recyclerView_chapters.invalidateItemDecorations() + binding.recyclerViewChapters.invalidateItemDecorations() it.invalidate() } != null } @@ -113,7 +116,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), R.id.action_select_all -> { val ids = chaptersAdapter?.items?.map { it.chapter.id } ?: return false selectionDecoration?.checkAll(ids) - recyclerView_chapters.invalidateItemDecorations() + binding.recyclerViewChapters.invalidateItemDecorations() mode.invalidate() true } @@ -142,7 +145,7 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), override fun onDestroyActionMode(mode: ActionMode?) { selectionDecoration?.clearSelection() - recyclerView_chapters.invalidateItemDecorations() + binding.recyclerViewChapters.invalidateItemDecorations() actionMode = null } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index 1ee1907f2..8d5ade675 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -16,9 +16,8 @@ import androidx.lifecycle.lifecycleScope import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator -import kotlinx.android.synthetic.main.activity_details.* import kotlinx.coroutines.launch -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R @@ -27,6 +26,7 @@ import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.browser.BrowserActivity import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.databinding.ActivityDetailsBinding import org.koitharu.kotatsu.download.DownloadService import org.koitharu.kotatsu.search.ui.global.GlobalSearchActivity import org.koitharu.kotatsu.utils.MangaShortcut @@ -34,7 +34,8 @@ import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.getThemeColor -class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrategy { +class DetailsActivity : BaseActivity(), + TabLayoutMediator.TabConfigurationStrategy { private val viewModel by viewModel { parametersOf(MangaIntent.from(intent)) @@ -42,10 +43,10 @@ class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrate override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_details) + setContentView(ActivityDetailsBinding.inflate(layoutInflater)) supportActionBar?.setDisplayHomeAsUpEnabled(true) - pager.adapter = MangaDetailsAdapter(this) - TabLayoutMediator(tabs, pager, this).attach() + binding.pager.adapter = MangaDetailsAdapter(this) + TabLayoutMediator(binding.tabs, binding.pager, this).attach() viewModel.manga.observe(this, ::onMangaUpdated) viewModel.newChaptersCount.observe(this, ::onNewChaptersChanged) @@ -71,12 +72,13 @@ class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrate Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show() finishAfterTransition() } else { - Snackbar.make(pager, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG).show() + Snackbar.make(binding.pager, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG) + .show() } } private fun onNewChaptersChanged(newChapters: Int) { - val tab = tabs.getTabAt(1) ?: return + val tab = binding.tabs.getTabAt(1) ?: return if (newChapters == 0) { tab.removeBadge() } else { @@ -171,7 +173,7 @@ class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrate lifecycleScope.launch { if (!MangaShortcut(it).requestPinShortcut(this@DetailsActivity)) { Snackbar.make( - pager, + binding.pager, R.string.operation_not_supported, Snackbar.LENGTH_SHORT ).show() @@ -193,13 +195,13 @@ class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrate override fun onSupportActionModeStarted(mode: ActionMode) { super.onSupportActionModeStarted(mode) - pager.isUserInputEnabled = false + binding.pager.isUserInputEnabled = false window?.statusBarColor = ContextCompat.getColor(this, R.color.grey_dark) } override fun onSupportActionModeFinished(mode: ActionMode) { super.onSupportActionModeFinished(mode) - pager.isUserInputEnabled = true + binding.pager.isUserInputEnabled = true window?.statusBarColor = getThemeColor(androidx.appcompat.R.attr.colorPrimaryDark) } diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt index d6b934876..fbc8f50a6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt @@ -2,20 +2,24 @@ package org.koitharu.kotatsu.details.ui import android.os.Bundle import android.text.Spanned +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.net.toUri import androidx.core.text.parseAsHtml import androidx.core.view.isVisible +import coil.ImageLoader import com.google.android.material.chip.Chip -import kotlinx.android.synthetic.main.fragment_details.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import org.koin.android.viewmodel.ext.android.sharedViewModel +import org.koin.android.ext.android.inject +import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory +import org.koitharu.kotatsu.databinding.FragmentDetailsBinding import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesDialog import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.search.ui.MangaSearchSheet @@ -23,10 +27,16 @@ import org.koitharu.kotatsu.utils.FileSizeUtils import org.koitharu.kotatsu.utils.ext.* import kotlin.math.roundToInt -class DetailsFragment : BaseFragment(R.layout.fragment_details), View.OnClickListener, +class DetailsFragment : BaseFragment(), View.OnClickListener, View.OnLongClickListener { private val viewModel by sharedViewModel() + private val coil by inject() + + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentDetailsBinding.inflate(inflater, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -37,63 +47,66 @@ class DetailsFragment : BaseFragment(R.layout.fragment_details), View.OnClickLis } private fun onMangaUpdated(manga: Manga) { - imageView_cover.newImageRequest(manga.largeCoverUrl ?: manga.coverUrl) - .fallback(R.drawable.ic_placeholder) - .crossfade(true) - .lifecycle(viewLifecycleOwner) - .enqueueWith(coil) - textView_title.text = manga.title - textView_subtitle.textAndVisible = manga.altTitle - textView_description.text = manga.description?.parseAsHtml()?.takeUnless(Spanned::isBlank) - ?: getString(R.string.no_description) - if (manga.rating == Manga.NO_RATING) { - ratingBar.isVisible = false - } else { - ratingBar.progress = (ratingBar.max * manga.rating).roundToInt() - ratingBar.isVisible = true - } - chips_tags.removeAllViews() - manga.author?.let { a -> - chips_tags.addChips(listOf(a)) { - create( - text = it, - iconRes = R.drawable.ic_chip_user, - tag = it, - onClickListener = this@DetailsFragment - ) + with(binding) { + imageViewCover.newImageRequest(manga.largeCoverUrl ?: manga.coverUrl) + .fallback(R.drawable.ic_placeholder) + .crossfade(true) + .lifecycle(viewLifecycleOwner) + .enqueueWith(coil) + textViewTitle.text = manga.title + textViewSubtitle.textAndVisible = manga.altTitle + textViewDescription.text = + manga.description?.parseAsHtml()?.takeUnless(Spanned::isBlank) + ?: getString(R.string.no_description) + if (manga.rating == Manga.NO_RATING) { + ratingBar.isVisible = false + } else { + ratingBar.progress = (ratingBar.max * manga.rating).roundToInt() + ratingBar.isVisible = true } - } - chips_tags.addChips(manga.tags) { - create( - text = it.title, - iconRes = R.drawable.ic_chip_tag, - tag = it, - onClickListener = this@DetailsFragment - ) - } - manga.url.toUri().toFileOrNull()?.let { f -> - viewLifecycleScope.launch { - val size = withContext(Dispatchers.IO) { - f.length() - } - chips_tags.addChips(listOf(f)) { + chipsTags.removeAllViews() + manga.author?.let { a -> + chipsTags.addChips(listOf(a)) { create( - text = FileSizeUtils.formatBytes(context, size), - iconRes = R.drawable.ic_chip_storage, + text = it, + iconRes = R.drawable.ic_chip_user, tag = it, onClickListener = this@DetailsFragment ) } } + chipsTags.addChips(manga.tags) { + create( + text = it.title, + iconRes = R.drawable.ic_chip_tag, + tag = it, + onClickListener = this@DetailsFragment + ) + } + manga.url.toUri().toFileOrNull()?.let { f -> + viewLifecycleScope.launch { + val size = withContext(Dispatchers.IO) { + f.length() + } + chipsTags.addChips(listOf(f)) { + create( + text = FileSizeUtils.formatBytes(context, size), + iconRes = R.drawable.ic_chip_storage, + tag = it, + onClickListener = this@DetailsFragment + ) + } + } + } + imageViewFavourite.setOnClickListener(this@DetailsFragment) + buttonRead.setOnClickListener(this@DetailsFragment) + buttonRead.setOnLongClickListener(this@DetailsFragment) + buttonRead.isEnabled = !manga.chapters.isNullOrEmpty() } - imageView_favourite.setOnClickListener(this) - button_read.setOnClickListener(this) - button_read.setOnLongClickListener(this) - button_read.isEnabled = !manga.chapters.isNullOrEmpty() } private fun onHistoryChanged(history: MangaHistory?) { - with(button_read) { + with(binding.buttonRead) { if (history == null) { setText(R.string.read) setIconResource(R.drawable.ic_read) @@ -105,7 +118,7 @@ class DetailsFragment : BaseFragment(R.layout.fragment_details), View.OnClickLis } private fun onFavouriteChanged(isFavourite: Boolean) { - imageView_favourite.setImageResource( + binding.imageViewFavourite.setImageResource( if (isFavourite) { R.drawable.ic_heart } else { @@ -115,7 +128,7 @@ class DetailsFragment : BaseFragment(R.layout.fragment_details), View.OnClickLis } private fun onLoadingStateChanged(isLoading: Boolean) { - progressBar.isVisible = isLoading + binding.progressBar.isVisible = isLoading } override fun onClick(v: View) { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/adapter/ChapterListItemAD.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/adapter/ChapterListItemAD.kt index afd24ee42..d339216c0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/adapter/ChapterListItemAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/adapter/ChapterListItemAD.kt @@ -1,17 +1,19 @@ package org.koitharu.kotatsu.details.ui.adapter -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import kotlinx.android.synthetic.main.item_chapter.* +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.MangaChapter +import org.koitharu.kotatsu.databinding.ItemChapterBinding import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.history.domain.ChapterExtra import org.koitharu.kotatsu.utils.ext.getThemeColor fun chapterListItemAD( clickListener: OnListItemClickListener -) = adapterDelegateLayoutContainer(R.layout.item_chapter) { +) = adapterDelegateViewBinding( + { inflater, parent -> ItemChapterBinding.inflate(inflater, parent, false) } +) { itemView.setOnClickListener { clickListener.onItemClick(item.chapter, it) @@ -21,24 +23,24 @@ fun chapterListItemAD( } bind { payload -> - textView_title.text = item.chapter.name - textView_number.text = item.chapter.number.toString() + binding.textViewTitle.text = item.chapter.name + binding.textViewNumber.text = item.chapter.number.toString() when (item.extra) { ChapterExtra.UNREAD -> { - textView_number.setBackgroundResource(R.drawable.bg_badge_default) - textView_number.setTextColor(context.getThemeColor(android.R.attr.textColorSecondaryInverse)) + binding.textViewNumber.setBackgroundResource(R.drawable.bg_badge_default) + binding.textViewNumber.setTextColor(context.getThemeColor(android.R.attr.textColorSecondaryInverse)) } ChapterExtra.READ -> { - textView_number.setBackgroundResource(R.drawable.bg_badge_outline) - textView_number.setTextColor(context.getThemeColor(android.R.attr.textColorTertiary)) + binding.textViewNumber.setBackgroundResource(R.drawable.bg_badge_outline) + binding.textViewNumber.setTextColor(context.getThemeColor(android.R.attr.textColorTertiary)) } ChapterExtra.CURRENT -> { - textView_number.setBackgroundResource(R.drawable.bg_badge_outline_accent) - textView_number.setTextColor(context.getThemeColor(androidx.appcompat.R.attr.colorAccent)) + binding.textViewNumber.setBackgroundResource(R.drawable.bg_badge_outline_accent) + binding.textViewNumber.setTextColor(context.getThemeColor(androidx.appcompat.R.attr.colorAccent)) } ChapterExtra.NEW -> { - textView_number.setBackgroundResource(R.drawable.bg_badge_accent) - textView_number.setTextColor(context.getThemeColor(android.R.attr.textColorPrimaryInverse)) + binding.textViewNumber.setBackgroundResource(R.drawable.bg_badge_accent) + binding.textViewNumber.setTextColor(context.getThemeColor(android.R.attr.textColorPrimaryInverse)) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/download/DownloadNotification.kt b/app/src/main/java/org/koitharu/kotatsu/download/DownloadNotification.kt index 387506326..fe7d290b8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/DownloadNotification.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/DownloadNotification.kt @@ -142,7 +142,6 @@ class DownloadNotification(private val context: Context) { private const val PROGRESS_STEP = 20 - @JvmStatic private fun createIntent(context: Context, manga: Manga) = PendingIntent.getActivity( context, manga.hashCode(), diff --git a/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt b/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt index b786e34a6..0b3c3d1b6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt @@ -55,9 +55,9 @@ class DownloadService : BaseService() { .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "kotatsu:downloading") } - override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - when (intent.action) { + when (intent?.action) { ACTION_DOWNLOAD_START -> { val manga = intent.getParcelableExtra(EXTRA_MANGA) val chapters = intent.getLongArrayExtra(EXTRA_CHAPTERS_IDS)?.toArraySet() diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/FavouritesModule.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/FavouritesModule.kt index 926202ea6..c0237f1cf 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/FavouritesModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/FavouritesModule.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.favourites -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.favourites.domain.FavouritesRepository diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt index 7f9ace391..53e879978 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt @@ -1,26 +1,24 @@ package org.koitharu.kotatsu.favourites.ui import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View +import android.view.* import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayoutMediator -import kotlinx.android.synthetic.main.fragment_favourites.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.core.model.FavouriteCategory +import org.koitharu.kotatsu.databinding.FragmentFavouritesBinding import org.koitharu.kotatsu.favourites.ui.categories.CategoriesActivity import org.koitharu.kotatsu.favourites.ui.categories.CategoriesEditDelegate import org.koitharu.kotatsu.favourites.ui.categories.FavouritesCategoriesViewModel +import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.showPopupMenu import java.util.* import kotlin.collections.ArrayList -class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), - FavouritesTabLongClickListener, CategoriesEditDelegate.CategoriesEditCallback { +class FavouritesContainerFragment : BaseFragment(), + FavouritesTabLongClickListener, CategoriesEditDelegate.CategoriesEditCallback { private val viewModel by viewModel() @@ -33,11 +31,16 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), setHasOptionsMenu(true) } + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentFavouritesBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val adapter = FavouritesPagerAdapter(this, this) - pager.adapter = adapter - TabLayoutMediator(tabs, pager, adapter).attach() + binding.pager.adapter = adapter + TabLayoutMediator(binding.tabs, binding.pager, adapter).attach() viewModel.categories.observe(viewLifecycleOwner, ::onCategoriesChanged) viewModel.onError.observe(viewLifecycleOwner, ::onError) @@ -47,7 +50,7 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), val data = ArrayList(categories.size + 1) data += FavouriteCategory(0L, getString(R.string.all_favourites), -1, Date()) data += categories - (pager.adapter as? FavouritesPagerAdapter)?.replaceData(data) + (binding.pager.adapter as? FavouritesPagerAdapter)?.replaceData(data) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -70,7 +73,7 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), } private fun onError(e: Throwable) { - Snackbar.make(pager, e.message ?: return, Snackbar.LENGTH_LONG).show() + Snackbar.make(binding.pager, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG).show() } override fun onTabLongClick(tabView: View, category: FavouriteCategory): Boolean { diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt index d722348a8..9f4b548c6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt @@ -11,16 +11,17 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.activity_categories.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.FavouriteCategory +import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.showPopupMenu -class CategoriesActivity : BaseActivity(), OnListItemClickListener, +class CategoriesActivity : BaseActivity(), + OnListItemClickListener, View.OnClickListener, CategoriesEditDelegate.CategoriesEditCallback { private val viewModel by viewModel() @@ -31,16 +32,16 @@ class CategoriesActivity : BaseActivity(), OnListItemClickListener) { adapter.items = categories - textView_holder.isVisible = categories.isEmpty() + binding.textViewHolder.isVisible = categories.isEmpty() } private fun onError(e: Throwable) { - Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG) + Snackbar.make(binding.recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG) .show() } diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoryAD.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoryAD.kt index 0bfd98070..97b38d926 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoryAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoryAD.kt @@ -1,21 +1,22 @@ package org.koitharu.kotatsu.favourites.ui.categories import android.view.MotionEvent -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import kotlinx.android.synthetic.main.item_category.* -import org.koitharu.kotatsu.R +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.FavouriteCategory +import org.koitharu.kotatsu.databinding.ItemCategoryBinding fun categoryAD( clickListener: OnListItemClickListener -) = adapterDelegateLayoutContainer(R.layout.item_category) { +) = adapterDelegateViewBinding( + { inflater, parent -> ItemCategoryBinding.inflate(inflater, parent, false) } +) { - imageView_more.setOnClickListener { + binding.imageViewMore.setOnClickListener { clickListener.onItemClick(item, it) } @Suppress("ClickableViewAccessibility") - imageView_handle.setOnTouchListener { v, event -> + binding.imageViewHandle.setOnTouchListener { v, event -> if (event.actionMasked == MotionEvent.ACTION_DOWN) { clickListener.onItemLongClick(item, itemView) } else { @@ -24,6 +25,6 @@ fun categoryAD( } bind { - textView_title.text = item.title + binding.textViewTitle.text = item.title } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt index 2754a9264..435944f9f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt @@ -1,11 +1,12 @@ package org.koitharu.kotatsu.favourites.ui.categories.select import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.FragmentManager -import kotlinx.android.synthetic.main.dialog_favorite_categories.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.domain.MangaIntent @@ -13,13 +14,14 @@ import org.koitharu.kotatsu.base.ui.BaseBottomSheet import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.databinding.DialogFavoriteCategoriesBinding import org.koitharu.kotatsu.favourites.ui.categories.CategoriesEditDelegate import org.koitharu.kotatsu.favourites.ui.categories.select.adapter.MangaCategoriesAdapter import org.koitharu.kotatsu.favourites.ui.categories.select.model.MangaCategoryItem import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.withArgs -class FavouriteCategoriesDialog : BaseBottomSheet(R.layout.dialog_favorite_categories), +class FavouriteCategoriesDialog : BaseBottomSheet(), OnListItemClickListener, CategoriesEditDelegate.CategoriesEditCallback, View.OnClickListener { @@ -32,11 +34,16 @@ class FavouriteCategoriesDialog : BaseBottomSheet(R.layout.dialog_favorite_categ CategoriesEditDelegate(requireContext(), this@FavouriteCategoriesDialog) } + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = DialogFavoriteCategoriesBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) adapter = MangaCategoriesAdapter(this) - recyclerView_categories.adapter = adapter - textView_add.setOnClickListener(this) + binding.recyclerViewCategories.adapter = adapter + binding.textViewAdd.setOnClickListener(this) viewModel.content.observe(viewLifecycleOwner, this::onContentChanged) viewModel.onError.observe(viewLifecycleOwner, ::onError) diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCaegoryAD.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCaegoryAD.kt index ae84a47d6..c231cc2cd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCaegoryAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCaegoryAD.kt @@ -1,15 +1,14 @@ package org.koitharu.kotatsu.favourites.ui.categories.select.adapter -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import kotlinx.android.synthetic.main.item_category_checkable.* -import org.koitharu.kotatsu.R +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.databinding.ItemCategoryCheckableBinding import org.koitharu.kotatsu.favourites.ui.categories.select.model.MangaCategoryItem fun mangaCategoryAD( clickListener: OnListItemClickListener -) = adapterDelegateLayoutContainer( - R.layout.item_category_checkable +) = adapterDelegateViewBinding( + { inflater, parent -> ItemCategoryCheckableBinding.inflate(inflater, parent, false) } ) { itemView.setOnClickListener { @@ -17,7 +16,9 @@ fun mangaCategoryAD( } bind { - checkedTextView.text = item.name - checkedTextView.isChecked = item.isChecked + with(binding.checkedTextView) { + text = item.name + isChecked = item.isChecked + } } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt index df3eb9e47..ea19da787 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt @@ -3,8 +3,7 @@ package org.koitharu.kotatsu.favourites.ui.list import android.view.Menu import android.view.MenuInflater import android.view.MenuItem -import kotlinx.android.synthetic.main.fragment_list.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga @@ -25,14 +24,14 @@ class FavouritesListFragment : MangaListFragment() { override fun onScrolledToEnd() = Unit override fun setUpEmptyListHolder() { - textView_holder.setText( + binding.textViewHolder.setText( if (categoryId == 0L) { R.string.you_have_not_favourites_yet } else { R.string.favourites_category_empty } ) - textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) + binding.textViewHolder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) } override fun onCreatePopupMenu(inflater: MenuInflater, menu: Menu, data: Manga) { diff --git a/app/src/main/java/org/koitharu/kotatsu/history/HistoryModule.kt b/app/src/main/java/org/koitharu/kotatsu/history/HistoryModule.kt index fe15db497..28587b063 100644 --- a/app/src/main/java/org/koitharu/kotatsu/history/HistoryModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/HistoryModule.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.history import org.koin.android.ext.koin.androidContext -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.history.domain.HistoryRepository import org.koitharu.kotatsu.history.ui.HistoryListViewModel diff --git a/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt index 1aef5c78f..0e3e4fe70 100644 --- a/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt @@ -7,8 +7,7 @@ import android.view.MenuItem import android.view.View import androidx.appcompat.app.AlertDialog import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_list.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.list.ui.MangaListFragment @@ -36,7 +35,8 @@ class HistoryListFragment : MangaListFragment() { override fun onPrepareOptionsMenu(menu: Menu) { super.onPrepareOptionsMenu(menu) - menu.findItem(R.id.action_history_grouping)?.isChecked = viewModel.isGroupingEnabled.value == true + menu.findItem(R.id.action_history_grouping)?.isChecked = + viewModel.isGroupingEnabled.value == true } override fun onOptionsItemSelected(item: MenuItem): Boolean { @@ -64,8 +64,8 @@ class HistoryListFragment : MangaListFragment() { } override fun setUpEmptyListHolder() { - textView_holder.setText(R.string.text_history_holder) - textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) + binding.textViewHolder.setText(R.string.text_history_holder) + binding.textViewHolder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) } override fun onCreatePopupMenu(inflater: MenuInflater, menu: Menu, data: Manga) { @@ -85,7 +85,7 @@ class HistoryListFragment : MangaListFragment() { private fun onItemRemoved(item: Manga) { Snackbar.make( - recyclerView, getString( + binding.recyclerView, getString( R.string._s_removed_from_history, item.title.ellipsize(16) ), Snackbar.LENGTH_SHORT diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt index 78491def3..c85e571c8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt @@ -1,18 +1,20 @@ package org.koitharu.kotatsu.list.ui import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.SeekBar import androidx.appcompat.app.AlertDialog import androidx.fragment.app.FragmentManager -import kotlinx.android.synthetic.main.dialog_list_mode.* import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ListMode +import org.koitharu.kotatsu.databinding.DialogListModeBinding -class ListModeSelectDialog : AlertDialogFragment(R.layout.dialog_list_mode), View.OnClickListener, +class ListModeSelectDialog : AlertDialogFragment(), View.OnClickListener, SeekBar.OnSeekBarChangeListener { private val settings by inject() @@ -26,6 +28,11 @@ class ListModeSelectDialog : AlertDialogFragment(R.layout.dialog_list_mode), Vie pendingGridSize = settings.gridSize } + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = DialogListModeBinding.inflate(inflater, container, false) + override fun onBuildDialog(builder: AlertDialog.Builder) { builder.setTitle(R.string.list_mode) .setPositiveButton(R.string.done, null) @@ -34,18 +41,18 @@ class ListModeSelectDialog : AlertDialogFragment(R.layout.dialog_list_mode), Vie override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - button_list.isChecked = mode == ListMode.LIST - button_list_detailed.isChecked = mode == ListMode.DETAILED_LIST - button_grid.isChecked = mode == ListMode.GRID + binding.buttonList.isChecked = mode == ListMode.LIST + binding.buttonListDetailed.isChecked = mode == ListMode.DETAILED_LIST + binding.buttonGrid.isChecked = mode == ListMode.GRID - with(seekbar_grid) { + with(binding.seekbarGrid) { progress = pendingGridSize - 50 setOnSeekBarChangeListener(this@ListModeSelectDialog) } - button_list.setOnClickListener(this) - button_grid.setOnClickListener(this) - button_list_detailed.setOnClickListener(this) + binding.buttonList.setOnClickListener(this) + binding.buttonGrid.setOnClickListener(this) + binding.buttonListDetailed.setOnClickListener(this) } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt index a40b68c1d..1bf30cd03 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt @@ -14,7 +14,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_list.* import org.koin.android.ext.android.get import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseFragment @@ -28,6 +27,7 @@ import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaFilter import org.koitharu.kotatsu.core.prefs.ListMode +import org.koitharu.kotatsu.databinding.FragmentListBinding import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.list.ui.adapter.MangaListAdapter import org.koitharu.kotatsu.list.ui.filter.FilterAdapter @@ -37,11 +37,11 @@ import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.hasItems import org.koitharu.kotatsu.utils.ext.toggleDrawer -abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), +abstract class MangaListFragment : BaseFragment(), PaginationScrollListener.Callback, OnListItemClickListener, OnFilterChangedListener, SectionItemDecoration.Callback, SwipeRefreshLayout.OnRefreshListener { - private var adapter: MangaListAdapter? = null + private var listAdapter: MangaListAdapter? = null private var paginationListener: PaginationScrollListener? = null private val spanResolver = MangaListSpanResolver() private val spanSizeLookup = SpanSizeLookup() @@ -54,19 +54,30 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), setHasOptionsMenu(true) } + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentListBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) - adapter = MangaListAdapter(get(), this) + binding.drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) + listAdapter = MangaListAdapter(get(), this) paginationListener = PaginationScrollListener(4, this) - recyclerView.setHasFixedSize(true) - recyclerView.adapter = adapter - recyclerView.addOnScrollListener(paginationListener!!) - swipeRefreshLayout.setOnRefreshListener(this) - swipeRefreshLayout.isEnabled = isSwipeRefreshEnabled - recyclerView_filter.setHasFixedSize(true) - recyclerView_filter.addItemDecoration(ItemTypeDividerDecoration(view.context)) - recyclerView_filter.addItemDecoration(SectionItemDecoration(false, this)) + with(binding.recyclerView) { + setHasFixedSize(true) + adapter = listAdapter + addOnScrollListener(paginationListener!!) + } + with(binding.swipeRefreshLayout) { + setOnRefreshListener(this@MangaListFragment) + isEnabled = isSwipeRefreshEnabled + } + with(binding.recyclerViewFilter) { + setHasFixedSize(true) + addItemDecoration(ItemTypeDividerDecoration(view.context)) + addItemDecoration(SectionItemDecoration(false, this@MangaListFragment)) + } viewModel.content.observe(viewLifecycleOwner, ::onListChanged) viewModel.filter.observe(viewLifecycleOwner, ::onInitFilter) @@ -78,7 +89,7 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), } override fun onDestroyView() { - adapter = null + listAdapter = null paginationListener = null spanSizeLookup.invalidateCache() super.onDestroyView() @@ -95,15 +106,15 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), true } R.id.action_filter -> { - drawer?.toggleDrawer(GravityCompat.END) + binding.drawer?.toggleDrawer(GravityCompat.END) true } else -> super.onOptionsItemSelected(item) } override fun onPrepareOptionsMenu(menu: Menu) { - menu.findItem(R.id.action_filter).isVisible = drawer != null && - drawer?.getDrawerLockMode(GravityCompat.END) != DrawerLayout.LOCK_MODE_LOCKED_CLOSED + menu.findItem(R.id.action_filter).isVisible = binding.drawer != null && + binding.drawer?.getDrawerLockMode(GravityCompat.END) != DrawerLayout.LOCK_MODE_LOCKED_CLOSED super.onPrepareOptionsMenu(menu) } @@ -128,12 +139,12 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), @CallSuper override fun onRefresh() { - swipeRefreshLayout.isRefreshing = true + binding.swipeRefreshLayout.isRefreshing = true } private fun onListChanged(list: List) { spanSizeLookup.invalidateCache() - adapter?.items = list + listAdapter?.items = list } private fun onError(e: Throwable) { @@ -141,27 +152,33 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), CloudFlareDialog.newInstance(e.url).show(childFragmentManager, CloudFlareDialog.TAG) } if (viewModel.isEmptyState.value == true) { - textView_holder.text = e.getDisplayMessage(resources) - textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds( + binding.textViewHolder.text = e.getDisplayMessage(resources) + binding.textViewHolder.setCompoundDrawablesRelativeWithIntrinsicBounds( 0, R.drawable.ic_error_large, 0, 0 ) - layout_holder.isVisible = true + binding.textViewHolder.isVisible = true } else { - Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT) + Snackbar.make( + binding.recyclerView, + e.getDisplayMessage(resources), + Snackbar.LENGTH_SHORT + ) .show() } } @CallSuper protected open fun onLoadingStateChanged(isLoading: Boolean) { - val hasItems = recyclerView.hasItems - progressBar.isVisible = isLoading && !hasItems && viewModel.isEmptyState.value != true - swipeRefreshLayout.isEnabled = isSwipeRefreshEnabled && !progressBar.isVisible + val hasItems = binding.recyclerView.hasItems + binding.progressBar.isVisible = + isLoading && !hasItems && viewModel.isEmptyState.value != true + binding.swipeRefreshLayout.isEnabled = + isSwipeRefreshEnabled && !binding.progressBar.isVisible if (!isLoading) { - swipeRefreshLayout.isRefreshing = false + binding.swipeRefreshLayout.isRefreshing = false } } @@ -169,47 +186,49 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), if (isEmpty) { setUpEmptyListHolder() } - layout_holder.isVisible = isEmpty + binding.layoutHolder.isVisible = isEmpty } protected fun onInitFilter(config: MangaFilterConfig) { - recyclerView_filter.adapter = FilterAdapter( + binding.recyclerViewFilter.adapter = FilterAdapter( sortOrders = config.sortOrders, tags = config.tags, state = config.currentFilter, listener = this ) - drawer?.setDrawerLockMode( + binding.drawer?.setDrawerLockMode( if (config.sortOrders.isEmpty() && config.tags.isEmpty()) { DrawerLayout.LOCK_MODE_LOCKED_CLOSED } else { DrawerLayout.LOCK_MODE_UNLOCKED } - ) ?: divider_filter?.let { + ) ?: binding.dividerFilter?.let { it.isGone = config.sortOrders.isEmpty() && config.tags.isEmpty() - recyclerView_filter.isVisible = it.isVisible + binding.recyclerViewFilter.isVisible = it.isVisible } activity?.invalidateOptionsMenu() } @CallSuper override fun onFilterChanged(filter: MangaFilter) { - drawer?.closeDrawers() + binding.drawer?.closeDrawers() } protected open fun setUpEmptyListHolder() { - textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null) - textView_holder.setText(R.string.nothing_found) + with(binding.textViewHolder) { + setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null) + setText(R.string.nothing_found) + } } private fun onGridScaleChanged(scale: Float) { spanSizeLookup.invalidateCache() - spanResolver.setGridSize(scale, recyclerView) + spanResolver.setGridSize(scale, binding.recyclerView) } private fun onListModeChanged(mode: ListMode) { spanSizeLookup.invalidateCache() - with(recyclerView) { + with(binding.recyclerView) { clearItemDecorations() removeOnLayoutChangeListener(spanResolver) when (mode) { @@ -246,13 +265,13 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), } final override fun isSection(position: Int): Boolean { - return position == 0 || recyclerView_filter.adapter?.run { + return position == 0 || binding.recyclerViewFilter.adapter?.run { getItemViewType(position) != getItemViewType(position - 1) } ?: false } final override fun getSectionTitle(position: Int): CharSequence? { - return when (recyclerView_filter.adapter?.getItemViewType(position)) { + return when (binding.recyclerViewFilter.adapter?.getItemViewType(position)) { FilterAdapter.VIEW_TYPE_SORT -> getString(R.string.sort_order) FilterAdapter.VIEW_TYPE_TAG -> getString(R.string.genre) else -> null @@ -271,8 +290,9 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), } override fun getSpanSize(position: Int): Int { - val total = (recyclerView.layoutManager as? GridLayoutManager)?.spanCount ?: return 1 - return when (adapter?.getItemViewType(position)) { + val total = + (binding.recyclerView.layoutManager as? GridLayoutManager)?.spanCount ?: return 1 + return when (listAdapter?.getItemViewType(position)) { MangaListAdapter.ITEM_TYPE_DATE, MangaListAdapter.ITEM_TYPE_PROGRESS -> total else -> 1 diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListSheet.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListSheet.kt index 77f27887a..4b1c4f324 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListSheet.kt @@ -2,8 +2,10 @@ package org.koitharu.kotatsu.list.ui import android.content.SharedPreferences import android.os.Bundle +import android.view.LayoutInflater import android.view.MenuItem import android.view.View +import android.view.ViewGroup import androidx.appcompat.widget.Toolbar import androidx.core.view.isVisible import androidx.recyclerview.widget.DividerItemDecoration @@ -13,7 +15,6 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.sheet_list.* import org.koin.android.ext.android.get import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R @@ -24,12 +25,13 @@ import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ListMode +import org.koitharu.kotatsu.databinding.SheetListBinding import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.list.ui.adapter.MangaListAdapter import org.koitharu.kotatsu.utils.UiUtils import org.koitharu.kotatsu.utils.ext.* -abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), +abstract class MangaListSheet : BaseBottomSheet(), PaginationScrollListener.Callback, OnListItemClickListener, SharedPreferences.OnSharedPreferenceChangeListener, Toolbar.OnMenuItemClickListener { @@ -39,22 +41,26 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), protected abstract val viewModel: MangaListViewModel + override fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): SheetListBinding { + return SheetListBinding.inflate(inflater, container, false) + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) adapter = MangaListAdapter(get(), this) initListMode(settings.listMode) - recyclerView.adapter = adapter - recyclerView.addOnScrollListener(PaginationScrollListener(4, this)) + binding.recyclerView.adapter = adapter + binding.recyclerView.addOnScrollListener(PaginationScrollListener(4, this)) settings.subscribe(this) - toolbar.inflateMenu(R.menu.opt_list_sheet) - toolbar.setOnMenuItemClickListener(this) - toolbar.setNavigationOnClickListener { + binding.toolbar.inflateMenu(R.menu.opt_list_sheet) + binding.toolbar.setOnMenuItemClickListener(this) + binding.toolbar.setNavigationOnClickListener { dismiss() } if (dialog !is BottomSheetDialog) { - toolbar.isVisible = true - textView_title.isVisible = false - appbar.elevation = resources.getDimension(R.dimen.elevation_large) + binding.toolbar.isVisible = true + binding.textViewTitle.isVisible = false + binding.appbar.elevation = resources.getDimension(R.dimen.elevation_large) } if (savedInstanceState == null) { onScrolledToEnd() @@ -72,12 +78,12 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), } protected fun setTitle(title: CharSequence) { - toolbar.title = title - textView_title.text = title + binding.toolbar.title = title + binding.textViewTitle.text = title } protected fun setSubtitle(subtitle: CharSequence) { - toolbar.subtitle = subtitle + binding.toolbar.subtitle = subtitle } override fun onCreateDialog(savedInstanceState: Bundle?) = @@ -90,13 +96,13 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), override fun onStateChanged(bottomSheet: View, newState: Int) { if (newState == BottomSheetBehavior.STATE_EXPANDED) { - toolbar.isVisible = true - textView_title.isVisible = false - appbar.elevation = elevation + binding.toolbar.isVisible = true + binding.textViewTitle.isVisible = false + binding.appbar.elevation = elevation } else { - toolbar.isVisible = false - textView_title.isVisible = true - appbar.elevation = 0f + binding.toolbar.isVisible = false + binding.textViewTitle.isVisible = true + binding.appbar.elevation = 0f } } }) @@ -114,7 +120,7 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { when (key) { AppSettings.KEY_LIST_MODE -> initListMode(settings.listMode) - AppSettings.KEY_GRID_SIZE -> UiUtils.SpanCountResolver.update(recyclerView) + AppSettings.KEY_GRID_SIZE -> UiUtils.SpanCountResolver.update(binding.recyclerView) } } @@ -124,28 +130,29 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), private fun onListChanged(list: List) { adapter?.items = list - textView_holder.isVisible = list.isEmpty() - recyclerView.callOnScrollListeners() + binding.textViewHolder.isVisible = list.isEmpty() + binding.recyclerView.callOnScrollListeners() } private fun onError(e: Throwable) { - Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show() + Snackbar.make(binding.recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT) + .show() } private fun onLoadingStateChanged(isLoading: Boolean) { - progressBar.isVisible = isLoading && !recyclerView.hasItems + binding.progressBar.isVisible = isLoading && !binding.recyclerView.hasItems if (isLoading) { - textView_holder.isVisible = false + binding.textViewHolder.isVisible = false } } private fun initListMode(mode: ListMode) { val ctx = context ?: return - val position = recyclerView.firstItem - recyclerView.layoutManager = null - recyclerView.clearItemDecorations() - recyclerView.removeOnLayoutChangeListener(UiUtils.SpanCountResolver) - recyclerView.layoutManager = when (mode) { + val position = binding.recyclerView.firstItem + binding.recyclerView.layoutManager = null + binding.recyclerView.clearItemDecorations() + binding.recyclerView.removeOnLayoutChangeListener(UiUtils.SpanCountResolver) + binding.recyclerView.layoutManager = when (mode) { ListMode.GRID -> { GridLayoutManager(ctx, UiUtils.resolveGridSpanCount(ctx)).apply { spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { @@ -156,7 +163,7 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), } else -> LinearLayoutManager(ctx) } - recyclerView.addItemDecoration( + binding.recyclerView.addItemDecoration( when (mode) { ListMode.LIST -> DividerItemDecoration(ctx, RecyclerView.VERTICAL) ListMode.DETAILED_LIST, @@ -166,9 +173,9 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), } ) if (mode == ListMode.GRID) { - recyclerView.addOnLayoutChangeListener(UiUtils.SpanCountResolver) + binding.recyclerView.addOnLayoutChangeListener(UiUtils.SpanCountResolver) } adapter?.notifyDataSetChanged() - recyclerView.firstItem = position + binding.recyclerView.firstItem = position } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt index 85639a746..29442d70b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaGridItemAD.kt @@ -2,11 +2,11 @@ package org.koitharu.kotatsu.list.ui.adapter import coil.ImageLoader import coil.request.Disposable -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import kotlinx.android.synthetic.main.item_manga_list.* +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.databinding.ItemMangaGridBinding import org.koitharu.kotatsu.list.ui.model.MangaGridModel import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest @@ -14,7 +14,9 @@ import org.koitharu.kotatsu.utils.ext.newImageRequest fun mangaGridItemAD( coil: ImageLoader, clickListener: OnListItemClickListener -) = adapterDelegateLayoutContainer(R.layout.item_manga_grid) { +) = adapterDelegateViewBinding( + { inflater, parent -> ItemMangaGridBinding.inflate(inflater, parent, false) } +) { var imageRequest: Disposable? = null @@ -26,9 +28,9 @@ fun mangaGridItemAD( } bind { - textView_title.text = item.title + binding.textViewTitle.text = item.title imageRequest?.dispose() - imageRequest = imageView_cover.newImageRequest(item.coverUrl) + imageRequest = binding.imageViewCover.newImageRequest(item.coverUrl) .placeholder(R.drawable.ic_placeholder) .fallback(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) @@ -37,6 +39,6 @@ fun mangaGridItemAD( onViewRecycled { imageRequest?.dispose() - imageView_cover.setImageDrawable(null) + binding.imageViewCover.setImageDrawable(null) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaListDetailedItemAD.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaListDetailedItemAD.kt index 00ec8ab56..6f48278bd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaListDetailedItemAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaListDetailedItemAD.kt @@ -2,11 +2,11 @@ package org.koitharu.kotatsu.list.ui.adapter import coil.ImageLoader import coil.request.Disposable -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import kotlinx.android.synthetic.main.item_manga_list_details.* +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.databinding.ItemMangaListDetailsBinding import org.koitharu.kotatsu.list.ui.model.MangaListDetailedModel import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest @@ -15,7 +15,9 @@ import org.koitharu.kotatsu.utils.ext.textAndVisible fun mangaListDetailedItemAD( coil: ImageLoader, clickListener: OnListItemClickListener -) = adapterDelegateLayoutContainer(R.layout.item_manga_list_details) { +) = adapterDelegateViewBinding( + { inflater, parent -> ItemMangaListDetailsBinding.inflate(inflater, parent, false) } +) { var imageRequest: Disposable? = null @@ -28,19 +30,19 @@ fun mangaListDetailedItemAD( bind { imageRequest?.dispose() - textView_title.text = item.title - textView_subtitle.textAndVisible = item.subtitle - imageRequest = imageView_cover.newImageRequest(item.coverUrl) + binding.textViewTitle.text = item.title + binding.textViewSubtitle.textAndVisible = item.subtitle + imageRequest = binding.imageViewCover.newImageRequest(item.coverUrl) .placeholder(R.drawable.ic_placeholder) .fallback(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .enqueueWith(coil) - textView_rating.textAndVisible = item.rating - textView_tags.text = item.tags + binding.textViewRating.textAndVisible = item.rating + binding.textViewTags.text = item.tags } onViewRecycled { imageRequest?.dispose() - imageView_cover.setImageDrawable(null) + binding.imageViewCover.setImageDrawable(null) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaListItemAD.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaListItemAD.kt index 9529c9a8c..e21dbb173 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaListItemAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/MangaListItemAD.kt @@ -2,11 +2,11 @@ package org.koitharu.kotatsu.list.ui.adapter import coil.ImageLoader import coil.request.Disposable -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import kotlinx.android.synthetic.main.item_manga_list.* +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.databinding.ItemMangaListBinding import org.koitharu.kotatsu.list.ui.model.MangaListModel import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest @@ -15,7 +15,9 @@ import org.koitharu.kotatsu.utils.ext.textAndVisible fun mangaListItemAD( coil: ImageLoader, clickListener: OnListItemClickListener -) = adapterDelegateLayoutContainer(R.layout.item_manga_list) { +) = adapterDelegateViewBinding( + { inflater, parent -> ItemMangaListBinding.inflate(inflater, parent, false) } +) { var imageRequest: Disposable? = null @@ -28,9 +30,9 @@ fun mangaListItemAD( bind { imageRequest?.dispose() - textView_title.text = item.title - textView_subtitle.textAndVisible = item.subtitle - imageRequest = imageView_cover.newImageRequest(item.coverUrl) + binding.textViewTitle.text = item.title + binding.textViewSubtitle.textAndVisible = item.subtitle + imageRequest = binding.imageViewCover.newImageRequest(item.coverUrl) .placeholder(R.drawable.ic_placeholder) .fallback(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) @@ -39,6 +41,6 @@ fun mangaListItemAD( onViewRecycled { imageRequest?.dispose() - imageView_cover.setImageDrawable(null) + binding.imageViewCover.setImageDrawable(null) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt index cc8464f0e..b0b32096a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt @@ -14,7 +14,7 @@ class FilterAdapter( tags: List = emptyList(), state: MangaFilter?, private val listener: OnFilterChangedListener -) : RecyclerView.Adapter>() { +) : RecyclerView.Adapter>() { private val sortOrders = ArrayList(sortOrders) private val tags = ArrayList(Collections.singletonList(null) + tags) @@ -37,7 +37,7 @@ class FilterAdapter( override fun getItemCount() = sortOrders.size + tags.size - override fun onBindViewHolder(holder: BaseViewHolder<*, Boolean>, position: Int) { + override fun onBindViewHolder(holder: BaseViewHolder<*, Boolean, *>, position: Int) { when (holder) { is FilterSortHolder -> { val item = sortOrders[position] diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterSortHolder.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterSortHolder.kt index 9abeab8eb..a182131b6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterSortHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterSortHolder.kt @@ -1,16 +1,18 @@ package org.koitharu.kotatsu.list.ui.filter +import android.view.LayoutInflater import android.view.ViewGroup -import kotlinx.android.synthetic.main.item_checkable_single.* -import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.SortOrder +import org.koitharu.kotatsu.databinding.ItemCheckableSingleBinding class FilterSortHolder(parent: ViewGroup) : - BaseViewHolder(parent, R.layout.item_checkable_single) { + BaseViewHolder( + ItemCheckableSingleBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ) { override fun onBind(data: SortOrder, extra: Boolean) { - radio.setText(data.titleRes) - radio.isChecked = extra + binding.radio.setText(data.titleRes) + binding.radio.isChecked = extra } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterTagHolder.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterTagHolder.kt index ed8ef8489..f3bf89635 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterTagHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterTagHolder.kt @@ -1,16 +1,19 @@ package org.koitharu.kotatsu.list.ui.filter +import android.view.LayoutInflater import android.view.ViewGroup -import kotlinx.android.synthetic.main.item_checkable_single.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.MangaTag +import org.koitharu.kotatsu.databinding.ItemCheckableSingleBinding class FilterTagHolder(parent: ViewGroup) : - BaseViewHolder(parent, R.layout.item_checkable_single) { + BaseViewHolder( + ItemCheckableSingleBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ) { override fun onBind(data: MangaTag?, extra: Boolean) { - radio.text = data?.title ?: context.getString(R.string.all) - radio.isChecked = extra + binding.radio.text = data?.title ?: context.getString(R.string.all) + binding.radio.isChecked = extra } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/local/LocalModule.kt b/app/src/main/java/org/koitharu/kotatsu/local/LocalModule.kt index bfdbc21f5..57ab25975 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/LocalModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/LocalModule.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.local import org.koin.android.ext.koin.androidContext -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.core.qualifier.named import org.koin.dsl.module import org.koitharu.kotatsu.core.model.MangaSource diff --git a/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt index 36da2d8aa..e72751389 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt @@ -11,8 +11,7 @@ import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AlertDialog import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_list.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga @@ -54,7 +53,9 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback { e.printStackTrace() } Snackbar.make( - recyclerView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT + binding.recyclerView, + R.string.operation_not_supported, + Snackbar.LENGTH_SHORT ).show() } true @@ -64,12 +65,12 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback { } override fun getTitle(): CharSequence? { - return getString(R.string.local_storage) + return context?.getString(R.string.local_storage) } override fun setUpEmptyListHolder() { - textView_holder.setText(R.string.text_local_holder) - textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) + binding.textViewHolder.setText(R.string.text_local_holder) + binding.textViewHolder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) } override fun onActivityResult(result: Uri?) { @@ -102,7 +103,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback { private fun onItemRemoved(item: Manga) { Snackbar.make( - recyclerView, getString( + binding.recyclerView, getString( R.string._s_deleted_from_local_storage, item.title.ellipsize(16) ), Snackbar.LENGTH_SHORT diff --git a/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt b/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt index c7b1b2785..aa8bc5247 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.main -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.main.ui.MainViewModel import org.koitharu.kotatsu.main.ui.protect.ProtectViewModel diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index 322fa8fba..be159eb81 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -15,12 +15,12 @@ import androidx.fragment.app.Fragment import androidx.swiperefreshlayout.widget.CircularProgressDrawable import com.google.android.material.navigation.NavigationView import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.activity_main.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.prefs.AppSection +import org.koitharu.kotatsu.databinding.ActivityMainBinding import org.koitharu.kotatsu.favourites.ui.FavouritesContainerFragment import org.koitharu.kotatsu.history.ui.HistoryListFragment import org.koitharu.kotatsu.local.ui.LocalListFragment @@ -37,7 +37,8 @@ import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.resolveDp import java.io.Closeable -class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener, +class MainActivity : BaseActivity(), + NavigationView.OnNavigationItemSelectedListener, View.OnClickListener { private val viewModel by viewModel() @@ -47,21 +48,27 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + setContentView(ActivityMainBinding.inflate(layoutInflater)) drawerToggle = - ActionBarDrawerToggle(this, drawer, toolbar, R.string.open_menu, R.string.close_menu) - drawer.addDrawerListener(drawerToggle) + ActionBarDrawerToggle( + this, + binding.drawer, + binding.toolbar, + R.string.open_menu, + R.string.close_menu + ) + binding.drawer.addDrawerListener(drawerToggle) supportActionBar?.setDisplayHomeAsUpEnabled(true) - navigationView.setNavigationItemSelectedListener(this) + binding.navigationView.setNavigationItemSelectedListener(this) - with(fab) { + with(binding.fab) { imageTintList = ColorStateList.valueOf(Color.WHITE) setOnClickListener(this@MainActivity) } supportFragmentManager.findFragmentById(R.id.container)?.let { - fab.isVisible = it is HistoryListFragment + binding.fab.isVisible = it is HistoryListFragment } ?: run { openDefaultSection() } @@ -94,8 +101,8 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } override fun onBackPressed() { - if (drawer.isDrawerOpen(navigationView)) { - drawer.closeDrawer(navigationView) + if (binding.drawer.isDrawerOpen(binding.navigationView)) { + binding.drawer.closeDrawer(binding.navigationView) } else { super.onBackPressed() } @@ -148,42 +155,43 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } else -> return false } - drawer.closeDrawers() + binding.drawer.closeDrawers() return true } private fun onOpenReader(state: ReaderState) { val options = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ActivityOptions.makeClipRevealAnimation( - fab, 0, 0, fab.measuredWidth, fab.measuredHeight + binding.fab, 0, 0, binding.fab.measuredWidth, binding.fab.measuredHeight ) } else { ActivityOptions.makeScaleUpAnimation( - fab, 0, 0, fab.measuredWidth, fab.measuredHeight + binding.fab, 0, 0, binding.fab.measuredWidth, binding.fab.measuredHeight ) } startActivity(ReaderActivity.newIntent(this, state), options?.toBundle()) } private fun onError(e: Throwable) { - Snackbar.make(container, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show() + Snackbar.make(binding.container, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT) + .show() } private fun onLoadingStateChanged(isLoading: Boolean) { - fab.isEnabled = !isLoading + binding.fab.isEnabled = !isLoading if (isLoading) { - fab.setImageDrawable(CircularProgressDrawable(this).also { + binding.fab.setImageDrawable(CircularProgressDrawable(this).also { it.setColorSchemeColors(Color.WHITE) it.strokeWidth = resources.resolveDp(2f) it.start() }) } else { - fab.setImageResource(R.drawable.ic_read_fill) + binding.fab.setImageResource(R.drawable.ic_read_fill) } } private fun updateSideMenu(remoteSources: List) { - val submenu = navigationView.menu.findItem(R.id.nav_remote_sources).subMenu + val submenu = binding.navigationView.menu.findItem(R.id.nav_remote_sources).subMenu submenu.removeGroup(R.id.group_remote_sources) remoteSources.forEachIndexed { index, source -> submenu.add(R.id.group_remote_sources, source.ordinal, index, source.title) @@ -194,19 +202,19 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList private fun openDefaultSection() { when (viewModel.defaultSection) { AppSection.LOCAL -> { - navigationView.setCheckedItem(R.id.nav_local_storage) + binding.navigationView.setCheckedItem(R.id.nav_local_storage) setPrimaryFragment(LocalListFragment.newInstance()) } AppSection.FAVOURITES -> { - navigationView.setCheckedItem(R.id.nav_favourites) + binding.navigationView.setCheckedItem(R.id.nav_favourites) setPrimaryFragment(FavouritesContainerFragment.newInstance()) } AppSection.HISTORY -> { - navigationView.setCheckedItem(R.id.nav_history) + binding.navigationView.setCheckedItem(R.id.nav_history) setPrimaryFragment(HistoryListFragment.newInstance()) } AppSection.FEED -> { - navigationView.setCheckedItem(R.id.nav_feed) + binding.navigationView.setCheckedItem(R.id.nav_feed) setPrimaryFragment(FeedFragment.newInstance()) } } @@ -216,6 +224,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList supportFragmentManager.beginTransaction() .replace(R.id.container, fragment) .commit() - fab.isVisible = fragment is HistoryListFragment + binding.fab.isVisible = fragment is HistoryListFragment } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt index f98e013d1..65d7df8c8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt @@ -10,21 +10,22 @@ import android.view.Menu import android.view.MenuItem import android.view.inputmethod.EditorInfo import android.widget.TextView -import kotlinx.android.synthetic.main.activity_protect.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity +import org.koitharu.kotatsu.databinding.ActivityProtectBinding import org.koitharu.kotatsu.utils.ext.getDisplayMessage -class ProtectActivity : BaseActivity(), TextView.OnEditorActionListener, TextWatcher { +class ProtectActivity : BaseActivity(), TextView.OnEditorActionListener, + TextWatcher { private val viewModel by viewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_protect) - edit_password.setOnEditorActionListener(this) - edit_password.addTextChangedListener(this) + setContentView(ActivityProtectBinding.inflate(layoutInflater)) + binding.editPassword.setOnEditorActionListener(this) + binding.editPassword.addTextChangedListener(this) supportActionBar?.run { setDisplayHomeAsUpEnabled(true) setHomeAsUpIndicator(R.drawable.ic_cross) @@ -42,7 +43,7 @@ class ProtectActivity : BaseActivity(), TextView.OnEditorActionListener, TextWat override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { R.id.action_done -> { - viewModel.tryUnlock(edit_password.text?.toString().orEmpty()) + viewModel.tryUnlock(binding.editPassword.text.toString().orEmpty()) true } else -> super.onOptionsItemSelected(item) @@ -50,7 +51,7 @@ class ProtectActivity : BaseActivity(), TextView.OnEditorActionListener, TextWat override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean { return if (actionId == EditorInfo.IME_ACTION_DONE) { - viewModel.tryUnlock(edit_password.text?.toString().orEmpty()) + viewModel.tryUnlock(binding.editPassword.text.toString().orEmpty()) true } else { false @@ -62,7 +63,7 @@ class ProtectActivity : BaseActivity(), TextView.OnEditorActionListener, TextWat override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit override fun afterTextChanged(s: Editable?) { - layout_password.error = null + binding.layoutPassword.error = null } private fun onUnlockSuccess(unit: Unit) { @@ -70,11 +71,11 @@ class ProtectActivity : BaseActivity(), TextView.OnEditorActionListener, TextWat } private fun onError(e: Throwable) { - layout_password.error = e.getDisplayMessage(resources) + binding.layoutPassword.error = e.getDisplayMessage(resources) } private fun onLoadingStateChanged(isLoading: Boolean) { - layout_password.isEnabled = !isLoading + binding.layoutPassword.isEnabled = !isLoading } companion object { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ReaderModule.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ReaderModule.kt index e3b8b5eb1..edb784918 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ReaderModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ReaderModule.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.reader -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.base.domain.MangaDataRepository import org.koitharu.kotatsu.local.data.PagesCache diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersDialog.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersDialog.kt index d2e8caf28..6ca5db113 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersDialog.kt @@ -1,22 +1,29 @@ package org.koitharu.kotatsu.reader.ui import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.dialog_chapters.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.MangaChapter +import org.koitharu.kotatsu.databinding.DialogChaptersBinding import org.koitharu.kotatsu.details.ui.adapter.ChaptersAdapter import org.koitharu.kotatsu.utils.ext.withArgs -class ChaptersDialog : AlertDialogFragment(R.layout.dialog_chapters), +class ChaptersDialog : AlertDialogFragment(), OnListItemClickListener { + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = DialogChaptersBinding.inflate(inflater, container, false) + override fun onBuildDialog(builder: AlertDialog.Builder) { builder.setTitle(R.string.chapters) .setNegativeButton(R.string.close, null) @@ -24,13 +31,13 @@ class ChaptersDialog : AlertDialogFragment(R.layout.dialog_chapters), } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - recyclerView_chapters.addItemDecoration( + binding.recyclerViewChapters.addItemDecoration( DividerItemDecoration( requireContext(), RecyclerView.VERTICAL ) ) - recyclerView_chapters.adapter = ChaptersAdapter(this).apply { + binding.recyclerViewChapters.adapter = ChaptersAdapter(this).apply { // arguments?.getParcelableArrayList(ARG_CHAPTERS)?.let(this::setItems) // currentChapterId = arguments?.getLong(ARG_CURRENT_ID, 0L)?.takeUnless { it == 0L } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index 7bde0b214..042060bff 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -19,14 +19,13 @@ import androidx.core.view.* import androidx.fragment.app.commit import androidx.lifecycle.lifecycleScope import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.activity_reader.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.koin.android.ext.android.inject -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseFullscreenActivity import org.koitharu.kotatsu.core.model.Manga @@ -35,6 +34,7 @@ import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.core.model.MangaPage import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode +import org.koitharu.kotatsu.databinding.ActivityReaderBinding import org.koitharu.kotatsu.reader.ui.base.AbstractReader import org.koitharu.kotatsu.reader.ui.reversed.ReversedReaderFragment import org.koitharu.kotatsu.reader.ui.standard.PagerReaderFragment @@ -48,7 +48,8 @@ import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.anim.Motion import org.koitharu.kotatsu.utils.ext.* -class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeListener, +class ReaderActivity : BaseFullscreenActivity(), + ChaptersDialog.OnChapterChangeListener, GridTouchHelper.OnGridTouchListener, OnPageSelectListener, ReaderConfigDialog.Callback, ReaderListener, SharedPreferences.OnSharedPreferenceChangeListener, ActivityResultCallback, OnApplyWindowInsetsListener { @@ -65,16 +66,16 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL private var isVolumeKeysSwitchEnabled = false private val reader - get() = supportFragmentManager.findFragmentById(R.id.container) as? AbstractReader + get() = supportFragmentManager.findFragmentById(R.id.container) as? AbstractReader<*> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_reader) + setContentView(ActivityReaderBinding.inflate(layoutInflater)) supportActionBar?.setDisplayHomeAsUpEnabled(true) touchHelper = GridTouchHelper(this, this) orientationHelper = ScreenOrientationHelper(this) - toolbar_bottom.inflateMenu(R.menu.opt_reader_bottom) - toolbar_bottom.setOnMenuItemClickListener(::onOptionsItemSelected) + binding.toolbarBottom.inflateMenu(R.menu.opt_reader_bottom) + binding.toolbarBottom.setOnMenuItemClickListener(::onOptionsItemSelected) @Suppress("RemoveExplicitTypeArguments") state = savedInstanceState?.getParcelable(EXTRA_STATE) @@ -91,13 +92,13 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL getString(R.string.chapter_d_of_d, state.chapter?.number ?: 0, size) } - ViewCompat.setOnApplyWindowInsetsListener(rootLayout, this) + ViewCompat.setOnApplyWindowInsetsListener(binding.rootLayout, this) settings.subscribe(this) loadSwitchSettings() orientationHelper.observeAutoOrientation() .onEach { - toolbar_bottom.menu.findItem(R.id.action_screen_rotate).isVisible = !it + binding.toolbarBottom.menu.findItem(R.id.action_screen_rotate).isVisible = !it }.launchIn(lifecycleScope) if (savedInstanceState == null) { @@ -133,14 +134,14 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL } } } - toolbar_bottom.menu.findItem(R.id.action_reader_mode).setIcon( + binding.toolbarBottom.menu.findItem(R.id.action_reader_mode).setIcon( when (mode) { ReaderMode.WEBTOON -> R.drawable.ic_script ReaderMode.REVERSED -> R.drawable.ic_read_reversed ReaderMode.STANDARD -> R.drawable.ic_book_page } ) - appbar_top.postDelayed(1000) { + binding.appbarTop.postDelayed(1000) { setUiIsVisible(false) } } @@ -242,8 +243,8 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL override fun onLoadingStateChanged(isLoading: Boolean) { val hasPages = reader?.hasItems == true - layout_loading.isVisible = isLoading && !hasPages - progressBar_bottom.isVisible = isLoading && hasPages + binding.layoutLoading.isVisible = isLoading && !hasPages + binding.progressBarBottom.isVisible = isLoading && hasPages } override fun onError(e: Throwable) { @@ -262,7 +263,7 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL override fun onGridTouch(area: Int) { when (area) { GridTouchHelper.AREA_CENTER -> { - setUiIsVisible(!appbar_top.isVisible) + setUiIsVisible(!binding.appbarTop.isVisible) } GridTouchHelper.AREA_TOP, GridTouchHelper.AREA_LEFT -> if (isTapSwitchEnabled) { @@ -276,12 +277,12 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL } override fun onProcessTouch(rawX: Int, rawY: Int): Boolean { - return if (appbar_top.hasGlobalPoint(rawX, rawY) - || appbar_bottom.hasGlobalPoint(rawX, rawY) + return if (binding.appbarTop.hasGlobalPoint(rawX, rawY) + || binding.appbarBottom.hasGlobalPoint(rawX, rawY) ) { false } else { - val targets = rootLayout.hitTest(rawX, rawY) + val targets = binding.rootLayout.hitTest(rawX, rawY) targets.none { it.hasOnClickListeners() } } } @@ -318,7 +319,7 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL true } KeyEvent.KEYCODE_DPAD_CENTER -> { - setUiIsVisible(!appbar_top.isVisible) + setUiIsVisible(!binding.appbarTop.isVisible) true } else -> super.onKeyDown(keyCode, event) @@ -350,14 +351,14 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL private fun onPageSaved(uri: Uri?) { if (uri != null) { - Snackbar.make(container, R.string.page_saved, Snackbar.LENGTH_LONG) - .setAnchorView(appbar_bottom) + Snackbar.make(binding.container, R.string.page_saved, Snackbar.LENGTH_LONG) + .setAnchorView(binding.appbarBottom) .setAction(R.string.share) { ShareHelper.shareImage(this, uri) }.show() } else { - Snackbar.make(container, R.string.error_occurred, Snackbar.LENGTH_SHORT) - .setAnchorView(appbar_bottom) + Snackbar.make(binding.container, R.string.error_occurred, Snackbar.LENGTH_SHORT) + .setAnchorView(binding.appbarBottom) .show() } } @@ -385,14 +386,14 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL } private fun setUiIsVisible(isUiVisible: Boolean) { - if (appbar_top.isVisible != isUiVisible) { + if (binding.appbarTop.isVisible != isUiVisible) { if (isUiVisible) { - appbar_top.showAnimated(Motion.SlideTop) - appbar_bottom.showAnimated(Motion.SlideBottom) + binding.appbarTop.showAnimated(Motion.SlideTop) + binding.appbarBottom.showAnimated(Motion.SlideBottom) showSystemUI() } else { - appbar_top.hideAnimated(Motion.SlideTop) - appbar_bottom.hideAnimated(Motion.SlideBottom) + binding.appbarTop.hideAnimated(Motion.SlideTop) + binding.appbarBottom.hideAnimated(Motion.SlideBottom) hideSystemUI() } } @@ -400,12 +401,12 @@ class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeL override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - appbar_top.updatePadding( + binding.appbarTop.updatePadding( top = systemBars.top, right = systemBars.right, left = systemBars.left ) - appbar_bottom.updatePadding( + binding.appbarBottom.updatePadding( bottom = systemBars.bottom, right = systemBars.right, left = systemBars.left diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderConfigDialog.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderConfigDialog.kt index 9902293ac..5201e489f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderConfigDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderConfigDialog.kt @@ -1,20 +1,27 @@ package org.koitharu.kotatsu.reader.ui import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.fragment.app.FragmentManager -import kotlinx.android.synthetic.main.dialog_reader_config.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.core.prefs.ReaderMode +import org.koitharu.kotatsu.databinding.DialogReaderConfigBinding import org.koitharu.kotatsu.utils.ext.withArgs -class ReaderConfigDialog : AlertDialogFragment(R.layout.dialog_reader_config), +class ReaderConfigDialog : AlertDialogFragment(), View.OnClickListener { private lateinit var mode: ReaderMode + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = DialogReaderConfigBinding.inflate(inflater, container, false) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mode = arguments?.getInt(ARG_MODE) @@ -29,14 +36,14 @@ class ReaderConfigDialog : AlertDialogFragment(R.layout.dialog_reader_config), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - button_standard.isChecked = mode == ReaderMode.STANDARD - button_reversed.isChecked = mode == ReaderMode.REVERSED - button_webtoon.isChecked = mode == ReaderMode.WEBTOON + binding.buttonStandard.isChecked = mode == ReaderMode.STANDARD + binding.buttonReversed.isChecked = mode == ReaderMode.REVERSED + binding.buttonWebtoon.isChecked = mode == ReaderMode.WEBTOON - button_ok.setOnClickListener(this) - button_standard.setOnClickListener(this) - button_reversed.setOnClickListener(this) - button_webtoon.setOnClickListener(this) + binding.buttonOk.setOnClickListener(this) + binding.buttonStandard.setOnClickListener(this) + binding.buttonReversed.setOnClickListener(this) + binding.buttonWebtoon.setOnClickListener(this) } override fun onClick(v: View) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderState.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderState.kt index f3ebae266..0fd78b849 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderState.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderState.kt @@ -2,7 +2,7 @@ package org.koitharu.kotatsu.reader.ui import android.os.Parcelable import kotlinx.android.parcel.IgnoredOnParcel -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt index ea02b4c0c..6f646203b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt @@ -7,15 +7,16 @@ import androidx.fragment.app.commit import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity +import org.koitharu.kotatsu.databinding.ActivitySettingsSimpleBinding import org.koitharu.kotatsu.settings.MainSettingsFragment import org.koitharu.kotatsu.settings.NetworkSettingsFragment import org.koitharu.kotatsu.settings.ReaderSettingsFragment -class SimpleSettingsActivity : BaseActivity() { +class SimpleSettingsActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_settings_simple) + setContentView(ActivitySettingsSimpleBinding.inflate(layoutInflater)) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportFragmentManager.commit { replace( diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/AbstractReader.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/AbstractReader.kt index 33678367a..834c75f1b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/AbstractReader.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/AbstractReader.kt @@ -6,6 +6,7 @@ import android.view.View import androidx.annotation.CallSuper import androidx.collection.LongSparseArray import androidx.core.view.postDelayed +import androidx.viewbinding.ViewBinding import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -20,8 +21,7 @@ import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.utils.ext.associateByLong import org.koitharu.kotatsu.utils.ext.viewLifecycleScope -abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayoutId), - OnBoundsScrollListener { +abstract class AbstractReader : BaseFragment(), OnBoundsScrollListener { protected lateinit var manga: Manga private set @@ -30,11 +30,11 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout PageLoader() } protected val pages = ArrayDeque() - protected var adapter: BaseReaderAdapter? = null + protected var readerAdapter: BaseReaderAdapter? = null private set val itemsCount: Int - get() = adapter?.itemCount ?: 0 + get() = readerAdapter?.itemCount ?: 0 val hasItems: Boolean get() = itemsCount != 0 @@ -52,7 +52,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - adapter = onCreateAdapter(pages) + readerAdapter = onCreateAdapter(pages) @Suppress("RemoveExplicitTypeArguments") val state = savedInstanceState?.getParcelable(ARG_STATE) ?: requireArguments().getParcelable(ARG_STATE)!! @@ -61,7 +61,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout it.mapIndexedTo(pages) { i, p -> ReaderPage.from(p, i, state.chapterId) } - adapter?.notifyDataSetChanged() + readerAdapter?.notifyDataSetChanged() setCurrentItem(state.page, false) if (state.scroll != 0) { restorePageScroll(state.page, state.scroll) @@ -100,7 +100,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout pages.addAll(0, it.mapIndexed { i, p -> ReaderPage.from(p, i, prevChapterId) }) - adapter?.notifyItemsPrepended(it.size) + readerAdapter?.notifyItemsPrepended(it.size) view?.postDelayed(500) { trimEnd() } @@ -115,7 +115,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout pages.addAll(it.mapIndexed { i, p -> ReaderPage.from(p, i, nextChapterId) }) - adapter?.notifyItemsAppended(it.size) + readerAdapter?.notifyItemsAppended(it.size) view?.postDelayed(500) { trimStart() } @@ -123,7 +123,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout } override fun onDestroyView() { - adapter = null + readerAdapter = null super.onDestroyView() } @@ -134,7 +134,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout @CallSuper open fun recreateAdapter() { - adapter = onCreateAdapter(pages) + readerAdapter = onCreateAdapter(pages) } fun getPages(): List? { @@ -212,13 +212,13 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout val currentChapterId = pages.getOrNull(getCurrentItem())?.chapterId ?: 0L if (chapterId != 0L && chapterId != currentChapterId) { pages.clear() - adapter?.notifyDataSetChanged() + readerAdapter?.notifyDataSetChanged() loadChapter(chapterId) { pages.clear() it.mapIndexedTo(pages) { i, p -> ReaderPage.from(p, i, chapterId) } - adapter?.notifyDataSetChanged() + readerAdapter?.notifyDataSetChanged() setCurrentItem( if (pageId == 0L) { 0 diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/BaseReaderAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/BaseReaderAdapter.kt index 67a54c62d..33385d34c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/BaseReaderAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/BaseReaderAdapter.kt @@ -5,14 +5,14 @@ import androidx.recyclerview.widget.RecyclerView import org.koitharu.kotatsu.base.ui.list.BaseViewHolder abstract class BaseReaderAdapter(protected val pages: List) : - RecyclerView.Adapter>() { + RecyclerView.Adapter>() { init { @Suppress("LeakingThis") setHasStableIds(true) } - override fun onBindViewHolder(holder: BaseViewHolder, position: Int) { + override fun onBindViewHolder(holder: BaseViewHolder, position: Int) { val item = pages[position] holder.bind(item, Unit) } @@ -42,11 +42,11 @@ abstract class BaseReaderAdapter(protected val pages: List) : final override fun onCreateViewHolder( parent: ViewGroup, viewType: Int - ): BaseViewHolder { + ): BaseViewHolder { return onCreateViewHolder(parent).also(this::onViewHolderCreated) } - protected open fun onViewHolderCreated(holder: BaseViewHolder) = Unit + protected open fun onViewHolderCreated(holder: BaseViewHolder) = Unit - protected abstract fun onCreateViewHolder(parent: ViewGroup): BaseViewHolder + protected abstract fun onCreateViewHolder(parent: ViewGroup): BaseViewHolder } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/ReaderPage.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/ReaderPage.kt index b73387360..a7dacac10 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/ReaderPage.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/ReaderPage.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.reader.ui.base import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.koitharu.kotatsu.core.model.MangaPage import org.koitharu.kotatsu.core.model.MangaSource diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageHolder.kt index 233ab81ef..a00df4490 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageHolder.kt @@ -3,7 +3,6 @@ package org.koitharu.kotatsu.reader.ui.reversed import android.graphics.PointF import android.view.ViewGroup import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView -import kotlinx.android.synthetic.main.item_page.* import org.koitharu.kotatsu.core.model.ZoomMode import org.koitharu.kotatsu.reader.ui.PageLoader import org.koitharu.kotatsu.reader.ui.standard.PageHolder @@ -11,37 +10,39 @@ import org.koitharu.kotatsu.reader.ui.standard.PageHolder class ReversedPageHolder(parent: ViewGroup, loader: PageLoader) : PageHolder(parent, loader) { override fun onImageShowing(zoom: ZoomMode) { - ssiv.maxScale = 2f * maxOf( - ssiv.width / ssiv.sWidth.toFloat(), - ssiv.height / ssiv.sHeight.toFloat() - ) - when (zoom) { - ZoomMode.FIT_CENTER -> { - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) - ssiv.resetScaleAndCenter() - } - ZoomMode.FIT_HEIGHT -> { - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) - ssiv.minScale = ssiv.height / ssiv.sHeight.toFloat() - ssiv.setScaleAndCenter( - ssiv.minScale, - PointF(ssiv.sWidth.toFloat(), ssiv.sHeight / 2f) - ) - } - ZoomMode.FIT_WIDTH -> { - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) - ssiv.minScale = ssiv.width / ssiv.sWidth.toFloat() - ssiv.setScaleAndCenter( - ssiv.minScale, - PointF(ssiv.sWidth / 2f, 0f) - ) - } - ZoomMode.KEEP_START -> { - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) - ssiv.setScaleAndCenter( - ssiv.maxScale, - PointF(ssiv.sWidth.toFloat(), 0f) - ) + with(binding.ssiv) { + maxScale = 2f * maxOf( + width / sWidth.toFloat(), + height / sHeight.toFloat() + ) + when (zoom) { + ZoomMode.FIT_CENTER -> { + setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) + resetScaleAndCenter() + } + ZoomMode.FIT_HEIGHT -> { + setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + minScale = height / sHeight.toFloat() + setScaleAndCenter( + minScale, + PointF(sWidth.toFloat(), sHeight / 2f) + ) + } + ZoomMode.FIT_WIDTH -> { + setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + minScale = width / sWidth.toFloat() + setScaleAndCenter( + minScale, + PointF(sWidth / 2f, 0f) + ) + } + ZoomMode.KEEP_START -> { + setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) + setScaleAndCenter( + maxScale, + PointF(sWidth.toFloat(), 0f) + ) + } } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPagesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPagesAdapter.kt index 620957714..ba631d8e1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPagesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPagesAdapter.kt @@ -13,7 +13,7 @@ class ReversedPagesAdapter( override fun onCreateViewHolder(parent: ViewGroup) = ReversedPageHolder(parent, loader) - override fun onBindViewHolder(holder: BaseViewHolder, position: Int) { + override fun onBindViewHolder(holder: BaseViewHolder, position: Int) { super.onBindViewHolder(holder, reversed(position)) } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedReaderFragment.kt index 5fce5dd4c..02be05afc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedReaderFragment.kt @@ -3,11 +3,12 @@ package org.koitharu.kotatsu.reader.ui.reversed import android.content.Context import android.content.SharedPreferences import android.os.Bundle +import android.view.LayoutInflater import android.view.View -import kotlinx.android.synthetic.main.fragment_reader_standard.* +import android.view.ViewGroup import org.koin.android.ext.android.inject -import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings +import org.koitharu.kotatsu.databinding.FragmentReaderStandardBinding import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.reader.ui.base.AbstractReader import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter @@ -18,23 +19,30 @@ import org.koitharu.kotatsu.utils.ext.doOnPageChanged import org.koitharu.kotatsu.utils.ext.swapAdapter import org.koitharu.kotatsu.utils.ext.withArgs -class ReversedReaderFragment : AbstractReader(R.layout.fragment_reader_standard), +class ReversedReaderFragment : AbstractReader(), SharedPreferences.OnSharedPreferenceChangeListener { private var paginationListener: PagerPaginationListener? = null private val settings by inject() + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentReaderStandardBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - paginationListener = PagerPaginationListener(adapter!!, 2, this) - pager.adapter = adapter - if (settings.readerAnimation) { - pager.setPageTransformer(ReversedPageAnimTransformer()) - } - pager.offscreenPageLimit = 2 - pager.registerOnPageChangeCallback(paginationListener!!) - pager.doOnPageChanged { - notifyPageChanged(reversed(it)) + paginationListener = PagerPaginationListener(readerAdapter!!, 2, this) + with(binding.pager) { + adapter = readerAdapter + if (settings.readerAnimation) { + setPageTransformer(ReversedPageAnimTransformer()) + } + offscreenPageLimit = 2 + registerOnPageChangeCallback(paginationListener!!) + doOnPageChanged { + notifyPageChanged(reversed(it)) + } } } @@ -59,13 +67,13 @@ class ReversedReaderFragment : AbstractReader(R.layout.fragment_reader_standard) override fun recreateAdapter() { super.recreateAdapter() - pager.swapAdapter(adapter) + binding.pager.swapAdapter(readerAdapter) } - override fun getCurrentItem() = reversed(pager.currentItem) + override fun getCurrentItem() = reversed(binding.pager.currentItem) override fun setCurrentItem(position: Int, isSmooth: Boolean) { - pager.setCurrentItem(reversed(position), isSmooth) + binding.pager.setCurrentItem(reversed(position), isSmooth) } override fun getCurrentPageScroll() = 0 @@ -76,9 +84,9 @@ class ReversedReaderFragment : AbstractReader(R.layout.fragment_reader_standard) when (key) { AppSettings.KEY_READER_ANIMATION -> { if (settings.readerAnimation) { - pager.setPageTransformer(PageAnimTransformer()) + binding.pager.setPageTransformer(PageAnimTransformer()) } else { - pager.setPageTransformer(null) + binding.pager.setPageTransformer(null) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageHolder.kt index 75725a5b5..3b59a7a3d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageHolder.kt @@ -2,29 +2,31 @@ package org.koitharu.kotatsu.reader.ui.standard import android.graphics.PointF import android.net.Uri +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView -import kotlinx.android.synthetic.main.item_page.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.ZoomMode +import org.koitharu.kotatsu.databinding.ItemPageBinding import org.koitharu.kotatsu.reader.ui.PageLoader import org.koitharu.kotatsu.reader.ui.base.PageHolderDelegate import org.koitharu.kotatsu.reader.ui.base.ReaderPage import org.koitharu.kotatsu.utils.ext.getDisplayMessage open class PageHolder(parent: ViewGroup, loader: PageLoader) : - BaseViewHolder(parent, R.layout.item_page), - PageHolderDelegate.Callback, View.OnClickListener { + BaseViewHolder( + ItemPageBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ), PageHolderDelegate.Callback, View.OnClickListener { private val delegate = PageHolderDelegate(loader, this) init { - ssiv.setOnImageEventListener(delegate) - button_retry.setOnClickListener(this) + binding.ssiv.setOnImageEventListener(delegate) + binding.buttonRetry.setOnClickListener(this) } override fun onBind(data: ReaderPage, extra: Unit) { @@ -33,49 +35,49 @@ open class PageHolder(parent: ViewGroup, loader: PageLoader) : override fun onRecycled() { delegate.onRecycle() - ssiv.recycle() + binding.ssiv.recycle() } override fun onLoadingStarted() { - layout_error.isVisible = false - progressBar.isVisible = true - ssiv.recycle() + binding.layoutError.isVisible = false + binding.progressBar.isVisible = true + binding.ssiv.recycle() } override fun onImageReady(uri: Uri) { - ssiv.setImage(ImageSource.uri(uri)) + binding.ssiv.setImage(ImageSource.uri(uri)) } override fun onImageShowing(zoom: ZoomMode) { - ssiv.maxScale = 2f * maxOf( - ssiv.width / ssiv.sWidth.toFloat(), - ssiv.height / ssiv.sHeight.toFloat() + binding.ssiv.maxScale = 2f * maxOf( + binding.ssiv.width / binding.ssiv.sWidth.toFloat(), + binding.ssiv.height / binding.ssiv.sHeight.toFloat() ) when (zoom) { ZoomMode.FIT_CENTER -> { - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) - ssiv.resetScaleAndCenter() + binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) + binding.ssiv.resetScaleAndCenter() } ZoomMode.FIT_HEIGHT -> { - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) - ssiv.minScale = ssiv.height / ssiv.sHeight.toFloat() - ssiv.setScaleAndCenter( - ssiv.minScale, - PointF(0f, ssiv.sHeight / 2f) + binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + binding.ssiv.minScale = binding.ssiv.height / binding.ssiv.sHeight.toFloat() + binding.ssiv.setScaleAndCenter( + binding.ssiv.minScale, + PointF(0f, binding.ssiv.sHeight / 2f) ) } ZoomMode.FIT_WIDTH -> { - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) - ssiv.minScale = ssiv.width / ssiv.sWidth.toFloat() - ssiv.setScaleAndCenter( - ssiv.minScale, - PointF(ssiv.sWidth / 2f, 0f) + binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + binding.ssiv.minScale = binding.ssiv.width / binding.ssiv.sWidth.toFloat() + binding.ssiv.setScaleAndCenter( + binding.ssiv.minScale, + PointF(binding.ssiv.sWidth / 2f, 0f) ) } ZoomMode.KEEP_START -> { - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) - ssiv.setScaleAndCenter( - ssiv.maxScale, + binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) + binding.ssiv.setScaleAndCenter( + binding.ssiv.maxScale, PointF(0f, 0f) ) } @@ -83,7 +85,7 @@ open class PageHolder(parent: ViewGroup, loader: PageLoader) : } override fun onImageShown() { - progressBar.isVisible = false + binding.progressBar.isVisible = false } override fun onClick(v: View) { @@ -93,8 +95,8 @@ open class PageHolder(parent: ViewGroup, loader: PageLoader) : } override fun onError(e: Throwable) { - textView_error.text = e.getDisplayMessage(context.resources) - layout_error.isVisible = true - progressBar.isVisible = false + binding.textViewError.text = e.getDisplayMessage(context.resources) + binding.layoutError.isVisible = true + binding.progressBar.isVisible = false } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerReaderFragment.kt index 2ce317e4b..c8047f060 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerReaderFragment.kt @@ -3,11 +3,12 @@ package org.koitharu.kotatsu.reader.ui.standard import android.content.Context import android.content.SharedPreferences import android.os.Bundle +import android.view.LayoutInflater import android.view.View -import kotlinx.android.synthetic.main.fragment_reader_standard.* +import android.view.ViewGroup import org.koin.android.ext.android.inject -import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings +import org.koitharu.kotatsu.databinding.FragmentReaderStandardBinding import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.reader.ui.base.AbstractReader import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter @@ -16,22 +17,29 @@ import org.koitharu.kotatsu.utils.ext.doOnPageChanged import org.koitharu.kotatsu.utils.ext.swapAdapter import org.koitharu.kotatsu.utils.ext.withArgs -class PagerReaderFragment : AbstractReader(R.layout.fragment_reader_standard), +class PagerReaderFragment : AbstractReader(), SharedPreferences.OnSharedPreferenceChangeListener { private var paginationListener: PagerPaginationListener? = null private val settings by inject() + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentReaderStandardBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - paginationListener = PagerPaginationListener(adapter!!, 2, this) - pager.adapter = adapter - if (settings.readerAnimation) { - pager.setPageTransformer(PageAnimTransformer()) + paginationListener = PagerPaginationListener(readerAdapter!!, 2, this) + with(binding.pager) { + adapter = readerAdapter + if (settings.readerAnimation) { + setPageTransformer(PageAnimTransformer()) + } + offscreenPageLimit = 2 + registerOnPageChangeCallback(paginationListener!!) + doOnPageChanged(::notifyPageChanged) } - pager.offscreenPageLimit = 2 - pager.registerOnPageChangeCallback(paginationListener!!) - pager.doOnPageChanged(::notifyPageChanged) } override fun onAttach(context: Context) { @@ -55,13 +63,13 @@ class PagerReaderFragment : AbstractReader(R.layout.fragment_reader_standard), override fun recreateAdapter() { super.recreateAdapter() - pager.swapAdapter(adapter) + binding.pager.swapAdapter(readerAdapter) } - override fun getCurrentItem() = pager.currentItem + override fun getCurrentItem() = binding.pager.currentItem override fun setCurrentItem(position: Int, isSmooth: Boolean) { - pager.setCurrentItem(position, isSmooth) + binding.pager.setCurrentItem(position, isSmooth) } override fun getCurrentPageScroll() = 0 @@ -72,9 +80,9 @@ class PagerReaderFragment : AbstractReader(R.layout.fragment_reader_standard), when (key) { AppSettings.KEY_READER_ANIMATION -> { if (settings.readerAnimation) { - pager.setPageTransformer(PageAnimTransformer()) + binding.pager.setPageTransformer(PageAnimTransformer()) } else { - pager.setPageTransformer(null) + binding.pager.setPageTransformer(null) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PageThumbnailHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PageThumbnailHolder.kt deleted file mode 100644 index 71048d6f0..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PageThumbnailHolder.kt +++ /dev/null @@ -1,58 +0,0 @@ -package org.koitharu.kotatsu.reader.ui.thumbnails - -import android.view.ViewGroup -import androidx.core.net.toUri -import coil.ImageLoader -import coil.request.ImageRequest -import coil.size.PixelSize -import coil.size.Size -import kotlinx.android.synthetic.main.item_page_thumb.* -import kotlinx.coroutines.* -import org.koin.core.component.inject -import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.base.ui.list.BaseViewHolder -import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.local.data.PagesCache -import org.koitharu.kotatsu.utils.ext.IgnoreErrors - -class PageThumbnailHolder(parent: ViewGroup, private val scope: CoroutineScope) : - BaseViewHolder(parent, R.layout.item_page_thumb) { - - private var job: Job? = null - private val thumbSize: Size - private val coil by inject() - - init { - val width = itemView.context.resources.getDimensionPixelSize(R.dimen.preferred_grid_width) - thumbSize = PixelSize( - width = width, - height = (width * 13f / 18f).toInt() - ) - } - - override fun onBind(data: MangaPage, extra: PagesCache) { - imageView_thumb.setImageDrawable(null) - textView_number.text = (bindingAdapterPosition + 1).toString() - job?.cancel() - job = scope.launch(Dispatchers.IO + IgnoreErrors) { - val url = data.preview ?: data.url.let { - val pageUrl = data.source.repository.getPageFullUrl(data) - extra[pageUrl]?.toUri()?.toString() ?: pageUrl - } - val drawable = coil.execute( - ImageRequest.Builder(context) - .data(url) - .size(thumbSize) - .build() - ).drawable - withContext(Dispatchers.Main.immediate) { - imageView_thumb.setImageDrawable(drawable) - } - } - } - - override fun onRecycled() { - job?.cancel() - imageView_thumb.setImageDrawable(null) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt index d88fb63f8..365fb7cf0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt @@ -1,50 +1,57 @@ package org.koitharu.kotatsu.reader.ui.thumbnails import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isVisible import androidx.fragment.app.FragmentManager import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog -import kotlinx.android.synthetic.main.sheet_pages.* -import kotlinx.coroutines.DisposableHandle import org.koin.android.ext.android.get import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseBottomSheet import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration import org.koitharu.kotatsu.core.model.MangaPage +import org.koitharu.kotatsu.databinding.SheetPagesBinding import org.koitharu.kotatsu.reader.ui.thumbnails.adapter.PageThumbnailAdapter import org.koitharu.kotatsu.utils.UiUtils import org.koitharu.kotatsu.utils.ext.resolveDp import org.koitharu.kotatsu.utils.ext.viewLifecycleScope import org.koitharu.kotatsu.utils.ext.withArgs -class PagesThumbnailsSheet : BaseBottomSheet(R.layout.sheet_pages), +class PagesThumbnailsSheet : BaseBottomSheet(), OnListItemClickListener { + override fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): SheetPagesBinding { + return SheetPagesBinding.inflate(inflater, container, false) + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - recyclerView.addItemDecoration(SpacingItemDecoration(view.resources.resolveDp(8))) + binding.recyclerView.addItemDecoration(SpacingItemDecoration(view.resources.resolveDp(8))) val pages = arguments?.getParcelableArrayList(ARG_PAGES) if (pages == null) { dismissAllowingStateLoss() return } - recyclerView.adapter = PageThumbnailAdapter(get(), viewLifecycleScope, get(), this).apply { - items = pages - } + binding.recyclerView.adapter = + PageThumbnailAdapter(get(), viewLifecycleScope, get(), this).apply { + items = pages + } val title = arguments?.getString(ARG_TITLE) - toolbar.title = title - toolbar.setNavigationOnClickListener { dismiss() } - toolbar.subtitle = resources.getQuantityString(R.plurals.pages, pages.size, pages.size) - textView_title.text = title + binding.toolbar.title = title + binding.toolbar.setNavigationOnClickListener { dismiss() } + binding.toolbar.subtitle = + resources.getQuantityString(R.plurals.pages, pages.size, pages.size) + binding.textViewTitle.text = title if (dialog !is BottomSheetDialog) { - toolbar.isVisible = true - textView_title.isVisible = false - appbar.elevation = resources.getDimension(R.dimen.elevation_large) + binding.toolbar.isVisible = true + binding.textViewTitle.isVisible = false + binding.appbar.elevation = resources.getDimension(R.dimen.elevation_large) } - recyclerView.addOnLayoutChangeListener(UiUtils.SpanCountResolver) + binding.recyclerView.addOnLayoutChangeListener(UiUtils.SpanCountResolver) } override fun onCreateDialog(savedInstanceState: Bundle?) = @@ -57,13 +64,13 @@ class PagesThumbnailsSheet : BaseBottomSheet(R.layout.sheet_pages), override fun onStateChanged(bottomSheet: View, newState: Int) { if (newState == BottomSheetBehavior.STATE_EXPANDED) { - toolbar.isVisible = true - textView_title.isVisible = false - appbar.elevation = elevation + binding.toolbar.isVisible = true + binding.textViewTitle.isVisible = false + binding.appbar.elevation = elevation } else { - toolbar.isVisible = false - textView_title.isVisible = true - appbar.elevation = 0f + binding.toolbar.isVisible = false + binding.textViewTitle.isVisible = true + binding.appbar.elevation = 0f } } }) @@ -71,8 +78,7 @@ class PagesThumbnailsSheet : BaseBottomSheet(R.layout.sheet_pages), } override fun onDestroyView() { - (recyclerView.adapter as? DisposableHandle)?.dispose() - recyclerView.adapter = null + binding.recyclerView.adapter = null super.onDestroyView() } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt index bd89a5b16..71337d377 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt @@ -4,12 +4,12 @@ import androidx.core.net.toUri import coil.ImageLoader import coil.request.ImageRequest import coil.size.PixelSize -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import kotlinx.android.synthetic.main.item_page_thumb.* +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import kotlinx.coroutines.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.MangaPage +import org.koitharu.kotatsu.databinding.ItemPageThumbBinding import org.koitharu.kotatsu.local.data.PagesCache import org.koitharu.kotatsu.utils.ext.IgnoreErrors @@ -18,7 +18,9 @@ fun pageThumbnailAD( scope: CoroutineScope, cache: PagesCache, clickListener: OnListItemClickListener -) = adapterDelegateLayoutContainer(R.layout.item_page_thumb) { +) = adapterDelegateViewBinding( + { inflater, parent -> ItemPageThumbBinding.inflate(inflater, parent, false) } +) { var job: Job? = null val gridWidth = itemView.context.resources.getDimensionPixelSize(R.dimen.preferred_grid_width) @@ -27,14 +29,14 @@ fun pageThumbnailAD( height = (gridWidth * 13f / 18f).toInt() ) - handle.setOnClickListener { + binding.handle.setOnClickListener { clickListener.onItemClick(item, itemView) } bind { job?.cancel() - imageView_thumb.setImageDrawable(null) - textView_number.text = (bindingAdapterPosition + 1).toString() + binding.imageViewThumb.setImageDrawable(null) + binding.textViewNumber.text = (bindingAdapterPosition + 1).toString() job = scope.launch(Dispatchers.Default + IgnoreErrors) { val url = item.preview ?: item.url.let { val pageUrl = item.source.repository.getPageFullUrl(item) @@ -47,13 +49,13 @@ fun pageThumbnailAD( .build() ).drawable withContext(Dispatchers.Main) { - imageView_thumb.setImageDrawable(drawable) + binding.imageViewThumb.setImageDrawable(drawable) } } } onViewRecycled { job?.cancel() - imageView_thumb.setImageDrawable(null) + binding.imageViewThumb.setImageDrawable(null) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonHolder.kt index 98d4ebe0e..51aa76bf8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonHolder.kt @@ -1,15 +1,16 @@ package org.koitharu.kotatsu.reader.ui.wetoon import android.net.Uri +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView -import kotlinx.android.synthetic.main.item_page_webtoon.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.ZoomMode +import org.koitharu.kotatsu.databinding.ItemPageWebtoonBinding import org.koitharu.kotatsu.reader.ui.PageLoader import org.koitharu.kotatsu.reader.ui.base.PageHolderDelegate import org.koitharu.kotatsu.reader.ui.base.ReaderPage @@ -17,15 +18,16 @@ import org.koitharu.kotatsu.utils.ext.getDisplayMessage class WebtoonHolder(parent: ViewGroup, private val loader: PageLoader) : - BaseViewHolder(parent, R.layout.item_page_webtoon), - PageHolderDelegate.Callback, View.OnClickListener { + BaseViewHolder( + ItemPageWebtoonBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ), PageHolderDelegate.Callback, View.OnClickListener { private val delegate = PageHolderDelegate(loader, this) private var scrollToRestore = 0 init { - ssiv.setOnImageEventListener(delegate) - button_retry.setOnClickListener(this) + binding.ssiv.setOnImageEventListener(delegate) + binding.buttonRetry.setOnClickListener(this) } override fun onBind(data: ReaderPage, extra: Unit) { @@ -34,34 +36,36 @@ class WebtoonHolder(parent: ViewGroup, private val loader: PageLoader) : override fun onRecycled() { delegate.onRecycle() - ssiv.recycle() + binding.ssiv.recycle() } override fun onLoadingStarted() { - layout_error.isVisible = false - progressBar.isVisible = true - ssiv.recycle() + binding.layoutError.isVisible = false + binding.progressBar.isVisible = true + binding.ssiv.recycle() } override fun onImageReady(uri: Uri) { - ssiv.setImage(ImageSource.uri(uri)) + binding.ssiv.setImage(ImageSource.uri(uri)) } override fun onImageShowing(zoom: ZoomMode) { - ssiv.maxScale = 2f * ssiv.width / ssiv.sWidth.toFloat() - ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) - ssiv.minScale = ssiv.width / ssiv.sWidth.toFloat() - ssiv.scrollTo( - when { - scrollToRestore != 0 -> scrollToRestore - itemView.top < 0 -> ssiv.getScrollRange() - else -> 0 - } - ) + with(binding.ssiv) { + maxScale = 2f * width / sWidth.toFloat() + setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + minScale = width / sWidth.toFloat() + scrollTo( + when { + scrollToRestore != 0 -> scrollToRestore + itemView.top < 0 -> getScrollRange() + else -> 0 + } + ) + } } override fun onImageShown() { - progressBar.isVisible = false + binding.progressBar.isVisible = false } override fun onClick(v: View) { @@ -71,16 +75,16 @@ class WebtoonHolder(parent: ViewGroup, private val loader: PageLoader) : } override fun onError(e: Throwable) { - textView_error.text = e.getDisplayMessage(context.resources) - layout_error.isVisible = true - progressBar.isVisible = false + binding.textViewError.text = e.getDisplayMessage(context.resources) + binding.layoutError.isVisible = true + binding.progressBar.isVisible = false } - fun getScrollY() = ssiv.getScroll() + fun getScrollY() = binding.ssiv.getScroll() fun restoreScroll(scroll: Int) { - if (ssiv.isReady) { - ssiv.scrollTo(scroll) + if (binding.ssiv.isReady) { + binding.ssiv.scrollTo(scroll) } else { scrollToRestore = scroll } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonReaderFragment.kt index d78cf8fd9..33ebdd185 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonReaderFragment.kt @@ -1,10 +1,11 @@ package org.koitharu.kotatsu.reader.ui.wetoon import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.animation.AccelerateDecelerateInterpolator -import kotlinx.android.synthetic.main.fragment_reader_webtoon.* -import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.databinding.FragmentReaderWebtoonBinding import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.reader.ui.base.AbstractReader import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter @@ -14,18 +15,25 @@ import org.koitharu.kotatsu.utils.ext.findCenterViewPosition import org.koitharu.kotatsu.utils.ext.firstItem import org.koitharu.kotatsu.utils.ext.withArgs -class WebtoonReaderFragment : AbstractReader(R.layout.fragment_reader_webtoon) { +class WebtoonReaderFragment : AbstractReader() { private val scrollInterpolator = AccelerateDecelerateInterpolator() private var paginationListener: ListPaginationListener? = null + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentReaderWebtoonBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) paginationListener = ListPaginationListener(2, this) - recyclerView.setHasFixedSize(true) - recyclerView.adapter = adapter - recyclerView.addOnScrollListener(paginationListener!!) - recyclerView.doOnCurrentItemChanged(::notifyPageChanged) + with(binding.recyclerView) { + setHasFixedSize(true) + adapter = readerAdapter + addOnScrollListener(paginationListener!!) + doOnCurrentItemChanged(::notifyPageChanged) + } } override fun onCreateAdapter(dataSet: List): BaseReaderAdapter { @@ -34,7 +42,7 @@ class WebtoonReaderFragment : AbstractReader(R.layout.fragment_reader_webtoon) { override fun recreateAdapter() { super.recreateAdapter() - recyclerView.swapAdapter(adapter, true) + binding.recyclerView.swapAdapter(readerAdapter, true) } override fun onDestroyView() { @@ -43,33 +51,33 @@ class WebtoonReaderFragment : AbstractReader(R.layout.fragment_reader_webtoon) { } override fun getCurrentItem(): Int { - return recyclerView.findCenterViewPosition() + return binding.recyclerView.findCenterViewPosition() } override fun setCurrentItem(position: Int, isSmooth: Boolean) { if (isSmooth) { - recyclerView.smoothScrollToPosition(position) + binding.recyclerView.smoothScrollToPosition(position) } else { - recyclerView.firstItem = position + binding.recyclerView.firstItem = position } } override fun switchPageBy(delta: Int) { - recyclerView.smoothScrollBy( + binding.recyclerView.smoothScrollBy( 0, - (recyclerView.height * 0.9).toInt() * delta, + (binding.recyclerView.height * 0.9).toInt() * delta, scrollInterpolator ) } override fun getCurrentPageScroll(): Int { - return (recyclerView.findViewHolderForAdapterPosition(getCurrentItem()) as? WebtoonHolder) + return (binding.recyclerView.findViewHolderForAdapterPosition(getCurrentItem()) as? WebtoonHolder) ?.getScrollY() ?: 0 } override fun restorePageScroll(position: Int, scroll: Int) { - recyclerView.post { - val holder = recyclerView.findViewHolderForAdapterPosition(position) ?: return@post + binding.recyclerView.post { + val holder = binding.recyclerView.findViewHolderForAdapterPosition(position) ?: return@post (holder as WebtoonHolder).restoreScroll(scroll) } } diff --git a/app/src/main/java/org/koitharu/kotatsu/remotelist/RemoteListModule.kt b/app/src/main/java/org/koitharu/kotatsu/remotelist/RemoteListModule.kt index f36bf7a69..802d35ab9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/remotelist/RemoteListModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/remotelist/RemoteListModule.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.remotelist -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.core.qualifier.named import org.koin.dsl.module import org.koitharu.kotatsu.core.model.MangaSource diff --git a/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt index 91f95c0a3..d59a914fd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.remotelist.ui import android.view.Menu import android.view.MenuInflater import android.view.MenuItem -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaFilter diff --git a/app/src/main/java/org/koitharu/kotatsu/search/SearchModule.kt b/app/src/main/java/org/koitharu/kotatsu/search/SearchModule.kt index c15e72132..a6a7db5c5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/SearchModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/SearchModule.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.search -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.core.qualifier.named import org.koin.dsl.module import org.koitharu.kotatsu.core.model.MangaSource diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSearchSheet.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSearchSheet.kt index c6c95b9ea..897910836 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSearchSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSearchSheet.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.search.ui import android.os.Bundle import android.view.View import androidx.fragment.app.FragmentManager -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaSource diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt index 33a19d383..aa11a4959 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt @@ -5,40 +5,42 @@ import android.content.Intent import android.os.Bundle import android.os.Parcelable import androidx.appcompat.widget.SearchView -import kotlinx.android.synthetic.main.activity_search.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.databinding.ActivitySearchBinding import org.koitharu.kotatsu.utils.ext.showKeyboard -class SearchActivity : BaseActivity(), SearchView.OnQueryTextListener { +class SearchActivity : BaseActivity(), SearchView.OnQueryTextListener { private lateinit var source: MangaSource override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_search) + setContentView(ActivitySearchBinding.inflate(layoutInflater)) source = intent.getParcelableExtra(EXTRA_SOURCE) ?: run { finishAfterTransition() return } val query = intent.getStringExtra(EXTRA_QUERY) supportActionBar?.setDisplayHomeAsUpEnabled(true) - searchView.queryHint = getString(R.string.search_on_s, source.title) - searchView.suggestionsAdapter = MangaSuggestionsProvider.getSuggestionAdapter(this) - searchView.setOnSuggestionListener(SearchHelper.SuggestionListener(searchView)) - searchView.setOnQueryTextListener(this) + with(binding.searchView) { + queryHint = getString(R.string.search_on_s, source.title) + suggestionsAdapter = MangaSuggestionsProvider.getSuggestionAdapter(this@SearchActivity) + setOnSuggestionListener(SearchHelper.SuggestionListener(this)) + setOnQueryTextListener(this@SearchActivity) - if (query.isNullOrBlank()) { - searchView.requestFocus() - searchView.showKeyboard() - } else { - searchView.setQuery(query, true) + if (query.isNullOrBlank()) { + requestFocus() + showKeyboard() + } else { + setQuery(query, true) + } } } override fun onDestroy() { - searchView.suggestionsAdapter?.changeCursor(null) //close cursor + binding.searchView.suggestionsAdapter.changeCursor(null) //close cursor super.onDestroy() } @@ -49,7 +51,7 @@ class SearchActivity : BaseActivity(), SearchView.OnQueryTextListener { .beginTransaction() .replace(R.id.container, SearchFragment.newInstance(source, query)) .commit() - searchView.clearFocus() + binding.searchView.clearFocus() MangaSuggestionsProvider.saveQueryAsync(applicationContext, query) true } else false diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchFragment.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchFragment.kt index bf7e5307a..1c9ab57c9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchFragment.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.search.ui -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.list.ui.MangaListFragment diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchHelper.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchHelper.kt index 7cbdad906..5ca13fad5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchHelper.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchHelper.kt @@ -12,7 +12,6 @@ import java.io.Closeable object SearchHelper { - @JvmStatic fun setupSearchView(menuItem: MenuItem): Closeable? { val view = menuItem.actionView as? SearchView ?: return null val context = view.context diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt index acddcca71..798d26f33 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt @@ -5,12 +5,13 @@ import android.content.Intent import android.os.Bundle import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity +import org.koitharu.kotatsu.databinding.ActivitySearchGlobalBinding -class GlobalSearchActivity : BaseActivity() { +class GlobalSearchActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_search_global) + setContentView(ActivitySearchGlobalBinding.inflate(layoutInflater)) val query = intent.getStringExtra(EXTRA_QUERY) if (query == null) { diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchFragment.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchFragment.kt index 515748775..5f0b13a73 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchFragment.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.search.ui.global -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.utils.ext.stringArgument diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt index e052e4109..2972fd239 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -10,13 +10,14 @@ import androidx.preference.PreferenceFragmentCompat import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.databinding.ActivitySettingsBinding -class SettingsActivity : BaseActivity(), +class SettingsActivity : BaseActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_settings) + setContentView(ActivitySettingsBinding.inflate(layoutInflater)) supportActionBar?.setDisplayHomeAsUpEnabled(true) if (supportFragmentManager.findFragmentById(R.id.container) == null) { diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt index 0a8b077f2..3e45efd24 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt @@ -2,7 +2,7 @@ package org.koitharu.kotatsu.settings import android.net.Uri import org.koin.android.ext.koin.androidContext -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.core.backup.BackupRepository import org.koitharu.kotatsu.core.backup.RestoreRepository diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt index 3b1380a4b..2eb2e517c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt @@ -1,26 +1,33 @@ package org.koitharu.kotatsu.settings.backup import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible -import kotlinx.android.synthetic.main.dialog_progress.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.AlertDialogFragment +import org.koitharu.kotatsu.databinding.DialogProgressBinding import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.progress.Progress import java.io.File -class BackupDialogFragment : AlertDialogFragment(R.layout.dialog_progress) { +class BackupDialogFragment : AlertDialogFragment() { private val viewModel by viewModel() + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = DialogProgressBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - textView_title.setText(R.string.create_backup) - textView_subtitle.setText(R.string.processing_) + binding.textViewTitle.setText(R.string.create_backup) + binding.textViewSubtitle.setText(R.string.processing_) viewModel.progress.observe(viewLifecycleOwner, this::onProgressChanged) viewModel.onBackupDone.observe(viewLifecycleOwner, this::onBackupDone) @@ -42,7 +49,7 @@ class BackupDialogFragment : AlertDialogFragment(R.layout.dialog_progress) { } private fun onProgressChanged(progress: Progress?) { - with(progressBar) { + with(binding.progressBar) { isVisible = true isIndeterminate = progress == null if (progress != null) { diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupSettingsFragment.kt index b7cc6ec68..93bde0e64 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupSettingsFragment.kt @@ -7,7 +7,6 @@ import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.preference.Preference import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_list.* import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BasePreferenceFragment @@ -39,7 +38,7 @@ class BackupSettingsFragment : BasePreferenceFragment(R.string.backup_restore), e.printStackTrace() } Snackbar.make( - recyclerView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT + listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT ).show() } true diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreDialogFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreDialogFragment.kt index 84e85dd8f..bd880aa06 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreDialogFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreDialogFragment.kt @@ -2,21 +2,28 @@ package org.koitharu.kotatsu.settings.backup import android.net.Uri import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible -import kotlinx.android.synthetic.main.dialog_progress.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.core.backup.CompositeResult +import org.koitharu.kotatsu.databinding.DialogProgressBinding import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.toUriOrNull import org.koitharu.kotatsu.utils.ext.withArgs import org.koitharu.kotatsu.utils.progress.Progress -class RestoreDialogFragment : AlertDialogFragment(R.layout.dialog_progress) { +class RestoreDialogFragment : AlertDialogFragment() { + + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = DialogProgressBinding.inflate(inflater, container, false) private val viewModel by viewModel { parametersOf(arguments?.getString(ARG_FILE)?.toUriOrNull()) @@ -24,8 +31,8 @@ class RestoreDialogFragment : AlertDialogFragment(R.layout.dialog_progress) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - textView_title.setText(R.string.restore_backup) - textView_subtitle.setText(R.string.preparing_) + binding.textViewTitle.setText(R.string.restore_backup) + binding.textViewSubtitle.setText(R.string.preparing_) viewModel.progress.observe(viewLifecycleOwner, this::onProgressChanged) viewModel.onRestoreDone.observe(viewLifecycleOwner, this::onRestoreDone) @@ -46,7 +53,7 @@ class RestoreDialogFragment : AlertDialogFragment(R.layout.dialog_progress) { } private fun onProgressChanged(progress: Progress?) { - with(progressBar) { + with(binding.progressBar) { isVisible = true isIndeterminate = progress == null if (progress != null) { diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourceViewHolder.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourceViewHolder.kt index 5039e1bc9..1d81f8e4c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourceViewHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourceViewHolder.kt @@ -1,16 +1,18 @@ package org.koitharu.kotatsu.settings.sources +import android.view.LayoutInflater import android.view.ViewGroup -import kotlinx.android.synthetic.main.item_source_config.* -import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.databinding.ItemSourceConfigBinding class SourceViewHolder(parent: ViewGroup) : - BaseViewHolder(parent, R.layout.item_source_config) { + BaseViewHolder( + ItemSourceConfigBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ) { override fun onBind(data: MangaSource, extra: Boolean) { - textView_title.text = data.title - imageView_hidden.isChecked = extra + binding.textViewTitle.text = data.title + binding.imageViewHidden.isChecked = extra } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesAdapter.kt index a4e4ddd60..29ed9c3e8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesAdapter.kt @@ -4,7 +4,6 @@ import android.annotation.SuppressLint import android.view.MotionEvent import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.item_source_config.* import org.koitharu.kotatsu.base.domain.MangaProviderFactory import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.MangaSource @@ -38,7 +37,7 @@ class SourcesAdapter( @SuppressLint("ClickableViewAccessibility") private fun onViewHolderCreated(holder: SourceViewHolder) { - holder.imageView_hidden.setOnCheckedChangeListener { + holder.binding.imageViewHidden.setOnCheckedChangeListener { if (it) { hiddenItems.remove(holder.requireData()) } else { @@ -46,10 +45,10 @@ class SourcesAdapter( } settings.hiddenSources = hiddenItems.mapToSet { x -> x.name } } - holder.imageView_config.setOnClickListener { v -> + holder.binding.imageViewConfig.setOnClickListener { v -> onItemClickListener.onItemClick(holder.requireData(), v) } - holder.imageView_handle.setOnTouchListener { v, event -> + holder.binding.imageViewHandle.setOnTouchListener { v, event -> if (event.actionMasked == MotionEvent.ACTION_DOWN) { onItemClickListener.onItemLongClick( holder.requireData(), diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt index 51d1ac860..cc8ad3f10 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt @@ -1,19 +1,21 @@ package org.koitharu.kotatsu.settings.sources import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.fragment_settings_sources.* import org.koin.android.ext.android.get import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.databinding.FragmentSettingsSourcesBinding import org.koitharu.kotatsu.settings.SettingsActivity -class SourcesSettingsFragment : BaseFragment(R.layout.fragment_settings_sources), +class SourcesSettingsFragment : BaseFragment(), OnListItemClickListener { private lateinit var reorderHelper: ItemTouchHelper @@ -23,6 +25,11 @@ class SourcesSettingsFragment : BaseFragment(R.layout.fragment_settings_sources) reorderHelper = ItemTouchHelper(SourcesReorderCallback()) } + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentSettingsSourcesBinding.inflate(inflater, container, false) + override fun onResume() { super.onResume() activity?.setTitle(R.string.remote_sources) @@ -30,9 +37,11 @@ class SourcesSettingsFragment : BaseFragment(R.layout.fragment_settings_sources) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - recyclerView.addItemDecoration(DividerItemDecoration(view.context, RecyclerView.VERTICAL)) - recyclerView.adapter = SourcesAdapter(get(), this) - reorderHelper.attachToRecyclerView(recyclerView) + with(binding.recyclerView) { + addItemDecoration(DividerItemDecoration(view.context, RecyclerView.VERTICAL)) + adapter = SourcesAdapter(get(), this@SourcesSettingsFragment) + reorderHelper.attachToRecyclerView(this) + } } override fun onDestroyView() { @@ -46,7 +55,7 @@ class SourcesSettingsFragment : BaseFragment(R.layout.fragment_settings_sources) override fun onItemLongClick(item: MangaSource, view: View): Boolean { reorderHelper.startDrag( - recyclerView.findContainingViewHolder(view) ?: return false + binding.recyclerView.findContainingViewHolder(view) ?: return false ) return true } diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/TrackerModule.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/TrackerModule.kt index 2d7a2ab7e..0230444f9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/tracker/TrackerModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/TrackerModule.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.tracker import org.koin.android.ext.koin.androidContext -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.tracker.domain.TrackingRepository import org.koitharu.kotatsu.tracker.ui.FeedViewModel diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt index 13b416f64..ef05ce1e9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt @@ -1,32 +1,29 @@ package org.koitharu.kotatsu.tracker.ui import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View +import android.view.* import androidx.core.view.isVisible import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_tracklogs.* import org.koin.android.ext.android.get -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.base.ui.list.PaginationScrollListener import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.databinding.FragmentFeedBinding import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.tracker.work.TrackWorker import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.hasItems -class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), PaginationScrollListener.Callback, +class FeedFragment : BaseFragment(), PaginationScrollListener.Callback, OnListItemClickListener { private val viewModel by viewModel() - private var adapter: FeedAdapter? = null + private var feedAdapter: FeedAdapter? = null override fun getTitle() = context?.getString(R.string.updates) @@ -35,15 +32,22 @@ class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), PaginationScroll setHasOptionsMenu(true) } + override fun onInflateView( + inflater: LayoutInflater, + container: ViewGroup? + ) = FragmentFeedBinding.inflate(inflater, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - adapter = FeedAdapter(get(), this) - recyclerView.adapter = adapter - recyclerView.addItemDecoration( - SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing)) - ) - recyclerView.setHasFixedSize(true) - recyclerView.addOnScrollListener(PaginationScrollListener(4, this)) + feedAdapter = FeedAdapter(get(), this) + with(binding.recyclerView) { + adapter = feedAdapter + addItemDecoration( + SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing)) + ) + setHasFixedSize(true) + addOnScrollListener(PaginationScrollListener(4, this@FeedFragment)) + } viewModel.content.observe(viewLifecycleOwner, this::onListChanged) viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged) @@ -59,47 +63,56 @@ class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), PaginationScroll override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { R.id.action_update -> { TrackWorker.startNow(requireContext()) - Snackbar.make(recyclerView, R.string.feed_will_update_soon, Snackbar.LENGTH_LONG).show() + Snackbar.make( + binding.recyclerView, + R.string.feed_will_update_soon, + Snackbar.LENGTH_LONG + ).show() true } else -> super.onOptionsItemSelected(item) } override fun onDestroyView() { - adapter = null + feedAdapter = null super.onDestroyView() } private fun onListChanged(list: List) { - adapter?.items = list + feedAdapter?.items = list } private fun onError(e: Throwable) { - if (recyclerView.hasItems) { - Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT) - .show() + if (binding.recyclerView.hasItems) { + Snackbar.make( + binding.recyclerView, + e.getDisplayMessage(resources), + Snackbar.LENGTH_SHORT + ).show() } else { - textView_holder.text = e.getDisplayMessage(resources) - textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds( - 0, - R.drawable.ic_error_large, - 0, - 0 - ) - layout_holder.isVisible = true + with(binding.textViewHolder) { + text = e.getDisplayMessage(resources) + setCompoundDrawablesRelativeWithIntrinsicBounds( + 0, + R.drawable.ic_error_large, + 0, + 0 + ) + isVisible = true + } } } private fun onLoadingStateChanged(isLoading: Boolean) { - val hasItems = recyclerView.hasItems - progressBar.isVisible = isLoading && !hasItems + val hasItems = binding.recyclerView.hasItems + binding.progressBar.isVisible = isLoading && !hasItems } private fun onEmptyStateChanged(isEmpty: Boolean) { if (isEmpty) { setUpEmptyListHolder() } - layout_holder.isVisible = isEmpty + binding.layoutHolder.isVisible = isEmpty } override fun onScrolledToEnd() { @@ -111,8 +124,10 @@ class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), PaginationScroll } private fun setUpEmptyListHolder() { - textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null) - textView_holder.setText(R.string.text_feed_holder) + with(binding.textViewHolder) { + setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null) + setText(R.string.text_feed_holder) + } } companion object { diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/adapter/FeedItemAD.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/adapter/FeedItemAD.kt index a4b01a155..afb9b6ce8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/adapter/FeedItemAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/adapter/FeedItemAD.kt @@ -2,11 +2,11 @@ package org.koitharu.kotatsu.tracker.ui.adapter import coil.ImageLoader import coil.request.Disposable -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import kotlinx.android.synthetic.main.item_tracklog.* +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.databinding.ItemTracklogBinding import org.koitharu.kotatsu.tracker.ui.model.FeedItem import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest @@ -14,7 +14,9 @@ import org.koitharu.kotatsu.utils.ext.newImageRequest fun feedItemAD( coil: ImageLoader, clickListener: OnListItemClickListener -) = adapterDelegateLayoutContainer(R.layout.item_tracklog) { +) = adapterDelegateViewBinding( + { inflater, parent -> ItemTracklogBinding.inflate(inflater, parent, false) } +) { var imageRequest: Disposable? = null @@ -24,18 +26,18 @@ fun feedItemAD( bind { imageRequest?.dispose() - imageRequest = imageView_cover.newImageRequest(item.imageUrl) + imageRequest = binding.imageViewCover.newImageRequest(item.imageUrl) .placeholder(R.drawable.ic_placeholder) .fallback(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .enqueueWith(coil) - textView_title.text = item.title - textView_subtitle.text = item.subtitle - textView_chapters.text = item.chapters + binding.textViewTitle.text = item.title + binding.textViewSubtitle.text = item.subtitle + binding.textViewChapters.text = item.chapters } onViewRecycled { imageRequest?.dispose() - imageView_cover.setImageDrawable(null) + binding.imageViewCover.setImageDrawable(null) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/FileSizeUtils.kt b/app/src/main/java/org/koitharu/kotatsu/utils/FileSizeUtils.kt index 0f3dabfc7..2c45c2e22 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/FileSizeUtils.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/FileSizeUtils.kt @@ -9,13 +9,10 @@ import kotlin.math.pow object FileSizeUtils { - @JvmStatic fun mbToBytes(mb: Int) = 1024L * 1024L * mb - @JvmStatic fun kbToBytes(kb: Int) = 1024L * kb - @JvmStatic fun formatBytes(context: Context, bytes: Long): String { val units = context.getString(R.string.text_file_sizes).split('|') if (bytes <= 0) { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/MediaStoreCompat.kt b/app/src/main/java/org/koitharu/kotatsu/utils/MediaStoreCompat.kt index 0d0127a03..40c8c033d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/MediaStoreCompat.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/MediaStoreCompat.kt @@ -13,7 +13,6 @@ import java.io.OutputStream object MediaStoreCompat { - @JvmStatic fun insertImage( resolver: ContentResolver, fileName: String, diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/progress/Progress.kt b/app/src/main/java/org/koitharu/kotatsu/utils/progress/Progress.kt index fadec62c5..44d01f33a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/progress/Progress.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/progress/Progress.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.utils.progress import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class Progress( diff --git a/app/src/main/java/org/koitharu/kotatsu/widget/AppWidgetModule.kt b/app/src/main/java/org/koitharu/kotatsu/widget/AppWidgetModule.kt index 41a45f413..3023da8b0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/widget/AppWidgetModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/AppWidgetModule.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.widget -import org.koin.android.viewmodel.dsl.viewModel +import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module import org.koitharu.kotatsu.widget.shelf.ShelfConfigViewModel diff --git a/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt index 011996af9..0d8cfa567 100644 --- a/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt @@ -13,17 +13,17 @@ import androidx.core.view.isVisible import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.activity_categories.* -import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.prefs.AppWidgetConfig +import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.widget.shelf.adapter.CategorySelectAdapter import org.koitharu.kotatsu.widget.shelf.model.CategoryItem -class ShelfConfigActivity : BaseActivity(), OnListItemClickListener { +class ShelfConfigActivity : BaseActivity(), OnListItemClickListener { private val viewModel by viewModel() @@ -32,13 +32,13 @@ class ShelfConfigActivity : BaseActivity(), OnListItemClickListener -) = adapterDelegateLayoutContainer( - R.layout.item_category_checkable_single +) = adapterDelegateViewBinding( + { inflater, parent -> ItemCategoryCheckableSingleBinding.inflate(inflater, parent, false) } ) { itemView.setOnClickListener { @@ -17,7 +17,9 @@ fun categorySelectItemAD( } bind { - checkedTextView.text = item.name ?: getString(R.string.all_favourites) - checkedTextView.isChecked = item.isSelected + with(binding.checkedTextView) { + text = item.name ?: getString(R.string.all_favourites) + isChecked = item.isSelected + } } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_cloudflare.xml b/app/src/main/res/layout/fragment_cloudflare.xml index 38289e9bf..75d2d813d 100644 --- a/app/src/main/res/layout/fragment_cloudflare.xml +++ b/app/src/main/res/layout/fragment_cloudflare.xml @@ -11,14 +11,13 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - + app:indicatorColor="?colorAccent" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_tracklogs.xml b/app/src/main/res/layout/fragment_feed.xml similarity index 100% rename from app/src/main/res/layout/fragment_tracklogs.xml rename to app/src/main/res/layout/fragment_feed.xml