diff --git a/app/build.gradle b/app/build.gradle
index f5c483557..60df07a42 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,16 +7,16 @@ plugins {
}
android {
- compileSdkVersion 32
- buildToolsVersion '32.0.0'
+ compileSdkVersion 33
+ buildToolsVersion '33.0.0'
namespace 'org.koitharu.kotatsu'
defaultConfig {
applicationId 'org.koitharu.kotatsu'
minSdkVersion 21
- targetSdkVersion 32
- versionCode 491
- versionName '4.0-a2'
+ targetSdkVersion 33
+ versionCode 492
+ versionName '4.0-a3'
generatedDensities = []
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -117,19 +117,19 @@ dependencies {
implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl:4.3.2'
implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:4.3.2'
- implementation "com.google.dagger:hilt-android:2.42"
- kapt "com.google.dagger:hilt-compiler:2.42"
+ implementation "com.google.dagger:hilt-android:2.43.2"
+ kapt "com.google.dagger:hilt-compiler:2.43.2"
implementation 'androidx.hilt:hilt-work:1.0.0'
kapt 'androidx.hilt:hilt-compiler:1.0.0'
implementation 'io.coil-kt:coil-base:2.2.0'
- implementation 'io.coil-kt:coil-svg:2.1.0'
+ implementation 'io.coil-kt:coil-svg:2.2.0'
// implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0'
implementation 'com.github.KotatsuApp:subsampling-scale-image-view:2942b797a2'
implementation 'com.github.solkin:disk-lru-cache:1.4'
- implementation 'ch.acra:acra-http:5.9.5'
- implementation 'ch.acra:acra-dialog:5.9.5'
+ implementation 'ch.acra:acra-http:5.9.6'
+ implementation 'ch.acra:acra-dialog:5.9.6'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
@@ -147,6 +147,6 @@ dependencies {
androidTestImplementation 'androidx.room:room-testing:2.4.3'
androidTestImplementation 'com.squareup.moshi:moshi-kotlin:1.13.0'
- androidTestImplementation 'com.google.dagger:hilt-android-testing:2.42'
- kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.42'
+ androidTestImplementation 'com.google.dagger:hilt-android-testing:2.43.2'
+ kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.43.2'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 22d6ecda5..39ac95b1a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,6 +17,7 @@
+
+ android:foregroundServiceType="dataSync"
+ android:stopWithTask="false" />
(KEY_MANGA)?.manga,
+ manga = intent?.getParcelableExtraCompat(KEY_MANGA)?.manga,
mangaId = intent?.getLongExtra(KEY_ID, ID_NONE) ?: ID_NONE,
- uri = intent?.data
+ uri = intent?.data,
)
constructor(args: Bundle?) : this(
- manga = args?.getParcelable(KEY_MANGA)?.manga,
+ manga = args?.getParcelableCompat(KEY_MANGA)?.manga,
mangaId = args?.getLong(KEY_ID, ID_NONE) ?: ID_NONE,
- uri = null
+ uri = null,
)
companion object {
diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/fastscroll/BubbleAnimator.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/fastscroll/BubbleAnimator.kt
index 591fd6b99..36b5e0e5f 100644
--- a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/fastscroll/BubbleAnimator.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/fastscroll/BubbleAnimator.kt
@@ -8,16 +8,18 @@ import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
+import kotlin.math.hypot
import org.koitharu.kotatsu.utils.ext.animatorDurationScale
import org.koitharu.kotatsu.utils.ext.measureWidth
-import kotlin.math.hypot
class BubbleAnimator(
private val bubble: View,
) {
- private val animationDuration = (bubble.resources.getInteger(android.R.integer.config_shortAnimTime) *
- bubble.context.animatorDurationScale).toLong()
+ private val animationDuration = (
+ bubble.resources.getInteger(android.R.integer.config_shortAnimTime) *
+ bubble.context.animatorDurationScale
+ ).toLong()
private var animator: Animator? = null
private var isHiding = false
@@ -65,12 +67,12 @@ class BubbleAnimator(
private var isCancelled = false
- override fun onAnimationCancel(animation: Animator?) {
+ override fun onAnimationCancel(animation: Animator) {
super.onAnimationCancel(animation)
isCancelled = true
}
- override fun onAnimationEnd(animation: Animator?) {
+ override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
if (!isCancelled && animation === this@BubbleAnimator.animator) {
bubble.isInvisible = true
@@ -79,4 +81,4 @@ class BubbleAnimator(
}
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/fastscroll/ScrollbarAnimator.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/fastscroll/ScrollbarAnimator.kt
index a00fc90b9..0a87f5262 100644
--- a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/fastscroll/ScrollbarAnimator.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/fastscroll/ScrollbarAnimator.kt
@@ -14,8 +14,10 @@ class ScrollbarAnimator(
private val scrollbarPaddingEnd: Float,
) {
- private val animationDuration = (scrollbar.resources.getInteger(R.integer.config_defaultAnimTime) *
- scrollbar.context.animatorDurationScale).toLong()
+ private val animationDuration = (
+ scrollbar.resources.getInteger(R.integer.config_defaultAnimTime) *
+ scrollbar.context.animatorDurationScale
+ ).toLong()
private var animator: ViewPropertyAnimator? = null
private var isHiding = false
@@ -40,30 +42,32 @@ class ScrollbarAnimator(
}
animator?.cancel()
isHiding = true
- animator = scrollbar
- .animate()
- .translationX(scrollbarPaddingEnd)
- .alpha(0f)
- .setDuration(animationDuration)
- .setListener(HideListener())
+ animator = scrollbar.animate().apply {
+ translationX(scrollbarPaddingEnd)
+ alpha(0f)
+ duration = animationDuration
+ setListener(HideListener(this))
+ }
}
- private inner class HideListener : AnimatorListenerAdapter() {
+ private inner class HideListener(
+ private val viewPropertyAnimator: ViewPropertyAnimator,
+ ) : AnimatorListenerAdapter() {
private var isCancelled = false
- override fun onAnimationCancel(animation: Animator?) {
+ override fun onAnimationCancel(animation: Animator) {
super.onAnimationCancel(animation)
isCancelled = true
}
- override fun onAnimationEnd(animation: Animator?) {
+ override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
- if (!isCancelled && animation === this@ScrollbarAnimator.animator) {
+ if (!isCancelled && this@ScrollbarAnimator.animator === viewPropertyAnimator) {
scrollbar.isInvisible = true
isHiding = false
this@ScrollbarAnimator.animator = null
}
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SlidingBottomNavigationView.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SlidingBottomNavigationView.kt
index f012d9a95..3e9e7b55d 100644
--- a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SlidingBottomNavigationView.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SlidingBottomNavigationView.kt
@@ -100,7 +100,7 @@ class SlidingBottomNavigationView @JvmOverloads constructor(
.applySystemAnimatorScale(context)
.setListener(
object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) {
+ override fun onAnimationEnd(animation: Animator) {
currentAnimator = null
postInvalidate()
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/ui/MangaErrorDialog.kt b/app/src/main/java/org/koitharu/kotatsu/core/ui/MangaErrorDialog.kt
index 532816f89..b5781451a 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/ui/MangaErrorDialog.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/ui/MangaErrorDialog.kt
@@ -16,6 +16,8 @@ import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
import org.koitharu.kotatsu.databinding.DialogMangaErrorBinding
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.utils.ext.report
+import org.koitharu.kotatsu.utils.ext.requireParcelable
+import org.koitharu.kotatsu.utils.ext.requireSerializable
import org.koitharu.kotatsu.utils.ext.withArgs
class MangaErrorDialog : AlertDialogFragment() {
@@ -26,8 +28,8 @@ class MangaErrorDialog : AlertDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val args = requireArguments()
- manga = requireNotNull(args.getParcelable(ARG_MANGA)?.manga)
- error = args.getSerializable(ARG_ERROR) as Throwable
+ manga = args.requireParcelable(ARG_MANGA).manga
+ error = args.requireSerializable(ARG_ERROR)
}
override fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): DialogMangaErrorBinding {
diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersMenuProvider.kt
index d9ca082ee..1733523b7 100644
--- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersMenuProvider.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersMenuProvider.kt
@@ -35,13 +35,13 @@ class ChaptersMenuProvider(
else -> false
}
- override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
+ override fun onMenuItemActionExpand(item: MenuItem): Boolean {
bottomSheetMediator?.lock()
return true
}
- override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
- (item?.actionView as? SearchView)?.setQuery("", false)
+ override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
+ (item.actionView as? SearchView)?.setQuery("", false)
viewModel.performChapterSearch(null)
bottomSheetMediator?.unlock()
return true
diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt
index fb0c023c4..e22b5cd86 100644
--- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt
@@ -25,6 +25,7 @@ import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity
import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.utils.ext.assistedViewModels
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
+import org.koitharu.kotatsu.utils.ext.getSerializableCompat
@AndroidEntryPoint
class FavouritesCategoryEditActivity :
@@ -69,8 +70,8 @@ class FavouritesCategoryEditActivity :
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
- val order = savedInstanceState.getSerializable(KEY_SORT_ORDER)
- if (order != null && order is SortOrder) {
+ val order = savedInstanceState.getSerializableCompat(KEY_SORT_ORDER)
+ if (order != null) {
selectedSortOrder = order
}
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/history/ui/util/ReadingProgressView.kt b/app/src/main/java/org/koitharu/kotatsu/history/ui/util/ReadingProgressView.kt
index fdf161282..243e8cb5d 100644
--- a/app/src/main/java/org/koitharu/kotatsu/history/ui/util/ReadingProgressView.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/history/ui/util/ReadingProgressView.kt
@@ -56,17 +56,17 @@ class ReadingProgressView @JvmOverloads constructor(
getProgressDrawable().progress = p
}
- override fun onAnimationStart(animation: Animator?) = Unit
+ override fun onAnimationStart(animation: Animator) = Unit
- override fun onAnimationEnd(animation: Animator?) {
+ override fun onAnimationEnd(animation: Animator) {
if (percentAnimator === animation) {
percentAnimator = null
}
}
- override fun onAnimationCancel(animation: Animator?) = Unit
+ override fun onAnimationCancel(animation: Animator) = Unit
- override fun onAnimationRepeat(animation: Animator?) = Unit
+ override fun onAnimationRepeat(animation: Animator) = Unit
fun setPercent(value: Float, animate: Boolean) {
val currentDrawable = peekProgressDrawable()
diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/ItemSizeResolver.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/ItemSizeResolver.kt
index 7b7b68582..64747aedd 100644
--- a/app/src/main/java/org/koitharu/kotatsu/list/ui/ItemSizeResolver.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/ItemSizeResolver.kt
@@ -47,12 +47,12 @@ class ItemSizeResolver(resources: Resources, private val settings: AppSettings)
}
}
- override fun onViewAttachedToWindow(v: View?) {
+ override fun onViewAttachedToWindow(v: View) {
settings.subscribe(this)
update()
}
- override fun onViewDetachedFromWindow(v: View?) {
+ override fun onViewDetachedFromWindow(v: View) {
settings.unsubscribe(this)
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt
index c80f7358a..6da92b951 100644
--- a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt
@@ -6,7 +6,6 @@ import android.os.Bundle
import android.view.*
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.FragmentManager
-import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseBottomSheet
import org.koitharu.kotatsu.databinding.SheetFilterBinding
@@ -39,7 +38,7 @@ class FilterBottomSheet :
initOptionsMenu()
}
- override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
+ override fun onMenuItemActionExpand(item: MenuItem): Boolean {
setExpanded(isExpanded = true, isLocked = true)
return true
}
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 48349e846..507dafe25 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
@@ -1,5 +1,8 @@
package org.koitharu.kotatsu.main.ui
+import android.Manifest
+import android.content.pm.PackageManager.PERMISSION_GRANTED
+import android.os.Build
import android.os.Bundle
import android.util.SparseIntArray
import android.view.MenuItem
@@ -7,6 +10,7 @@ import android.view.View
import androidx.activity.result.ActivityResultCallback
import androidx.activity.viewModels
import androidx.appcompat.view.ActionMode
+import androidx.core.app.ActivityCompat
import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.ContextCompat
import androidx.core.graphics.Insets
@@ -24,7 +28,6 @@ import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
-import kotlinx.coroutines.yield
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseActivity
import org.koitharu.kotatsu.base.ui.widgets.SlidingBottomNavigationView
@@ -291,12 +294,11 @@ class MainActivity :
TrackWorker.setup(applicationContext)
SuggestionsWorker.setup(applicationContext)
}
+ requestNotificationsPermission()
when {
!settings.isSourcesSelected -> OnboardDialogFragment.showWelcome(supportFragmentManager)
settings.newSources.isNotEmpty() -> NewSourcesDialogFragment.show(supportFragmentManager)
}
- yield()
- // TODO get().requestFullSyncAndGc(get())
}
}
@@ -347,6 +349,15 @@ class MainActivity :
showNav(!isOpened)
}
+ private fun requestNotificationsPermission() {
+ if (
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
+ ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PERMISSION_GRANTED
+ ) {
+ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1)
+ }
+ }
+
private inner class VoiceInputCallback : ActivityResultCallback {
override fun onActivityResult(result: String?) {
diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainViewModel.kt
index 1f117f03f..0805d872e 100644
--- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainViewModel.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainViewModel.kt
@@ -9,11 +9,12 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.combine
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseViewModel
+import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException
import org.koitharu.kotatsu.core.github.AppUpdateRepository
-import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.history.domain.HistoryRepository
import org.koitharu.kotatsu.parsers.model.Manga
+import org.koitharu.kotatsu.sync.domain.SyncController
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import org.koitharu.kotatsu.utils.SingleLiveEvent
import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
@@ -23,6 +24,8 @@ class MainViewModel @Inject constructor(
private val historyRepository: HistoryRepository,
private val appUpdateRepository: AppUpdateRepository,
private val trackingRepository: TrackingRepository,
+ syncController: SyncController,
+ database: MangaDatabase,
) : BaseViewModel() {
val onOpenReader = SingleLiveEvent()
@@ -45,6 +48,9 @@ class MainViewModel @Inject constructor(
launchJob {
appUpdateRepository.fetchUpdate()
}
+ launchJob {
+ syncController.requestFullSyncAndGc(database)
+ }
}
fun openLastReader() {
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 b3d0322bf..4a6886068 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
@@ -22,6 +22,7 @@ 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
+import org.koitharu.kotatsu.utils.ext.getParcelableExtraCompat
@AndroidEntryPoint
class ProtectActivity :
@@ -44,7 +45,7 @@ class ProtectActivity :
viewModel.onError.observe(this, this::onError)
viewModel.isLoading.observe(this, this::onLoadingStateChanged)
viewModel.onUnlockSuccess.observe(this) {
- val intent = intent.getParcelableExtra(EXTRA_INTENT)
+ val intent = intent.getParcelableExtraCompat(EXTRA_INTENT)
startActivity(intent)
finishAfterTransition()
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt
index 7d4eb83e1..9efa3cef6 100644
--- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt
@@ -6,6 +6,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import dagger.hilt.android.AndroidEntryPoint
+import javax.inject.Inject
+import kotlin.math.roundToInt
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseBottomSheet
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
@@ -17,9 +19,8 @@ import org.koitharu.kotatsu.details.ui.model.ChapterListItem
import org.koitharu.kotatsu.details.ui.model.toListItem
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback
+import org.koitharu.kotatsu.utils.ext.getParcelableCompat
import org.koitharu.kotatsu.utils.ext.withArgs
-import javax.inject.Inject
-import kotlin.math.roundToInt
@AndroidEntryPoint
class ChaptersBottomSheet : BaseBottomSheet(), OnListItemClickListener {
@@ -33,7 +34,7 @@ class ChaptersBottomSheet : BaseBottomSheet(), OnListItemC
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- val chapters = arguments?.getParcelable(ARG_CHAPTERS)?.chapters
+ val chapters = arguments?.getParcelableCompat(ARG_CHAPTERS)?.chapters
if (chapters.isNullOrEmpty()) {
dismissAllowingStateLoss()
return
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 ecee19b44..e958796b1 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
@@ -63,7 +63,7 @@ class ReaderActivity :
val viewModel by assistedViewModels {
viewModelFactory.create(
intent = MangaIntent(intent),
- initialState = intent?.getParcelableExtra(EXTRA_STATE),
+ initialState = intent?.getParcelableExtraCompat(EXTRA_STATE),
preselectedBranch = intent?.getStringExtra(EXTRA_BRANCH),
)
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReader.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReader.kt
index 52894b4da..6bd234afd 100644
--- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReader.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReader.kt
@@ -8,6 +8,7 @@ import androidx.viewbinding.ViewBinding
import org.koitharu.kotatsu.base.ui.BaseFragment
import org.koitharu.kotatsu.reader.ui.ReaderState
import org.koitharu.kotatsu.reader.ui.ReaderViewModel
+import org.koitharu.kotatsu.utils.ext.getParcelableCompat
private const val KEY_STATE = "state"
@@ -18,7 +19,7 @@ abstract class BaseReader : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- var restoredState = savedInstanceState?.getParcelable(KEY_STATE)
+ var restoredState = savedInstanceState?.getParcelableCompat(KEY_STATE)
viewModel.content.observe(viewLifecycleOwner) {
onPagesChanged(it.pages, restoredState ?: it.state)
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 96740a971..fe9122989 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
@@ -24,6 +24,7 @@ import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.reader.domain.PageLoader
import org.koitharu.kotatsu.reader.ui.ReaderActivity
import org.koitharu.kotatsu.reader.ui.thumbnails.adapter.PageThumbnailAdapter
+import org.koitharu.kotatsu.utils.ext.getParcelableCompat
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
import org.koitharu.kotatsu.utils.ext.withArgs
@@ -52,7 +53,7 @@ class PagesThumbnailsSheet :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- val pages = arguments?.getParcelable(ARG_PAGES)?.pages
+ val pages = arguments?.getParcelableCompat(ARG_PAGES)?.pages
if (pages.isNullOrEmpty()) {
dismissAllowingStateLoss()
return
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 9148a373b..2779c5d33 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
@@ -99,7 +99,7 @@ class RemoteListFragment : MangaListFragment() {
override fun onQueryTextChange(newText: String?): Boolean = false
- override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
+ override fun onMenuItemActionExpand(item: MenuItem): Boolean {
(activity as? AppBarOwner)?.appBar?.setExpanded(false, true)
return true
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt
index 06045eae9..151452acb 100644
--- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt
@@ -26,6 +26,7 @@ import org.koitharu.kotatsu.scrobbling.ui.selector.adapter.ShikiMangaSelectionDe
import org.koitharu.kotatsu.scrobbling.ui.selector.adapter.ShikimoriSelectorAdapter
import org.koitharu.kotatsu.utils.ext.assistedViewModels
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
+import org.koitharu.kotatsu.utils.ext.requireParcelable
import org.koitharu.kotatsu.utils.ext.withArgs
@AndroidEntryPoint
@@ -47,7 +48,7 @@ class ScrobblingSelectorBottomSheet :
private val viewModel by assistedViewModels {
viewModelFactory.create(
- requireNotNull(requireArguments().getParcelable(MangaIntent.KEY_MANGA)).manga,
+ requireArguments().requireParcelable(MangaIntent.KEY_MANGA).manga,
)
}
@@ -84,7 +85,7 @@ class ScrobblingSelectorBottomSheet :
dismiss()
}
viewModel.searchQuery.observe(viewLifecycleOwner) {
- binding.headerBar.toolbar.subtitle = it
+ binding.headerBar.subtitle = it
}
}
@@ -102,7 +103,7 @@ class ScrobblingSelectorBottomSheet :
viewModel.loadList(append = true)
}
- override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
+ override fun onMenuItemActionExpand(item: MenuItem): Boolean {
setExpanded(isExpanded = true, isLocked = true)
return true
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaListActivity.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaListActivity.kt
index b3eca260d..6247a3707 100644
--- a/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaListActivity.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaListActivity.kt
@@ -17,6 +17,7 @@ import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.remotelist.ui.RemoteListFragment
+import org.koitharu.kotatsu.utils.ext.getParcelableExtraCompat
@AndroidEntryPoint
class MangaListActivity :
@@ -29,7 +30,7 @@ class MangaListActivity :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(ActivityContainerBinding.inflate(layoutInflater))
- val tags = intent.getParcelableExtra(EXTRA_TAGS)?.tags
+ val tags = intent.getParcelableExtraCompat(EXTRA_TAGS)?.tags
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val source = intent.getSerializableExtra(EXTRA_SOURCE) as? MangaSource ?: tags?.firstOrNull()?.source
if (source == null) {
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 816d9d31b..e1962a000 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
@@ -120,7 +120,7 @@ class SourcesSettingsFragment :
else -> false
}
- override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
+ override fun onMenuItemActionExpand(item: MenuItem): Boolean {
(activity as? AppBarOwner)?.appBar?.setExpanded(false, true)
return true
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/Bundle.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/Bundle.kt
new file mode 100644
index 000000000..3d7b2523c
--- /dev/null
+++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/Bundle.kt
@@ -0,0 +1,46 @@
+package org.koitharu.kotatsu.utils.ext
+
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.os.Parcelable
+import java.io.Serializable
+
+@Suppress("DEPRECATION")
+inline fun Bundle.getParcelableCompat(key: String): T? {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ getParcelable(key, T::class.java)
+ } else {
+ getParcelable(key) as? T
+ }
+}
+
+@Suppress("DEPRECATION")
+inline fun Intent.getParcelableExtraCompat(key: String): T? {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ getParcelableExtra(key, T::class.java)
+ } else {
+ getParcelableExtra(key) as? T
+ }
+}
+
+@Suppress("DEPRECATION")
+inline fun Bundle.getSerializableCompat(key: String): T? {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ getSerializable(key, T::class.java)
+ } else {
+ getSerializable(key) as? T
+ }
+}
+
+inline fun Bundle.requireSerializable(key: String): T {
+ return checkNotNull(getSerializableCompat(key)) {
+ "Serializable of type \"${T::class.java.name}\" not found at \"$key\""
+ }
+}
+
+inline fun Bundle.requireParcelable(key: String): T {
+ return checkNotNull(getParcelableCompat(key)) {
+ "Parcelable of type \"${T::class.java.name}\" not found at \"$key\""
+ }
+}
diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt
index ea4132ac5..41336e509 100644
--- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FragmentExt.kt
@@ -1,7 +1,6 @@
package org.koitharu.kotatsu.utils.ext
import android.os.Bundle
-import android.os.Parcelable
import androidx.core.view.MenuProvider
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
@@ -20,14 +19,6 @@ inline fun T.withArgs(size: Int, block: Bundle.() -> Unit): T {
val Fragment.viewLifecycleScope
inline get() = viewLifecycleOwner.lifecycle.coroutineScope
-fun Fragment.parcelableArgument(name: String): Lazy {
- return lazy(LazyThreadSafetyMode.NONE) {
- requireNotNull(arguments?.getParcelable(name)) {
- "No argument $name passed into ${javaClass.simpleName}"
- }
- }
-}
-
fun Fragment.serializableArgument(name: String): Lazy {
return lazy(LazyThreadSafetyMode.NONE) {
@Suppress("UNCHECKED_CAST")
diff --git a/build.gradle b/build.gradle
index a877a7cdd..3bf7a03ae 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.2.1'
+ classpath 'com.android.tools.build:gradle:7.2.2'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21'
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.42'
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 26b7873ed..35ed03800 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
-#Sun May 15 16:26:09 EEST 2022
+#Wed Aug 24 10:43:54 EEST 2022
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
-distributionSha256Sum=29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda
+distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4