Clean up some build warnings (#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) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt # core/common/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt # core/common/src/main/kotlin/mihon/core/common/archive/ArchiveInputStream.kt
This commit is contained in:
@@ -157,6 +157,7 @@ kotlin {
|
||||
"-opt-in=kotlinx.coroutines.FlowPreview",
|
||||
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
|
||||
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
|
||||
"-Xannotation-default-target=param-property",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.PlainTooltip
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.TooltipAnchorPosition
|
||||
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.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
@@ -195,7 +196,7 @@ fun AppBarActions(
|
||||
|
||||
actions.filterIsInstance<AppBar.Action>().map {
|
||||
TooltipBox(
|
||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
||||
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||
tooltip = {
|
||||
PlainTooltip {
|
||||
Text(it.title)
|
||||
@@ -220,7 +221,7 @@ fun AppBarActions(
|
||||
val overflowActions = actions.filterIsInstance<AppBar.OverflowAction>()
|
||||
if (overflowActions.isNotEmpty()) {
|
||||
TooltipBox(
|
||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
||||
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||
tooltip = {
|
||||
PlainTooltip {
|
||||
Text(stringResource(MR.strings.action_menu_overflow_description))
|
||||
@@ -349,7 +350,7 @@ fun SearchToolbar(
|
||||
// Don't show search action
|
||||
} else if (searchQuery == null) {
|
||||
TooltipBox(
|
||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
||||
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||
tooltip = {
|
||||
PlainTooltip {
|
||||
Text(stringResource(MR.strings.action_search))
|
||||
@@ -369,7 +370,7 @@ fun SearchToolbar(
|
||||
}
|
||||
} else if (searchQuery.isNotEmpty()) {
|
||||
TooltipBox(
|
||||
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
||||
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
|
||||
tooltip = {
|
||||
PlainTooltip {
|
||||
Text(stringResource(MR.strings.action_reset))
|
||||
|
||||
@@ -245,7 +245,6 @@ object AboutScreen : Screen() {
|
||||
is GetApplicationRelease.Result.OsTooOld -> {
|
||||
context.toast(MR.strings.update_check_eol)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
context.toast(e.message)
|
||||
|
||||
+5
@@ -2,13 +2,16 @@ package eu.kanade.presentation.more.settings.screen.about
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
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.util.htmlReadyLicenseContent
|
||||
import eu.kanade.presentation.components.AppBar
|
||||
import eu.kanade.presentation.util.Screen
|
||||
import eu.kanade.tachiyomi.R
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.material.Scaffold
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
@@ -27,7 +30,9 @@ class OpenSourceLicensesScreen : Screen() {
|
||||
)
|
||||
},
|
||||
) { contentPadding ->
|
||||
val libraries by produceLibraries(R.raw.aboutlibraries)
|
||||
LibrariesContainer(
|
||||
libraries = libraries,
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
contentPadding = contentPadding,
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ class DebugInfoScreen : Screen() {
|
||||
val status by produceState(initialValue = "-") {
|
||||
val result = ProfileVerifier.getCompilationStatusAsync().await().profileInstallResultCode
|
||||
value = when (result) {
|
||||
ProfileVerifier.CompilationStatus.RESULT_CODE_NO_PROFILE -> "No profile installed"
|
||||
ProfileVerifier.CompilationStatus.RESULT_CODE_NO_PROFILE_INSTALLED -> "No profile installed"
|
||||
ProfileVerifier.CompilationStatus.RESULT_CODE_COMPILED_WITH_PROFILE -> "Compiled"
|
||||
ProfileVerifier.CompilationStatus.RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING ->
|
||||
"Compiled non-matching"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package eu.kanade.presentation.track
|
||||
|
||||
import android.content.ClipData
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
@@ -47,6 +48,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
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.graphics.Color
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.platform.ClipboardManager
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.Clipboard
|
||||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
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.input.ImeAction
|
||||
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.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||
import kotlinx.coroutines.launch
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
||||
import tachiyomi.presentation.core.components.material.Scaffold
|
||||
@@ -240,7 +243,7 @@ private fun SearchResultItem(
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val clipboardManager: ClipboardManager = LocalClipboardManager.current
|
||||
val clipboard: Clipboard = LocalClipboard.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
val type = trackSearch.publishing_type.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 borderColor = if (selected) MaterialTheme.colorScheme.outline else Color.Transparent
|
||||
var dropDownMenuExpanded by remember { mutableStateOf(false) }
|
||||
val scope = rememberCoroutineScope()
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -295,7 +299,13 @@ private fun SearchResultItem(
|
||||
expanded = dropDownMenuExpanded,
|
||||
onCollapseMenu = { dropDownMenuExpanded = false },
|
||||
onCopyName = {
|
||||
clipboardManager.setText(AnnotatedString(trackSearch.title))
|
||||
scope.launch {
|
||||
val clipEntry = ClipData.newPlainText(
|
||||
trackSearch.title,
|
||||
trackSearch.title,
|
||||
).toClipEntry()
|
||||
clipboard.setClipEntry(clipEntry)
|
||||
}
|
||||
},
|
||||
onOpenInBrowser = {
|
||||
val url = trackSearch.tracking_url
|
||||
|
||||
@@ -9,21 +9,21 @@ import tachiyomi.domain.source.model.SourceNotInstalledException
|
||||
import tachiyomi.i18n.MR
|
||||
import java.net.UnknownHostException
|
||||
|
||||
context(Context)
|
||||
context(context: Context)
|
||||
val Throwable.formattedMessage: String
|
||||
get() {
|
||||
when (this) {
|
||||
is HttpException -> return stringResource(MR.strings.exception_http, code)
|
||||
is HttpException -> return context.stringResource(MR.strings.exception_http, code)
|
||||
is UnknownHostException -> {
|
||||
return if (!isOnline()) {
|
||||
stringResource(MR.strings.exception_offline)
|
||||
return if (!context.isOnline()) {
|
||||
context.stringResource(MR.strings.exception_offline)
|
||||
} 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 SourceNotInstalledException -> return stringResource(MR.strings.loader_not_implemented_error)
|
||||
is NoResultsException -> return context.stringResource(MR.strings.no_results_found)
|
||||
is SourceNotInstalledException -> return context.stringResource(MR.strings.loader_not_implemented_error)
|
||||
}
|
||||
return when (val className = this::class.simpleName) {
|
||||
"Exception", "IOException" -> message ?: className
|
||||
|
||||
@@ -4,5 +4,7 @@ import androidx.compose.foundation.lazy.LazyItemScope
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
// https://issuetracker.google.com/352584409
|
||||
context(LazyItemScope)
|
||||
fun Modifier.animateItemFastScroll() = this.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||
context(itemScope: LazyItemScope)
|
||||
fun Modifier.animateItemFastScroll() = with(itemScope) {
|
||||
this@animateItemFastScroll.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ fun EhLoginWebViewScreen(
|
||||
)
|
||||
is LoadingState.Loading -> {
|
||||
val animatedProgress by animateFloatAsState(
|
||||
(loadingState as? LoadingState.Loading)?.progress ?: 1f,
|
||||
loadingState.progress,
|
||||
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
|
||||
label = "webview_loading",
|
||||
)
|
||||
|
||||
@@ -273,7 +273,7 @@ fun WebViewScreenContent(
|
||||
.align(Alignment.BottomCenter),
|
||||
)
|
||||
is LoadingState.Loading -> LinearProgressIndicator(
|
||||
progress = { (loadingState as? LoadingState.Loading)?.progress ?: 1f },
|
||||
progress = { loadingState.progress },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.align(Alignment.BottomCenter),
|
||||
|
||||
@@ -45,9 +45,9 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||
|
||||
suspend fun addLibManga(track: Track): Track {
|
||||
return withIOContext {
|
||||
val query = """
|
||||
|mutation AddManga(${'$'}mangaId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}private: Boolean) {
|
||||
|SaveMediaListEntry (mediaId: ${'$'}mangaId, progress: ${'$'}progress, status: ${'$'}status, private: ${'$'}private) {
|
||||
val query = $$"""
|
||||
|mutation AddManga($mangaId: Int, $progress: Int, $status: MediaListStatus, $private: Boolean) {
|
||||
|SaveMediaListEntry (mediaId: $mangaId, progress: $progress, status: $status, private: $private) {
|
||||
| id
|
||||
| status
|
||||
|}
|
||||
@@ -82,14 +82,14 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||
|
||||
suspend fun updateLibManga(track: Track): Track {
|
||||
return withIOContext {
|
||||
val query = """
|
||||
val query = $$"""
|
||||
|mutation UpdateManga(
|
||||
|${'$'}listId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}private: Boolean,
|
||||
|${'$'}score: Int, ${'$'}startedAt: FuzzyDateInput, ${'$'}completedAt: FuzzyDateInput
|
||||
|$listId: Int, $progress: Int, $status: MediaListStatus, $private: Boolean,
|
||||
|$score: Int, $startedAt: FuzzyDateInput, $completedAt: FuzzyDateInput
|
||||
|) {
|
||||
|SaveMediaListEntry(
|
||||
|id: ${'$'}listId, progress: ${'$'}progress, status: ${'$'}status, private: ${'$'}private,
|
||||
|scoreRaw: ${'$'}score, startedAt: ${'$'}startedAt, completedAt: ${'$'}completedAt
|
||||
|id: $listId, progress: $progress, status: $status, private: $private,
|
||||
|scoreRaw: $score, startedAt: $startedAt, completedAt: $completedAt
|
||||
|) {
|
||||
|id
|
||||
|status
|
||||
@@ -118,9 +118,9 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||
|
||||
suspend fun deleteLibManga(track: DomainTrack) {
|
||||
withIOContext {
|
||||
val query = """
|
||||
|mutation DeleteManga(${'$'}listId: Int) {
|
||||
|DeleteMediaListEntry(id: ${'$'}listId) {
|
||||
val query = $$"""
|
||||
|mutation DeleteManga($listId: Int) {
|
||||
|DeleteMediaListEntry(id: $listId) {
|
||||
|deleted
|
||||
|}
|
||||
|}
|
||||
@@ -139,10 +139,10 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||
|
||||
suspend fun search(search: String): List<TrackSearch> {
|
||||
return withIOContext {
|
||||
val query = """
|
||||
|query Search(${'$'}query: String) {
|
||||
val query = $$"""
|
||||
|query Search($query: String) {
|
||||
|Page (perPage: 50) {
|
||||
|media(search: ${'$'}query, type: MANGA, format_not_in: [NOVEL]) {
|
||||
|media(search: $query, type: MANGA, format_not_in: [NOVEL]) {
|
||||
|id
|
||||
|staff {
|
||||
|edges {
|
||||
@@ -201,10 +201,10 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||
|
||||
suspend fun findLibManga(track: Track, userid: Int): Track? {
|
||||
return withIOContext {
|
||||
val query = """
|
||||
|query (${'$'}id: Int!, ${'$'}manga_id: Int!) {
|
||||
val query = $$"""
|
||||
|query ($id: Int!, $manga_id: Int!) {
|
||||
|Page {
|
||||
|mediaList(userId: ${'$'}id, type: MANGA, mediaId: ${'$'}manga_id) {
|
||||
|mediaList(userId: $id, type: MANGA, mediaId: $manga_id) {
|
||||
|id
|
||||
|status
|
||||
|scoreRaw: score(format: POINT_100)
|
||||
|
||||
@@ -113,7 +113,7 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
|
||||
// Users can set a 'username' (not nickname) once which effectively
|
||||
// replaces the stringified ID in certain queries.
|
||||
// If no username is set, the API returns the user ID as a strings
|
||||
var username = api.getUsername()
|
||||
val username = api.getUsername()
|
||||
saveCredentials(username, oauth.accessToken)
|
||||
} catch (_: Throwable) {
|
||||
logout()
|
||||
|
||||
@@ -137,7 +137,7 @@ class Kavita(id: Long) : BaseTracker(id, "Kavita"), EnhancedTracker {
|
||||
}
|
||||
|
||||
authentication.apiUrl = prefApiUrl
|
||||
authentication.jwtToken = token.toString()
|
||||
authentication.jwtToken = token
|
||||
}
|
||||
authentications = oauth
|
||||
}
|
||||
|
||||
@@ -37,14 +37,14 @@ class SuwayomiApi(private val trackId: Long) {
|
||||
public fun sourcePreferences(): SharedPreferences = configurableSource.sourcePreferences()
|
||||
|
||||
suspend fun getTrackSearch(mangaId: Long): TrackSearch = withIOContext {
|
||||
val query = """
|
||||
|query GetManga(${'$'}mangaId: Int!) {
|
||||
| manga(id: ${'$'}mangaId) {
|
||||
val query = $$"""
|
||||
|query GetManga($mangaId: Int!) {
|
||||
| manga(id: $mangaId) {
|
||||
| ...MangaFragment
|
||||
| }
|
||||
|}
|
||||
|
|
||||
|$MangaFragment
|
||||
|$$MangaFragment
|
||||
""".trimMargin()
|
||||
val payload = buildJsonObject {
|
||||
put("query", query)
|
||||
@@ -87,9 +87,9 @@ class SuwayomiApi(private val trackId: Long) {
|
||||
|
||||
// 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
|
||||
val chaptersQuery = """
|
||||
|query GetMangaUnreadChapters(${'$'}mangaId: Int!) {
|
||||
| chapters(condition: {mangaId: ${'$'}mangaId, isRead: false}) {
|
||||
val chaptersQuery = $$"""
|
||||
|query GetMangaUnreadChapters($mangaId: Int!) {
|
||||
| chapters(condition: {mangaId: $mangaId, isRead: false}) {
|
||||
| nodes {
|
||||
| id
|
||||
| chapterNumber
|
||||
@@ -119,20 +119,20 @@ class SuwayomiApi(private val trackId: Long) {
|
||||
}
|
||||
|
||||
val markQuery = if (deleteDownloadsOnServer) {
|
||||
"""
|
||||
|mutation MarkChaptersRead(${'$'}chapters: [Int!]!) {
|
||||
| updateChapters(input: {ids: ${'$'}chapters, patch: {isRead: true}}) {
|
||||
$$"""
|
||||
|mutation MarkChaptersRead($chapters: [Int!]!) {
|
||||
| updateChapters(input: {ids: $chapters, patch: {isRead: true}}) {
|
||||
| __typename
|
||||
| }
|
||||
| deleteDownloadedChapters(input: {ids: ${'$'}chapters}) {
|
||||
| deleteDownloadedChapters(input: {ids: $chapters}) {
|
||||
| __typename
|
||||
| }
|
||||
|}
|
||||
""".trimMargin()
|
||||
} else {
|
||||
"""
|
||||
|mutation MarkChaptersRead(${'$'}chapters: [Int!]!) {
|
||||
| updateChapters(input: {ids: ${'$'}chapters, patch: {isRead: true}}) {
|
||||
$$"""
|
||||
|mutation MarkChaptersRead($chapters: [Int!]!) {
|
||||
| updateChapters(input: {ids: $chapters, patch: {isRead: true}}) {
|
||||
| __typename
|
||||
| }
|
||||
|}
|
||||
@@ -156,9 +156,9 @@ class SuwayomiApi(private val trackId: Long) {
|
||||
.awaitSuccess()
|
||||
}
|
||||
|
||||
val trackQuery = """
|
||||
|mutation TrackManga(${'$'}mangaId: Int!) {
|
||||
| trackProgress(input: {mangaId: ${'$'}mangaId}) {
|
||||
val trackQuery = $$"""
|
||||
|mutation TrackManga($mangaId: Int!) {
|
||||
| trackProgress(input: {mangaId: $mangaId}) {
|
||||
| __typename
|
||||
| }
|
||||
|}
|
||||
|
||||
@@ -655,7 +655,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||
* if setting is enabled and [currentChapter] is queued for download
|
||||
*/
|
||||
private fun cancelQueuedDownloads(currentChapter: ReaderChapter): Download? {
|
||||
return downloadManager.getQueuedDownloadOrNull(currentChapter.chapter.id!!.toLong())?.also {
|
||||
return downloadManager.getQueuedDownloadOrNull(currentChapter.chapter.id!!)?.also {
|
||||
downloadManager.cancelQueuedDownloads(listOf(it))
|
||||
}
|
||||
}
|
||||
@@ -848,7 +848,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
||||
viewModelScope.launchNonCancellable {
|
||||
updateChapter.await(
|
||||
ChapterUpdate(
|
||||
id = chapter.id!!.toLong(),
|
||||
id = chapter.id!!,
|
||||
bookmark = bookmarked,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -5,6 +5,7 @@ package androidx.preference
|
||||
/**
|
||||
* Returns package-private [EditTextPreference.getOnBindEditTextListener]
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
fun EditTextPreference.getOnBindEditTextListener(): EditTextPreference.OnBindEditTextListener? {
|
||||
return onBindEditTextListener
|
||||
}
|
||||
|
||||
@@ -54,9 +54,11 @@ fun CalenderHeader(
|
||||
}
|
||||
Row {
|
||||
IconButton(onClick = onPreviousClick) {
|
||||
@Suppress("DEPRECATION")
|
||||
Icon(Icons.Default.KeyboardArrowLeft, stringResource(MR.strings.upcoming_calendar_prev))
|
||||
}
|
||||
IconButton(onClick = onNextClick) {
|
||||
@Suppress("DEPRECATION")
|
||||
Icon(Icons.Default.KeyboardArrowRight, stringResource(MR.strings.upcoming_calendar_next))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.gradle.kotlin.dsl.provideDelegate
|
||||
import org.gradle.kotlin.dsl.the
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension
|
||||
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import java.io.File
|
||||
|
||||
@@ -42,7 +41,7 @@ internal fun Project.configureAndroid(commonExtension: CommonExtension<*, *, *,
|
||||
compilerOptions {
|
||||
jvmTarget.set(AndroidConfig.JvmTarget)
|
||||
freeCompilerArgs.addAll(
|
||||
"-Xcontext-receivers",
|
||||
"-Xcontext-parameters",
|
||||
"-opt-in=kotlin.RequiresOptIn",
|
||||
)
|
||||
|
||||
@@ -73,8 +72,6 @@ internal fun Project.configureCompose(commonExtension: CommonExtension<*, *, *,
|
||||
}
|
||||
|
||||
extensions.configure<ComposeCompilerGradlePluginExtension> {
|
||||
featureFlags.set(setOf(ComposeFeatureFlag.OptimizeNonSkippingGroups))
|
||||
|
||||
val enableMetrics = project.providers.gradleProperty("enableComposeCompilerMetrics").orNull.toBoolean()
|
||||
val enableReports = project.providers.gradleProperty("enableComposeCompilerReports").orNull.toBoolean()
|
||||
|
||||
|
||||
@@ -134,18 +134,18 @@ fun OkHttpClient.newCachelessCallWithProgress(request: Request, listener: Progre
|
||||
return progressClient.newCall(request)
|
||||
}
|
||||
|
||||
context(Json)
|
||||
context(_: Json)
|
||||
inline fun <reified T> Response.parseAs(): T {
|
||||
return decodeFromJsonResponse(serializer(), this)
|
||||
}
|
||||
|
||||
context(Json)
|
||||
context(json: Json)
|
||||
fun <T> decodeFromJsonResponse(
|
||||
deserializer: DeserializationStrategy<T>,
|
||||
response: Response,
|
||||
): T {
|
||||
return response.body.source().use {
|
||||
decodeFromBufferedSource(deserializer, it)
|
||||
json.decodeFromBufferedSource(deserializer, it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -73,7 +73,7 @@ class CloudflareInterceptor(
|
||||
executor.execute {
|
||||
webview = createWebView(originalRequest)
|
||||
|
||||
webview?.webViewClient = object : WebViewClientCompat() {
|
||||
webview.webViewClient = object : WebViewClientCompat() {
|
||||
override fun onPageFinished(view: WebView, url: String) {
|
||||
fun isCloudFlareBypassed(): Boolean {
|
||||
return cookieManager.get(origRequestUrl.toHttpUrl())
|
||||
@@ -111,7 +111,7 @@ class CloudflareInterceptor(
|
||||
}
|
||||
}
|
||||
|
||||
webview?.loadUrl(origRequestUrl, headers)
|
||||
webview.loadUrl(origRequestUrl, headers)
|
||||
}
|
||||
|
||||
latch.awaitFor30Seconds()
|
||||
|
||||
@@ -7,6 +7,7 @@ import me.zhanghai.android.libarchive.ArchiveException
|
||||
import java.io.InputStream
|
||||
import java.nio.ByteBuffer
|
||||
import kotlin.concurrent.Volatile
|
||||
import mihon.core.common.archive.ArchiveEntry as MihonArchiveEntry
|
||||
|
||||
class ArchiveInputStream(
|
||||
buffer: Long,
|
||||
@@ -67,18 +68,20 @@ class ArchiveInputStream(
|
||||
Archive.readFree(archive)
|
||||
}
|
||||
|
||||
fun getNextEntry() = Archive.readNextHeader(archive).takeUnless { it == 0L }?.let { entry ->
|
||||
val name = ArchiveEntry.pathnameUtf8(entry) ?: ArchiveEntry.pathname(entry)?.decodeToString() ?: return null
|
||||
val isFile = ArchiveEntry.filetype(entry) == ArchiveEntry.AE_IFREG
|
||||
// SY -->
|
||||
val isEncrypted = ArchiveEntry.isEncrypted(entry)
|
||||
// SY <--
|
||||
ArchiveEntry(
|
||||
name,
|
||||
isFile,
|
||||
fun getNextEntry(): MihonArchiveEntry? {
|
||||
return Archive.readNextHeader(archive).takeUnless { it == 0L }?.let { entry ->
|
||||
val name = ArchiveEntry.pathnameUtf8(entry) ?: ArchiveEntry.pathname(entry)?.decodeToString() ?: return null
|
||||
val isFile = ArchiveEntry.filetype(entry) == ArchiveEntry.AE_IFREG
|
||||
// SY -->
|
||||
isEncrypted,
|
||||
val isEncrypted = ArchiveEntry.isEncrypted(entry)
|
||||
// SY <--
|
||||
)
|
||||
MihonArchiveEntry(
|
||||
name,
|
||||
isFile,
|
||||
// SY -->
|
||||
isEncrypted,
|
||||
// SY <--
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -23,11 +23,11 @@ import androidx.compose.material.icons.rounded.CheckBoxOutlineBlank
|
||||
import androidx.compose.material.icons.rounded.DisabledByDefault
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExposedDropdownMenuAnchorType
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MenuAnchorType
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Surface
|
||||
@@ -293,7 +293,7 @@ fun SelectItem(
|
||||
) {
|
||||
OutlinedTextField(
|
||||
modifier = Modifier
|
||||
.menuAnchor(MenuAnchorType.PrimaryNotEditable)
|
||||
.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable)
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
horizontal = SettingsItemsPaddings.Horizontal,
|
||||
|
||||
Reference in New Issue
Block a user