From 71032e3010ddc8cd667a2262160caaf9df849b01 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 19:37:23 +0000 Subject: [PATCH 01/25] Update ktor to v2.3.4 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b537339e3..51d4cc6b1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -246,7 +246,7 @@ dependencies { implementation("io.coil-kt:coil-compose") implementation("io.coil-kt:coil-gif") - val ktor = "2.3.3" + val ktor = "2.3.4" implementation("io.ktor:ktor-io-jvm:$ktor") implementation("io.ktor:ktor-utils-jvm:$ktor") From ea93960bf415fe3fe6cb4c22905378980f14c011 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 1 Sep 2023 19:27:23 +0800 Subject: [PATCH 02/25] Fix pages fields in AdvancedSearch --- .../com/hippo/ehviewer/ui/legacy/SearchLayout.kt | 3 ++- .../com/hippo/ehviewer/ui/main/AdvancedSearch.kt | 15 ++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/ui/legacy/SearchLayout.kt b/app/src/main/java/com/hippo/ehviewer/ui/legacy/SearchLayout.kt index 8656bd157..7f6e1c688 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/legacy/SearchLayout.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/legacy/SearchLayout.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.rememberScrollState @@ -71,7 +72,7 @@ class SearchLayout @JvmOverloads constructor( } } Mdc3Theme { - Column(modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.search_layout_margin_h)).verticalScroll(rememberScrollState())) { + Column(modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.search_layout_margin_h)).imePadding().verticalScroll(rememberScrollState())) { AnimatedVisibility(visible = isNormalMode) { ElevatedCard(modifier = Modifier.fillMaxWidth().padding(vertical = dimensionResource(id = R.dimen.search_layout_margin_v))) { Column(modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.search_category_padding_h), vertical = dimensionResource(id = R.dimen.search_category_padding_v))) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/main/AdvancedSearch.kt b/app/src/main/java/com/hippo/ehviewer/ui/main/AdvancedSearch.kt index 0b090c0fd..a0249fec5 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/main/AdvancedSearch.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/main/AdvancedSearch.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import com.hippo.ehviewer.R +import com.hippo.ehviewer.util.toIntOrDefault @Composable fun SearchAdvanced( @@ -55,9 +56,6 @@ fun SearchAdvanced( onExpandedChange = { expanded = !expanded }, ) { val softwareKeyboardController = LocalSoftwareKeyboardController.current - SideEffect { - softwareKeyboardController?.hide() - } OutlinedTextField( modifier = Modifier.menuAnchor(), readOnly = true, @@ -71,6 +69,9 @@ fun SearchAdvanced( expanded = expanded, onDismissRequest = { expanded = false }, ) { + SideEffect { + softwareKeyboardController?.hide() + } minRatingItems.forEach { selectionOption -> DropdownMenuItem( text = { Text(selectionOption) }, @@ -88,18 +89,18 @@ fun SearchAdvanced( Checkbox(checked = enabled, onCheckedChange = { enabled = it }) Text(text = stringResource(id = R.string.search_sp), modifier = Modifier.align(Alignment.CenterVertically)) OutlinedTextField( - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword), value = if (enabled && state.fromPage != -1) state.fromPage.toString() else "", - onValueChange = { onStateChanged(state.copy(fromPage = it.toInt())) }, + onValueChange = { onStateChanged(state.copy(fromPage = it.toIntOrDefault(-1))) }, modifier = Modifier.width(96.dp).padding(16.dp), singleLine = true, enabled = enabled, ) Text(text = stringResource(id = R.string.search_sp_to), modifier = Modifier.align(Alignment.CenterVertically)) OutlinedTextField( - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword), value = if (enabled && state.toPage != -1) state.toPage.toString() else "", - onValueChange = { onStateChanged(state.copy(toPage = it.toInt())) }, + onValueChange = { onStateChanged(state.copy(toPage = it.toIntOrDefault(-1))) }, modifier = Modifier.width(96.dp).padding(16.dp), singleLine = true, enabled = enabled, From 0b64eadb0c4010a9592f63ba65bed8cb86e820dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 13:41:00 +0000 Subject: [PATCH 03/25] Update actions/checkout action to v4 --- .github/workflows/ci.yml | 2 +- .github/workflows/pull_request.yml | 2 +- .github/workflows/releases.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7f73bc1b..c6c88dfbc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 with: submodules: 'recursive' diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 7fac5f1ee..97f2ce726 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 with: submodules: 'recursive' diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index 28d638bc0..80776d228 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 with: submodules: 'recursive' From c7c0446f2365482a4f605bfad727d64f59b4ba20 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:49:28 +0800 Subject: [PATCH 04/25] Tweak ParseException --- .../main/java/com/hippo/ehviewer/client/EhEngine.kt | 4 ++-- .../ehviewer/client/exception/ParseException.kt | 13 ++----------- .../hippo/ehviewer/client/parser/FavoritesParser.kt | 2 +- .../ehviewer/client/parser/GalleryDetailParser.kt | 10 +++++----- .../ehviewer/client/parser/GalleryListParser.kt | 2 +- .../parser/GalleryMultiPageViewerPTokenParser.kt | 2 +- .../ehviewer/client/parser/GalleryPageApiParser.kt | 4 ++-- .../ehviewer/client/parser/GalleryPageParser.kt | 2 +- .../com/hippo/ehviewer/client/parser/HomeParser.kt | 2 +- .../hippo/ehviewer/client/parser/ProfileParser.kt | 2 +- .../hippo/ehviewer/client/parser/SignInParser.kt | 2 +- .../hippo/ehviewer/client/parser/TorrentParser.kt | 5 ++++- .../main/java/com/hippo/ehviewer/util/AppConfig.kt | 4 ++-- app/src/main/rust/src/parser/torrent.rs | 2 +- 14 files changed, 25 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt index 9d80f269f..d6442efa7 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt @@ -120,8 +120,8 @@ private fun rethrowExactly(code: Int, headers: Headers, body: String, e: Throwab } else if ("<" !in body) { throw EhException(body) } else { - if (Settings.saveParseErrorBody) AppConfig.saveParseErrorBody(e) - throw EhException(appCtx.getString(R.string.error_parse_error)) + if (Settings.saveParseErrorBody) AppConfig.saveParseErrorBody(e, body) + throw EhException(appCtx.getString(R.string.error_parse_error), e) } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/exception/ParseException.kt b/app/src/main/java/com/hippo/ehviewer/client/exception/ParseException.kt index df59bcce7..101d1ed54 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/exception/ParseException.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/exception/ParseException.kt @@ -16,16 +16,7 @@ package com.hippo.ehviewer.client.exception class ParseException : EhException { - val body: String + constructor(detailMessage: String?) : super(detailMessage) - constructor(detailMessage: String?, body: String) : super(detailMessage) { - this.body = body - } - - constructor(detailMessage: String?, body: String, cause: Throwable?) : super( - detailMessage, - cause, - ) { - this.body = body - } + constructor(detailMessage: String?, cause: Throwable?) : super(detailMessage, cause) } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt index 1eee9ec63..0ac3aecb9 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/FavoritesParser.kt @@ -12,7 +12,7 @@ object FavoritesParser { } val catArray = arrayOfNulls(10) val countArray = parseFav(body, catArray) - if (countArray.isEmpty()) throw ParseException("Parse favorites error", body) + if (countArray.isEmpty()) throw ParseException("Parse favorites error") val result = GalleryListParser.parse(body) return Result(catArray.requireNoNulls(), countArray, result) } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt index 366c5dd4d..648d89872 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryDetailParser.kt @@ -114,9 +114,9 @@ object GalleryDetailParser { gd.token = groupValues[2] gd.apiUid = groupValues[3].toLongOrNull() ?: -1L gd.apiKey = groupValues[4] - } ?: throw ParseException("Can't parse gallery detail", body) + } ?: throw ParseException("Can't parse gallery detail") if (gd.gid == -1L) { - throw ParseException("Can't parse gallery detail", body) + throw ParseException("Can't parse gallery detail") } PATTERN_TORRENT.find(body)?.run { gd.torrentUrl = groupValues[1].trim().unescapeXml() @@ -214,7 +214,7 @@ object GalleryDetailParser { } } catch (e: Throwable) { ExceptionUtils.throwIfFatal(e) - throw ParseException("Can't parse gallery detail", body) + throw ParseException("Can't parse gallery detail") } // newer version @@ -450,7 +450,7 @@ object GalleryDetailParser { */ fun parsePreviewPages(body: String): Int { return PATTERN_PREVIEW_PAGES.find(body)?.groupValues?.get(1)?.toIntOrNull() - ?: throw ParseException("Parse preview page count error", body) + ?: throw ParseException("Parse preview page count error") } /** @@ -458,7 +458,7 @@ object GalleryDetailParser { */ fun parsePages(body: String): Int { return PATTERN_PAGES.find(body)?.groupValues?.get(1)?.toIntOrNull() - ?: throw ParseException("Parse pages error", body) + ?: throw ParseException("Parse pages error") } fun parsePreviewList(body: String): Pair, List> { diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryListParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryListParser.kt index 7381df195..bb5788a4a 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryListParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryListParser.kt @@ -25,7 +25,7 @@ object GalleryListParser { if (body.contains("No hits found

")) { throw EhException(R.string.gallery_list_empty_hit) } - throw ParseException("Can't parse gallery list", body, it) + throw ParseException("Can't parse gallery list", it) } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryMultiPageViewerPTokenParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryMultiPageViewerPTokenParser.kt index 845fa5d3e..628930854 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryMultiPageViewerPTokenParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryMultiPageViewerPTokenParser.kt @@ -33,7 +33,7 @@ object GalleryMultiPageViewerPTokenParser { imagelist.parseAs>().map(Item::token) }.getOrElse { ExceptionUtils.throwIfFatal(it) - throw ParseException("Parse pToken from MPV error", body, it) + throw ParseException("Parse pToken from MPV error", it) } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageApiParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageApiParser.kt index 8ca00e06a..1722d8c98 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageApiParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageApiParser.kt @@ -27,7 +27,7 @@ object GalleryPageApiParser { private val PATTERN_ORIGIN_IMAGE_URL = Regex("") fun parse(body: String): Result { - runCatching { body.parseAs() }.onSuccess { throw ParseException(it.error, body) } + runCatching { body.parseAs() }.onSuccess { throw ParseException(it.error) } val res = body.parseAs() val imageUrl = PATTERN_IMAGE_URL.find(res.imageUrl)?.run { groupValues[1].trim().unescapeXml() @@ -41,7 +41,7 @@ object GalleryPageApiParser { if (!imageUrl.isNullOrEmpty()) { return Result(imageUrl, skipHathKey, originImageUrl) } else { - throw ParseException("Parse image url and skip hath key error", body) + throw ParseException("Parse image url and skip hath key error") } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageParser.kt index ef8e5a125..afd813f95 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryPageParser.kt @@ -56,7 +56,7 @@ object GalleryPageParser { return if (!imageUrl.isNullOrEmpty() && !showKey.isNullOrEmpty()) { Result(imageUrl, skipHathKey, originImageUrl, showKey) } else { - throw ParseException("Parse image url and show error", body) + throw ParseException("Parse image url and show error") } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt index 823f12a9b..d4b70e580 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/HomeParser.kt @@ -24,7 +24,7 @@ object HomeParser { val fundsGP = ParserUtils.parseInt(get(2), 0) * 1000 return Funds(fundsGP, fundsC) } - throw ParseException("Parse funds error", body) + throw ParseException("Parse funds error") } @Parcelize diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/ProfileParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/ProfileParser.kt index afbfc57e6..5e612c1d9 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/ProfileParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/ProfileParser.kt @@ -46,7 +46,7 @@ object ProfileParser { Result(displayName, avatar) }.getOrElse { ExceptionUtils.throwIfFatal(it) - throw ParseException("Parse forums error", body) + throw ParseException("Parse forums error") } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/SignInParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/SignInParser.kt index 1ad7bc990..0568f0546 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/SignInParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/SignInParser.kt @@ -35,7 +35,7 @@ object SignInParser { if (m.find()) { throw EhException(m.group(1) ?: m.group(2)) } else { - throw ParseException("Can't parse sign in", body) + throw ParseException("Can't parse sign in") } } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.kt index f4e880980..40f54df6e 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.kt @@ -1,9 +1,12 @@ package com.hippo.ehviewer.client.parser +import com.hippo.ehviewer.client.exception.ParseException import java.nio.ByteBuffer object TorrentParser { - fun parse(body: ByteBuffer) = parseTorrent(body) + fun parse(body: ByteBuffer) = runCatching { + parseTorrent(body) + }.getOrElse { throw ParseException("Can't parse torrent list", it) } } class Torrent( diff --git a/app/src/main/java/com/hippo/ehviewer/util/AppConfig.kt b/app/src/main/java/com/hippo/ehviewer/util/AppConfig.kt index afeda9a5d..8147a3345 100644 --- a/app/src/main/java/com/hippo/ehviewer/util/AppConfig.kt +++ b/app/src/main/java/com/hippo/ehviewer/util/AppConfig.kt @@ -60,12 +60,12 @@ object AppConfig { return FileUtils.createTempFile(tempDir, null) } - fun saveParseErrorBody(e: ParseException) { + fun saveParseErrorBody(e: ParseException, body: String) { val dir = externalParseErrorDir ?: return File(dir, ReadableTime.getFilenamableTime(System.currentTimeMillis()) + ".txt").writer().use { it.write(e.message) it.appendLine() - it.append(e.body) + it.append(body) } } diff --git a/app/src/main/rust/src/parser/torrent.rs b/app/src/main/rust/src/parser/torrent.rs index 0fa140f33..38b6c9b2b 100644 --- a/app/src/main/rust/src/parser/torrent.rs +++ b/app/src/main/rust/src/parser/torrent.rs @@ -30,7 +30,7 @@ pub fn parseTorrent(env: JNIEnv, _class: JClass, buffer: JByteBuffer, limit: jin parse_bytebuffer(&mut env, buffer, limit, |dom, parser, _env| { Some(dom.query_selector("table")?.filter_map(|e| { let html = e.get(parser)?.inner_html(parser); - let grp = regex!(" ([0-9-]+) [0-9:]+[\\s\\S]+ ([0-9.]+ [KMGT]B)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+([^<]+)[\\s\\S]+onclick=\"document.location='([^\"]+)'[^<]+>([^<]+)").captures(&html)?; + let grp = regex!(" ([0-9-]+) [0-9:]+[\\s\\S]+ ([0-9.]+ [KMGT]B)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+([^<]+)[\\s\\S]+onclick=\"document.location='([^\"]+)'[^<]+>([^<]+)").captures(&html).unwrap(); let name = unescape(&grp[8]).ok()?; Some(Torrent { posted: grp[1].to_string(), From 30d29bfa802498a6dd8d76d37a1a389cbf0319f8 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:52:04 +0800 Subject: [PATCH 05/25] Fix torrent parsing --- app/src/main/rust/src/parser/torrent.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/rust/src/parser/torrent.rs b/app/src/main/rust/src/parser/torrent.rs index 38b6c9b2b..96e2cbac8 100644 --- a/app/src/main/rust/src/parser/torrent.rs +++ b/app/src/main/rust/src/parser/torrent.rs @@ -30,7 +30,7 @@ pub fn parseTorrent(env: JNIEnv, _class: JClass, buffer: JByteBuffer, limit: jin parse_bytebuffer(&mut env, buffer, limit, |dom, parser, _env| { Some(dom.query_selector("table")?.filter_map(|e| { let html = e.get(parser)?.inner_html(parser); - let grp = regex!(" ([0-9-]+) [0-9:]+[\\s\\S]+ ([0-9.]+ [KMGT]B)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+([^<]+)[\\s\\S]+onclick=\"document.location='([^\"]+)'[^<]+>([^<]+)").captures(&html).unwrap(); + let grp = regex!(" ([0-9-]+) [0-9:]+[\\s\\S]+ ([0-9.]+ [KMGT]iB)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+([^<]+)[\\s\\S]+onclick=\"document.location='([^\"]+)'[^<]+>([^<]+)").captures(&html).unwrap(); let name = unescape(&grp[8]).ok()?; Some(Torrent { posted: grp[1].to_string(), From 576d6515db9207520c37b726b407ff7444e1dd30 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 07:49:50 +0000 Subject: [PATCH 06/25] Update dependency androidx.activity:activity-compose to v1.8.0-beta01 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f1da4ee5e..8a3e74278 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -167,7 +167,7 @@ android { dependencies { // https://developer.android.com/jetpack/androidx/releases/activity - implementation("androidx.activity:activity-compose:1.8.0-alpha07") + implementation("androidx.activity:activity-compose:1.8.0-beta01") implementation("androidx.appcompat:appcompat:1.6.1") implementation("androidx.biometric:biometric-ktx:1.2.0-alpha05") implementation("androidx.browser:browser:1.6.0") From 0f626629634f007d94cd7a449675041c0c02d19a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 07:49:54 +0000 Subject: [PATCH 07/25] Update dependency androidx.collection:collection-ktx to v1.3.0-rc01 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8a3e74278..96a7b274a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -171,7 +171,7 @@ dependencies { implementation("androidx.appcompat:appcompat:1.6.1") implementation("androidx.biometric:biometric-ktx:1.2.0-alpha05") implementation("androidx.browser:browser:1.6.0") - implementation("androidx.collection:collection-ktx:1.3.0-beta01") + implementation("androidx.collection:collection-ktx:1.3.0-rc01") // https://developer.android.com/jetpack/androidx/releases/compose-material3 // api(platform("androidx.compose:compose-bom:2023.05.00")) From 80c77c740e6eb3922adfb5df667fa225b306396b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 08:00:51 +0000 Subject: [PATCH 08/25] Update dependency androidx.core:core-ktx to v1.12.0 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 96a7b274a..99af617af 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -181,7 +181,7 @@ dependencies { implementation("androidx.compose.material3:material3-window-size-class") implementation("androidx.compose.ui:ui-util") - implementation("androidx.core:core-ktx:1.12.0-rc01") + implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha12") implementation("androidx.coordinatorlayout:coordinatorlayout:1.2.0") From 9a3c9b9cbd6b135fe357dccfcb28f3f8662d40ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 08:00:55 +0000 Subject: [PATCH 09/25] Update dependency androidx.fragment:fragment-ktx to v1.7.0-alpha04 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 99af617af..548abba59 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -185,7 +185,7 @@ dependencies { implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha12") implementation("androidx.coordinatorlayout:coordinatorlayout:1.2.0") - implementation("androidx.fragment:fragment-ktx:1.7.0-alpha03") + implementation("androidx.fragment:fragment-ktx:1.7.0-alpha04") // https://developer.android.com/jetpack/androidx/releases/lifecycle implementation("androidx.lifecycle:lifecycle-process:2.6.1") From 02ac048d743877bb2bc56df5c9a2f18cc9ba17dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 07:11:50 +0000 Subject: [PATCH 10/25] Update dependency androidx.lifecycle:lifecycle-process to v2.6.2 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 548abba59..de6c89b9f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -187,7 +187,7 @@ dependencies { implementation("androidx.coordinatorlayout:coordinatorlayout:1.2.0") implementation("androidx.fragment:fragment-ktx:1.7.0-alpha04") // https://developer.android.com/jetpack/androidx/releases/lifecycle - implementation("androidx.lifecycle:lifecycle-process:2.6.1") + implementation("androidx.lifecycle:lifecycle-process:2.6.2") // https://developer.android.com/jetpack/androidx/releases/navigation val nav_version = "2.7.1" From bd7db1a016b8a8ab370ed6d68c72d3b71fd381a8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 07:26:59 +0000 Subject: [PATCH 11/25] Update dependency io.arrow-kt:arrow-stack to v1.2.1 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index de6c89b9f..133ef1b2f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -238,7 +238,7 @@ dependencies { implementation("dev.rikka.rikkax.insets:insets:1.3.0") implementation("dev.rikka.rikkax.layoutinflater:layoutinflater:1.3.0") - implementation(platform("io.arrow-kt:arrow-stack:1.2.0")) + implementation(platform("io.arrow-kt:arrow-stack:1.2.1")) implementation("io.arrow-kt:arrow-fx-coroutines") // https://coil-kt.github.io/coil/changelog/ From ea5dd8b1bf9c17b2de5753b152acfdd7901b3574 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 08:32:44 +0000 Subject: [PATCH 12/25] Update nav_version to v2.7.2 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 133ef1b2f..ef3f06d06 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -190,7 +190,7 @@ dependencies { implementation("androidx.lifecycle:lifecycle-process:2.6.2") // https://developer.android.com/jetpack/androidx/releases/navigation - val nav_version = "2.7.1" + val nav_version = "2.7.2" implementation("androidx.navigation:navigation-fragment-ktx:$nav_version") implementation("androidx.navigation:navigation-ui-ktx:$nav_version") implementation("androidx.navigation:navigation-compose:$nav_version") From f8e19f7772197f32dcd3bb711da136de5e68e8d4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 08:51:47 +0000 Subject: [PATCH 13/25] Update paging to v3.2.1 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ef3f06d06..e9e80e4cd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -196,7 +196,7 @@ dependencies { implementation("androidx.navigation:navigation-compose:$nav_version") // https://developer.android.com/jetpack/androidx/releases/paging - val paging = "3.2.0" + val paging = "3.2.1" implementation("androidx.paging:paging-compose:$paging") implementation("androidx.paging:paging-runtime-ktx:$paging") implementation("androidx.recyclerview:recyclerview:1.3.1") From e3b4caa37d32040a7850c65d9625583eea1a8e06 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 8 Sep 2023 17:15:46 +0800 Subject: [PATCH 14/25] Ignore expunged torrents --- app/src/main/rust/src/parser/torrent.rs | 26 ++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/app/src/main/rust/src/parser/torrent.rs b/app/src/main/rust/src/parser/torrent.rs index 96e2cbac8..f422c20aa 100644 --- a/app/src/main/rust/src/parser/torrent.rs +++ b/app/src/main/rust/src/parser/torrent.rs @@ -30,17 +30,21 @@ pub fn parseTorrent(env: JNIEnv, _class: JClass, buffer: JByteBuffer, limit: jin parse_bytebuffer(&mut env, buffer, limit, |dom, parser, _env| { Some(dom.query_selector("table")?.filter_map(|e| { let html = e.get(parser)?.inner_html(parser); - let grp = regex!(" ([0-9-]+) [0-9:]+[\\s\\S]+ ([0-9.]+ [KMGT]iB)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+([^<]+)[\\s\\S]+onclick=\"document.location='([^\"]+)'[^<]+>([^<]+)").captures(&html).unwrap(); - let name = unescape(&grp[8]).ok()?; - Some(Torrent { - posted: grp[1].to_string(), - size: grp[2].to_string(), - seeds: grp[3].parse().ok()?, - peers: grp[4].parse().ok()?, - downloads: grp[5].parse().ok()?, - url: grp[7].to_string(), - name: name.to_string() - }) + if html.contains("Expunged") { + None + } else { + let grp = regex!(" ([0-9-]+) [0-9:]+[\\s\\S]+ ([0-9.]+ [KMGT]iB)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+([^<]+)[\\s\\S]+onclick=\"document.location='([^\"]+)'[^<]+>([^<]+)").captures(&html).unwrap(); + let name = unescape(&grp[8]).ok()?; + Some(Torrent { + posted: grp[1].to_string(), + size: grp[2].to_string(), + seeds: grp[3].parse().ok()?, + peers: grp[4].parse().ok()?, + downloads: grp[5].parse().ok()?, + url: grp[7].to_string(), + name: name.to_string() + }) + } }).collect::>()) }).unwrap().into_java(&env).forget().into_raw() } From de3d6de4cfa0e9e9f253179e07ccf570d71a1847 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 8 Sep 2023 18:01:58 +0800 Subject: [PATCH 15/25] Revert "Sync rootProjName with repo name" This reverts commit de9fa5be5a0aa5fa2e98ff78d63651c5551c7165. --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index a5af90543..8c28e8012 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,5 +19,5 @@ dependencyResolutionManagement { } enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -rootProject.name = "Ehviewer" +rootProject.name = "EhViewer" include(":app") From 70b7bf390a37f3852b9da77238eda22a2bf799a0 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 8 Sep 2023 18:24:00 +0800 Subject: [PATCH 16/25] Sync with 1.8.9.x versionCode --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e9e80e4cd..ef07a39e2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -63,8 +63,8 @@ android { applicationId = "moe.tarsin.ehviewer" minSdk = 28 targetSdk = 34 - versionCode = 180042 - versionName = "1.8.9.0-SNAPSHOT" + versionCode = 180043 + versionName = "1.8.10.0-SNAPSHOT" resourceConfigurations.addAll( listOf( "zh", From 875858618e1e000fd23cd5e15131b96cecd15d0a Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:39:56 +0800 Subject: [PATCH 17/25] Maintenance mode --- .github/ISSUE_TEMPLATE/bug-report.yml | 5 +- .github/ISSUE_TEMPLATE/config.yml | 6 +- .github/ISSUE_TEMPLATE/feature-request.yml | 94 ---------------------- README.md | 4 + 4 files changed, 6 insertions(+), 103 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/feature-request.yml diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 4983009e3..7e8f9c4a6 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -135,10 +135,7 @@ body: - label: 如果您有足够的时间和能力,并愿意为此提交 PR ,请勾上此复选框 / Pull request is welcome. Check this if you want to start a pull request required: false - - label: 您已仔细查看并知情 [Q&A](https://github.com/Ehviewer-Overhauled/Ehviewer/issues/61) 中的内容 / You have checked [Q&A](https://github.com/Ehviewer-Overhauled/Ehviewer/issues/61) carefully - required: true - - - label: 您已搜索过 [Issue Tracker](https://github.com/Ehviewer-Overhauled/Ehviewer/issues),没有找到类似内容 / I have searched on [Issue Tracker](https://github.com/Ehviewer-Overhauled/Ehviewer/issues), No duplicate or related open issue has been found + - label: 您已搜索过 [Issue Tracker](https://github.com/FooIbar/EhViewer/issues),没有找到类似内容 / I have searched on [Issue Tracker](https://github.com/FooIbar/EhViewer/issues), No duplicate or related open issue has been found required: true - label: 您确保这个 Issue 只提及一个问题。如果您有多个问题报告,烦请发起多个 Issue / Ensure there is only one bug report in this issue. Please make mutiply issue for mutiply bugs diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 86148a6fc..ec4bb386b 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1 @@ -blank_issues_enabled: false -contact_links: - - name: 所有其他问题 / All other questions - url: https://github.com/Ehviewer-Overhauled/Ehviewer/discussions - about: 转到 Discussions / Turn to discussions \ No newline at end of file +blank_issues_enabled: false \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml deleted file mode 100644 index 91241d65c..000000000 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: 功能请求 / Feature request -description: 提出一个功能建议 / Suggest an idea -labels: - - "enhancement" -body: - - type: markdown - attributes: - value: | - 感谢您愿意为 Ehviewer-Overhauled 做出贡献! - 提交功能建议前,还请首先完成文末的自查步骤 - - Thanks for your contribution on Ehviewer-Overhauled Project! - Please finish verify steps which list in the end first before suggest an idea - - - type: textarea - id: request - attributes: - label: 需求 / Requirement - description: | - 在此处描述您的需求。这通常会是一个您想要的功能 - Ddescribe what you need here. - placeholder: | - 我需要 XXX 功能 ... - I want ABC feature ... - validations: - required: true - - - type: textarea - id: impl - attributes: - label: 建议实现 / Suggested implements - description: | - 在此处表述您建议的实现方式。如有可能,UI 类功能请求还请尽量附上图示 - Describe your suggested implements here, It's recommend to add a photo if you are making a UI feature request. - placeholder: | - 建议在 XX 处添加 XX ... - I recommend add ABC feature to DEF... - 图片(如果有)/ Photos (if exists) - validations: - required: true - - - type: textarea - id: more - attributes: - label: 备注 / Addition details - description: | - 在此处写下其他您想说的内容 - Describe addition details here - placeholder: | - 其他有用的信息与附件 - Additional details and attachments - validations: - required: false - - - type: input - id: version - attributes: - label: EhViewer 版本号 / EhViewer version code - description: 您可以在设置 - 关于处找到版本号 / You can get version code in Settings - About - placeholder: 1.6.9.13 - validations: - required: true - - - type: input - id: ci - attributes: - label: EhViewer CI 版本 / EhViewer CI Version - description: 位于设置 - 关于中的版本号后 / Next to the version code in Settings - About - placeholder: 26f05a0 - validations: - required: true - - - type: checkboxes - id: check - attributes: - label: 自查步骤 / Verify steps - description: | - 请确认您已经遵守所有必选项 - Please ensure you have obtained all needed options - options: - - label: 如果您有足够的时间和能力,并愿意为此提交 PR ,请勾上此复选框 / Pull request is welcome. Check this if you want to start a pull request - required: false - - - label: 您已仔细查看并知情 [Q&A](https://github.com/Ehviewer-Overhauled/Ehviewer/issues/61) 中的内容 / You have checked [Q&A](https://github.com/Ehviewer-Overhauled/Ehviewer/issues/61) carefully - required: true - - - label: 您已搜索过 [Issue Tracker](https://github.com/Ehviewer-Overhauled/Ehviewer/issues),没有找到类似内容 / I have searched on [Issue Tracker](https://github.com/Ehviewer-Overhauled/Ehviewer/issues), No duplicate or related open issue has been found - required: true - - - label: 您确保这个 Issue 只提及一个功能。如果您有多个功能请求,烦请发起多个 Issue / Ensure there is only one feature request in this issue. Please make mutiply issue for mutiply feature request - required: true - - - label: 您确保已使用最新 CI 版本测试,并且该功能在最新 CI 版本中并未按照预期实现 / This feature don't implement correctly in latest CI version - required: true diff --git a/README.md b/README.md index bf6f5aade..ac285be73 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# Maintenance Mode + +The project is in maintenance mode, will only receive bugfixes. +

English | From 58628b6556a4a89e1534cf3ed2d781e4aaa2b43e Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sat, 9 Sep 2023 16:04:07 +0800 Subject: [PATCH 18/25] Update jni_fn to v0.1.2 --- app/src/main/rust/Cargo.toml | 2 +- app/src/main/rust/jni_fn/.gitignore | 2 - app/src/main/rust/jni_fn/Cargo.toml | 22 -- app/src/main/rust/jni_fn/src/lib.rs | 398 ---------------------------- 4 files changed, 1 insertion(+), 423 deletions(-) delete mode 100644 app/src/main/rust/jni_fn/.gitignore delete mode 100644 app/src/main/rust/jni_fn/Cargo.toml delete mode 100644 app/src/main/rust/jni_fn/src/lib.rs diff --git a/app/src/main/rust/Cargo.toml b/app/src/main/rust/Cargo.toml index ad388629e..6f953b13c 100644 --- a/app/src/main/rust/Cargo.toml +++ b/app/src/main/rust/Cargo.toml @@ -12,7 +12,7 @@ jnix = { path = "jnix" } jnix-macros = "0.4" catch_panic = { path = "catch_panic" } catch_panic_macros = { path = "catch_panic_macros" } -jni_fn = { path = "jni_fn" } +jni_fn = "0.1.2" quick-xml = { default-features = false, version = "0.30" } tl = "0.7" log = "0.4" diff --git a/app/src/main/rust/jni_fn/.gitignore b/app/src/main/rust/jni_fn/.gitignore deleted file mode 100644 index 96ef6c0b9..000000000 --- a/app/src/main/rust/jni_fn/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -Cargo.lock diff --git a/app/src/main/rust/jni_fn/Cargo.toml b/app/src/main/rust/jni_fn/Cargo.toml deleted file mode 100644 index 3cbaed651..000000000 --- a/app/src/main/rust/jni_fn/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "jni_fn" -version = "0.1.0" -authors = ["Anton Lazarev "] -edition = "2021" -description = "JNI-compatible method signature generator" -repository = "https://gitlab.com/antonok/jni_fn" -readme = "README.md" -keywords = ["jni", "java", "jvm", "android", "ndk"] -categories = ["api-bindings", "development-tools::procedural-macro-helpers"] -license = "MIT OR Apache-2.0" - -[lib] -proc-macro = true - -[dependencies] -syn = { version = "1.0", features = ["full"] } -quote = "1.0" -proc-macro2 = "1.0" - -[dev-dependencies] -jni = "0.20" diff --git a/app/src/main/rust/jni_fn/src/lib.rs b/app/src/main/rust/jni_fn/src/lib.rs deleted file mode 100644 index 03700c8db..000000000 --- a/app/src/main/rust/jni_fn/src/lib.rs +++ /dev/null @@ -1,398 +0,0 @@ -//! JNI-compatible method signature generator for Rust libraries. -//! -//! This crate was designed for use with the [`jni`](https://crates.io/crates/jni) crate, which -//! exposes JNI-compatible type bindings. Although it's possible to use `jni` without `jni_fn`, the -//! procedural macro defined here will make it easier to write the method signatures correctly. -//! -//! See the `jni_fn` attribute macro documentation below for more info and usage examples. - -#![deny(missing_docs)] -#![deny(unsafe_code)] - -use proc_macro2::TokenStream; -use quote::ToTokens; -use syn::spanned::Spanned; - -/// Annotate a function with this procedural macro attribute to expose it over the JNI. -/// -/// This attribute takes a single string literal as an argument, specifying the package namespace -/// this function should be placed under. -/// -/// ``` -/// use jni::{ JNIEnv, objects::{ JClass, JString }, sys::jstring }; -/// use jni_fn::jni_fn; -/// -/// #[jni_fn("com.example.RustBindings")] -/// pub fn sayHello(env: JNIEnv, _: JClass, name: JString) -> jstring { -/// let name_javastr = env.get_string(name).unwrap(); -/// let name = name_javastr.to_str().unwrap(); -/// -/// env.new_string(format!("Hello, {}!", name)) -/// .expect("Couldn't create java string!") -/// .into_inner() -/// } -/// ``` -/// -/// The `sayHello` function will automatically be expanded to have the correct ABI specification -/// and the appropriate JNI-compatible name, i.e. in this case - -/// `Java_com_example_RustBindings_sayHello`. -/// -/// Then it can be accessed by, for example, Kotlin code as follows: -/// ```kotlin -/// package com.example.RustBindings -/// -/// class RustBindings { -/// private external fun sayHello(name: String): String -/// -/// fun greetWorld() { -/// println(sayHello("world")) -/// } -/// } -/// ``` -#[proc_macro_attribute] -pub fn jni_fn( - attr: proc_macro::TokenStream, - item: proc_macro::TokenStream, -) -> proc_macro::TokenStream { - jni_fn2(attr.into(), item.into()).into() -} - -/// Deals exclusively with `proc_macro2::TokenStream` instead of `proc_macro::TokenStream`, -/// allowing it and all interior functionality to be unit tested. -fn jni_fn2(attr: TokenStream, item: TokenStream) -> TokenStream { - let attr_span = attr.span(); - let item_span = item.span(); - - let mut function: syn::ItemFn = match syn::parse2(item) { - Ok(f) => f, - Err(_e) => { - return syn::Error::new( - item_span, - "The `jni_fn` attribute can only be applied to `fn` items", - ) - .to_compile_error() - } - }; - - let namespace = match syn::parse2::(attr) { - Ok(n) => n, - Err(_e) => return syn::Error::new(attr_span, "The `jni_fn` attribute must have a single string literal supplied to specify the namespace").to_compile_error(), - }.value(); - - if !valid_namespace(&namespace) { - return syn::Error::new( - attr_span, - "Invalid package namespace supplied to `jni_fn` attribute", - ) - .to_compile_error(); - } - - let orig_fn_name = function.sig.ident.to_string(); - - function.sig.ident = syn::Ident::new( - &create_jni_fn_name(&namespace, &orig_fn_name), - function.sig.ident.span(), - ); - - function.attrs.push(syn::Attribute { - pound_token: Default::default(), - style: syn::AttrStyle::Outer, - bracket_token: Default::default(), - path: syn::parse_str("no_mangle").unwrap(), - tokens: TokenStream::new(), - }); - function.attrs.push(syn::Attribute { - pound_token: Default::default(), - style: syn::AttrStyle::Outer, - bracket_token: Default::default(), - path: syn::parse_str("allow").unwrap(), - tokens: quote::quote! { (non_snake_case) }, - }); - - if function.sig.abi.is_some() { - return syn::Error::new(function.sig.abi.span(), "Don't specify an ABI for `jni_fn` attributed functions - the correct ABI will be added automatically").to_compile_error(); - } - function.sig.abi = Some(syn::Abi { - extern_token: Default::default(), - name: Some(syn::LitStr::new("system", function.sig.ident.span())), - }); - - if !matches!(function.vis, syn::Visibility::Public(_)) { - return syn::Error::new( - function.vis.span(), - "`jni_fn` attributed functions must have public visibility (`pub`)", - ) - .to_compile_error(); - } - - function.into_token_stream() -} - -/// Ensures that `namespace` appears roughly like a valid package name. -/// -/// A package name is a '.'-separated identifier list. -/// -/// Identifiers are described in section 3.8 of the Java language specification, although some -/// JVM-compatible languages have slightly different restrictions on what is considered a valid -/// identifier. This function attempts to catch obviously incorrect strings. -/// -/// Please submit an issue report or patch to make this more permissive if it's required for -/// valid JVM code! Otherwise, making it more restrictive is appreciated as long as it's confirmed -/// to work with multiple JVM-compatible languages. -fn valid_namespace(namespace: &str) -> bool { - /// These shouldn't occur _anywhere_ in the package name. - const FORBIDDEN_CHARS: &[char] = &[ - ' ', ',', ':', ';', '|', '\\', '/', '!', '@', '#', '%', '^', '&', '*', '(', ')', '{', '}', - '[', ']', '-', '`', '~', '\t', '\n', '\r', - ]; - - for c in FORBIDDEN_CHARS { - if namespace.contains(*c) { - return false; - } - } - - fn is_valid_ident(ident: &str) -> bool { - /// These shouldn't occur as the first character of an identifier. - const FORBIDDEN_START_CHARS: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; - - if ident.is_empty() { - return false; - } - - for c in FORBIDDEN_START_CHARS { - if ident.starts_with(*c) { - return false; - } - } - - true - } - - for ident in namespace.split('.') { - if !is_valid_ident(ident) { - return false; - } - } - - true -} - -/// Creates a JNI-compatible function name from the given namespace and function name. -/// This does _not_ transform the provided function name into `snakeCase` if it's not already; but -/// `#[allow(non_snake_case)]` should be added to prevent errors. -/// -/// Importantly, any underscores in the original namespace or function name need to be replaced by -/// "_1", and then dot separators need to be turned into underscores. -fn create_jni_fn_name(namespace: &str, fn_name: &str) -> String { - let namespace_underscored = namespace.replace('_', "_1").replace('.', "_"); - let fn_name_underscored = fn_name.replace('_', "_1"); - format!("Java_{}_{}", namespace_underscored, fn_name_underscored) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_create_jni_fn_name() { - assert_eq!( - create_jni_fn_name("com.example.Foo", "init"), - "Java_com_example_Foo_init" - ); - assert_eq!( - create_jni_fn_name("com.example.Bar", "closeIt"), - "Java_com_example_Bar_closeIt" - ); - assert_eq!( - create_jni_fn_name("com.example.Bar", "close_it"), - "Java_com_example_Bar_close_1it" - ); - assert_eq!( - create_jni_fn_name( - "org.signal.client.internal.Native", - "IdentityKeyPair_Deserialize" - ), - "Java_org_signal_client_internal_Native_IdentityKeyPair_1Deserialize" - ); - } - - #[test] - fn test_valid_namespace() { - assert!(valid_namespace("com.example.Foo")); - assert!(valid_namespace("com.antonok.kb")); - assert!(valid_namespace("org.signal.client.internal.Native")); - assert!(valid_namespace("net.under_score")); - assert!(!valid_namespace("com example Foo")); - assert!(!valid_namespace(" com.example.Foo")); - assert!(!valid_namespace("com.example.Foo ")); - assert!(!valid_namespace("com.example.1Foo")); - } - - #[test] - fn test_code_generation() { - let attr = quote::quote! { - "com.example.Bar" - }; - let source = quote::quote! { - pub fn close_it(env: JNIEnv, _: JClass, filename: JString) -> jboolean { - unimplemented!() - } - }; - - let expanded = jni_fn2(attr.into(), source.into()); - - assert_eq!( - format!("{}", expanded), - format!( - "{}", - quote::quote! { - #[no_mangle] - #[allow(non_snake_case)] - pub extern "system" fn Java_com_example_Bar_close_1it (env: JNIEnv, _: JClass, filename: JString) -> jboolean { - unimplemented!() - } - } - ) - ); - } - - #[test] - fn test_unsafe_fn() { - let attr = quote::quote! { - "com.example.Bar" - }; - let source = quote::quote! { - pub unsafe fn close_it(env: JNIEnv, _: JClass, filename: JString) -> jboolean { - unimplemented!() - } - }; - - let expanded = jni_fn2(attr.into(), source.into()); - - assert_eq!( - format!("{}", expanded), - format!( - "{}", - quote::quote! { - #[no_mangle] - #[allow(non_snake_case)] - pub unsafe extern "system" fn Java_com_example_Bar_close_1it (env: JNIEnv, _: JClass, filename: JString) -> jboolean { - unimplemented!() - } - } - ) - ); - } - - #[test] - fn test_non_function() { - let attr = quote::quote! { "com.example.Foo" }; - let source = quote::quote! { - enum NotAFunction { - Variant1, - Variant2(u8), - } - }; - - let expanded = jni_fn2(attr.into(), source.into()); - - assert_eq!( - format!("{}", expanded), - format!( - "{}", - quote::quote! { - compile_error! { "The `jni_fn` attribute can only be applied to `fn` items" } - } - ) - ); - } - - #[test] - fn test_empty_attribute() { - let attr = quote::quote! {}; - let source = quote::quote! { - pub fn close_it(env: JNIEnv, _: JClass, filename: JString) -> jboolean { - unimplemented!() - } - }; - - let expanded = jni_fn2(attr.into(), source.into()); - - assert_eq!( - format!("{}", expanded), - format!( - "{}", - quote::quote! { - compile_error! { "The `jni_fn` attribute must have a single string literal supplied to specify the namespace" } - } - ) - ); - } - - #[test] - fn test_invalid_namespace() { - let attr = quote::quote! { "." }; - let source = quote::quote! { - pub fn close_it(env: JNIEnv, _: JClass, filename: JString) -> jboolean { - unimplemented!() - } - }; - - let expanded = jni_fn2(attr.into(), source.into()); - - assert_eq!( - format!("{}", expanded), - format!( - "{}", - quote::quote! { - compile_error! { "Invalid package namespace supplied to `jni_fn` attribute" } - } - ) - ); - } - - #[test] - fn test_specified_abi() { - let attr = quote::quote! { "com.example.Foo" }; - let source = quote::quote! { - pub extern "C" fn close_it(env: JNIEnv, _: JClass, filename: JString) -> jboolean { - unimplemented!() - } - }; - - let expanded = jni_fn2(attr.into(), source.into()); - - assert_eq!( - format!("{}", expanded), - format!( - "{}", - quote::quote! { - compile_error! { "Don't specify an ABI for `jni_fn` attributed functions - the correct ABI will be added automatically" } - } - ) - ); - } - - #[test] - fn test_wrong_visibility() { - let attr = quote::quote! { "com.example.Foo" }; - let source = quote::quote! { - fn close_it(env: JNIEnv, _: JClass, filename: JString) -> jboolean { - unimplemented!() - } - }; - - let expanded = jni_fn2(attr.into(), source.into()); - - assert_eq!( - format!("{}", expanded), - format!( - "{}", - quote::quote! { - compile_error! { "`jni_fn` attributed functions must have public visibility (`pub`)" } - } - ) - ); - } -} From 41f35498fed59f18b282aa9f5778178aea6a79c0 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sat, 9 Sep 2023 16:06:46 +0800 Subject: [PATCH 19/25] Update syn to v2.0 --- .../main/rust/catch_panic_macros/Cargo.toml | 2 +- .../main/rust/catch_panic_macros/src/lib.rs | 38 +++++++------------ 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/app/src/main/rust/catch_panic_macros/Cargo.toml b/app/src/main/rust/catch_panic_macros/Cargo.toml index 65f0b739e..137878c44 100644 --- a/app/src/main/rust/catch_panic_macros/Cargo.toml +++ b/app/src/main/rust/catch_panic_macros/Cargo.toml @@ -19,4 +19,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = { version = "1.0", features = ["full"] } +syn = { version = "2.0", features = ["full"] } diff --git a/app/src/main/rust/catch_panic_macros/src/lib.rs b/app/src/main/rust/catch_panic_macros/src/lib.rs index bf4184c0f..174a3d81a 100644 --- a/app/src/main/rust/catch_panic_macros/src/lib.rs +++ b/app/src/main/rust/catch_panic_macros/src/lib.rs @@ -3,10 +3,7 @@ use std::ops::Deref; use proc_macro::TokenStream; use quote::{quote, quote_spanned, ToTokens}; use syn::spanned::Spanned; -use syn::{ - parse_macro_input, AttributeArgs, Expr, FnArg, ItemFn, Lit, Meta, MetaNameValue, NestedMeta, - Pat, Path, -}; +use syn::{parse_macro_input, Expr, FnArg, ItemFn, LitStr, Pat, Path}; const ONLY_FUNCTIONS_MSG: &str = "#[catch_panic] can only be applied to functions"; const FIRST_ARG_MSG: &str = @@ -33,30 +30,21 @@ pub fn catch_panic(attr: TokenStream, item: TokenStream) -> TokenStream { let item = proc_macro2::TokenStream::from(item); // parse macro arguments - let args = parse_macro_input!(attr as AttributeArgs); let mut default_value = None; let mut handler = None; - - for arg in args { - if let NestedMeta::Meta(Meta::NameValue(MetaNameValue { - path, - lit: Lit::Str(str), - .. - })) = arg - { - match path.get_ident() { - Some(id) if id == "default" => match str.parse::() { - Ok(expr) => default_value = Some(expr), - Err(err) => abort!(err.to_compile_error(), item), - }, - Some(id) if id == "handler" => match str.parse::() { - Ok(expr) => handler = Some(expr), - Err(err) => abort!(err.to_compile_error(), item), - }, - _ => {} - } + let parser = syn::meta::parser(|meta| { + if meta.path.is_ident("default") { + default_value = Some(meta.value()?.parse::()?.parse::()?); + Ok(()) + } else if meta.path.is_ident("handler") { + handler = Some(meta.value()?.parse::()?.parse::()?); + Ok(()) + } else { + Err(meta.error("unsupported argument")) } - } + }); + + parse_macro_input!(attr with parser); let default_value = match default_value { Some(val) => val.to_token_stream(), From a9f9706be3a4269eb9f58593f779f89cb3b6164d Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sat, 9 Sep 2023 17:32:49 +0800 Subject: [PATCH 20/25] Migrate from intFromStrPref to intPref --- .../main/java/com/hippo/ehviewer/Settings.kt | 27 +++++-------- .../hippo/ehviewer/ui/settings/AboutScreen.kt | 2 +- .../ehviewer/ui/settings/PreferenceWidgets.kt | 14 ------- app/src/main/res/values/arrays.xml | 40 +++++++++---------- 4 files changed, 31 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/Settings.kt b/app/src/main/java/com/hippo/ehviewer/Settings.kt index 4cde64a0b..4773db5a4 100755 --- a/app/src/main/java/com/hippo/ehviewer/Settings.kt +++ b/app/src/main/java/com/hippo/ehviewer/Settings.kt @@ -30,16 +30,16 @@ object Settings : DataStorePreferences(null) { var downloadQuery by stringOrNullPref("image_query", null) var downloadFragment by stringOrNullPref("image_fragment", null) var archivePasswds by stringSetOrNullPref("archive_passwds") - var downloadDelay by intFromStrPref("download_delay", 0) - var gallerySite by intFromStrPref("gallery_site", 0).observed { updateWhenGallerySiteChanges() } - var multiThreadDownload by intFromStrPref("download_thread", 3) - var preloadImage by intFromStrPref("preload_image", 5) - var theme by intFromStrPref("theme", -1).observed { updateWhenThemeChanges() } - var listMode by intFromStrPref("list_mode", 0) - var detailSize by intFromStrPref("detail_size", 0) - var thumbResolution by intFromStrPref("thumb_resolution", 0) - var readCacheSize by intFromStrPref("read_cache_size", 640) - var launchPage by intFromStrPref("launch_page", 0) + var downloadDelay by intPref("download_delay_2", 0) + var gallerySite by intPref("gallery_site_2", 0).observed { updateWhenGallerySiteChanges() } + var multiThreadDownload by intPref("download_thread_2", 3) + var preloadImage by intPref("preload_image_2", 5) + var theme by intPref("theme_2", -1).observed { updateWhenThemeChanges() } + var listMode by intPref("list_mode_2", 0) + var detailSize by intPref("detail_size_2", 0) + var thumbResolution by intPref("thumb_resolution_2", 0) + var readCacheSize by intPref("read_cache_size_2", 640) + var launchPage by intPref("launch_page_2", 0) var forceEhThumb by boolPref("force_eh_thumb", false) var showComments by boolPref("show_gallery_comments", true) var requestNews by boolPref("request_news", false).observed { updateWhenRequestNewsChanges() } @@ -94,13 +94,6 @@ object Settings : DataStorePreferences(null) { operator fun setValue(thisRef: Any?, prop: KProperty<*>?, value: R) } - private fun intFromStrPref(key: String, defValue: Int) = object : Delegate { - override val flowGetter: () -> Flow - private var _value by stringPref(key, defValue.toString()).also { flowGetter = { it.changesFlow() } } - override fun getValue(thisRef: Any?, prop: KProperty<*>?) = _value.toIntOrNull() ?: defValue - override fun setValue(thisRef: Any?, prop: KProperty<*>?, value: Int) { _value = value.toString() } - } - private fun intArrayPref(key: String, count: Int) = object : Delegate { override val flowGetter: () -> Flow = { _value.asFlow().flatMapMerge { it.changesFlow() }.conflate() } private var _value = (0 until count).map { intPref("${key}_$it", 0) }.toTypedArray() diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/AboutScreen.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/AboutScreen.kt index c3afab38a..8ceb72a1e 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/AboutScreen.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/AboutScreen.kt @@ -112,7 +112,7 @@ fun AboutScreen() { title = stringResource(id = R.string.use_ci_update_channel), value = Settings::useCIUpdateChannel, ) - SimpleMenuPreferenceInt2( + SimpleMenuPreferenceInt( title = stringResource(id = R.string.auto_updates), entry = R.array.update_frequency, entryValueRes = R.array.update_frequency_values, diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt index 4c7402be2..3b9130fc1 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt @@ -114,20 +114,6 @@ fun HtmlPreference(title: String, summary: AnnotatedString? = null, onClick: () @Composable fun SimpleMenuPreferenceInt(title: String, summary: String? = null, @ArrayRes entry: Int, @ArrayRes entryValueRes: Int, value: MutableState) { - val entryArray = stringArrayResource(id = entry) - val valuesArray = stringArrayResource(id = entryValueRes) - val map = remember { - val iter = entryArray.iterator() - valuesArray.associateWith { iter.next() } - } - var v by value - fun set(new: String) { v = new.toInt() } - check(entryArray.size == valuesArray.size) - DropDownPref(title = title, summary = summary, defaultValue = v.toString(), onValueChange = ::set, useSelectedAsSummary = summary.isNullOrBlank(), entries = map) -} - -@Composable -fun SimpleMenuPreferenceInt2(title: String, summary: String? = null, @ArrayRes entry: Int, @ArrayRes entryValueRes: Int, value: MutableState) { val entryArray = stringArrayResource(id = entry) val valuesArray = integerArrayResource(id = entryValueRes) val map = remember { diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index acacee360..0fb32f402 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -21,20 +21,20 @@ @string/settings_eh_list_mode_thumb - + 0 1 - + @string/site_e @string/site_ex - + 0 1 - + @string/homepage @@ -43,22 +43,22 @@ @string/toplist - + 0 1 2 3 - + @string/settings_eh_detail_size_long @string/settings_eh_detail_size_short - + 0 1 - + @string/settings_eh_thumb_resolution_auto @@ -66,11 +66,11 @@ 300x - + 0 1 2 - + @string/unlimited @@ -87,12 +87,12 @@ 7 - + 1 3 5 7 - + 0 @@ -107,7 +107,7 @@ 20000 - + 0 500 1000 @@ -118,7 +118,7 @@ 5000 10000 20000 - + 3 @@ -129,14 +129,14 @@ 17 - + 3 5 7 11 13 17 - + 320 MB @@ -146,13 +146,13 @@ 5120 MB - + 320 640 1280 2560 5120 - + @string/filter_title @@ -208,11 +208,11 @@ @string/dark_theme_on - + -1 1 2 - + @string/download_all From afd22635bdf96c662d7aa4cfbfa21bbea8f1ee64 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 11 Aug 2023 14:29:32 +0800 Subject: [PATCH 21/25] Update releases.yml --- .github/workflows/releases.yml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index 837bb2778..951332ef0 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -45,7 +45,6 @@ jobs: uses: softprops/action-gh-release@v1 with: body: Bump Version - discussion_category_name: Announcements files: | app/build/outputs/apk/release/EhViewer-universal.apk app/build/outputs/apk/release/EhViewer-arm64-v8a.apk @@ -53,24 +52,3 @@ jobs: app/build/outputs/apk/release/EhViewer-x86.apk app/build/outputs/apk/release/EhViewer-armeabi-v7a.apk app/build/outputs/mapping/release/mapping.txt - - - name: Collect Apks - run: | - mkdir app/build/outputs/apk/release/fdroid - cp app/build/outputs/apk/release/app-arm64-v8a-release.apk app/build/outputs/apk/release/fdroid/EhViewer-v$GITHUB_REF_NAME.apk - cp app/build/outputs/apk/release/app-armeabi-v7a-release.apk app/build/outputs/apk/release/fdroid/EhViewer-v$GITHUB_REF_NAME-armv7.apk - - - name: Push Apks - uses: Ehviewer-Overhauled/github-action-push-to-another-repository@main - env: - SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} - with: - source-directory: app/build/outputs/apk/release/fdroid - destination-github-username: Ehviewer-Overhauled - destination-repository-name: fdroid-repo - user-name: 'github-actions[bot]' - user-email: 'github-actions[bot]@users.noreply.github.com' - target-branch: deploy - create-target-branch: true - commit-message: Add apks from $GITHUB_REF - target-directory: fdroid/tmp-apks \ No newline at end of file From f9ad1f724beaed1f3eaa2e4978eff3d3fa614c8e Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sun, 10 Sep 2023 18:29:16 +0800 Subject: [PATCH 22/25] Don't show search fab when search view is expanded --- .../hippo/ehviewer/ui/scene/DownloadsScene.kt | 6 --- .../hippo/ehviewer/ui/scene/FavoritesScene.kt | 4 +- .../ehviewer/ui/scene/GalleryListScene.kt | 12 ++++- .../hippo/ehviewer/ui/scene/SearchBarScene.kt | 46 ++++++++++--------- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt index cc6c3cf46..249067181 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt @@ -366,12 +366,6 @@ class DownloadsScene : override fun onSearchViewExpanded() { super.onSearchViewExpanded() if (tracker.isInCustomChoice) tracker.clearSelection() - showSearchFab(true) - } - - override fun onSearchViewHidden() { - super.onSearchViewHidden() - hideSearchFab(true) } override fun onDestroyView() { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt index bdda08917..3e8120a2c 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt @@ -479,12 +479,12 @@ class FavoritesScene : SearchBarScene() { override fun onSearchViewExpanded() { super.onSearchViewExpanded() - selectSearchFab(true) + hideActionFab(true) } override fun onSearchViewHidden() { super.onSearchViewHidden() - selectActionFab(true) + showActionFab(true) } private fun showGoToDialog() { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt index 0573f3c38..9a546cc76 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt @@ -688,12 +688,20 @@ class GalleryListScene : SearchBarScene() { override fun onSearchViewExpanded() { super.onSearchViewExpanded() - if (mState == State.NORMAL) selectSearchFab(true) + if (mState == State.NORMAL) { + hideActionFab(true) + } else { + hideSearchFab(true) + } } override fun onSearchViewHidden() { super.onSearchViewHidden() - if (mState == State.NORMAL) selectActionFab(true) + if (mState == State.NORMAL) { + showActionFab(true) + } else { + showSearchFab(true) + } } private fun showActionFab() { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/SearchBarScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/SearchBarScene.kt index d1113dada..a9e2d55e7 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/SearchBarScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/SearchBarScene.kt @@ -167,8 +167,7 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene { fun showSearchFab(animation: Boolean, delay: Long = 0) { if (animation) { mSearchFab.visibility = View.VISIBLE - mSearchFab.rotation = -45.0f - mSearchFab.animate().scaleX(1.0f).scaleY(1.0f).rotation(0.0f).setListener(null) + mSearchFab.animate().scaleX(1.0f).scaleY(1.0f).setListener(null) .setDuration(ANIMATE_TIME).setStartDelay(delay) .setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR).start() } else { @@ -196,10 +195,26 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene { } } - fun selectSearchFab(animation: Boolean) { - _binding ?: return + fun showActionFab(animation: Boolean, delay: Long = ANIMATE_TIME) { + mShowActionFab = true + if (animation) { + val fab = fabLayout.primaryFab!! + fab.visibility = View.VISIBLE + fab.animate().scaleX(1.0f).scaleY(1.0f).setListener(null) + .setDuration(ANIMATE_TIME).setStartDelay(delay) + .setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR).start() + } else { + fabLayout.setExpanded(expanded = false, animation = false) + val fab = fabLayout.primaryFab!! + fab.visibility = View.VISIBLE + fab.scaleX = 1.0f + fab.scaleY = 1.0f + } + } + + fun hideActionFab(animation: Boolean): Long { mShowActionFab = false - val delay = if (animation) { + return if (animation) { val fab = fabLayout.primaryFab!! if (View.INVISIBLE == fab.visibility) { 0L @@ -218,27 +233,16 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene { fab.scaleY = 0.0f 0L } + } + + fun selectSearchFab(animation: Boolean) { + val delay = hideActionFab(animation) showSearchFab(animation, delay) } fun selectActionFab(animation: Boolean) { - _binding ?: return - mShowActionFab = true val delay = hideSearchFab(animation) - if (animation) { - val fab = fabLayout.primaryFab!! - fab.visibility = View.VISIBLE - fab.rotation = -45.0f - fab.animate().scaleX(1.0f).scaleY(1.0f).rotation(0.0f).setListener(null) - .setDuration(ANIMATE_TIME).setStartDelay(delay) - .setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR).start() - } else { - fabLayout.setExpanded(expanded = false, animation = false) - val fab = fabLayout.primaryFab!! - fab.visibility = View.VISIBLE - fab.scaleX = 1.0f - fab.scaleY = 1.0f - } + showActionFab(animation, delay) } fun setSearchBarHint(hint: String?) { From b68dc98ae0e7f88a47a4052a2c14185ae5cb111b Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sun, 10 Sep 2023 18:34:54 +0800 Subject: [PATCH 23/25] Fix drawer lock states saving --- app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt | 2 +- app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt | 2 +- .../main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt index 249067181..9a1a3fb39 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt @@ -364,8 +364,8 @@ class DownloadsScene : } override fun onSearchViewExpanded() { + hideActionFab(true) super.onSearchViewExpanded() - if (tracker.isInCustomChoice) tracker.clearSelection() } override fun onDestroyView() { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt index 3e8120a2c..487ea9c73 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt @@ -478,8 +478,8 @@ class FavoritesScene : SearchBarScene() { } override fun onSearchViewExpanded() { - super.onSearchViewExpanded() hideActionFab(true) + super.onSearchViewExpanded() } override fun onSearchViewHidden() { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt index 9a546cc76..c0fe7ab77 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt @@ -687,12 +687,12 @@ class GalleryListScene : SearchBarScene() { } override fun onSearchViewExpanded() { - super.onSearchViewExpanded() if (mState == State.NORMAL) { hideActionFab(true) } else { hideSearchFab(true) } + super.onSearchViewExpanded() } override fun onSearchViewHidden() { From 6f22269d9376d8c8d1f2d7b1e0526f66061361c5 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sun, 10 Sep 2023 21:06:00 +0800 Subject: [PATCH 24/25] Disable swiping and dragging when in selection mode --- .../com/hippo/ehviewer/ui/scene/DownloadsScene.kt | 13 +++++-------- .../com/hippo/ehviewer/ui/scene/FavoritesScene.kt | 6 +++++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt index 9a1a3fb39..1ce5249d0 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.kt @@ -57,7 +57,6 @@ import androidx.drawerlayout.widget.DrawerLayout import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.ItemTouchHelper.ACTION_STATE_DRAG import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -299,15 +298,13 @@ class DownloadsScene : } recyclerView.addItemDecoration(decoration) mItemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() { - override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) { - super.onSelectedChanged(viewHolder, actionState) - if (actionState == ACTION_STATE_DRAG) { - tracker.clearSelection() - } - } override fun isLongPressDragEnabled() = false override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int { - return makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) + return if (tracker.isInCustomChoice) { + 0 + } else { + makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) + } } override fun onMove( recyclerView: RecyclerView, diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt index 487ea9c73..9d8c43f0e 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.kt @@ -392,7 +392,11 @@ class FavoritesScene : SearchBarScene() { } val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() { override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int { - return makeMovementFlags(0, ItemTouchHelper.LEFT) + return if (tracker.isInCustomChoice) { + 0 + } else { + makeMovementFlags(0, ItemTouchHelper.LEFT) + } } override fun onMove( recyclerView: RecyclerView, From 6bfa8d1ea4d94c2bd6b4bf500515fc2c941de985 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sun, 10 Sep 2023 21:15:25 +0800 Subject: [PATCH 25/25] Fix crashing when reordering downloads --- .../java/com/hippo/ehviewer/download/DownloadManager.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt b/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt index 5eda17d11..068f59623 100644 --- a/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt +++ b/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt @@ -462,7 +462,11 @@ object DownloadManager : OnSpiderListener { fun moveDownload(fromItem: DownloadInfo, toItem: DownloadInfo): List { val fromPosition = allInfoList.indexOf(fromItem) val toPosition = allInfoList.indexOf(toItem) - return moveDownload(fromPosition, toPosition) + return if (fromPosition != -1 && toPosition != -1) { + moveDownload(fromPosition, toPosition) + } else { + emptyList() + } } suspend fun resetAllReadingProgress() = coroutineScope {