diff --git a/app/src/main/kotlin/androidx/compose/foundation/gestures/AnchoredHorizontalDraggable.kt b/app/src/main/kotlin/androidx/compose/foundation/gestures/AnchoredHorizontalDraggable.kt index cea70922a..d4c34c068 100644 --- a/app/src/main/kotlin/androidx/compose/foundation/gestures/AnchoredHorizontalDraggable.kt +++ b/app/src/main/kotlin/androidx/compose/foundation/gestures/AnchoredHorizontalDraggable.kt @@ -243,9 +243,8 @@ private class AnchoredHorizontalDraggableNode( private fun Offset.reverseIfNeeded() = if (isReverseDirection) this * -1f else this * 1f } -internal fun AnchoredDraggableState.newOffsetForDelta(delta: Float) = - ((if (offset.isNaN()) 0f else offset) + delta) - .coerceIn(anchors.minPosition(), anchors.maxPosition()) +internal fun AnchoredDraggableState.newOffsetForDelta(delta: Float) = ((if (offset.isNaN()) 0f else offset) + delta) + .coerceIn(anchors.minPosition(), anchors.maxPosition()) /** * Compute the target anchor based on the [currentOffset], [velocity] and [positionalThreshold] and @@ -299,17 +298,16 @@ internal fun anchoredDraggableFlingBehavior( density: Density, positionalThreshold: (totalDistance: Float) -> Float, snapAnimationSpec: AnimationSpec, -): TargetedFlingBehavior = - snapFlingBehavior( - decayAnimationSpec = NoOpDecayAnimationSpec, - snapAnimationSpec = snapAnimationSpec, - snapLayoutInfoProvider = - AnchoredDraggableLayoutInfoProvider( - state = state, - positionalThreshold = positionalThreshold, - velocityThreshold = { with(density) { 125.dp.toPx() } }, - ), - ) +): TargetedFlingBehavior = snapFlingBehavior( + decayAnimationSpec = NoOpDecayAnimationSpec, + snapAnimationSpec = snapAnimationSpec, + snapLayoutInfoProvider = + AnchoredDraggableLayoutInfoProvider( + state = state, + positionalThreshold = positionalThreshold, + velocityThreshold = { with(density) { 125.dp.toPx() } }, + ), +) @Suppress("FunctionName") @OptIn(ExperimentalFoundationApi::class) @@ -317,25 +315,24 @@ private fun AnchoredDraggableLayoutInfoProvider( state: AnchoredDraggableState, positionalThreshold: (totalDistance: Float) -> Float, velocityThreshold: () -> Float, -): SnapLayoutInfoProvider = - object : SnapLayoutInfoProvider { +): SnapLayoutInfoProvider = object : SnapLayoutInfoProvider { - // We never decay in AnchoredDraggable's fling - override fun calculateApproachOffset(velocity: Float, decayOffset: Float) = 0f + // We never decay in AnchoredDraggable's fling + override fun calculateApproachOffset(velocity: Float, decayOffset: Float) = 0f - override fun calculateSnapOffset(velocity: Float): Float { - val currentOffset = state.requireOffset() - val target = - state.anchors.computeTarget( - currentOffset = currentOffset, - currentValue = state.currentValue, - velocity = velocity, - positionalThreshold = positionalThreshold, - velocityThreshold = velocityThreshold, - ) - return state.anchors.positionOf(target) - currentOffset - } + override fun calculateSnapOffset(velocity: Float): Float { + val currentOffset = state.requireOffset() + val target = + state.anchors.computeTarget( + currentOffset = currentOffset, + currentValue = state.currentValue, + velocity = velocity, + positionalThreshold = positionalThreshold, + velocityThreshold = velocityThreshold, + ) + return state.anchors.positionOf(target) - currentOffset } +} private val NoOpDecayAnimationSpec: DecayAnimationSpec = object : FloatDecayAnimationSpec { diff --git a/app/src/main/kotlin/androidx/compose/material3/SideDrawer.kt b/app/src/main/kotlin/androidx/compose/material3/SideDrawer.kt index 600f5a5f2..2fb332d2d 100644 --- a/app/src/main/kotlin/androidx/compose/material3/SideDrawer.kt +++ b/app/src/main/kotlin/androidx/compose/material3/SideDrawer.kt @@ -206,11 +206,10 @@ class DrawerState2( /** * The default [Saver] implementation for [DrawerState2]. */ - fun Saver(confirmStateChange: (DrawerValue) -> Boolean) = - Saver( - save = { it.currentValue }, - restore = { DrawerState2(it, confirmStateChange) }, - ) + fun Saver(confirmStateChange: (DrawerValue) -> Boolean) = Saver( + save = { it.currentValue }, + restore = { DrawerState2(it, confirmStateChange) }, + ) } } diff --git a/app/src/main/kotlin/com/google/accompanist/systemuicontroller/SystemUiController.kt b/app/src/main/kotlin/com/google/accompanist/systemuicontroller/SystemUiController.kt index 31462b8fa..58a478380 100644 --- a/app/src/main/kotlin/com/google/accompanist/systemuicontroller/SystemUiController.kt +++ b/app/src/main/kotlin/com/google/accompanist/systemuicontroller/SystemUiController.kt @@ -98,16 +98,14 @@ fun rememberSystemUiController( } @Composable -private fun findWindow(): Window? = - (LocalView.current.parent as? DialogWindowProvider)?.window - ?: LocalView.current.context.findWindow() +private fun findWindow(): Window? = (LocalView.current.parent as? DialogWindowProvider)?.window + ?: LocalView.current.context.findWindow() -private tailrec fun Context.findWindow(): Window? = - when (this) { - is Activity -> window - is ContextWrapper -> baseContext.findWindow() - else -> null - } +private tailrec fun Context.findWindow(): Window? = when (this) { + is Activity -> window + is ContextWrapper -> baseContext.findWindow() + else -> null +} /** * A helper class for setting the navigation and status bar colors for a [View], gracefully diff --git a/app/src/main/kotlin/com/google/accompanist/web/WebView.kt b/app/src/main/kotlin/com/google/accompanist/web/WebView.kt index 8b6847a71..b0d5cf0ff 100644 --- a/app/src/main/kotlin/com/google/accompanist/web/WebView.kt +++ b/app/src/main/kotlin/com/google/accompanist/web/WebView.kt @@ -635,8 +635,7 @@ data class WebViewError( fun rememberWebViewState( url: String, additionalHttpHeaders: Map = emptyMap(), -): WebViewState = -// Rather than using .apply {} here we will recreate the state, this prevents +): WebViewState = // Rather than using .apply {} here we will recreate the state, this prevents // a recomposition loop when the webview updates the url itself. remember { WebViewState( diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt b/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt index 8cc940c91..e565d01a8 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt @@ -303,9 +303,8 @@ object EhEngine { }.executeSafely { } } - suspend fun getFavoriteNote(gid: Long, token: String) = - ehRequest(EhUrl.getAddFavorites(gid, token), EhUrl.getGalleryDetailUrl(gid, token)) - .fetchUsingAsText(FavoritesParser::parseNote) + suspend fun getFavoriteNote(gid: Long, token: String) = ehRequest(EhUrl.getAddFavorites(gid, token), EhUrl.getGalleryDetailUrl(gid, token)) + .fetchUsingAsText(FavoritesParser::parseNote) suspend fun downloadArchive(gid: Long, token: String, or: String, res: String, isHAtH: Boolean): String? { val url = EhUrl.getDownloadArchive(gid, token, or) @@ -384,54 +383,51 @@ object EhEngine { } }.fetchUsingAsText(String::parseAs) - suspend fun fillGalleryListByApi(galleryInfoList: List, referer: String? = null) = - galleryInfoList.chunked(MAX_REQUEST_SIZE).chunked(MAX_SEQUENTIAL_REQUESTS).forEachIndexed { index, chunk -> - if (index != 0) { - delay(REQUEST_INTERVAL) - } - chunk.parMap { - ehRequest(EhUrl.apiUrl, referer, EhUrl.origin) { - jsonBody { - put("method", "gdata") - array("gidlist") { - it.forEach { - addJsonArray { - add(it.gid) - add(it.token) - } + suspend fun fillGalleryListByApi(galleryInfoList: List, referer: String? = null) = galleryInfoList.chunked(MAX_REQUEST_SIZE).chunked(MAX_SEQUENTIAL_REQUESTS).forEachIndexed { index, chunk -> + if (index != 0) { + delay(REQUEST_INTERVAL) + } + chunk.parMap { + ehRequest(EhUrl.apiUrl, referer, EhUrl.origin) { + jsonBody { + put("method", "gdata") + array("gidlist") { + it.forEach { + addJsonArray { + add(it.gid) + add(it.token) } } - put("namespace", 1) } - }.fetchUsingAsText { GalleryApiParser.parse(this, it) } - } + put("namespace", 1) + } + }.fetchUsingAsText { GalleryApiParser.parse(this, it) } } + } - suspend fun voteComment(apiUid: Long, apiKey: String?, gid: Long, token: String, commentId: Long, commentVote: Int): VoteCommentResult = - ehRequest(EhUrl.apiUrl, EhUrl.referer, EhUrl.origin) { - jsonBody { - put("method", "votecomment") - put("apiuid", apiUid) - put("apikey", requireNotNull(apiKey)) - put("gid", gid) - put("token", token) - put("comment_id", commentId) - put("comment_vote", commentVote) - } - }.fetchUsingAsText(String::parseAs) + suspend fun voteComment(apiUid: Long, apiKey: String?, gid: Long, token: String, commentId: Long, commentVote: Int): VoteCommentResult = ehRequest(EhUrl.apiUrl, EhUrl.referer, EhUrl.origin) { + jsonBody { + put("method", "votecomment") + put("apiuid", apiUid) + put("apikey", requireNotNull(apiKey)) + put("gid", gid) + put("token", token) + put("comment_id", commentId) + put("comment_vote", commentVote) + } + }.fetchUsingAsText(String::parseAs) - suspend fun voteTag(apiUid: Long, apiKey: String?, gid: Long, token: String, tags: String, vote: Int) = - ehRequest(EhUrl.apiUrl, EhUrl.referer, EhUrl.origin) { - jsonBody { - put("method", "taggallery") - put("apiuid", apiUid) - put("apikey", requireNotNull(apiKey)) - put("gid", gid) - put("token", token) - put("tags", tags) - put("vote", vote) - } - }.fetchUsingAsText(VoteTagParser::parse) + suspend fun voteTag(apiUid: Long, apiKey: String?, gid: Long, token: String, tags: String, vote: Int) = ehRequest(EhUrl.apiUrl, EhUrl.referer, EhUrl.origin) { + jsonBody { + put("method", "taggallery") + put("apiuid", apiUid) + put("apikey", requireNotNull(apiKey)) + put("gid", gid) + put("token", token) + put("tags", tags) + put("vote", vote) + } + }.fetchUsingAsText(VoteTagParser::parse) suspend fun getGalleryToken(gid: Long, gtoken: String, page: Int) = ehRequest(EhUrl.apiUrl, EhUrl.referer, EhUrl.origin) { jsonBody { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/EhTagDatabase.kt b/app/src/main/kotlin/com/hippo/ehviewer/client/EhTagDatabase.kt index 6e331e2b3..0b383db2f 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/EhTagDatabase.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/client/EhTagDatabase.kt @@ -125,8 +125,7 @@ object EhTagDatabase : CoroutineScope { private fun String.removeSpace(): String = replace(" ", "") - private fun String.containsIgnoreSpace(other: String, ignoreCase: Boolean = true): Boolean = - removeSpace().contains(other.removeSpace(), ignoreCase) + private fun String.containsIgnoreSpace(other: String, ignoreCase: Boolean = true): Boolean = removeSpace().contains(other.removeSpace(), ignoreCase) private fun getMetadata(context: Context): Array? = context.resources.getStringArray(R.array.tag_translation_metadata) .takeIf { it.size == 4 } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/EhUrl.kt b/app/src/main/kotlin/com/hippo/ehviewer/client/EhUrl.kt index 419b68152..ebc14005c 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/EhUrl.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/client/EhUrl.kt @@ -108,11 +108,10 @@ object EhUrl { else -> URL_IMAGE_SEARCH_E } - fun getGalleryDetailUrl(gid: Long, token: String, index: Int = 0, allComment: Boolean = false) = - ehUrl(listOf("g", "$gid", token)) { - if (index != 0) addQueryParameter("p", "$index") - if (allComment) addQueryParameter("hc", "1") - }.buildString() + fun getGalleryDetailUrl(gid: Long, token: String, index: Int = 0, allComment: Boolean = false) = ehUrl(listOf("g", "$gid", token)) { + if (index != 0) addQueryParameter("p", "$index") + if (allComment) addQueryParameter("hc", "1") + }.buildString() fun getGalleryMultiPageViewerUrl(gid: Long, token: String) = ehUrl(listOf("mpv", "$gid", token)).buildString() diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ktor/Cronet.kt b/app/src/main/kotlin/com/hippo/ehviewer/ktor/Cronet.kt index 5291dead9..773f6748a 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ktor/Cronet.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ktor/Cronet.kt @@ -4,6 +4,5 @@ import io.ktor.client.engine.HttpClientEngine import io.ktor.client.engine.HttpClientEngineFactory object Cronet : HttpClientEngineFactory { - override fun create(block: CronetConfig.() -> Unit): HttpClientEngine = - CronetEngine(CronetConfig().apply(block)) + override fun create(block: CronetConfig.() -> Unit): HttpClientEngine = CronetEngine(CronetConfig().apply(block)) } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderDen.kt b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderDen.kt index 07995cd0c..7392d50cb 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderDen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderDen.kt @@ -315,8 +315,7 @@ class SpiderDen(val info: GalleryInfo) { return archived } - suspend fun exportAsCbz(file: Path) = - downloadDir!!.find(archiveName)?.sendTo(file) ?: archiveTo(file) + suspend fun exportAsCbz(file: Path) = downloadDir!!.find(archiveName)?.sendTo(file) ?: archiveTo(file) private suspend fun archiveTo(file: Path) = resourceScope { val comicInfo = closeable { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/CommonOperations.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/CommonOperations.kt index f4fe5ce92..e9a1ec57c 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/CommonOperations.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/CommonOperations.kt @@ -106,8 +106,7 @@ suspend fun keepNoMediaFileStatus(downloadDir: Path = downloadLocation) { } } -fun getFavoriteIcon(favorited: Boolean) = - if (favorited) Icons.Default.Favorite else Icons.Default.FavoriteBorder +fun getFavoriteIcon(favorited: Boolean) = if (favorited) Icons.Default.Favorite else Icons.Default.FavoriteBorder suspend fun DialogState.startDownload( context: Context, @@ -281,14 +280,11 @@ suspend fun removeFromFavorites(galleryInfo: BaseGalleryInfo) = doModifyFavorite localFavorited = EhDB.containLocalFavorites(galleryInfo.gid), ) -fun DestinationsNavigator.navToReader(info: BaseGalleryInfo, page: Int = -1) = - navToReader(ReaderScreenArgs.Gallery(info, page)) +fun DestinationsNavigator.navToReader(info: BaseGalleryInfo, page: Int = -1) = navToReader(ReaderScreenArgs.Gallery(info, page)) -fun DestinationsNavigator.navToReader(uri: Uri) = - navToReader(ReaderScreenArgs.Archive(uri)) +fun DestinationsNavigator.navToReader(uri: Uri) = navToReader(ReaderScreenArgs.Archive(uri)) -private fun DestinationsNavigator.navToReader(args: ReaderScreenArgs) = - navigate(ReaderScreenDestination(args)) { launchSingleTop = true } +private fun DestinationsNavigator.navToReader(args: ReaderScreenArgs) = navigate(ReaderScreenDestination(args)) { launchSingleTop = true } context(DialogState, Context, DestinationsNavigator) suspend fun doGalleryInfoAction(info: BaseGalleryInfo) { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/SecurityActivity.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/SecurityActivity.kt index d9a760f27..de0f28db3 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/SecurityActivity.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/SecurityActivity.kt @@ -94,8 +94,7 @@ class SecurityActivity : AppCompatActivity() { result: BiometricPrompt.AuthenticationResult, ) = onAuthenticationSucceeded(activity, result) - override fun onAuthenticationFailed(activity: FragmentActivity?) = - onAuthenticationFailed(activity) + override fun onAuthenticationFailed(activity: FragmentActivity?) = onAuthenticationFailed(activity) } private fun onSuccess() { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/PagerViewer.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/PagerViewer.kt index 81ac225d4..5e0a9812f 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/PagerViewer.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/PagerViewer.kt @@ -238,21 +238,19 @@ private fun PageContainer( } } -private suspend fun ZoomableState?.panLeft(distance: Float, bounds: Rect): Boolean = - if (canPan { it.right - bounds.right }) { - panBy(Offset(-distance, 0f)) - true - } else { - false - } +private suspend fun ZoomableState?.panLeft(distance: Float, bounds: Rect): Boolean = if (canPan { it.right - bounds.right }) { + panBy(Offset(-distance, 0f)) + true +} else { + false +} -private suspend fun ZoomableState?.panRight(distance: Float, bounds: Rect): Boolean = - if (canPan { bounds.left - it.left }) { - panBy(Offset(distance, 0f)) - true - } else { - false - } +private suspend fun ZoomableState?.panRight(distance: Float, bounds: Rect): Boolean = if (canPan { bounds.left - it.left }) { + panBy(Offset(distance, 0f)) + true +} else { + false +} private inline fun ZoomableState?.canPan(getRemaining: (Rect) -> Float): Boolean { // TODO: Remove when K2 mode in IDE is stable diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsFilterState.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsFilterState.kt index d7a08f83f..6d8a55c89 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsFilterState.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsFilterState.kt @@ -14,11 +14,10 @@ data class DownloadsFilterState( val keyword: String = "", ) : Parcelable -fun DownloadsFilterState.take(info: DownloadInfo) = - mode.take(info, label) && - (state == -1 || info.state == state) && - with(info) { - title.containsIgnoreCase(keyword) || - titleJpn.containsIgnoreCase(keyword) || - simpleTags?.any { it.containsIgnoreCase(keyword) } ?: false - } +fun DownloadsFilterState.take(info: DownloadInfo) = mode.take(info, label) && + (state == -1 || info.state == state) && + with(info) { + title.containsIgnoreCase(keyword) || + titleJpn.containsIgnoreCase(keyword) || + simpleTags?.any { it.containsIgnoreCase(keyword) } ?: false + } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/SearchBarScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/SearchBarScreen.kt index d62e68a58..9ebfcd569 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/SearchBarScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/SearchBarScreen.kt @@ -95,8 +95,7 @@ abstract class Suggestion { open val canOpenDirectly: Boolean = false } -suspend fun SearchDao.suggestions(prefix: String, limit: Int) = - (if (prefix.isBlank()) list(limit) else rawSuggestions(prefix, limit)) +suspend fun SearchDao.suggestions(prefix: String, limit: Int) = (if (prefix.isBlank()) list(limit) else rawSuggestions(prefix, limit)) context(DialogState, DestinationsNavigator) @Composable diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/Modifier.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/Modifier.kt index 087ca3d16..3c03c3240 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/Modifier.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/Modifier.kt @@ -2,5 +2,4 @@ package com.hippo.ehviewer.ui.tools import androidx.compose.ui.Modifier -inline fun Modifier.thenIf(condition: Boolean, crossinline block: Modifier.() -> Modifier) = - if (condition) block() else this +inline fun Modifier.thenIf(condition: Boolean, crossinline block: Modifier.() -> Modifier) = if (condition) block() else this diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/SharedElementTransition.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/SharedElementTransition.kt index 7b327d109..76f6dfeea 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/SharedElementTransition.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/SharedElementTransition.kt @@ -29,8 +29,7 @@ value class TransitionsVisibilityScope(val scopes: Set) context(TransitionsVisibilityScope) @Composable -inline fun togetherWith(scope: AnimatedVisibilityScope, block: @Composable TransitionsVisibilityScope.() -> T) = - block(remember(scopes, scope) { TransitionsVisibilityScope(scopes + scope) }) +inline fun togetherWith(scope: AnimatedVisibilityScope, block: @Composable TransitionsVisibilityScope.() -> T) = block(remember(scopes, scope) { TransitionsVisibilityScope(scopes + scope) }) context(SharedTransitionScope, TransitionsVisibilityScope, SETNodeGenerator) @Composable diff --git a/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt b/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt index 1b6b06abb..4176b2cf6 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/updater/AppUpdater.kt @@ -66,22 +66,21 @@ object AppUpdater { return null } - suspend fun downloadUpdate(url: String, file: File) = - ghStatement(url).executeSafely { response -> - response.status.ensureSuccess() - if (url.endsWith("zip")) { - response.bodyAsChannel().toInputStream().use { stream -> - ZipInputStream(stream).use { zip -> - zip.nextEntry - file.outputStream().use { - zip.copyTo(it) - } + suspend fun downloadUpdate(url: String, file: File) = ghStatement(url).executeSafely { response -> + response.status.ensureSuccess() + if (url.endsWith("zip")) { + response.bodyAsChannel().toInputStream().use { stream -> + ZipInputStream(stream).use { zip -> + zip.nextEntry + file.outputStream().use { + zip.copyTo(it) } } - } else { - response.bodyAsChannel().copyTo(file) } + } else { + response.bodyAsChannel().copyTo(file) } + } } private suspend inline fun ghStatement(url: String) = ktorClient.prepareGet(url) { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/AppConfig.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/AppConfig.kt index abd09877a..4e0758e58 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/util/AppConfig.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/AppConfig.kt @@ -51,8 +51,7 @@ object AppConfig { return null } - private fun getDirInExternalAppDir(filename: String, create: Boolean = true) = - externalAppDir?.run { File(this, filename).takeIf { if (create) it.ensureDirectory() else it.isDirectory } } + private fun getDirInExternalAppDir(filename: String, create: Boolean = true) = externalAppDir?.run { File(this, filename).takeIf { if (create) it.ensureDirectory() else it.isDirectory } } val defaultDownloadDir: File? get() = getDirInExternalAppDir(DOWNLOAD, false) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/DateTimeUtil.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/DateTimeUtil.kt index 7fd241680..1a2c1f9a8 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/util/DateTimeUtil.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/DateTimeUtil.kt @@ -8,11 +8,8 @@ import kotlinx.datetime.atStartOfDayIn import kotlinx.datetime.toInstant import kotlinx.datetime.toLocalDateTime -fun LocalDate.toEpochMillis(timeZone: TimeZone = TimeZone.UTC): Long = - atStartOfDayIn(timeZone).toEpochMilliseconds() +fun LocalDate.toEpochMillis(timeZone: TimeZone = TimeZone.UTC): Long = atStartOfDayIn(timeZone).toEpochMilliseconds() -fun LocalDateTime.toEpochMillis(timeZone: TimeZone = TimeZone.UTC): Long = - toInstant(timeZone).toEpochMilliseconds() +fun LocalDateTime.toEpochMillis(timeZone: TimeZone = TimeZone.UTC): Long = toInstant(timeZone).toEpochMilliseconds() -fun Long.toLocalDateTime(timeZone: TimeZone = TimeZone.UTC): LocalDateTime = - Instant.fromEpochMilliseconds(this).toLocalDateTime(timeZone) +fun Long.toLocalDateTime(timeZone: TimeZone = TimeZone.UTC): LocalDateTime = Instant.fromEpochMilliseconds(this).toLocalDateTime(timeZone) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/FDUtils.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/FDUtils.kt index f9ea1136e..b86e6d011 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/util/FDUtils.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/FDUtils.kt @@ -12,8 +12,7 @@ import java.io.FileDescriptor import okio.Path @RequiresApi(Build.VERSION_CODES.P) -private fun sendFileTotally(from: FileDescriptor, to: FileDescriptor): Long = - Os.sendfile(to, from, Int64Ref(0), Long.MAX_VALUE) +private fun sendFileTotally(from: FileDescriptor, to: FileDescriptor): Long = Os.sendfile(to, from, Int64Ref(0), Long.MAX_VALUE) infix fun Path.sendTo(file: Path): Long { if (isAtLeastP) { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/FileUtils.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/FileUtils.kt index 31d9c4ad3..e41b78c72 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/util/FileUtils.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/FileUtils.kt @@ -28,8 +28,7 @@ object FileUtils { // ext4 through a FUSE layer, so use that limit. private const val MAX_FILENAME_BYTES = 255 - fun ensureDirectory(file: File?) = - file?.let { if (it.exists()) it.isDirectory else it.mkdirs() } ?: false + fun ensureDirectory(file: File?) = file?.let { if (it.exists()) it.isDirectory else it.mkdirs() } ?: false /** * Convert byte to human readable string.

@@ -81,22 +80,21 @@ object FileUtils { } } - private fun isValidFatFilenameChar(c: Char) = - when (c.code) { - in 0x00..0x1F, - '"'.code, - '*'.code, - '/'.code, - ':'.code, - '<'.code, - '>'.code, - '?'.code, - '\\'.code, - '|'.code, - 0x7F, - -> false - else -> true - } + private fun isValidFatFilenameChar(c: Char) = when (c.code) { + in 0x00..0x1F, + '"'.code, + '*'.code, + '/'.code, + ':'.code, + '<'.code, + '>'.code, + '?'.code, + '\\'.code, + '|'.code, + 0x7F, + -> false + else -> true + } // From https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/os/FileUtils.java;l=1142;drc=7b647e4ea0e92f33c19b315eaed364ee067ba0aa /** @@ -135,8 +133,7 @@ object FileUtils { * @param filename the complete filename * @return null for can't find extension */ - fun getExtensionFromFilename(filename: String?) = - filename?.substringAfterLast('.', "")?.ifEmpty { null } + fun getExtensionFromFilename(filename: String?) = filename?.substringAfterLast('.', "")?.ifEmpty { null } /** * Get name from filename @@ -144,8 +141,7 @@ object FileUtils { * @param filename the complete filename * @return null for start with . dot */ - fun getNameFromFilename(filename: String?) = - filename?.substringBeforeLast('.')?.ifEmpty { null } + fun getNameFromFilename(filename: String?) = filename?.substringBeforeLast('.')?.ifEmpty { null } /** * Create a temp file, you need to delete it by you self. diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/RangeSet.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/RangeSet.kt index f09290526..0e5e2d5a9 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/util/RangeSet.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/RangeSet.kt @@ -116,8 +116,7 @@ abstract class RangeSet> : * @param elements ranges of values to determine presence of * @return whether all values are all contained within the set */ - override fun containsAll(elements: Collection>): Boolean = - elements.all { contains(it) } + override fun containsAll(elements: Collection>): Boolean = elements.all { contains(it) } /** * @return whether the set contains any values diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/RangeSets.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/RangeSets.kt index 187f22892..3eae59299 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/util/RangeSets.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/RangeSets.kt @@ -34,8 +34,7 @@ class IntRangeSet : RangeSet { private constructor(rangeSet: IntRangeSet) : super(rangeSet) - override fun createRange(start: Int, endInclusive: Int): IntRange = - IntRange(start, endInclusive) + override fun createRange(start: Int, endInclusive: Int): IntRange = IntRange(start, endInclusive) override fun incrementValue(value: Int): Int = value + 1 diff --git a/app/src/main/kotlin/com/hippo/ehviewer/util/ReadableTime.kt b/app/src/main/kotlin/com/hippo/ehviewer/util/ReadableTime.kt index bf7f0c67a..62c93cab8 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/util/ReadableTime.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/util/ReadableTime.kt @@ -156,6 +156,5 @@ object ReadableTime { } } - fun getFilenamableTime(time: Instant = Clock.System.now()): String = - FILENAMABLE_DATE_FORMAT.format(time.toLocalDateTime(TimeZone.currentSystemDefault())) + fun getFilenamableTime(time: Instant = Clock.System.now()): String = FILENAMABLE_DATE_FORMAT.format(time.toLocalDateTime(TimeZone.currentSystemDefault())) } diff --git a/app/src/main/kotlin/com/hippo/files/Paths.kt b/app/src/main/kotlin/com/hippo/files/Paths.kt index 4630773dc..4fac07ad1 100644 --- a/app/src/main/kotlin/com/hippo/files/Paths.kt +++ b/app/src/main/kotlin/com/hippo/files/Paths.kt @@ -29,11 +29,9 @@ fun Path.moveTo(target: Path) = SystemFileSystem.atomicMove(this, target) fun Path.openFileDescriptor(mode: String) = SystemFileSystem.openFileDescriptor(this, mode) -fun Path.openInputStream(): FileInputStream = - ParcelFileDescriptor.AutoCloseInputStream(SystemFileSystem.openFileDescriptor(this, "r")) +fun Path.openInputStream(): FileInputStream = ParcelFileDescriptor.AutoCloseInputStream(SystemFileSystem.openFileDescriptor(this, "r")) -fun Path.openOutputStream(): FileOutputStream = - ParcelFileDescriptor.AutoCloseOutputStream(SystemFileSystem.openFileDescriptor(this, "wt")) +fun Path.openOutputStream(): FileOutputStream = ParcelFileDescriptor.AutoCloseOutputStream(SystemFileSystem.openFileDescriptor(this, "wt")) fun Path.toUri(): Uri { val str = toString() diff --git a/app/src/main/kotlin/com/jamal/composeprefs3/ui/PrefsUtils.kt b/app/src/main/kotlin/com/jamal/composeprefs3/ui/PrefsUtils.kt index fbd5febbf..f441fa900 100644 --- a/app/src/main/kotlin/com/jamal/composeprefs3/ui/PrefsUtils.kt +++ b/app/src/main/kotlin/com/jamal/composeprefs3/ui/PrefsUtils.kt @@ -4,11 +4,9 @@ import androidx.compose.runtime.Composable import java.math.BigDecimal import java.math.RoundingMode -fun Any?.ifNotNullThen(content: @Composable () -> Unit): (@Composable () -> Unit)? = - if (this != null) content else null +fun Any?.ifNotNullThen(content: @Composable () -> Unit): (@Composable () -> Unit)? = if (this != null) content else null -fun Boolean.ifTrueThen(content: @Composable () -> Unit): (@Composable () -> Unit)? = - if (this) content else null +fun Boolean.ifTrueThen(content: @Composable () -> Unit): (@Composable () -> Unit)? = if (this) content else null fun roundToDP(value: Double, places: Int): Double = BigDecimal(value).setScale(places, RoundingMode.HALF_EVEN).toDouble() diff --git a/app/src/main/kotlin/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt b/app/src/main/kotlin/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt index 9135cc08e..6e4c4f1d3 100644 --- a/app/src/main/kotlin/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt +++ b/app/src/main/kotlin/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt @@ -7,18 +7,14 @@ import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -fun CoroutineScope.launchUI(block: suspend CoroutineScope.() -> Unit): Job = - launch(Dispatchers.Main, block = block) +fun CoroutineScope.launchUI(block: suspend CoroutineScope.() -> Unit): Job = launch(Dispatchers.Main, block = block) -fun CoroutineScope.launchIO(block: suspend CoroutineScope.() -> Unit): Job = - launch(Dispatchers.IO, block = block) +fun CoroutineScope.launchIO(block: suspend CoroutineScope.() -> Unit): Job = launch(Dispatchers.IO, block = block) -fun CoroutineScope.launchNonCancellable(block: suspend CoroutineScope.() -> Unit): Job = - launchIO { withContext(NonCancellable, block) } +fun CoroutineScope.launchNonCancellable(block: suspend CoroutineScope.() -> Unit): Job = launchIO { withContext(NonCancellable, block) } suspend fun withUIContext(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Main, block) suspend fun withIOContext(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.IO, block) -suspend fun withNonCancellableContext(block: suspend CoroutineScope.() -> T) = - withContext(NonCancellable, block) +suspend fun withNonCancellableContext(block: suspend CoroutineScope.() -> T) = withContext(NonCancellable, block)