Browse Source

Switch to different ktlint plugin

Should be better at incremental builds.
To format, run `./gradlew ktlintFormat`.
arkon 1 năm trước cách đây
mục cha
commit
d29b7c4e57
69 tập tin đã thay đổi với 625 bổ sung288 xóa
  1. 2 2
      .editorconfig
  2. 16 17
      app/build.gradle.kts
  3. 2 2
      app/src/main/java/eu/kanade/presentation/category/components/CategoryDialogs.kt
  4. 2 2
      app/src/main/java/eu/kanade/presentation/history/components/HistoryDialogs.kt
  5. 1 1
      app/src/main/java/eu/kanade/presentation/manga/components/MangaDialogs.kt
  6. 5 5
      app/src/main/java/eu/kanade/presentation/more/MoreScreen.kt
  7. 0 1
      app/src/main/java/eu/kanade/presentation/more/settings/Preference.kt
  8. 1 1
      app/src/main/java/eu/kanade/presentation/updates/UpdatesDialog.kt
  9. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterDialog.kt
  10. 24 6
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt
  11. 1 1
      buildSrc/build.gradle.kts
  12. 9 15
      buildSrc/src/main/kotlin/tachiyomi.lint.gradle.kts
  13. 0 1
      core-metadata/build.gradle.kts
  14. 3 1
      core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt
  15. 4 1
      core/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt
  16. 9 2
      core/src/main/java/eu/kanade/tachiyomi/network/ProgressResponseBody.kt
  17. 5 1
      core/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt
  18. 5 6
      core/src/main/java/eu/kanade/tachiyomi/network/interceptor/SpecificHostRateLimitInterceptor.kt
  19. 10 2
      core/src/main/java/eu/kanade/tachiyomi/util/system/ToastExtensions.kt
  20. 1 4
      core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewClientCompat.kt
  21. 15 3
      core/src/main/java/tachiyomi/core/preference/AndroidPreference.kt
  22. 5 1
      core/src/main/java/tachiyomi/core/preference/AndroidPreferenceStore.kt
  23. 3 1
      core/src/main/java/tachiyomi/core/preference/Preference.kt
  24. 8 2
      core/src/main/java/tachiyomi/core/util/lang/CoroutinesExtensions.kt
  25. 8 7
      data/src/main/java/tachiyomi/data/DatabaseAdapter.kt
  26. 15 1
      data/src/main/java/tachiyomi/data/chapter/ChapterMapper.kt
  27. 19 3
      data/src/main/java/tachiyomi/data/chapter/ChapterRepositoryImpl.kt
  28. 13 1
      data/src/main/java/tachiyomi/data/history/HistoryMapper.kt
  29. 55 2
      data/src/main/java/tachiyomi/data/manga/MangaMapper.kt
  30. 14 2
      data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt
  31. 3 1
      data/src/main/java/tachiyomi/data/release/GithubRelease.kt
  32. 3 1
      data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt
  33. 15 1
      data/src/main/java/tachiyomi/data/track/TrackMapper.kt
  34. 16 1
      data/src/main/java/tachiyomi/data/updates/UpdatesMapper.kt
  35. 10 2
      data/src/main/java/tachiyomi/data/updates/UpdatesRepositoryImpl.kt
  36. 2 4
      domain/src/main/java/tachiyomi/domain/category/interactor/ReorderCategory.kt
  37. 5 1
      domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt
  38. 0 0
      domain/src/main/java/tachiyomi/domain/chapter/interactor/SetMangaDefaultChapterFlags.kt
  39. 5 1
      domain/src/main/java/tachiyomi/domain/chapter/service/ChapterRecognition.kt
  40. 7 1
      domain/src/main/java/tachiyomi/domain/chapter/service/ChapterSort.kt
  41. 24 6
      domain/src/main/java/tachiyomi/domain/download/service/DownloadPreferences.kt
  42. 5 1
      domain/src/main/java/tachiyomi/domain/history/interactor/GetNextChapters.kt
  43. 12 1
      domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt
  44. 95 23
      domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt
  45. 11 3
      domain/src/main/java/tachiyomi/domain/manga/interactor/SetFetchInterval.kt
  46. 16 3
      domain/src/main/java/tachiyomi/domain/release/interactor/GetApplicationRelease.kt
  47. 4 1
      domain/src/test/java/tachiyomi/domain/library/model/LibraryFlagsTest.kt
  48. 6 2
      domain/src/test/java/tachiyomi/domain/release/interactor/GetApplicationReleaseTest.kt
  49. 1 1
      gradle/libs.versions.toml
  50. 7 2
      macrobenchmark/src/main/java/tachiyomi/macrobenchmark/StartupBenchmark.kt
  51. 42 38
      presentation-core/src/main/java/tachiyomi/presentation/core/components/AdaptiveSheet.kt
  52. 1 3
      presentation-core/src/main/java/tachiyomi/presentation/core/components/CircularProgressIndicator.kt
  53. 1 4
      presentation-core/src/main/java/tachiyomi/presentation/core/components/CollapsibleBox.kt
  54. 1 6
      presentation-core/src/main/java/tachiyomi/presentation/core/components/LinkIcon.kt
  55. 1 4
      presentation-core/src/main/java/tachiyomi/presentation/core/components/ListGroupHeader.kt
  56. 9 39
      presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt
  57. 2 1
      presentation-core/src/main/java/tachiyomi/presentation/core/components/VerticalFastScroller.kt
  58. 12 4
      presentation-core/src/main/java/tachiyomi/presentation/core/components/material/AlertDialog.kt
  59. 13 14
      presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Button.kt
  60. 0 0
      presentation-core/src/main/java/tachiyomi/presentation/core/components/material/IconButtonTokens.kt
  61. 4 1
      presentation-core/src/main/java/tachiyomi/presentation/core/components/material/NavigationRail.kt
  62. 12 3
      presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Scaffold.kt
  63. 1 3
      presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Surface.kt
  64. 2 8
      presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Tabs.kt
  65. 0 0
      presentation-core/src/main/java/tachiyomi/presentation/core/util/ThemePreviews.kt
  66. 1 4
      presentation-widget/src/main/java/tachiyomi/presentation/widget/components/UpdatesMangaCover.kt
  67. 6 2
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt
  68. 4 1
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/Filter.kt
  69. 10 2
      source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt

+ 2 - 2
.editorconfig

@@ -3,5 +3,5 @@ indent_size=4
 insert_final_newline=true
 ij_kotlin_allow_trailing_comma=true
 ij_kotlin_allow_trailing_comma_on_call_site=true
-ij_kotlin_name_count_to_use_star_import = 2147483647
-ij_kotlin_name_count_to_use_star_import_for_members = 2147483647
+ij_kotlin_name_count_to_use_star_import=2147483647
+ij_kotlin_name_count_to_use_star_import_for_members=2147483647

+ 16 - 17
app/build.gradle.kts

@@ -1,5 +1,4 @@
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import org.jmailen.gradle.kotlinter.tasks.LintTask
 
 plugins {
     id("com.android.application")
@@ -104,15 +103,17 @@ android {
     }
 
     packaging {
-        resources.excludes.addAll(listOf(
-            "META-INF/DEPENDENCIES",
-            "LICENSE.txt",
-            "META-INF/LICENSE",
-            "META-INF/LICENSE.txt",
-            "META-INF/README.md",
-            "META-INF/NOTICE",
-            "META-INF/*.kotlin_module",
-        ))
+        resources.excludes.addAll(
+            listOf(
+                "META-INF/DEPENDENCIES",
+                "LICENSE.txt",
+                "META-INF/LICENSE",
+                "META-INF/LICENSE.txt",
+                "META-INF/README.md",
+                "META-INF/NOTICE",
+                "META-INF/*.kotlin_module",
+            ),
+        )
     }
 
     dependenciesInfo {
@@ -264,7 +265,9 @@ androidComponents {
     beforeVariants { variantBuilder ->
         // Disables standardBenchmark
         if (variantBuilder.buildType == "benchmark") {
-            variantBuilder.enable = variantBuilder.productFlavors.containsAll(listOf("default" to "dev"))
+            variantBuilder.enable = variantBuilder.productFlavors.containsAll(
+                listOf("default" to "dev"),
+            )
         }
     }
     onVariants(selector().withFlavor("default" to "standard")) {
@@ -275,10 +278,6 @@ androidComponents {
 }
 
 tasks {
-    withType<LintTask>().configureEach {
-        exclude { it.file.path.contains("generated[\\\\/]".toRegex()) }
-    }
-
     // See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers)
     withType<KotlinCompile> {
         kotlinOptions.freeCompilerArgs += listOf(
@@ -303,12 +302,12 @@ tasks {
             kotlinOptions.freeCompilerArgs += listOf(
                 "-P",
                 "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
-                    project.buildDir.absolutePath + "/compose_metrics"
+                    project.buildDir.absolutePath + "/compose_metrics",
             )
             kotlinOptions.freeCompilerArgs += listOf(
                 "-P",
                 "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
-                    project.buildDir.absolutePath + "/compose_metrics"
+                    project.buildDir.absolutePath + "/compose_metrics",
             )
         }
     }

+ 2 - 2
app/src/main/java/eu/kanade/presentation/category/components/CategoryDialogs.kt

@@ -162,7 +162,7 @@ fun CategoryDeleteDialog(
             TextButton(onClick = {
                 onDelete()
                 onDismissRequest()
-            },) {
+            }) {
                 Text(text = stringResource(R.string.action_ok))
             }
         },
@@ -217,7 +217,7 @@ fun ChangeCategoryDialog(
                 tachiyomi.presentation.core.components.material.TextButton(onClick = {
                     onDismissRequest()
                     onEditCategories()
-                },) {
+                }) {
                     Text(text = stringResource(R.string.action_edit))
                 }
                 Spacer(modifier = Modifier.weight(1f))

+ 2 - 2
app/src/main/java/eu/kanade/presentation/history/components/HistoryDialogs.kt

@@ -61,7 +61,7 @@ fun HistoryDeleteDialog(
             TextButton(onClick = {
                 onDelete(removeEverything)
                 onDismissRequest()
-            },) {
+            }) {
                 Text(text = stringResource(R.string.action_remove))
             }
         },
@@ -90,7 +90,7 @@ fun HistoryDeleteAllDialog(
             TextButton(onClick = {
                 onDelete()
                 onDismissRequest()
-            },) {
+            }) {
                 Text(text = stringResource(R.string.action_ok))
             }
         },

+ 1 - 1
app/src/main/java/eu/kanade/presentation/manga/components/MangaDialogs.kt

@@ -91,7 +91,7 @@ fun SetIntervalDialog(
             TextButton(onClick = {
                 onValueChanged(selectedInterval)
                 onDismissRequest()
-            },) {
+            }) {
                 Text(text = stringResource(R.string.action_ok))
             }
         },

+ 5 - 5
app/src/main/java/eu/kanade/presentation/more/MoreScreen.kt

@@ -108,11 +108,11 @@ fun MoreScreen(
                                 stringResource(R.string.paused)
                             } else {
                                 "${stringResource(R.string.paused)} • ${
-                                pluralStringResource(
-                                    id = R.plurals.download_queue_summary,
-                                    count = pending,
-                                    pending,
-                                )
+                                    pluralStringResource(
+                                        id = R.plurals.download_queue_summary,
+                                        count = pending,
+                                        pending,
+                                    )
                                 }"
                             }
                         }

+ 0 - 1
app/src/main/java/eu/kanade/presentation/more/settings/PreferenceModel.kt → app/src/main/java/eu/kanade/presentation/more/settings/Preference.kt

@@ -4,7 +4,6 @@ import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.res.stringResource
-import eu.kanade.presentation.more.settings.Preference.PreferenceItem
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.track.TrackService
 import tachiyomi.core.preference.Preference as PreferenceData

+ 1 - 1
app/src/main/java/eu/kanade/presentation/updates/UpdatesDialog.kt

@@ -21,7 +21,7 @@ fun UpdatesDeleteConfirmationDialog(
             TextButton(onClick = {
                 onConfirm()
                 onDismissRequest()
-            },) {
+            }) {
                 Text(text = stringResource(R.string.action_ok))
             }
         },

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterDialog.kt

@@ -64,7 +64,7 @@ fun SourceFilterDialog(
                     Button(onClick = {
                         onFilter()
                         onDismissRequest()
-                    },) {
+                    }) {
                         Text(stringResource(R.string.action_filter))
                     }
                 }

+ 24 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt

@@ -271,7 +271,10 @@ private data class TrackStatusSelectorScreen(
             selection = state.selection,
             onSelectionChange = sm::setSelection,
             selections = remember { sm.getSelections() },
-            onConfirm = { sm.setStatus(); navigator.pop() },
+            onConfirm = {
+                sm.setStatus()
+                navigator.pop()
+            },
             onDismissRequest = navigator::pop,
         )
     }
@@ -322,7 +325,10 @@ private data class TrackChapterSelectorScreen(
             selection = state.selection,
             onSelectionChange = sm::setSelection,
             range = remember { sm.getRange() },
-            onConfirm = { sm.setChapter(); navigator.pop() },
+            onConfirm = {
+                sm.setChapter()
+                navigator.pop()
+            },
             onDismissRequest = navigator::pop,
         )
     }
@@ -378,7 +384,10 @@ private data class TrackScoreSelectorScreen(
             selection = state.selection,
             onSelectionChange = sm::setSelection,
             selections = remember { sm.getSelections() },
-            onConfirm = { sm.setScore(); navigator.pop() },
+            onConfirm = {
+                sm.setScore()
+                navigator.pop()
+            },
             onDismissRequest = navigator::pop,
         )
     }
@@ -495,7 +504,10 @@ private data class TrackDateSelectorScreen(
             },
             initialSelectedDateMillis = sm.initialSelection,
             selectableDates = selectableDates,
-            onConfirm = { sm.setDate(it); navigator.pop() },
+            onConfirm = {
+                sm.setDate(it)
+                navigator.pop()
+            },
             onRemove = { sm.confirmRemoveDate(navigator) }.takeIf { canRemove },
             onDismissRequest = navigator::pop,
         )
@@ -584,7 +596,10 @@ private data class TrackDateRemoverScreen(
                         Text(text = stringResource(android.R.string.cancel))
                     }
                     FilledTonalButton(
-                        onClick = { sm.removeDate(); navigator.popUntil { it is TrackInfoDialogHomeScreen } },
+                        onClick = {
+                            sm.removeDate()
+                            navigator.popUntil { it is TrackInfoDialogHomeScreen }
+                        },
                         colors = ButtonDefaults.filledTonalButtonColors(
                             containerColor = MaterialTheme.colorScheme.errorContainer,
                             contentColor = MaterialTheme.colorScheme.onErrorContainer,
@@ -646,7 +661,10 @@ data class TrackServiceSearchScreen(
             queryResult = state.queryResult,
             selected = state.selected,
             onSelectedChange = sm::updateSelection,
-            onConfirmSelection = { sm.registerTracking(state.selected!!); navigator.pop() },
+            onConfirmSelection = {
+                sm.registerTracking(state.selected!!)
+                navigator.pop()
+            },
             onDismissRequest = navigator::pop,
         )
     }

+ 1 - 1
buildSrc/build.gradle.kts

@@ -5,7 +5,7 @@ plugins {
 dependencies {
     implementation(androidxLibs.gradle)
     implementation(kotlinLibs.gradle)
-    implementation(libs.kotlinter)
+    implementation(libs.ktlint)
     implementation(gradleApi())
 }
 

+ 9 - 15
buildSrc/src/main/kotlin/tachiyomi.lint.gradle.kts

@@ -1,20 +1,14 @@
-import org.jmailen.gradle.kotlinter.KotlinterExtension
-import org.jmailen.gradle.kotlinter.KotlinterPlugin
+import org.jlleitschuh.gradle.ktlint.KtlintExtension
+import org.jlleitschuh.gradle.ktlint.KtlintPlugin
 
-apply<KotlinterPlugin>()
+apply<KtlintPlugin>()
 
-extensions.configure<KotlinterExtension>("kotlinter") {
-    experimentalRules = true
+extensions.configure<KtlintExtension>("ktlint") {
+    version.set("0.50.0")
+    android.set(true)
+    enableExperimentalRules.set(true)
 
-    disabledRules = arrayOf(
-        "experimental:argument-list-wrapping", // Doesn't play well with Android Studio
-        "filename", // Often broken to give a more general name
-    )
-}
-
-tasks {
-    named<DefaultTask>("preBuild").configure {
-        if (!System.getenv("CI").toBoolean())
-            dependsOn("formatKotlin")
+    filter {
+        exclude("**/generated/**")
     }
 }

+ 0 - 1
core-metadata/build.gradle.kts

@@ -11,7 +11,6 @@ android {
         testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
         consumerProguardFiles("consumer-rules.pro")
     }
-
 }
 
 dependencies {

+ 3 - 1
core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt

@@ -39,7 +39,9 @@ class NetworkHelper(
             builder.addNetworkInterceptor(httpLoggingInterceptor)
         }
 
-        builder.addInterceptor(CloudflareInterceptor(context, cookieJar, ::defaultUserAgentProvider))
+        builder.addInterceptor(
+            CloudflareInterceptor(context, cookieJar, ::defaultUserAgentProvider),
+        )
 
         when (preferences.dohProvider().get()) {
             PREF_DOH_CLOUDFLARE -> builder.dohCloudflare()

+ 4 - 1
core/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt

@@ -17,6 +17,9 @@ class NetworkPreferences(
     }
 
     fun defaultUserAgent(): Preference<String> {
-        return preferenceStore.getString("default_user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0")
+        return preferenceStore.getString(
+            "default_user_agent",
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0",
+        )
     }
 }

+ 9 - 2
core/src/main/java/eu/kanade/tachiyomi/network/ProgressResponseBody.kt

@@ -9,7 +9,10 @@ import okio.Source
 import okio.buffer
 import java.io.IOException
 
-class ProgressResponseBody(private val responseBody: ResponseBody, private val progressListener: ProgressListener) : ResponseBody() {
+class ProgressResponseBody(
+    private val responseBody: ResponseBody,
+    private val progressListener: ProgressListener,
+) : ResponseBody() {
 
     private val bufferedSource: BufferedSource by lazy {
         source(responseBody.source()).buffer()
@@ -36,7 +39,11 @@ class ProgressResponseBody(private val responseBody: ResponseBody, private val p
                 val bytesRead = super.read(sink, byteCount)
                 // read() returns the number of bytes read, or -1 if this source is exhausted.
                 totalBytesRead += if (bytesRead != -1L) bytesRead else 0
-                progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1L)
+                progressListener.update(
+                    totalBytesRead,
+                    responseBody.contentLength(),
+                    bytesRead == -1L,
+                )
                 return bytesRead
             }
         }

+ 5 - 1
core/src/main/java/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt

@@ -31,7 +31,11 @@ class CloudflareInterceptor(
         return response.code in ERROR_CODES && response.header("Server") in SERVER_CHECK
     }
 
-    override fun intercept(chain: Interceptor.Chain, request: Request, response: Response): Response {
+    override fun intercept(
+        chain: Interceptor.Chain,
+        request: Request,
+        response: Response,
+    ): Response {
         try {
             response.close()
             cookieManager.remove(request.url, COOKIE_NAMES, 0)

+ 5 - 6
core/src/main/java/eu/kanade/tachiyomi/network/interceptor/SpecificHostRateLimitInterceptor.kt

@@ -33,7 +33,9 @@ fun OkHttpClient.Builder.rateLimitHost(
     permits: Int,
     period: Long = 1,
     unit: TimeUnit = TimeUnit.SECONDS,
-) = addInterceptor(RateLimitInterceptor(httpUrl.host, permits, period.toDuration(unit.toDurationUnit())))
+) = addInterceptor(
+    RateLimitInterceptor(httpUrl.host, permits, period.toDuration(unit.toDurationUnit())),
+)
 
 /**
  * An OkHttp interceptor that handles given url host's rate limiting.
@@ -69,8 +71,5 @@ fun OkHttpClient.Builder.rateLimitHost(
  * @param permits [Int]     Number of requests allowed within a period of units.
  * @param period [Duration] The limiting duration. Defaults to 1.seconds.
  */
-fun OkHttpClient.Builder.rateLimitHost(
-    url: String,
-    permits: Int,
-    period: Duration = 1.seconds,
-) = addInterceptor(RateLimitInterceptor(url.toHttpUrlOrNull()?.host, permits, period))
+fun OkHttpClient.Builder.rateLimitHost(url: String, permits: Int, period: Duration = 1.seconds) =
+    addInterceptor(RateLimitInterceptor(url.toHttpUrlOrNull()?.host, permits, period))

+ 10 - 2
core/src/main/java/eu/kanade/tachiyomi/util/system/ToastExtensions.kt

@@ -10,7 +10,11 @@ import androidx.annotation.StringRes
  * @param resource the text resource.
  * @param duration the duration of the toast. Defaults to short.
  */
-fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast {
+fun Context.toast(
+    @StringRes resource: Int,
+    duration: Int = Toast.LENGTH_SHORT,
+    block: (Toast) -> Unit = {},
+): Toast {
     return toast(getString(resource), duration, block)
 }
 
@@ -20,7 +24,11 @@ fun Context.toast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT,
  * @param text the text to display.
  * @param duration the duration of the toast. Defaults to short.
  */
-fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT, block: (Toast) -> Unit = {}): Toast {
+fun Context.toast(
+    text: String?,
+    duration: Int = Toast.LENGTH_SHORT,
+    block: (Toast) -> Unit = {},
+): Toast {
     return Toast.makeText(applicationContext, text.orEmpty(), duration).also {
         block(it)
         it.show()

+ 1 - 4
core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewClientCompat.kt

@@ -47,10 +47,7 @@ abstract class WebViewClientCompat : WebViewClient() {
         return shouldInterceptRequestCompat(view, request.url.toString())
     }
 
-    final override fun shouldInterceptRequest(
-        view: WebView,
-        url: String,
-    ): WebResourceResponse? {
+    final override fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {
         return shouldInterceptRequestCompat(view, url)
     }
 

+ 15 - 3
core/src/main/java/tachiyomi/core/preference/AndroidPreference.kt

@@ -68,7 +68,11 @@ sealed class AndroidPreference<T>(
         key: String,
         defaultValue: String,
     ) : AndroidPreference<String>(preferences, keyFlow, key, defaultValue) {
-        override fun read(preferences: SharedPreferences, key: String, defaultValue: String): String {
+        override fun read(
+            preferences: SharedPreferences,
+            key: String,
+            defaultValue: String,
+        ): String {
             return preferences.getString(key, defaultValue) ?: defaultValue
         }
 
@@ -128,7 +132,11 @@ sealed class AndroidPreference<T>(
         key: String,
         defaultValue: Boolean,
     ) : AndroidPreference<Boolean>(preferences, keyFlow, key, defaultValue) {
-        override fun read(preferences: SharedPreferences, key: String, defaultValue: Boolean): Boolean {
+        override fun read(
+            preferences: SharedPreferences,
+            key: String,
+            defaultValue: Boolean,
+        ): Boolean {
             return preferences.getBoolean(key, defaultValue)
         }
 
@@ -143,7 +151,11 @@ sealed class AndroidPreference<T>(
         key: String,
         defaultValue: Set<String>,
     ) : AndroidPreference<Set<String>>(preferences, keyFlow, key, defaultValue) {
-        override fun read(preferences: SharedPreferences, key: String, defaultValue: Set<String>): Set<String> {
+        override fun read(
+            preferences: SharedPreferences,
+            key: String,
+            defaultValue: Set<String>,
+        ): Set<String> {
             return preferences.getStringSet(key, defaultValue) ?: defaultValue
         }
 

+ 5 - 1
core/src/main/java/tachiyomi/core/preference/AndroidPreferenceStore.kt

@@ -64,7 +64,11 @@ class AndroidPreferenceStore(
 
 private val SharedPreferences.keyFlow
     get() = callbackFlow {
-        val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key: String? -> trySend(key) }
+        val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key: String? ->
+            trySend(
+                key,
+            )
+        }
         registerOnSharedPreferenceChangeListener(listener)
         awaitClose {
             unregisterOnSharedPreferenceChangeListener(listener)

+ 3 - 1
core/src/main/java/tachiyomi/core/preference/Preference.kt

@@ -23,7 +23,9 @@ interface Preference<T> {
     fun stateIn(scope: CoroutineScope): StateFlow<T>
 }
 
-inline fun <reified T, R : T> Preference<T>.getAndSet(crossinline block: (T) -> R) = set(block(get()))
+inline fun <reified T, R : T> Preference<T>.getAndSet(crossinline block: (T) -> R) = set(
+    block(get()),
+)
 
 operator fun <T> Preference<Set<T>>.plusAssign(item: T) {
     set(get() + item)

+ 8 - 2
core/src/main/java/tachiyomi/core/util/lang/CoroutinesExtensions.kt

@@ -52,9 +52,15 @@ fun CoroutineScope.launchIO(block: suspend CoroutineScope.() -> Unit): Job =
 fun CoroutineScope.launchNonCancellable(block: suspend CoroutineScope.() -> Unit): Job =
     launchIO { withContext(NonCancellable, block) }
 
-suspend fun <T> withUIContext(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Main, block)
+suspend fun <T> withUIContext(block: suspend CoroutineScope.() -> T) = withContext(
+    Dispatchers.Main,
+    block,
+)
 
-suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.IO, block)
+suspend fun <T> withIOContext(block: suspend CoroutineScope.() -> T) = withContext(
+    Dispatchers.IO,
+    block,
+)
 
 suspend fun <T> withNonCancellableContext(block: suspend CoroutineScope.() -> T) =
     withContext(NonCancellable, block)

+ 8 - 7
data/src/main/java/tachiyomi/data/DatabaseAdapter.kt

@@ -11,13 +11,14 @@ object DateColumnAdapter : ColumnAdapter<Date, Long> {
 
 private const val LIST_OF_STRINGS_SEPARATOR = ", "
 object StringListColumnAdapter : ColumnAdapter<List<String>, String> {
-    override fun decode(databaseValue: String) =
-        if (databaseValue.isEmpty()) {
-            emptyList()
-        } else {
-            databaseValue.split(LIST_OF_STRINGS_SEPARATOR)
-        }
-    override fun encode(value: List<String>) = value.joinToString(separator = LIST_OF_STRINGS_SEPARATOR)
+    override fun decode(databaseValue: String) = if (databaseValue.isEmpty()) {
+        emptyList()
+    } else {
+        databaseValue.split(LIST_OF_STRINGS_SEPARATOR)
+    }
+    override fun encode(value: List<String>) = value.joinToString(
+        separator = LIST_OF_STRINGS_SEPARATOR,
+    )
 }
 
 object UpdateStrategyColumnAdapter : ColumnAdapter<UpdateStrategy, Long> {

+ 15 - 1
data/src/main/java/tachiyomi/data/chapter/ChapterMapper.kt

@@ -2,7 +2,21 @@ package tachiyomi.data.chapter
 
 import tachiyomi.domain.chapter.model.Chapter
 
-val chapterMapper: (Long, Long, String, String, String?, Boolean, Boolean, Long, Double, Long, Long, Long, Long) -> Chapter =
+val chapterMapper: (
+    Long,
+    Long,
+    String,
+    String,
+    String?,
+    Boolean,
+    Boolean,
+    Long,
+    Double,
+    Long,
+    Long,
+    Long,
+    Long,
+) -> Chapter =
     { id, mangaId, url, name, scanlator, read, bookmark, lastPageRead, chapterNumber, sourceOrder, dateFetch, dateUpload, lastModifiedAt ->
         Chapter(
             id = id,

+ 19 - 3
data/src/main/java/tachiyomi/data/chapter/ChapterRepositoryImpl.kt

@@ -81,7 +81,12 @@ class ChapterRepositoryImpl(
     }
 
     override suspend fun getBookmarkedChaptersByMangaId(mangaId: Long): List<Chapter> {
-        return handler.awaitList { chaptersQueries.getBookmarkedChaptersByMangaId(mangaId, chapterMapper) }
+        return handler.awaitList {
+            chaptersQueries.getBookmarkedChaptersByMangaId(
+                mangaId,
+                chapterMapper,
+            )
+        }
     }
 
     override suspend fun getChapterById(id: Long): Chapter? {
@@ -89,10 +94,21 @@ class ChapterRepositoryImpl(
     }
 
     override suspend fun getChapterByMangaIdAsFlow(mangaId: Long): Flow<List<Chapter>> {
-        return handler.subscribeToList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
+        return handler.subscribeToList {
+            chaptersQueries.getChaptersByMangaId(
+                mangaId,
+                chapterMapper,
+            )
+        }
     }
 
     override suspend fun getChapterByUrlAndMangaId(url: String, mangaId: Long): Chapter? {
-        return handler.awaitOneOrNull { chaptersQueries.getChapterByUrlAndMangaId(url, mangaId, chapterMapper) }
+        return handler.awaitOneOrNull {
+            chaptersQueries.getChapterByUrlAndMangaId(
+                url,
+                mangaId,
+                chapterMapper,
+            )
+        }
     }
 }

+ 13 - 1
data/src/main/java/tachiyomi/data/history/HistoryMapper.kt

@@ -14,7 +14,19 @@ val historyMapper: (Long, Long, Date?, Long) -> History = { id, chapterId, readA
     )
 }
 
-val historyWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Double, Date?, Long) -> HistoryWithRelations = {
+val historyWithRelationsMapper: (
+    Long,
+    Long,
+    Long,
+    String,
+    String?,
+    Long,
+    Boolean,
+    Long,
+    Double,
+    Date?,
+    Long,
+) -> HistoryWithRelations = {
         historyId, mangaId, chapterId, title, thumbnailUrl, sourceId, isFavorite, coverLastModified, chapterNumber, readAt, readDuration ->
     HistoryWithRelations(
         id = historyId,

+ 55 - 2
data/src/main/java/tachiyomi/data/manga/MangaMapper.kt

@@ -4,7 +4,30 @@ import eu.kanade.tachiyomi.source.model.UpdateStrategy
 import tachiyomi.domain.library.model.LibraryManga
 import tachiyomi.domain.manga.model.Manga
 
-val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, Long, Long, Long?) -> Manga =
+val mangaMapper: (
+    Long,
+    Long,
+    String,
+    String?,
+    String?,
+    String?,
+    List<String>?,
+    String,
+    Long,
+    String?,
+    Boolean,
+    Long?,
+    Long?,
+    Boolean,
+    Long,
+    Long,
+    Long,
+    Long,
+    UpdateStrategy,
+    Long,
+    Long,
+    Long?,
+) -> Manga =
     { id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, nextUpdate, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy, calculateInterval, lastModifiedAt, favoriteModifiedAt ->
         Manga(
             id = id,
@@ -32,7 +55,37 @@ val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?,
         )
     }
 
-val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, Long, Long, Long?, Long, Double, Long, Long, Long, Double, Long) -> LibraryManga =
+val libraryManga: (
+    Long,
+    Long,
+    String,
+    String?,
+    String?,
+    String?,
+    List<String>?,
+    String,
+    Long,
+    String?,
+    Boolean,
+    Long?,
+    Long?,
+    Boolean,
+    Long,
+    Long,
+    Long,
+    Long,
+    UpdateStrategy,
+    Long,
+    Long,
+    Long?,
+    Long,
+    Double,
+    Long,
+    Long,
+    Long,
+    Double,
+    Long,
+) -> LibraryManga =
     { id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, nextUpdate, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy, calculateInterval, lastModifiedAt, favoriteModifiedAt, totalCount, readCount, latestUpload, chapterFetchedAt, lastRead, bookmarkCount, category ->
         LibraryManga(
             manga = mangaMapper(

+ 14 - 2
data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt

@@ -24,11 +24,23 @@ class MangaRepositoryImpl(
     }
 
     override suspend fun getMangaByUrlAndSourceId(url: String, sourceId: Long): Manga? {
-        return handler.awaitOneOrNull(inTransaction = true) { mangasQueries.getMangaByUrlAndSource(url, sourceId, mangaMapper) }
+        return handler.awaitOneOrNull(inTransaction = true) {
+            mangasQueries.getMangaByUrlAndSource(
+                url,
+                sourceId,
+                mangaMapper,
+            )
+        }
     }
 
     override fun getMangaByUrlAndSourceIdAsFlow(url: String, sourceId: Long): Flow<Manga?> {
-        return handler.subscribeToOneOrNull { mangasQueries.getMangaByUrlAndSource(url, sourceId, mangaMapper) }
+        return handler.subscribeToOneOrNull {
+            mangasQueries.getMangaByUrlAndSource(
+                url,
+                sourceId,
+                mangaMapper,
+            )
+        }
     }
 
     override suspend fun getFavorites(): List<Manga> {

+ 3 - 1
data/src/main/java/tachiyomi/data/release/GithubRelease.kt

@@ -32,7 +32,9 @@ data class GitHubAssets(@SerialName("browser_download_url") val downloadLink: St
  * Reference: https://stackoverflow.com/a/30281147
  */
 val gitHubUsernameMentionRegex =
-    """\B@([a-z0-9](?:-(?=[a-z0-9])|[a-z0-9]){0,38}(?<=[a-z0-9]))""".toRegex(RegexOption.IGNORE_CASE)
+    """\B@([a-z0-9](?:-(?=[a-z0-9])|[a-z0-9]){0,38}(?<=[a-z0-9]))""".toRegex(
+        RegexOption.IGNORE_CASE,
+    )
 
 val releaseMapper: (GithubRelease) -> Release = {
     Release(

+ 3 - 1
data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt

@@ -9,7 +9,9 @@ import tachiyomi.core.util.lang.awaitSingle
 import tachiyomi.core.util.lang.withIOContext
 import tachiyomi.domain.source.repository.SourcePagingSourceType
 
-class SourceSearchPagingSource(source: CatalogueSource, val query: String, val filters: FilterList) : SourcePagingSource(source) {
+class SourceSearchPagingSource(source: CatalogueSource, val query: String, val filters: FilterList) : SourcePagingSource(
+    source,
+) {
     override suspend fun requestNextPage(currentPage: Int): MangasPage {
         return source.fetchSearchManga(currentPage, query, filters).awaitSingle()
     }

+ 15 - 1
data/src/main/java/tachiyomi/data/track/TrackMapper.kt

@@ -2,7 +2,21 @@ package tachiyomi.data.track
 
 import tachiyomi.domain.track.model.Track
 
-val trackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Double, String, Long, Long) -> Track =
+val trackMapper: (
+    Long,
+    Long,
+    Long,
+    Long,
+    Long?,
+    String,
+    Double,
+    Long,
+    Long,
+    Double,
+    String,
+    Long,
+    Long,
+) -> Track =
     { id, mangaId, syncId, remoteId, libraryId, title, lastChapterRead, totalChapters, status, score, remoteUrl, startDate, finishDate ->
         Track(
             id = id,

+ 16 - 1
data/src/main/java/tachiyomi/data/updates/UpdatesMapper.kt

@@ -3,7 +3,22 @@ package tachiyomi.data.updates
 import tachiyomi.domain.manga.model.MangaCover
 import tachiyomi.domain.updates.model.UpdatesWithRelations
 
-val updateWithRelationMapper: (Long, String, Long, String, String?, Boolean, Boolean, Long, Long, Boolean, String?, Long, Long, Long) -> UpdatesWithRelations = {
+val updateWithRelationMapper: (
+    Long,
+    String,
+    Long,
+    String,
+    String?,
+    Boolean,
+    Boolean,
+    Long,
+    Long,
+    Boolean,
+    String?,
+    Long,
+    Long,
+    Long,
+) -> UpdatesWithRelations = {
         mangaId, mangaTitle, chapterId, chapterName, scanlator, read, bookmark, lastPageRead, sourceId, favorite, thumbnailUrl, coverLastModified, _, dateFetch ->
     UpdatesWithRelations(
         mangaId = mangaId,

+ 10 - 2
data/src/main/java/tachiyomi/data/updates/UpdatesRepositoryImpl.kt

@@ -9,7 +9,11 @@ class UpdatesRepositoryImpl(
     private val databaseHandler: DatabaseHandler,
 ) : UpdatesRepository {
 
-    override suspend fun awaitWithRead(read: Boolean, after: Long, limit: Long): List<UpdatesWithRelations> {
+    override suspend fun awaitWithRead(
+        read: Boolean,
+        after: Long,
+        limit: Long,
+    ): List<UpdatesWithRelations> {
         return databaseHandler.awaitList {
             updatesViewQueries.getUpdatesByReadStatus(
                 read = read,
@@ -26,7 +30,11 @@ class UpdatesRepositoryImpl(
         }
     }
 
-    override fun subscribeWithRead(read: Boolean, after: Long, limit: Long): Flow<List<UpdatesWithRelations>> {
+    override fun subscribeWithRead(
+        read: Boolean,
+        after: Long,
+        limit: Long,
+    ): Flow<List<UpdatesWithRelations>> {
         return databaseHandler.subscribeToList {
             updatesViewQueries.getUpdatesByReadStatus(
                 read = read,

+ 2 - 4
domain/src/main/java/tachiyomi/domain/category/interactor/ReorderCategory.kt

@@ -16,11 +16,9 @@ class ReorderCategory(
 
     private val mutex = Mutex()
 
-    suspend fun moveUp(category: Category): Result =
-        await(category, MoveTo.UP)
+    suspend fun moveUp(category: Category): Result = await(category, MoveTo.UP)
 
-    suspend fun moveDown(category: Category): Result =
-        await(category, MoveTo.DOWN)
+    suspend fun moveDown(category: Category): Result = await(category, MoveTo.DOWN)
 
     private suspend fun await(category: Category, moveTo: MoveTo) = withNonCancellableContext {
         mutex.withLock {

+ 5 - 1
domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt

@@ -28,7 +28,11 @@ class SetSortModeForCategory(
         }
     }
 
-    suspend fun await(category: Category?, type: LibrarySort.Type, direction: LibrarySort.Direction) {
+    suspend fun await(
+        category: Category?,
+        type: LibrarySort.Type,
+        direction: LibrarySort.Direction,
+    ) {
         await(category?.id, type, direction)
     }
 }

+ 0 - 0
domain/src/main/java/tachiyomi/domain/chapter/interactor/SetDefaultChapterSettings.kt → domain/src/main/java/tachiyomi/domain/chapter/interactor/SetMangaDefaultChapterFlags.kt


+ 5 - 1
domain/src/main/java/tachiyomi/domain/chapter/service/ChapterRecognition.kt

@@ -30,7 +30,11 @@ object ChapterRecognition {
      */
     private val unwantedWhiteSpace = Regex("""\s(?=extra|special|omake)""")
 
-    fun parseChapterNumber(mangaTitle: String, chapterName: String, chapterNumber: Double? = null): Double {
+    fun parseChapterNumber(
+        mangaTitle: String,
+        chapterName: String,
+        chapterNumber: Double? = null,
+    ): Double {
         // If chapter number is known return.
         if (chapterNumber != null && (chapterNumber == -2.0 || chapterNumber > -1.0)) {
             return chapterNumber

+ 7 - 1
domain/src/main/java/tachiyomi/domain/chapter/service/ChapterSort.kt

@@ -3,7 +3,13 @@ package tachiyomi.domain.chapter.service
 import tachiyomi.domain.chapter.model.Chapter
 import tachiyomi.domain.manga.model.Manga
 
-fun getChapterSort(manga: Manga, sortDescending: Boolean = manga.sortDescending()): (Chapter, Chapter) -> Int {
+fun getChapterSort(
+    manga: Manga,
+    sortDescending: Boolean = manga.sortDescending(),
+): (
+    Chapter,
+    Chapter,
+) -> Int {
     return when (manga.sorting) {
         Manga.CHAPTER_SORTING_SOURCE -> when (sortDescending) {
             true -> { c1, c2 -> c1.sourceOrder.compareTo(c2.sourceOrder) }

+ 24 - 6
domain/src/main/java/tachiyomi/domain/download/service/DownloadPreferences.kt

@@ -8,9 +8,15 @@ class DownloadPreferences(
     private val preferenceStore: PreferenceStore,
 ) {
 
-    fun downloadsDirectory() = preferenceStore.getString("download_directory", folderProvider.path())
+    fun downloadsDirectory() = preferenceStore.getString(
+        "download_directory",
+        folderProvider.path(),
+    )
 
-    fun downloadOnlyOverWifi() = preferenceStore.getBoolean("pref_download_only_over_wifi_key", true)
+    fun downloadOnlyOverWifi() = preferenceStore.getBoolean(
+        "pref_download_only_over_wifi_key",
+        true,
+    )
 
     fun saveChaptersAsCBZ() = preferenceStore.getBoolean("save_chapter_as_cbz", true)
 
@@ -20,15 +26,27 @@ class DownloadPreferences(
 
     fun removeAfterReadSlots() = preferenceStore.getInt("remove_after_read_slots", -1)
 
-    fun removeAfterMarkedAsRead() = preferenceStore.getBoolean("pref_remove_after_marked_as_read_key", false)
+    fun removeAfterMarkedAsRead() = preferenceStore.getBoolean(
+        "pref_remove_after_marked_as_read_key",
+        false,
+    )
 
     fun removeBookmarkedChapters() = preferenceStore.getBoolean("pref_remove_bookmarked", false)
 
-    fun removeExcludeCategories() = preferenceStore.getStringSet("remove_exclude_categories", emptySet())
+    fun removeExcludeCategories() = preferenceStore.getStringSet(
+        "remove_exclude_categories",
+        emptySet(),
+    )
 
     fun downloadNewChapters() = preferenceStore.getBoolean("download_new", false)
 
-    fun downloadNewChapterCategories() = preferenceStore.getStringSet("download_new_categories", emptySet())
+    fun downloadNewChapterCategories() = preferenceStore.getStringSet(
+        "download_new_categories",
+        emptySet(),
+    )
 
-    fun downloadNewChapterCategoriesExclude() = preferenceStore.getStringSet("download_new_categories_exclude", emptySet())
+    fun downloadNewChapterCategoriesExclude() = preferenceStore.getStringSet(
+        "download_new_categories_exclude",
+        emptySet(),
+    )
 }

+ 5 - 1
domain/src/main/java/tachiyomi/domain/history/interactor/GetNextChapters.kt

@@ -30,7 +30,11 @@ class GetNextChapters(
         }
     }
 
-    suspend fun await(mangaId: Long, fromChapterId: Long, onlyUnread: Boolean = true): List<Chapter> {
+    suspend fun await(
+        mangaId: Long,
+        fromChapterId: Long,
+        onlyUnread: Boolean = true,
+    ): List<Chapter> {
         val chapters = await(mangaId, onlyUnread)
         val currChapterIndex = chapters.indexOfFirst { it.id == fromChapterId }
         val nextChapters = chapters.subList(max(0, currChapterIndex), chapters.size)

+ 12 - 1
domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt

@@ -65,7 +65,18 @@ data class LibrarySort(
     }
 
     companion object {
-        val types by lazy { setOf(Type.Alphabetical, Type.LastRead, Type.LastUpdate, Type.UnreadCount, Type.TotalChapters, Type.LatestChapter, Type.ChapterFetchDate, Type.DateAdded) }
+        val types by lazy {
+            setOf(
+                Type.Alphabetical,
+                Type.LastRead,
+                Type.LastUpdate,
+                Type.UnreadCount,
+                Type.TotalChapters,
+                Type.LatestChapter,
+                Type.ChapterFetchDate,
+                Type.DateAdded,
+            )
+        }
         val directions by lazy { setOf(Direction.Ascending, Direction.Descending) }
         val default = LibrarySort(Type.Alphabetical, Direction.Ascending)
 

+ 95 - 23
domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt

@@ -11,9 +11,19 @@ class LibraryPreferences(
     private val preferenceStore: PreferenceStore,
 ) {
 
-    fun displayMode() = preferenceStore.getObject("pref_display_mode_library", LibraryDisplayMode.default, LibraryDisplayMode.Serializer::serialize, LibraryDisplayMode.Serializer::deserialize)
+    fun displayMode() = preferenceStore.getObject(
+        "pref_display_mode_library",
+        LibraryDisplayMode.default,
+        LibraryDisplayMode.Serializer::serialize,
+        LibraryDisplayMode.Serializer::deserialize,
+    )
 
-    fun sortingMode() = preferenceStore.getObject("library_sorting_mode", LibrarySort.default, LibrarySort.Serializer::serialize, LibrarySort.Serializer::deserialize)
+    fun sortingMode() = preferenceStore.getObject(
+        "library_sorting_mode",
+        LibrarySort.default,
+        LibrarySort.Serializer::serialize,
+        LibrarySort.Serializer::deserialize,
+    )
 
     fun portraitColumns() = preferenceStore.getInt("pref_library_columns_portrait_key", 0)
 
@@ -42,31 +52,64 @@ class LibraryPreferences(
 
     fun autoUpdateTrackers() = preferenceStore.getBoolean("auto_update_trackers", false)
 
-    fun showContinueReadingButton() = preferenceStore.getBoolean("display_continue_reading_button", false)
+    fun showContinueReadingButton() = preferenceStore.getBoolean(
+        "display_continue_reading_button",
+        false,
+    )
 
     // region Filter
 
-    fun filterDownloaded() = preferenceStore.getEnum("pref_filter_library_downloaded_v2", TriState.DISABLED)
+    fun filterDownloaded() = preferenceStore.getEnum(
+        "pref_filter_library_downloaded_v2",
+        TriState.DISABLED,
+    )
 
     fun filterUnread() = preferenceStore.getEnum("pref_filter_library_unread_v2", TriState.DISABLED)
 
-    fun filterStarted() = preferenceStore.getEnum("pref_filter_library_started_v2", TriState.DISABLED)
+    fun filterStarted() = preferenceStore.getEnum(
+        "pref_filter_library_started_v2",
+        TriState.DISABLED,
+    )
 
-    fun filterBookmarked() = preferenceStore.getEnum("pref_filter_library_bookmarked_v2", TriState.DISABLED)
+    fun filterBookmarked() = preferenceStore.getEnum(
+        "pref_filter_library_bookmarked_v2",
+        TriState.DISABLED,
+    )
 
-    fun filterCompleted() = preferenceStore.getEnum("pref_filter_library_completed_v2", TriState.DISABLED)
+    fun filterCompleted() = preferenceStore.getEnum(
+        "pref_filter_library_completed_v2",
+        TriState.DISABLED,
+    )
 
-    fun filterIntervalCustom() = preferenceStore.getEnum("pref_filter_library_interval_custom", TriState.DISABLED)
+    fun filterIntervalCustom() = preferenceStore.getEnum(
+        "pref_filter_library_interval_custom",
+        TriState.DISABLED,
+    )
 
-    fun filterIntervalLong() = preferenceStore.getEnum("pref_filter_library_interval_long", TriState.DISABLED)
+    fun filterIntervalLong() = preferenceStore.getEnum(
+        "pref_filter_library_interval_long",
+        TriState.DISABLED,
+    )
 
-    fun filterIntervalLate() = preferenceStore.getEnum("pref_filter_library_interval_late", TriState.DISABLED)
+    fun filterIntervalLate() = preferenceStore.getEnum(
+        "pref_filter_library_interval_late",
+        TriState.DISABLED,
+    )
 
-    fun filterIntervalDropped() = preferenceStore.getEnum("pref_filter_library_interval_dropped", TriState.DISABLED)
+    fun filterIntervalDropped() = preferenceStore.getEnum(
+        "pref_filter_library_interval_dropped",
+        TriState.DISABLED,
+    )
 
-    fun filterIntervalPassed() = preferenceStore.getEnum("pref_filter_library_interval_passed", TriState.DISABLED)
+    fun filterIntervalPassed() = preferenceStore.getEnum(
+        "pref_filter_library_interval_passed",
+        TriState.DISABLED,
+    )
 
-    fun filterTracking(id: Int) = preferenceStore.getEnum("pref_filter_library_tracked_${id}_v2", TriState.DISABLED)
+    fun filterTracking(id: Int) = preferenceStore.getEnum(
+        "pref_filter_library_tracked_${id}_v2",
+        TriState.DISABLED,
+    )
 
     // endregion
 
@@ -97,24 +140,45 @@ class LibraryPreferences(
 
     fun updateCategories() = preferenceStore.getStringSet("library_update_categories", emptySet())
 
-    fun updateCategoriesExclude() = preferenceStore.getStringSet("library_update_categories_exclude", emptySet())
+    fun updateCategoriesExclude() = preferenceStore.getStringSet(
+        "library_update_categories_exclude",
+        emptySet(),
+    )
 
     // endregion
 
     // region Chapter
 
-    fun filterChapterByRead() = preferenceStore.getLong("default_chapter_filter_by_read", Manga.SHOW_ALL)
+    fun filterChapterByRead() = preferenceStore.getLong(
+        "default_chapter_filter_by_read",
+        Manga.SHOW_ALL,
+    )
 
-    fun filterChapterByDownloaded() = preferenceStore.getLong("default_chapter_filter_by_downloaded", Manga.SHOW_ALL)
+    fun filterChapterByDownloaded() = preferenceStore.getLong(
+        "default_chapter_filter_by_downloaded",
+        Manga.SHOW_ALL,
+    )
 
-    fun filterChapterByBookmarked() = preferenceStore.getLong("default_chapter_filter_by_bookmarked", Manga.SHOW_ALL)
+    fun filterChapterByBookmarked() = preferenceStore.getLong(
+        "default_chapter_filter_by_bookmarked",
+        Manga.SHOW_ALL,
+    )
 
     // and upload date
-    fun sortChapterBySourceOrNumber() = preferenceStore.getLong("default_chapter_sort_by_source_or_number", Manga.CHAPTER_SORTING_SOURCE)
+    fun sortChapterBySourceOrNumber() = preferenceStore.getLong(
+        "default_chapter_sort_by_source_or_number",
+        Manga.CHAPTER_SORTING_SOURCE,
+    )
 
-    fun displayChapterByNameOrNumber() = preferenceStore.getLong("default_chapter_display_by_name_or_number", Manga.CHAPTER_DISPLAY_NAME)
+    fun displayChapterByNameOrNumber() = preferenceStore.getLong(
+        "default_chapter_display_by_name_or_number",
+        Manga.CHAPTER_DISPLAY_NAME,
+    )
 
-    fun sortChapterByAscendingOrDescending() = preferenceStore.getLong("default_chapter_sort_by_ascending_or_descending", Manga.CHAPTER_SORT_DESC)
+    fun sortChapterByAscendingOrDescending() = preferenceStore.getLong(
+        "default_chapter_sort_by_ascending_or_descending",
+        Manga.CHAPTER_SORT_DESC,
+    )
 
     fun setChapterSettingsDefault(manga: Manga) {
         filterChapterByRead().set(manga.unreadFilterRaw)
@@ -122,7 +186,9 @@ class LibraryPreferences(
         filterChapterByBookmarked().set(manga.bookmarkedFilterRaw)
         sortChapterBySourceOrNumber().set(manga.sorting)
         displayChapterByNameOrNumber().set(manga.displayMode)
-        sortChapterByAscendingOrDescending().set(if (manga.sortDescending()) Manga.CHAPTER_SORT_DESC else Manga.CHAPTER_SORT_ASC)
+        sortChapterByAscendingOrDescending().set(
+            if (manga.sortDescending()) Manga.CHAPTER_SORT_DESC else Manga.CHAPTER_SORT_ASC,
+        )
     }
 
     fun autoClearChapterCache() = preferenceStore.getBoolean("auto_clear_chapter_cache", false)
@@ -131,9 +197,15 @@ class LibraryPreferences(
 
     // region Swipe Actions
 
-    fun swipeToStartAction() = preferenceStore.getEnum("pref_chapter_swipe_end_action", ChapterSwipeAction.ToggleBookmark)
+    fun swipeToStartAction() = preferenceStore.getEnum(
+        "pref_chapter_swipe_end_action",
+        ChapterSwipeAction.ToggleBookmark,
+    )
 
-    fun swipeToEndAction() = preferenceStore.getEnum("pref_chapter_swipe_start_action", ChapterSwipeAction.ToggleRead)
+    fun swipeToEndAction() = preferenceStore.getEnum(
+        "pref_chapter_swipe_start_action",
+        ChapterSwipeAction.ToggleRead,
+    )
 
     // endregion
 

+ 11 - 3
domain/src/main/java/tachiyomi/domain/manga/interactor/SetFetchInterval.kt

@@ -27,7 +27,10 @@ class SetFetchInterval(
             window
         }
         val chapters = getChapterByMangaId.await(manga.id)
-        val interval = manga.fetchInterval.takeIf { it < 0 } ?: calculateInterval(chapters, dateTime)
+        val interval = manga.fetchInterval.takeIf { it < 0 } ?: calculateInterval(
+            chapters,
+            dateTime,
+        )
         val nextUpdate = calculateNextUpdate(manga, interval, dateTime, currentWindow)
 
         return if (manga.nextUpdate == nextUpdate && manga.fetchInterval == interval) {
@@ -46,7 +49,9 @@ class SetFetchInterval(
 
     internal fun calculateInterval(chapters: List<Chapter>, zonedDateTime: ZonedDateTime): Int {
         val sortedChapters = chapters
-            .sortedWith(compareByDescending<Chapter> { it.dateUpload }.thenByDescending { it.dateFetch })
+            .sortedWith(
+                compareByDescending<Chapter> { it.dateUpload }.thenByDescending { it.dateFetch },
+            )
             .take(50)
 
         val uploadDates = sortedChapters
@@ -95,7 +100,10 @@ class SetFetchInterval(
             manga.nextUpdate !in window.first.rangeTo(window.second + 1) ||
             manga.fetchInterval == 0
         ) {
-            val latestDate = ZonedDateTime.ofInstant(Instant.ofEpochMilli(manga.lastUpdate), dateTime.zone)
+            val latestDate = ZonedDateTime.ofInstant(
+                Instant.ofEpochMilli(manga.lastUpdate),
+                dateTime.zone,
+            )
                 .toLocalDate()
                 .atStartOfDay()
             val timeSinceLatest = ChronoUnit.DAYS.between(latestDate, dateTime).toInt()

+ 16 - 3
domain/src/main/java/tachiyomi/domain/release/interactor/GetApplicationRelease.kt

@@ -20,7 +20,10 @@ class GetApplicationRelease(
         val now = Instant.now()
 
         // Limit checks to once every 3 days at most
-        if (arguments.forceCheck.not() && now.isBefore(Instant.ofEpochMilli(lastChecked.get()).plus(3, ChronoUnit.DAYS))) {
+        if (arguments.forceCheck.not() && now.isBefore(
+                Instant.ofEpochMilli(lastChecked.get()).plus(3, ChronoUnit.DAYS),
+            )
+        ) {
             return Result.NoNewUpdate
         }
 
@@ -29,7 +32,12 @@ class GetApplicationRelease(
         lastChecked.set(now.toEpochMilli())
 
         // Check if latest version is different from current version
-        val isNewVersion = isNewVersion(arguments.isPreview, arguments.commitCount, arguments.versionName, release.version)
+        val isNewVersion = isNewVersion(
+            arguments.isPreview,
+            arguments.commitCount,
+            arguments.versionName,
+            release.version,
+        )
         return when {
             isNewVersion && arguments.isThirdParty -> Result.ThirdPartyInstallation
             isNewVersion -> Result.NewUpdate(release)
@@ -37,7 +45,12 @@ class GetApplicationRelease(
         }
     }
 
-    private fun isNewVersion(isPreview: Boolean, commitCount: Int, versionName: String, versionTag: String): Boolean {
+    private fun isNewVersion(
+        isPreview: Boolean,
+        commitCount: Int,
+        versionName: String,
+        versionTag: String,
+    ): Boolean {
         // Removes prefixes like "r" or "v"
         val newVersion = versionTag.replace("[^\\d.]".toRegex(), "")
         return if (isPreview) {

+ 4 - 1
domain/src/test/java/tachiyomi/domain/library/model/LibraryFlagsTest.kt

@@ -34,7 +34,10 @@ class LibraryFlagsTest {
 
     @Test
     fun `Test Flag plus operator with old flag as base`() {
-        val currentSort = LibrarySort(LibrarySort.Type.UnreadCount, LibrarySort.Direction.Descending)
+        val currentSort = LibrarySort(
+            LibrarySort.Type.UnreadCount,
+            LibrarySort.Direction.Descending,
+        )
         currentSort.flag shouldBe 0b00001100
 
         val sort = LibrarySort(LibrarySort.Type.DateAdded, LibrarySort.Direction.Ascending)

+ 6 - 2
domain/src/test/java/tachiyomi/domain/release/interactor/GetApplicationReleaseTest.kt

@@ -79,7 +79,9 @@ class GetApplicationReleaseTest {
             ),
         )
 
-        (result as GetApplicationRelease.Result.NewUpdate).release shouldBe GetApplicationRelease.Result.NewUpdate(release).release
+        (result as GetApplicationRelease.Result.NewUpdate).release shouldBe GetApplicationRelease.Result.NewUpdate(
+            release,
+        ).release
     }
 
     @Test
@@ -106,7 +108,9 @@ class GetApplicationReleaseTest {
             ),
         )
 
-        (result as GetApplicationRelease.Result.NewUpdate).release shouldBe GetApplicationRelease.Result.NewUpdate(release).release
+        (result as GetApplicationRelease.Result.NewUpdate).release shouldBe GetApplicationRelease.Result.NewUpdate(
+            release,
+        ).release
     }
 
     @Test

+ 1 - 1
gradle/libs.versions.toml

@@ -90,7 +90,7 @@ voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.
 voyager-tab-navigator = { module = "cafe.adriel.voyager:voyager-tab-navigator", version.ref = "voyager" }
 voyager-transitions = { module = "cafe.adriel.voyager:voyager-transitions", version.ref = "voyager" }
 
-kotlinter = "org.jmailen.gradle:kotlinter-gradle:3.13.0"
+ktlint = "org.jlleitschuh.gradle:ktlint-gradle:11.5.1"
 
 [bundles]
 okhttp = ["okhttp-core", "okhttp-logging", "okhttp-dnsoverhttps"]

+ 7 - 2
macrobenchmark/src/main/java/tachiyomi/macrobenchmark/StartupBenchmark.kt

@@ -60,11 +60,16 @@ abstract class AbstractStartupBenchmark(private val startupMode: StartupMode) {
 
     @Test
     fun startupBaselineProfileDisabled() = startup(
-        CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Disable, warmupIterations = 1),
+        CompilationMode.Partial(
+            baselineProfileMode = BaselineProfileMode.Disable,
+            warmupIterations = 1,
+        ),
     )
 
     @Test
-    fun startupBaselineProfile() = startup(CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require))
+    fun startupBaselineProfile() = startup(
+        CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require),
+    )
 
     @Test
     fun startupFullCompilation() = startup(CompilationMode.Full())

+ 42 - 38
presentation-core/src/main/java/tachiyomi/presentation/core/components/AdaptiveSheet.kt

@@ -182,7 +182,10 @@ fun AdaptiveSheet(
                 shape = MaterialTheme.shapes.extraLarge,
                 tonalElevation = tonalElevation,
                 content = {
-                    BackHandler(enabled = anchoredDraggableState.targetValue == 0, onBack = internalOnDismissRequest)
+                    BackHandler(
+                        enabled = anchoredDraggableState.targetValue == 0,
+                        onBack = internalOnDismissRequest,
+                    )
                     content()
                 },
             )
@@ -200,49 +203,50 @@ fun AdaptiveSheet(
     }
 }
 
-private fun <T> AnchoredDraggableState<T>.preUpPostDownNestedScrollConnection() = object : NestedScrollConnection {
-    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
-        val delta = available.toFloat()
-        return if (delta < 0 && source == NestedScrollSource.Drag) {
-            dispatchRawDelta(delta).toOffset()
-        } else {
-            Offset.Zero
+private fun <T> AnchoredDraggableState<T>.preUpPostDownNestedScrollConnection() =
+    object : NestedScrollConnection {
+        override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+            val delta = available.toFloat()
+            return if (delta < 0 && source == NestedScrollSource.Drag) {
+                dispatchRawDelta(delta).toOffset()
+            } else {
+                Offset.Zero
+            }
         }
-    }
 
-    override fun onPostScroll(
-        consumed: Offset,
-        available: Offset,
-        source: NestedScrollSource,
-    ): Offset {
-        return if (source == NestedScrollSource.Drag) {
-            dispatchRawDelta(available.toFloat()).toOffset()
-        } else {
-            Offset.Zero
+        override fun onPostScroll(
+            consumed: Offset,
+            available: Offset,
+            source: NestedScrollSource,
+        ): Offset {
+            return if (source == NestedScrollSource.Drag) {
+                dispatchRawDelta(available.toFloat()).toOffset()
+            } else {
+                Offset.Zero
+            }
         }
-    }
 
-    override suspend fun onPreFling(available: Velocity): Velocity {
-        val toFling = available.toFloat()
-        return if (toFling < 0 && offset > anchors.minAnchor()) {
-            settle(toFling)
-            // since we go to the anchor with tween settling, consume all for the best UX
-            available
-        } else {
-            Velocity.Zero
+        override suspend fun onPreFling(available: Velocity): Velocity {
+            val toFling = available.toFloat()
+            return if (toFling < 0 && offset > anchors.minAnchor()) {
+                settle(toFling)
+                // since we go to the anchor with tween settling, consume all for the best UX
+                available
+            } else {
+                Velocity.Zero
+            }
         }
-    }
 
-    override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
-        settle(velocity = available.toFloat())
-        return available
-    }
+        override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
+            settle(velocity = available.toFloat())
+            return available
+        }
 
-    private fun Float.toOffset(): Offset = Offset(0f, this)
+        private fun Float.toOffset(): Offset = Offset(0f, this)
 
-    @JvmName("velocityToFloat")
-    private fun Velocity.toFloat() = this.y
+        @JvmName("velocityToFloat")
+        private fun Velocity.toFloat() = this.y
 
-    @JvmName("offsetToFloat")
-    private fun Offset.toFloat(): Float = this.y
-}
+        @JvmName("offsetToFloat")
+        private fun Offset.toFloat(): Float = this.y
+    }

+ 1 - 3
presentation-core/src/main/java/tachiyomi/presentation/core/components/CircularProgressIndicator.kt

@@ -37,9 +37,7 @@ import androidx.compose.ui.tooling.preview.Preview
  * By always rotating we give the feedback to the user that the application isn't 'stuck'.
  */
 @Composable
-fun CombinedCircularProgressIndicator(
-    progress: Float,
-) {
+fun CombinedCircularProgressIndicator(progress: Float) {
     val animatedProgress by animateFloatAsState(
         targetValue = progress,
         animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,

+ 1 - 4
presentation-core/src/main/java/tachiyomi/presentation/core/components/CollapsibleBox.kt

@@ -23,10 +23,7 @@ import androidx.compose.ui.unit.dp
 import tachiyomi.presentation.core.theme.header
 
 @Composable
-fun CollapsibleBox(
-    heading: String,
-    content: @Composable () -> Unit,
-) {
+fun CollapsibleBox(heading: String, content: @Composable () -> Unit) {
     var expanded by remember { mutableStateOf(false) }
 
     Column {

+ 1 - 6
presentation-core/src/main/java/tachiyomi/presentation/core/components/LinkIcon.kt

@@ -11,12 +11,7 @@ import androidx.compose.ui.platform.LocalUriHandler
 import androidx.compose.ui.unit.dp
 
 @Composable
-fun LinkIcon(
-    modifier: Modifier = Modifier,
-    label: String,
-    icon: ImageVector,
-    url: String,
-) {
+fun LinkIcon(modifier: Modifier = Modifier, label: String, icon: ImageVector, url: String) {
     val uriHandler = LocalUriHandler.current
     IconButton(
         modifier = modifier.padding(4.dp),

+ 1 - 4
presentation-core/src/main/java/tachiyomi/presentation/core/components/ListGroupHeader.kt

@@ -9,10 +9,7 @@ import androidx.compose.ui.text.font.FontWeight
 import tachiyomi.presentation.core.components.material.padding
 
 @Composable
-fun ListGroupHeader(
-    modifier: Modifier = Modifier,
-    text: String,
-) {
+fun ListGroupHeader(modifier: Modifier = Modifier, text: String) {
     Text(
         text = text,
         modifier = modifier

+ 9 - 39
presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt

@@ -51,16 +51,12 @@ object SettingsItemsPaddings {
 }
 
 @Composable
-fun HeadingItem(
-    @StringRes labelRes: Int,
-) {
+fun HeadingItem(@StringRes labelRes: Int) {
     HeadingItem(stringResource(labelRes))
 }
 
 @Composable
-fun HeadingItem(
-    text: String,
-) {
+fun HeadingItem(text: String) {
     Text(
         text = text,
         style = MaterialTheme.typography.header,
@@ -74,11 +70,7 @@ fun HeadingItem(
 }
 
 @Composable
-fun IconItem(
-    label: String,
-    icon: ImageVector,
-    onClick: () -> Unit,
-) {
+fun IconItem(label: String, icon: ImageVector, onClick: () -> Unit) {
     BaseSettingsItem(
         label = label,
         widget = {
@@ -93,11 +85,7 @@ fun IconItem(
 }
 
 @Composable
-fun SortItem(
-    label: String,
-    sortDescending: Boolean?,
-    onClick: () -> Unit,
-) {
+fun SortItem(label: String, sortDescending: Boolean?, onClick: () -> Unit) {
     val arrowIcon = when (sortDescending) {
         true -> Icons.Default.ArrowDownward
         false -> Icons.Default.ArrowUpward
@@ -122,10 +110,7 @@ fun SortItem(
 }
 
 @Composable
-fun CheckboxItem(
-    label: String,
-    pref: Preference<Boolean>,
-) {
+fun CheckboxItem(label: String, pref: Preference<Boolean>) {
     val checked by pref.collectAsState()
     CheckboxItem(
         label = label,
@@ -135,11 +120,7 @@ fun CheckboxItem(
 }
 
 @Composable
-fun CheckboxItem(
-    label: String,
-    checked: Boolean,
-    onClick: () -> Unit,
-) {
+fun CheckboxItem(label: String, checked: Boolean, onClick: () -> Unit) {
     BaseSettingsItem(
         label = label,
         widget = {
@@ -153,11 +134,7 @@ fun CheckboxItem(
 }
 
 @Composable
-fun RadioItem(
-    label: String,
-    selected: Boolean,
-    onClick: () -> Unit,
-) {
+fun RadioItem(label: String, selected: Boolean, onClick: () -> Unit) {
     BaseSettingsItem(
         label = label,
         widget = {
@@ -314,11 +291,7 @@ fun TriStateItem(
 }
 
 @Composable
-fun TextItem(
-    label: String,
-    value: String,
-    onChange: (String) -> Unit,
-) {
+fun TextItem(label: String, value: String, onChange: (String) -> Unit) {
     OutlinedTextField(
         modifier = Modifier
             .fillMaxWidth()
@@ -331,10 +304,7 @@ fun TextItem(
 }
 
 @Composable
-fun SettingsChipRow(
-    @StringRes labelRes: Int,
-    content: @Composable FlowRowScope.() -> Unit,
-) {
+fun SettingsChipRow(@StringRes labelRes: Int, content: @Composable FlowRowScope.() -> Unit) {
     Column {
         HeadingItem(labelRes)
         FlowRow(

+ 2 - 1
presentation-core/src/main/java/tachiyomi/presentation/core/components/VerticalFastScroller.kt

@@ -197,7 +197,8 @@ private fun rememberColumnWidthSums(
     horizontalArrangement,
     contentPadding,
 ) {
-    { constraints ->
+    {
+            constraints ->
         require(constraints.maxWidth != Constraints.Infinity) {
             "LazyVerticalGrid's width should be bound by parent"
         }

+ 12 - 4
presentation-core/src/main/java/tachiyomi/presentation/core/components/material/AlertDialog.kt

@@ -30,7 +30,9 @@ fun AlertDialogContent(
         title = title,
         content = {
             Column {
-                CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant) {
+                CompositionLocalProvider(
+                    LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant,
+                ) {
                     val textStyle = MaterialTheme.typography.bodyMedium
                     ProvideTextStyle(textStyle) {
                         Box(
@@ -54,7 +56,9 @@ fun AlertDialogContent(
                         )
                         .align(Alignment.End),
                 ) {
-                    CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.primary) {
+                    CompositionLocalProvider(
+                        LocalContentColor provides MaterialTheme.colorScheme.primary,
+                    ) {
                         val textStyle = MaterialTheme.typography.labelLarge
                         ProvideTextStyle(value = textStyle, content = buttons)
                     }
@@ -86,7 +90,9 @@ fun AlertDialogContent(
                     .fillMaxWidth(),
             ) {
                 icon?.let {
-                    CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.secondary) {
+                    CompositionLocalProvider(
+                        LocalContentColor provides MaterialTheme.colorScheme.secondary,
+                    ) {
                         Box(
                             Modifier
                                 .padding(IconPadding)
@@ -97,7 +103,9 @@ fun AlertDialogContent(
                     }
                 }
                 title?.let {
-                    CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
+                    CompositionLocalProvider(
+                        LocalContentColor provides MaterialTheme.colorScheme.onSurface,
+                    ) {
                         val textStyle = MaterialTheme.typography.headlineSmall
                         ProvideTextStyle(textStyle) {
                             Box(

+ 13 - 14
presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Button.kt

@@ -64,20 +64,19 @@ fun TextButton(
     ),
     contentPadding: PaddingValues = M3ButtonDefaults.TextButtonContentPadding,
     content: @Composable RowScope.() -> Unit,
-) =
-    Button(
-        onClick = onClick,
-        modifier = modifier,
-        onLongClick = onLongClick,
-        enabled = enabled,
-        interactionSource = interactionSource,
-        elevation = elevation,
-        shape = shape,
-        border = border,
-        colors = colors,
-        contentPadding = contentPadding,
-        content = content,
-    )
+) = Button(
+    onClick = onClick,
+    modifier = modifier,
+    onLongClick = onLongClick,
+    enabled = enabled,
+    interactionSource = interactionSource,
+    elevation = elevation,
+    shape = shape,
+    border = border,
+    colors = colors,
+    contentPadding = contentPadding,
+    content = content,
+)
 
 /**
  * Button with additional onLongClick functionality.

+ 0 - 0
presentation-core/src/main/java/tachiyomi/presentation/core/components/material/IconButton.kt → presentation-core/src/main/java/tachiyomi/presentation/core/components/material/IconButtonTokens.kt


+ 4 - 1
presentation-core/src/main/java/tachiyomi/presentation/core/components/material/NavigationRail.kt

@@ -48,7 +48,10 @@ fun NavigationRail(
                 .padding(vertical = MaterialTheme.padding.tiny)
                 .selectableGroup(),
             horizontalAlignment = Alignment.CenterHorizontally,
-            verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.tiny, alignment = Alignment.CenterVertically),
+            verticalArrangement = Arrangement.spacedBy(
+                MaterialTheme.padding.tiny,
+                alignment = Alignment.CenterVertically,
+            ),
         ) {
             if (header != null) {
                 header()

+ 12 - 3
presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Scaffold.kt

@@ -99,7 +99,9 @@ import kotlin.math.max
 @Composable
 fun Scaffold(
     modifier: Modifier = Modifier,
-    topBarScrollBehavior: TopAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()),
+    topBarScrollBehavior: TopAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(
+        rememberTopAppBarState(),
+    ),
     topBar: @Composable (TopAppBarScrollBehavior) -> Unit = {},
     bottomBar: @Composable () -> Unit = {},
     startBar: @Composable () -> Unit = {},
@@ -116,7 +118,11 @@ fun Scaffold(
     androidx.compose.material3.Surface(
         modifier = Modifier
             .nestedScroll(topBarScrollBehavior.nestedScrollConnection)
-            .onConsumedWindowInsetsChanged { remainingWindowInsets.insets = contentWindowInsets.exclude(it) }
+            .onConsumedWindowInsetsChanged {
+                remainingWindowInsets.insets = contentWindowInsets.exclude(
+                    it,
+                )
+            }
             .then(modifier),
         color = containerColor,
         contentColor = contentColor,
@@ -271,7 +277,10 @@ private fun ScaffoldLayout(
                     } else {
                         max(bottomBarHeightPx.toDp(), fabOffsetDp)
                     },
-                    start = max(insets.calculateStartPadding((this@SubcomposeLayout).layoutDirection), startBarWidth.toDp()),
+                    start = max(
+                        insets.calculateStartPadding((this@SubcomposeLayout).layoutDirection),
+                        startBarWidth.toDp(),
+                    ),
                     end = insets.calculateEndPadding((this@SubcomposeLayout).layoutDirection),
                 )
                 content(innerPadding)

+ 1 - 3
presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Surface.kt

@@ -104,9 +104,7 @@ private fun surfaceColorAtElevation(color: Color, elevation: Dp): Color {
     }
 }
 
-private fun ColorScheme.surfaceColorAtElevation(
-    elevation: Dp,
-): Color {
+private fun ColorScheme.surfaceColorAtElevation(elevation: Dp): Color {
     if (elevation == 0.dp) return surface
     val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f
     return surfaceTint.copy(alpha = alpha).compositeOver(surface)

+ 2 - 8
presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Tabs.kt

@@ -46,10 +46,7 @@ private fun Modifier.tabIndicatorOffset(
     }
 
 @Composable
-fun TabIndicator(
-    currentTabPosition: TabPosition,
-    currentPageOffsetFraction: Float,
-) {
+fun TabIndicator(currentTabPosition: TabPosition, currentPageOffsetFraction: Float) {
     SecondaryIndicator(
         modifier = Modifier
             .tabIndicatorOffset(currentTabPosition, currentPageOffsetFraction)
@@ -59,10 +56,7 @@ fun TabIndicator(
 }
 
 @Composable
-fun TabText(
-    text: String,
-    badgeCount: Int? = null,
-) {
+fun TabText(text: String, badgeCount: Int? = null) {
     val pillAlpha = if (isSystemInDarkTheme()) 0.12f else 0.08f
 
     Row(

+ 0 - 0
presentation-core/src/main/java/tachiyomi/presentation/core/util/Preview.kt → presentation-core/src/main/java/tachiyomi/presentation/core/util/ThemePreviews.kt


+ 1 - 4
presentation-widget/src/main/java/tachiyomi/presentation/widget/components/UpdatesMangaCover.kt

@@ -17,10 +17,7 @@ val CoverWidth = 58.dp
 val CoverHeight = 87.dp
 
 @Composable
-fun UpdatesMangaCover(
-    modifier: GlanceModifier = GlanceModifier,
-    cover: Bitmap?,
-) {
+fun UpdatesMangaCover(modifier: GlanceModifier = GlanceModifier, cover: Bitmap?) {
     Box(
         modifier = modifier
             .size(width = CoverWidth, height = CoverHeight)

+ 6 - 2
source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/Source.kt

@@ -64,7 +64,9 @@ interface Source {
         "Use the non-RxJava API instead",
         ReplaceWith("getMangaDetails"),
     )
-    fun fetchMangaDetails(manga: SManga): Observable<SManga> = throw IllegalStateException("Not used")
+    fun fetchMangaDetails(manga: SManga): Observable<SManga> = throw IllegalStateException(
+        "Not used",
+    )
 
     /**
      * Returns an observable with all the available chapters for a manga.
@@ -75,7 +77,9 @@ interface Source {
         "Use the non-RxJava API instead",
         ReplaceWith("getChapterList"),
     )
-    fun fetchChapterList(manga: SManga): Observable<List<SChapter>> = throw IllegalStateException("Not used")
+    fun fetchChapterList(manga: SManga): Observable<List<SChapter>> = throw IllegalStateException(
+        "Not used",
+    )
 
     /**
      * Returns an observable with the list of pages a chapter has. Pages should be returned

+ 4 - 1
source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/model/Filter.kt

@@ -3,7 +3,10 @@ package eu.kanade.tachiyomi.source.model
 sealed class Filter<T>(val name: String, var state: T) {
     open class Header(name: String) : Filter<Any>(name, 0)
     open class Separator(name: String = "") : Filter<Any>(name, 0)
-    abstract class Select<V>(name: String, val values: Array<V>, state: Int = 0) : Filter<Int>(name, state)
+    abstract class Select<V>(name: String, val values: Array<V>, state: Int = 0) : Filter<Int>(
+        name,
+        state,
+    )
     abstract class Text(name: String, state: String = "") : Filter<String>(name, state)
     abstract class CheckBox(name: String, state: Boolean = false) : Filter<Boolean>(name, state)
     abstract class TriState(name: String, state: Int = STATE_IGNORE) : Filter<Int>(name, state) {

+ 10 - 2
source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt

@@ -135,7 +135,11 @@ abstract class HttpSource : CatalogueSource {
      * @param query the search query.
      * @param filters the list of filters to apply.
      */
-    override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
+    override fun fetchSearchManga(
+        page: Int,
+        query: String,
+        filters: FilterList,
+    ): Observable<MangasPage> {
         return Observable.defer {
             try {
                 client.newCall(searchMangaRequest(page, query, filters)).asObservableSuccess()
@@ -157,7 +161,11 @@ abstract class HttpSource : CatalogueSource {
      * @param query the search query.
      * @param filters the list of filters to apply.
      */
-    protected abstract fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request
+    protected abstract fun searchMangaRequest(
+        page: Int,
+        query: String,
+        filters: FilterList,
+    ): Request
 
     /**
      * Parses the response from the site and returns a [MangasPage] object.