Clean up some build warnings (mihonapp/mihon#2929)
* Replace deprecated rememberPlainTooltipPositionProvider * Remove superfluous when branch This when is marked as exhaustive. * Replace deprecated LibrariesContainer call AboutLibraries now wants us to produce the libraries ourselves. * Replace deprecated ClipboardManager with Clipboard Clipboard uses suspend functions, hence the coroutine scope addition. * Use multi-dollar strs to simplify GraphQL queries These have been available since Kotlin 2.1. * Remove various redundant casts & conversions - WebViewScreenContent: loadingState is in the LoadingState.Loading branch, no need to cast at all - Bangumi: username is not modified, make val - Kavita: token is already a String - PagerViewerAdapter: insertPageLastPage is already null-checked - PagerViewerAdapter: use reified filterIsInstance - ReaderViewModel: chapter IDs are already Longs - CloudflareInterceptor: webview is smart-cast to non-null here * Replace deprecated MenuAnchorType Literally just a typealias for ExposedDropdownMenuAnchorType anyway. * OptimizeNonSkippingGroups is enabled by default * Suppress shadowing warning This is explicitly intentional according to the KDocs. * Migrate Context Receivers to Context Parameters Requires changing the compiler arg, but that is part of the migration: https://blog.jetbrains.com/kotlin/2025/04/update-on-context-parameters Apparently, the only visible change is that names are required now. "_" can be used for anonymous context parameters. * Fix expression bodies with explicit return Naming conflict resolved by aliasing. From 2.4/2.5 onward, these will only be allowed with explicit return types, or have to be turned into a block body. I opted for the latter since the function is reasonably dense already. see: https://youtrack.jetbrains.com/issue/KTLC-288 * Suppress deprecation of non-AutoMirrored icons We use these arrows for navigation in the Upcoming screen. I strongly doubt the AutoMirrored versions would make sense for our use-case. * Explicitly opt-in to new annotation default rules affects the following annotated value-parameters: - Preference.SliderPreference.steps (`@IntRange`) - ReaderViewModel.State.brightnessOverlayValue (`@IntRange`) - ReadingMode.iconRes (`@DrawableRes`) - MigrationListScreenModel.Dialog.Progress.progress (`@FloatRange`) see: https://youtrack.jetbrains.com/issue/KT-73255 see: https://github.com/Kotlin/KEEP/blob/change-defaulting-rule/proposals/annotation-target-in-properties.md Warning message was the following: This annotation is currently applied to the value parameter only, but in the future it will also be applied to field. - To opt in to applying to both value parameter and field, add '-Xannotation-default-target=param-property' to your compiler arguments. - To keep applying to the value parameter only, use the '@param:' annotation target. (cherry picked from commit b543bc089a442c5e93b0fb6c83bc4037740b1eb5)
This commit is contained in:
parent
ccf404c4f7
commit
34102027d1
15 changed files with 98 additions and 78 deletions
|
|
@ -175,6 +175,7 @@ kotlin {
|
||||||
"-opt-in=kotlinx.coroutines.FlowPreview",
|
"-opt-in=kotlinx.coroutines.FlowPreview",
|
||||||
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
|
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
|
||||||
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
|
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
|
||||||
|
"-Xannotation-default-target=param-property",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,9 @@ import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.PlainTooltip
|
import androidx.compose.material3.PlainTooltip
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextFieldDefaults
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
|
import androidx.compose.material3.TooltipAnchorPosition
|
||||||
import androidx.compose.material3.TooltipBox
|
import androidx.compose.material3.TooltipBox
|
||||||
import androidx.compose.material3.TooltipDefaults
|
import androidx.compose.material3.TooltipDefaults.rememberTooltipPositionProvider
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
|
|
@ -216,7 +217,7 @@ fun AppBarActions(
|
||||||
|
|
||||||
actions.filterIsInstance<AppBar.Action>().map {
|
actions.filterIsInstance<AppBar.Action>().map {
|
||||||
TooltipBox(
|
TooltipBox(
|
||||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||||
tooltip = {
|
tooltip = {
|
||||||
PlainTooltip {
|
PlainTooltip {
|
||||||
Text(it.title)
|
Text(it.title)
|
||||||
|
|
@ -241,7 +242,7 @@ fun AppBarActions(
|
||||||
// KMK -->
|
// KMK -->
|
||||||
actions.filterIsInstance<AppBar.ActionCompose>().map {
|
actions.filterIsInstance<AppBar.ActionCompose>().map {
|
||||||
TooltipBox(
|
TooltipBox(
|
||||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||||
tooltip = {
|
tooltip = {
|
||||||
PlainTooltip {
|
PlainTooltip {
|
||||||
Text(it.title)
|
Text(it.title)
|
||||||
|
|
@ -264,7 +265,7 @@ fun AppBarActions(
|
||||||
val overflowActions = actions.filterIsInstance<AppBar.OverflowAction>()
|
val overflowActions = actions.filterIsInstance<AppBar.OverflowAction>()
|
||||||
if (overflowActions.isNotEmpty()) {
|
if (overflowActions.isNotEmpty()) {
|
||||||
TooltipBox(
|
TooltipBox(
|
||||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||||
tooltip = {
|
tooltip = {
|
||||||
PlainTooltip {
|
PlainTooltip {
|
||||||
Text(stringResource(MR.strings.action_menu_overflow_description))
|
Text(stringResource(MR.strings.action_menu_overflow_description))
|
||||||
|
|
@ -393,7 +394,7 @@ fun SearchToolbar(
|
||||||
// Don't show search action
|
// Don't show search action
|
||||||
} else if (searchQuery == null) {
|
} else if (searchQuery == null) {
|
||||||
TooltipBox(
|
TooltipBox(
|
||||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||||
tooltip = {
|
tooltip = {
|
||||||
PlainTooltip {
|
PlainTooltip {
|
||||||
Text(stringResource(MR.strings.action_search))
|
Text(stringResource(MR.strings.action_search))
|
||||||
|
|
@ -413,7 +414,7 @@ fun SearchToolbar(
|
||||||
}
|
}
|
||||||
} else if (searchQuery.isNotEmpty()) {
|
} else if (searchQuery.isNotEmpty()) {
|
||||||
TooltipBox(
|
TooltipBox(
|
||||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||||
tooltip = {
|
tooltip = {
|
||||||
PlainTooltip {
|
PlainTooltip {
|
||||||
Text(stringResource(MR.strings.action_reset))
|
Text(stringResource(MR.strings.action_reset))
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@ package eu.kanade.presentation.more.settings.screen.about
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import com.mikepenz.aboutlibraries.ui.compose.android.produceLibraries
|
||||||
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
|
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
|
||||||
import com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent
|
import com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
|
|
@ -27,7 +30,9 @@ class OpenSourceLicensesScreen : Screen() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
|
val libraries by produceLibraries(R.raw.aboutlibraries)
|
||||||
LibrariesContainer(
|
LibrariesContainer(
|
||||||
|
libraries = libraries,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.presentation.track
|
package eu.kanade.presentation.track
|
||||||
|
|
||||||
|
import android.content.ClipData
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
|
|
@ -47,6 +48,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
@ -55,11 +57,11 @@ import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
import androidx.compose.ui.platform.ClipboardManager
|
import androidx.compose.ui.platform.Clipboard
|
||||||
import androidx.compose.ui.platform.LocalClipboardManager
|
import androidx.compose.ui.platform.LocalClipboard
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.platform.toClipEntry
|
||||||
import androidx.compose.ui.text.capitalize
|
import androidx.compose.ui.text.capitalize
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.intl.Locale
|
import androidx.compose.ui.text.intl.Locale
|
||||||
|
|
@ -73,6 +75,7 @@ import eu.kanade.presentation.manga.components.MangaCover
|
||||||
import eu.kanade.presentation.theme.TachiyomiPreviewTheme
|
import eu.kanade.presentation.theme.TachiyomiPreviewTheme
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.util.system.openInBrowser
|
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
|
@ -240,7 +243,7 @@ private fun SearchResultItem(
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val clipboardManager: ClipboardManager = LocalClipboardManager.current
|
val clipboard: Clipboard = LocalClipboard.current
|
||||||
val focusManager = LocalFocusManager.current
|
val focusManager = LocalFocusManager.current
|
||||||
val type = trackSearch.publishing_type.toLowerCase(Locale.current).capitalize(Locale.current)
|
val type = trackSearch.publishing_type.toLowerCase(Locale.current).capitalize(Locale.current)
|
||||||
val status = trackSearch.publishing_status.toLowerCase(Locale.current).capitalize(Locale.current)
|
val status = trackSearch.publishing_status.toLowerCase(Locale.current).capitalize(Locale.current)
|
||||||
|
|
@ -248,6 +251,7 @@ private fun SearchResultItem(
|
||||||
val shape = RoundedCornerShape(16.dp)
|
val shape = RoundedCornerShape(16.dp)
|
||||||
val borderColor = if (selected) MaterialTheme.colorScheme.outline else Color.Transparent
|
val borderColor = if (selected) MaterialTheme.colorScheme.outline else Color.Transparent
|
||||||
var dropDownMenuExpanded by remember { mutableStateOf(false) }
|
var dropDownMenuExpanded by remember { mutableStateOf(false) }
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
@ -295,7 +299,13 @@ private fun SearchResultItem(
|
||||||
expanded = dropDownMenuExpanded,
|
expanded = dropDownMenuExpanded,
|
||||||
onCollapseMenu = { dropDownMenuExpanded = false },
|
onCollapseMenu = { dropDownMenuExpanded = false },
|
||||||
onCopyName = {
|
onCopyName = {
|
||||||
clipboardManager.setText(AnnotatedString(trackSearch.title))
|
scope.launch {
|
||||||
|
val clipEntry = ClipData.newPlainText(
|
||||||
|
trackSearch.title,
|
||||||
|
trackSearch.title,
|
||||||
|
).toClipEntry()
|
||||||
|
clipboard.setClipEntry(clipEntry)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onOpenInBrowser = {
|
onOpenInBrowser = {
|
||||||
val url = trackSearch.tracking_url
|
val url = trackSearch.tracking_url
|
||||||
|
|
|
||||||
|
|
@ -9,21 +9,21 @@ import tachiyomi.domain.source.model.SourceNotInstalledException
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
|
|
||||||
context(Context)
|
context(context: Context)
|
||||||
val Throwable.formattedMessage: String
|
val Throwable.formattedMessage: String
|
||||||
get() {
|
get() {
|
||||||
when (this) {
|
when (this) {
|
||||||
is HttpException -> return stringResource(MR.strings.exception_http, code)
|
is HttpException -> return context.stringResource(MR.strings.exception_http, code)
|
||||||
is UnknownHostException -> {
|
is UnknownHostException -> {
|
||||||
return if (!isOnline()) {
|
return if (!context.isOnline()) {
|
||||||
stringResource(MR.strings.exception_offline)
|
context.stringResource(MR.strings.exception_offline)
|
||||||
} else {
|
} else {
|
||||||
stringResource(MR.strings.exception_unknown_host, message ?: "")
|
context.stringResource(MR.strings.exception_unknown_host, message ?: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is NoResultsException -> return stringResource(MR.strings.no_results_found)
|
is NoResultsException -> return context.stringResource(MR.strings.no_results_found)
|
||||||
is SourceNotInstalledException -> return stringResource(MR.strings.loader_not_implemented_error)
|
is SourceNotInstalledException -> return context.stringResource(MR.strings.loader_not_implemented_error)
|
||||||
}
|
}
|
||||||
return when (val className = this::class.simpleName) {
|
return when (val className = this::class.simpleName) {
|
||||||
"Exception", "IOException" -> message ?: className
|
"Exception", "IOException" -> message ?: className
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,7 @@ import androidx.compose.foundation.lazy.LazyItemScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
// https://issuetracker.google.com/352584409
|
// https://issuetracker.google.com/352584409
|
||||||
context(LazyItemScope)
|
context(itemScope: LazyItemScope)
|
||||||
fun Modifier.animateItemFastScroll() = this.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
fun Modifier.animateItemFastScroll() = with(itemScope) {
|
||||||
|
this@animateItemFastScroll.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,9 +134,9 @@ class BackupRestorer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context(CoroutineScope)
|
context(scope: CoroutineScope)
|
||||||
private /* KMK --> */suspend /* KMK <-- */ fun restoreCategories(backupCategories: List<BackupCategory>) {
|
private /* KMK --> */suspend /* KMK <-- */ fun restoreCategories(backupCategories: List<BackupCategory>) {
|
||||||
ensureActive()
|
scope.ensureActive()
|
||||||
categoriesRestorer(backupCategories)
|
categoriesRestorer(backupCategories)
|
||||||
|
|
||||||
restoreProgress += 1
|
restoreProgress += 1
|
||||||
|
|
@ -289,7 +289,7 @@ class BackupRestorer(
|
||||||
}
|
}
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (_: Exception) {
|
||||||
// Empty
|
// Empty
|
||||||
}
|
}
|
||||||
return File("")
|
return File("")
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,9 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||||
|
|
||||||
suspend fun addLibManga(track: Track): Track {
|
suspend fun addLibManga(track: Track): Track {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val query = """
|
val query = $$"""
|
||||||
|mutation AddManga(${'$'}mangaId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}private: Boolean) {
|
|mutation AddManga($mangaId: Int, $progress: Int, $status: MediaListStatus, $private: Boolean) {
|
||||||
|SaveMediaListEntry (mediaId: ${'$'}mangaId, progress: ${'$'}progress, status: ${'$'}status, private: ${'$'}private) {
|
|SaveMediaListEntry (mediaId: $mangaId, progress: $progress, status: $status, private: $private) {
|
||||||
| id
|
| id
|
||||||
| status
|
| status
|
||||||
|}
|
|}
|
||||||
|
|
@ -82,14 +82,14 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||||
|
|
||||||
suspend fun updateLibManga(track: Track): Track {
|
suspend fun updateLibManga(track: Track): Track {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val query = """
|
val query = $$"""
|
||||||
|mutation UpdateManga(
|
|mutation UpdateManga(
|
||||||
|${'$'}listId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}private: Boolean,
|
|$listId: Int, $progress: Int, $status: MediaListStatus, $private: Boolean,
|
||||||
|${'$'}score: Int, ${'$'}startedAt: FuzzyDateInput, ${'$'}completedAt: FuzzyDateInput
|
|$score: Int, $startedAt: FuzzyDateInput, $completedAt: FuzzyDateInput
|
||||||
|) {
|
|) {
|
||||||
|SaveMediaListEntry(
|
|SaveMediaListEntry(
|
||||||
|id: ${'$'}listId, progress: ${'$'}progress, status: ${'$'}status, private: ${'$'}private,
|
|id: $listId, progress: $progress, status: $status, private: $private,
|
||||||
|scoreRaw: ${'$'}score, startedAt: ${'$'}startedAt, completedAt: ${'$'}completedAt
|
|scoreRaw: $score, startedAt: $startedAt, completedAt: $completedAt
|
||||||
|) {
|
|) {
|
||||||
|id
|
|id
|
||||||
|status
|
|status
|
||||||
|
|
@ -118,9 +118,9 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||||
|
|
||||||
suspend fun deleteLibManga(track: DomainTrack) {
|
suspend fun deleteLibManga(track: DomainTrack) {
|
||||||
withIOContext {
|
withIOContext {
|
||||||
val query = """
|
val query = $$"""
|
||||||
|mutation DeleteManga(${'$'}listId: Int) {
|
|mutation DeleteManga($listId: Int) {
|
||||||
|DeleteMediaListEntry(id: ${'$'}listId) {
|
|DeleteMediaListEntry(id: $listId) {
|
||||||
|deleted
|
|deleted
|
||||||
|}
|
|}
|
||||||
|}
|
|}
|
||||||
|
|
@ -139,10 +139,10 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||||
|
|
||||||
suspend fun search(search: String): List<TrackSearch> {
|
suspend fun search(search: String): List<TrackSearch> {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val query = """
|
val query = $$"""
|
||||||
|query Search(${'$'}query: String) {
|
|query Search($query: String) {
|
||||||
|Page (perPage: 50) {
|
|Page (perPage: 50) {
|
||||||
|media(search: ${'$'}query, type: MANGA, format_not_in: [NOVEL]) {
|
|media(search: $query, type: MANGA, format_not_in: [NOVEL]) {
|
||||||
|id
|
|id
|
||||||
|staff {
|
|staff {
|
||||||
|edges {
|
|edges {
|
||||||
|
|
@ -201,10 +201,10 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||||
|
|
||||||
suspend fun findLibManga(track: Track, userid: Int): Track? {
|
suspend fun findLibManga(track: Track, userid: Int): Track? {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val query = """
|
val query = $$"""
|
||||||
|query (${'$'}id: Int!, ${'$'}manga_id: Int!) {
|
|query ($id: Int!, $manga_id: Int!) {
|
||||||
|Page {
|
|Page {
|
||||||
|mediaList(userId: ${'$'}id, type: MANGA, mediaId: ${'$'}manga_id) {
|
|mediaList(userId: $id, type: MANGA, mediaId: $manga_id) {
|
||||||
|id
|
|id
|
||||||
|status
|
|status
|
||||||
|scoreRaw: score(format: POINT_100)
|
|scoreRaw: score(format: POINT_100)
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker {
|
||||||
}
|
}
|
||||||
|
|
||||||
authentication.apiUrl = prefApiUrl
|
authentication.apiUrl = prefApiUrl
|
||||||
authentication.jwtToken = token.toString()
|
authentication.jwtToken = token
|
||||||
}
|
}
|
||||||
authentications = oauth
|
authentications = oauth
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,14 @@ class SuwayomiApi(private val trackId: Long) {
|
||||||
public fun sourcePreferences(): SharedPreferences = configurableSource.sourcePreferences()
|
public fun sourcePreferences(): SharedPreferences = configurableSource.sourcePreferences()
|
||||||
|
|
||||||
suspend fun getTrackSearch(mangaId: Long): TrackSearch = withIOContext {
|
suspend fun getTrackSearch(mangaId: Long): TrackSearch = withIOContext {
|
||||||
val query = """
|
val query = $$"""
|
||||||
|query GetManga(${'$'}mangaId: Int!) {
|
|query GetManga($mangaId: Int!) {
|
||||||
| manga(id: ${'$'}mangaId) {
|
| manga(id: $mangaId) {
|
||||||
| ...MangaFragment
|
| ...MangaFragment
|
||||||
| }
|
| }
|
||||||
|}
|
|}
|
||||||
|
|
|
|
||||||
|$MangaFragment
|
|$$MangaFragment
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
val payload = buildJsonObject {
|
val payload = buildJsonObject {
|
||||||
put("query", query)
|
put("query", query)
|
||||||
|
|
@ -87,9 +87,9 @@ class SuwayomiApi(private val trackId: Long) {
|
||||||
|
|
||||||
// TODO: Include a filter on the chapter number here
|
// TODO: Include a filter on the chapter number here
|
||||||
// Below, we only consider older chapters; since v2.1.1985 filtering works properly in the query
|
// Below, we only consider older chapters; since v2.1.1985 filtering works properly in the query
|
||||||
val chaptersQuery = """
|
val chaptersQuery = $$"""
|
||||||
|query GetMangaUnreadChapters(${'$'}mangaId: Int!) {
|
|query GetMangaUnreadChapters($mangaId: Int!) {
|
||||||
| chapters(condition: {mangaId: ${'$'}mangaId, isRead: false}) {
|
| chapters(condition: {mangaId: $mangaId, isRead: false}) {
|
||||||
| nodes {
|
| nodes {
|
||||||
| id
|
| id
|
||||||
| chapterNumber
|
| chapterNumber
|
||||||
|
|
@ -119,20 +119,20 @@ class SuwayomiApi(private val trackId: Long) {
|
||||||
}
|
}
|
||||||
|
|
||||||
val markQuery = if (deleteDownloadsOnServer) {
|
val markQuery = if (deleteDownloadsOnServer) {
|
||||||
"""
|
$$"""
|
||||||
|mutation MarkChaptersRead(${'$'}chapters: [Int!]!) {
|
|mutation MarkChaptersRead($chapters: [Int!]!) {
|
||||||
| updateChapters(input: {ids: ${'$'}chapters, patch: {isRead: true}}) {
|
| updateChapters(input: {ids: $chapters, patch: {isRead: true}}) {
|
||||||
| __typename
|
| __typename
|
||||||
| }
|
| }
|
||||||
| deleteDownloadedChapters(input: {ids: ${'$'}chapters}) {
|
| deleteDownloadedChapters(input: {ids: $chapters}) {
|
||||||
| __typename
|
| __typename
|
||||||
| }
|
| }
|
||||||
|}
|
|}
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
} else {
|
} else {
|
||||||
"""
|
$$"""
|
||||||
|mutation MarkChaptersRead(${'$'}chapters: [Int!]!) {
|
|mutation MarkChaptersRead($chapters: [Int!]!) {
|
||||||
| updateChapters(input: {ids: ${'$'}chapters, patch: {isRead: true}}) {
|
| updateChapters(input: {ids: $chapters, patch: {isRead: true}}) {
|
||||||
| __typename
|
| __typename
|
||||||
| }
|
| }
|
||||||
|}
|
|}
|
||||||
|
|
@ -156,9 +156,9 @@ class SuwayomiApi(private val trackId: Long) {
|
||||||
.awaitSuccess()
|
.awaitSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
val trackQuery = """
|
val trackQuery = $$"""
|
||||||
|mutation TrackManga(${'$'}mangaId: Int!) {
|
|mutation TrackManga($mangaId: Int!) {
|
||||||
| trackProgress(input: {mangaId: ${'$'}mangaId}) {
|
| trackProgress(input: {mangaId: $mangaId}) {
|
||||||
| __typename
|
| __typename
|
||||||
| }
|
| }
|
||||||
|}
|
|}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ package androidx.preference
|
||||||
/**
|
/**
|
||||||
* Returns package-private [EditTextPreference.getOnBindEditTextListener]
|
* Returns package-private [EditTextPreference.getOnBindEditTextListener]
|
||||||
*/
|
*/
|
||||||
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||||
fun EditTextPreference.getOnBindEditTextListener(): EditTextPreference.OnBindEditTextListener? {
|
fun EditTextPreference.getOnBindEditTextListener(): EditTextPreference.OnBindEditTextListener? {
|
||||||
return onBindEditTextListener
|
return onBindEditTextListener
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import org.gradle.kotlin.dsl.provideDelegate
|
||||||
import org.gradle.kotlin.dsl.the
|
import org.gradle.kotlin.dsl.the
|
||||||
import org.gradle.kotlin.dsl.withType
|
import org.gradle.kotlin.dsl.withType
|
||||||
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension
|
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension
|
||||||
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
@ -42,7 +41,7 @@ internal fun Project.configureAndroid(commonExtension: CommonExtension<*, *, *,
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
jvmTarget.set(AndroidConfig.JvmTarget)
|
jvmTarget.set(AndroidConfig.JvmTarget)
|
||||||
freeCompilerArgs.addAll(
|
freeCompilerArgs.addAll(
|
||||||
"-Xcontext-receivers",
|
"-Xcontext-parameters",
|
||||||
"-opt-in=kotlin.RequiresOptIn",
|
"-opt-in=kotlin.RequiresOptIn",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -73,8 +72,6 @@ internal fun Project.configureCompose(commonExtension: CommonExtension<*, *, *,
|
||||||
}
|
}
|
||||||
|
|
||||||
extensions.configure<ComposeCompilerGradlePluginExtension> {
|
extensions.configure<ComposeCompilerGradlePluginExtension> {
|
||||||
featureFlags.set(setOf(ComposeFeatureFlag.OptimizeNonSkippingGroups))
|
|
||||||
|
|
||||||
val enableMetrics = project.providers.gradleProperty("enableComposeCompilerMetrics").orNull.toBoolean()
|
val enableMetrics = project.providers.gradleProperty("enableComposeCompilerMetrics").orNull.toBoolean()
|
||||||
val enableReports = project.providers.gradleProperty("enableComposeCompilerReports").orNull.toBoolean()
|
val enableReports = project.providers.gradleProperty("enableComposeCompilerReports").orNull.toBoolean()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import me.zhanghai.android.libarchive.ArchiveException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import kotlin.concurrent.Volatile
|
import kotlin.concurrent.Volatile
|
||||||
|
import mihon.core.archive.ArchiveEntry as MihonArchiveEntry
|
||||||
|
|
||||||
class ArchiveInputStream(
|
class ArchiveInputStream(
|
||||||
buffer: Long,
|
buffer: Long,
|
||||||
|
|
@ -66,18 +67,20 @@ class ArchiveInputStream(
|
||||||
Archive.readFree(archive)
|
Archive.readFree(archive)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNextEntry() = Archive.readNextHeader(archive).takeUnless { it == 0L }?.let { entry ->
|
fun getNextEntry(): MihonArchiveEntry? {
|
||||||
val name = ArchiveEntry.pathnameUtf8(entry) ?: ArchiveEntry.pathname(entry)?.decodeToString() ?: return null
|
return Archive.readNextHeader(archive).takeUnless { it == 0L }?.let { entry ->
|
||||||
val isFile = ArchiveEntry.filetype(entry) == ArchiveEntry.AE_IFREG
|
val name = ArchiveEntry.pathnameUtf8(entry) ?: ArchiveEntry.pathname(entry)?.decodeToString() ?: return null
|
||||||
// SY -->
|
val isFile = ArchiveEntry.filetype(entry) == ArchiveEntry.AE_IFREG
|
||||||
val isEncrypted = ArchiveEntry.isEncrypted(entry)
|
|
||||||
// SY <--
|
|
||||||
ArchiveEntry(
|
|
||||||
name,
|
|
||||||
isFile,
|
|
||||||
// SY -->
|
// SY -->
|
||||||
isEncrypted,
|
val isEncrypted = ArchiveEntry.isEncrypted(entry)
|
||||||
// SY <--
|
// SY <--
|
||||||
)
|
MihonArchiveEntry(
|
||||||
|
name,
|
||||||
|
isFile,
|
||||||
|
// SY -->
|
||||||
|
isEncrypted,
|
||||||
|
// SY <--
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,18 +134,18 @@ fun OkHttpClient.newCachelessCallWithProgress(request: Request, listener: Progre
|
||||||
return progressClient.newCall(request)
|
return progressClient.newCall(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
context(Json)
|
context(_: Json)
|
||||||
inline fun <reified T> Response.parseAs(): T {
|
inline fun <reified T> Response.parseAs(): T {
|
||||||
return decodeFromJsonResponse(serializer(), this)
|
return decodeFromJsonResponse(serializer(), this)
|
||||||
}
|
}
|
||||||
|
|
||||||
context(Json)
|
context(json: Json)
|
||||||
fun <T> decodeFromJsonResponse(
|
fun <T> decodeFromJsonResponse(
|
||||||
deserializer: DeserializationStrategy<T>,
|
deserializer: DeserializationStrategy<T>,
|
||||||
response: Response,
|
response: Response,
|
||||||
): T {
|
): T {
|
||||||
return response.body.source().use {
|
return response.body.source().use {
|
||||||
decodeFromBufferedSource(deserializer, it)
|
json.decodeFromBufferedSource(deserializer, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ class CloudflareInterceptor(
|
||||||
executor.execute {
|
executor.execute {
|
||||||
webview = createWebView(originalRequest)
|
webview = createWebView(originalRequest)
|
||||||
|
|
||||||
webview?.webViewClient = object : WebViewClient() {
|
webview.webViewClient = object : WebViewClient() {
|
||||||
override fun onPageFinished(view: WebView, url: String) {
|
override fun onPageFinished(view: WebView, url: String) {
|
||||||
fun isCloudFlareBypassed(): Boolean {
|
fun isCloudFlareBypassed(): Boolean {
|
||||||
return cookieManager.get(origRequestUrl.toHttpUrl())
|
return cookieManager.get(origRequestUrl.toHttpUrl())
|
||||||
|
|
@ -121,7 +121,7 @@ class CloudflareInterceptor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
webview?.loadUrl(origRequestUrl, headers)
|
webview.loadUrl(origRequestUrl, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
latch.awaitFor30Seconds()
|
latch.awaitFor30Seconds()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue