diff --git a/app/build.gradle b/app/build.gradle
index 3e24d9a35..5f3632d76 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -83,7 +83,7 @@ dependencies {
}
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.8.21'
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.core:core-ktx:1.10.0'
@@ -140,14 +140,14 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.json:json:20230227'
- testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
+ testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.0'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.test:core-ktx:1.5.0'
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.5'
- androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
+ androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.0'
androidTestImplementation 'androidx.room:room-testing:2.5.1'
androidTestImplementation 'com.squareup.moshi:moshi-kotlin:1.14.0'
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index f2f5b932b..791a045d4 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -1,4 +1,5 @@
-optimizationpasses 8
+-dontobfuscate
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
public static void checkExpressionValueIsNotNull(...);
public static void checkNotNullExpressionValue(...);
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0b2110a2b..10faa7ae2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -163,10 +163,6 @@
-
+ android:exported="false"
+ tools:node="remove">
+
+
{
- @Suppress("unused")
constructor() : super()
- @Suppress("unused")
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
override fun onStartNestedScroll(
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/EntityMapping.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/EntityMapping.kt
index 467fcab9a..7bba6f4df 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/EntityMapping.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/EntityMapping.kt
@@ -1,7 +1,10 @@
package org.koitharu.kotatsu.core.db.entity
import org.koitharu.kotatsu.core.model.MangaSource
-import org.koitharu.kotatsu.parsers.model.*
+import org.koitharu.kotatsu.parsers.model.Manga
+import org.koitharu.kotatsu.parsers.model.MangaState
+import org.koitharu.kotatsu.parsers.model.MangaTag
+import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.parsers.util.mapToSet
import org.koitharu.kotatsu.parsers.util.toTitleCase
import org.koitharu.kotatsu.utils.ext.longHashCode
@@ -66,7 +69,6 @@ fun SortOrder(name: String, fallback: SortOrder): SortOrder = runCatching {
SortOrder.valueOf(name)
}.getOrDefault(fallback)
-@Suppress("FunctionName")
fun MangaState(name: String): MangaState? = runCatching {
MangaState.valueOf(name)
}.getOrNull()
diff --git a/app/src/main/java/org/koitharu/kotatsu/core/os/ShortcutsUpdater.kt b/app/src/main/java/org/koitharu/kotatsu/core/os/ShortcutsUpdater.kt
index 39708b1bd..1de7b7c35 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/os/ShortcutsUpdater.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/os/ShortcutsUpdater.kt
@@ -11,6 +11,7 @@ import androidx.annotation.VisibleForTesting
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
+import androidx.core.graphics.drawable.toBitmap
import androidx.room.InvalidationTracker
import coil.ImageLoader
import coil.request.ImageRequest
@@ -27,9 +28,9 @@ 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.reader.ui.ReaderActivity
+import org.koitharu.kotatsu.utils.ext.getDrawableOrThrow
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
import org.koitharu.kotatsu.utils.ext.processLifecycleScope
-import org.koitharu.kotatsu.utils.ext.requireBitmap
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
import javax.inject.Inject
import javax.inject.Singleton
@@ -92,6 +93,14 @@ class ShortcutsUpdater @Inject constructor(
return manager.maxShortcutCountPerActivity > 0
}
+ fun notifyMangaOpened(mangaId: Long) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
+ return
+ }
+ val manager = context.getSystemService(Context.SHORTCUT_SERVICE) as ShortcutManager
+ manager.reportShortcutUsed(mangaId.toString())
+ }
+
@RequiresApi(Build.VERSION_CODES.N_MR1)
private suspend fun updateShortcutsImpl() = runCatchingCancellable {
val manager = context.getSystemService(Context.SHORTCUT_SERVICE) as ShortcutManager
@@ -122,7 +131,7 @@ class ShortcutsUpdater @Inject constructor(
.precision(Precision.EXACT)
.scale(Scale.FILL)
.build(),
- ).requireBitmap()
+ ).getDrawableOrThrow().toBitmap()
}.fold(
onSuccess = { IconCompat.createWithAdaptiveBitmap(it) },
onFailure = { IconCompat.createWithResource(context, R.drawable.ic_shortcut_default) },
diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderInfoBarView.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderInfoBarView.kt
index 02e7f91ad..f4fd28289 100644
--- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderInfoBarView.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderInfoBarView.kt
@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.reader.ui
+import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -179,6 +180,7 @@ class ReaderInfoBarView @JvmOverloads constructor(
}
}
+ @SuppressLint("DiscouragedApi")
private fun getSystemUiDimensionOffset(name: String, fallback: Int = 0): Int = runCatching {
val manager = context.packageManager
val resources = manager.getResourcesForApplication("com.android.systemui")
diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt
index c877742b9..5595387e9 100644
--- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt
@@ -19,6 +19,8 @@ import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
@@ -34,6 +36,7 @@ import org.koitharu.kotatsu.base.domain.MangaIntent
import org.koitharu.kotatsu.base.ui.BaseViewModel
import org.koitharu.kotatsu.bookmarks.domain.Bookmark
import org.koitharu.kotatsu.bookmarks.domain.BookmarksRepository
+import org.koitharu.kotatsu.core.os.ShortcutsUpdater
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.ReaderMode
@@ -75,6 +78,7 @@ class ReaderViewModel @Inject constructor(
private val pageSaveHelper: PageSaveHelper,
private val pageLoader: PageLoader,
private val chaptersLoader: ChaptersLoader,
+ private val shortcutsUpdater: ShortcutsUpdater,
) : BaseViewModel() {
private val intent = MangaIntent(savedStateHandle)
@@ -149,6 +153,10 @@ class ReaderViewModel @Inject constructor(
.onEach { key ->
if (key == AppSettings.KEY_READER_SLIDER) notifyStateChanged()
}.launchIn(viewModelScope + Dispatchers.Default)
+ launchJob(Dispatchers.Default) {
+ val mangaId = mangaData.filterNotNull().first().id
+ shortcutsUpdater.notifyMangaOpened(mangaId)
+ }
}
fun reload() {
diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt
index edf8bce98..6d8076baf 100644
--- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt
@@ -33,7 +33,9 @@ open class PageHolder(
binding.ssiv.bindToLifecycle(owner)
binding.ssiv.isEagerLoadingEnabled = !isLowRamDevice(context)
binding.ssiv.addOnImageEventListener(delegate)
+ @Suppress("LeakingThis")
bindingInfo.buttonRetry.setOnClickListener(this)
+ @Suppress("LeakingThis")
bindingInfo.buttonErrorDetails.setOnClickListener(this)
binding.textViewNumber.isVisible = settings.isPagesNumbersEnabled
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/anilist/data/AniListRepository.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/anilist/data/AniListRepository.kt
index 97d93c7b1..f2bd44e7f 100644
--- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/anilist/data/AniListRepository.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/anilist/data/AniListRepository.kt
@@ -241,6 +241,7 @@ class AniListRepository(
descriptionHtml = json.getString("description"),
)
+ @Suppress("FunctionName")
private fun AniListUser(json: JSONObject) = ScrobblerUser(
id = json.getLong("id"),
nickname = json.getString("name"),
diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/mal/data/MALRepository.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/mal/data/MALRepository.kt
index 6c4d7af38..f17d51ea7 100644
--- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/mal/data/MALRepository.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/mal/data/MALRepository.kt
@@ -200,6 +200,7 @@ class MALRepository(
descriptionHtml = json.getString("synopsis"),
)
+ @Suppress("FunctionName")
private fun MALUser(json: JSONObject) = ScrobblerUser(
id = json.getLong("id"),
nickname = json.getString("name"),
diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/shikimori/data/ShikimoriRepository.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/shikimori/data/ShikimoriRepository.kt
index 1967249d2..9e4c90289 100644
--- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/shikimori/data/ShikimoriRepository.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/shikimori/data/ShikimoriRepository.kt
@@ -207,6 +207,7 @@ class ShikimoriRepository(
descriptionHtml = json.getString("description_html"),
)
+ @Suppress("FunctionName")
private fun ShikimoriUser(json: JSONObject) = ScrobblerUser(
id = json.getLong("id"),
nickname = json.getString("nickname"),
diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt
index f87555fb7..fb2f70804 100644
--- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt
@@ -66,7 +66,7 @@ fun View.hasGlobalPoint(x: Int, y: Int): Boolean {
fun View.measureHeight(): Int {
val vh = height
return if (vh == 0) {
- measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
+ measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
measuredHeight
} else vh
}
@@ -74,7 +74,7 @@ fun View.measureHeight(): Int {
fun View.measureWidth(): Int {
val vw = width
return if (vw == 0) {
- measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
+ measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
measuredWidth
} else vw
}
@@ -178,7 +178,6 @@ val View.parents: Sequence
}
}
-@Suppress("unused")
fun View.measureDimension(desiredSize: Int, measureSpec: Int): Int {
var result: Int
val specMode = MeasureSpec.getMode(measureSpec)
diff --git a/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentListFactory.kt b/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentListFactory.kt
index c023f9d05..f88a0525a 100644
--- a/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentListFactory.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentListFactory.kt
@@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import android.widget.RemoteViews
import android.widget.RemoteViewsService
+import androidx.core.graphics.drawable.toBitmap
import coil.ImageLoader
import coil.executeBlocking
import coil.request.ImageRequest
@@ -15,7 +16,7 @@ import org.koitharu.kotatsu.base.domain.MangaIntent
import org.koitharu.kotatsu.history.domain.HistoryRepository
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.util.replaceWith
-import org.koitharu.kotatsu.utils.ext.requireBitmap
+import org.koitharu.kotatsu.utils.ext.getDrawableOrThrow
class RecentListFactory(
private val context: Context,
@@ -56,7 +57,7 @@ class RecentListFactory(
.tag(item.source)
.transformations(transformation)
.build(),
- ).requireBitmap()
+ ).getDrawableOrThrow().toBitmap()
}.onSuccess { cover ->
views.setImageViewBitmap(R.id.imageView_cover, cover)
}.onFailure {
diff --git a/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfListFactory.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfListFactory.kt
index f3dd62b87..74caff390 100644
--- a/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfListFactory.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfListFactory.kt
@@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import android.widget.RemoteViews
import android.widget.RemoteViewsService
+import androidx.core.graphics.drawable.toBitmap
import coil.ImageLoader
import coil.executeBlocking
import coil.request.ImageRequest
@@ -16,7 +17,7 @@ import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.util.replaceWith
-import org.koitharu.kotatsu.utils.ext.requireBitmap
+import org.koitharu.kotatsu.utils.ext.getDrawableOrThrow
class ShelfListFactory(
private val context: Context,
@@ -67,7 +68,7 @@ class ShelfListFactory(
.tag(item.source)
.transformations(transformation)
.build(),
- ).requireBitmap()
+ ).getDrawableOrThrow().toBitmap()
}.onSuccess { cover ->
views.setImageViewBitmap(R.id.imageView_cover, cover)
}.onFailure {
diff --git a/app/src/main/res/layout-w720dp/activity_details.xml b/app/src/main/res/layout-w720dp/activity_details.xml
index 91234ae5d..6fe5b7452 100644
--- a/app/src/main/res/layout-w720dp/activity_details.xml
+++ b/app/src/main/res/layout-w720dp/activity_details.xml
@@ -83,6 +83,7 @@
android:paddingHorizontal="@dimen/margin_normal"
android:singleLine="true"
android:textAppearance="?textAppearanceTitleMedium"
+ tools:ignore="InconsistentLayout"
tools:text="@string/chapter_d_of_d" />
diff --git a/app/src/main/res/layout/item_color_scheme.xml b/app/src/main/res/layout/item_color_scheme.xml
index 80b62babb..9389a70c2 100644
--- a/app/src/main/res/layout/item_color_scheme.xml
+++ b/app/src/main/res/layout/item_color_scheme.xml
@@ -92,5 +92,5 @@
android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?android:attr/textColorPrimary"
- tools:text="@string/theme_name_mint" />
+ tools:text="@string/theme_name_miku" />
diff --git a/app/src/main/res/layout/item_empty_state.xml b/app/src/main/res/layout/item_empty_state.xml
index d89b79276..ff9a86494 100644
--- a/app/src/main/res/layout/item_empty_state.xml
+++ b/app/src/main/res/layout/item_empty_state.xml
@@ -1,7 +1,6 @@
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/layout_synchronization.xml b/app/src/main/res/layout/layout_synchronization.xml
index 44afb83fd..d9d728fbe 100644
--- a/app/src/main/res/layout/layout_synchronization.xml
+++ b/app/src/main/res/layout/layout_synchronization.xml
@@ -31,16 +31,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
- android:text="mail@mail.com"
- android:textAppearance="?textAppearanceBodyLarge" />
+ android:textAppearance="?textAppearanceBodyLarge"
+ tools:text="mail@mail.com" />
+ android:textAppearance="?textAppearanceBodySmall"
+ tools:text="Last checked: 6:00 PM" />
diff --git a/app/src/main/res/xml/locales.xml b/app/src/main/res/xml/locales.xml
index 3f6f313ef..8d4010179 100644
--- a/app/src/main/res/xml/locales.xml
+++ b/app/src/main/res/xml/locales.xml
@@ -26,4 +26,11 @@
+
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
index f4a9e2465..daf977e07 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,8 +4,8 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.0.0'
- classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.20'
+ classpath 'com.android.tools.build:gradle:8.0.1'
+ classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.21'
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.45'
}
}
@@ -20,16 +20,6 @@ allprojects {
}
}
-String currentBranch() {
- def branchName = ""
- try {
- branchName = "git rev-parse --abbrev-ref HEAD".execute().text.trim()
- } catch (ignored) {
- println "Git not found"
- }
- return branchName
-}
-
task clean(type: Delete) {
delete rootProject.buildDir
}