Compare commits

..
70 Commits
Author SHA1 Message Date
FooIbar 019b961461 Merge branch '1.8.9.x' into 1.8.9.x-gms
Releases / Build (push) Has been cancelled
# Conflicts:
#	app/build.gradle.kts
2023-10-01 23:01:17 +08:00
FooIbar 97f988991e Release 1.8.9.7
Releases / Build (push) Has been cancelled
2023-10-01 22:59:52 +08:00
FooIbar 0dbc3b7ea7 Merge branch '1.8.x.x' into 1.8.9.x 2023-10-01 22:59:17 +08:00
FooIbar cac65d9030 Fix insets for pre API 30 2023-09-30 23:19:52 +08:00
FooIbar 4a83829dfd Fix padding for scrollable 2023-09-30 23:19:52 +08:00
FooIbar c0348484fe Fix padding for the IME 2023-09-30 23:19:52 +08:00
FooIbar 213133ab45 Fix SignInScreen drawing behind the system bars 2023-09-30 23:19:52 +08:00
renovate[bot] 8469eac18c Update plugin com.diffplug.spotless to v6.22.0 (#33)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-29 07:35:40 +00:00
FooIbar 5aaa1bb5b3 Fix spotless 2023-09-29 15:20:43 +08:00
renovate[bot] 9f500b85e6 Update plugin com.android.application to v8.1.2 2023-09-28 18:40:08 +00:00
FooIbar 0d6fd8d7ad Workaround for SideSheetDialog (#31) 2023-09-27 14:05:21 +00:00
FooIbar 7e4b6dbf31 Fix memory leak 2023-09-27 19:47:57 +08:00
renovate[bot] 8bf3f0f094 Update plugin com.mikepenz.aboutlibraries.plugin to v10.9.1 2023-09-27 01:41:01 +00:00
renovate[bot] 198acef666 Update dependency com.mikepenz:aboutlibraries-core to v10.9.1 2023-09-26 21:03:06 +00:00
FooIbar 1d0c76b2b2 Fix OOB access when no results found 2023-09-26 19:26:32 +08:00
FooIbar 567875cf00 Apply quick search in place if not in Popular (#30) 2023-09-26 08:50:07 +00:00
FooIbar 58069e8925 Fix cmake cache for CI 2023-09-26 01:35:37 +08:00
FooIbar a90cf3c72b Update issue template 2023-09-26 01:28:01 +08:00
FooIbar 2fbf226ccd Update author summary in about 2023-09-26 01:23:11 +08:00
FooIbar d674672ce2 Update libarchive to v3.7.2 2023-09-26 00:28:54 +08:00
FooIbar dab7968ce3 Update liblzma to v5.4.4 2023-09-26 00:28:54 +08:00
FooIbar 510719f890 Convert libnettle build to FetchContent 2023-09-26 00:27:48 +08:00
renovate[bot] 96b92239b0 Update plugin com.mikepenz.aboutlibraries.plugin to v10.9.1-debug01 2023-09-25 08:06:51 +00:00
FooIbar 363029cbdd Upgrade r8 (#27) 2023-09-24 15:55:51 +00:00
FooIbar 7783a8de15 Cleanup build cache for CI 2023-09-24 17:52:06 +08:00
FooIbar 26a589fc1d Add native build cache for CI (#26)
* Add rust cache for CI

* Add cmake cache for CI

* Use cache for release as well

* Add build cache for CI
2023-09-24 08:10:17 +00:00
FooIbar 4c467c304f NDK will be installed automatically 2023-09-24 03:17:12 +08:00
FooIbar 9496b9396a Upgrade ndk to 26.0.10792818 (#24) 2023-09-23 18:52:46 +00:00
FooIbar 669a9ee1e3 Use spotless for ktlint integration 2023-09-24 02:12:39 +08:00
FooIbar d08b7c2d94 Update README 2023-09-23 22:32:54 +08:00
FooIbar 534f6aa22c Merge pull request workflow to CI 2023-09-23 19:13:43 +08:00
FooIbar 8ea731159f Prevent unnecessary regeneration of BuildConfig 2023-09-23 18:59:29 +08:00
renovate[bot] 7704fa9318 Update plugin com.mikepenz.aboutlibraries.plugin to v10.9.0 2023-09-23 09:34:12 +00:00
FooIbar d974cb56df Use versionNameSuffix for the gms variant 2023-09-23 16:44:56 +08:00
renovate[bot] d0e3de7121 Update dependency com.mikepenz:aboutlibraries-core to v10.9.0 2023-09-23 07:37:51 +00:00
renovate[bot] 40af1862a0 Update actions/checkout digest to 8ade135 2023-09-23 05:50:16 +00:00
FooIbar 33e24aa46c Fix CI for renovate 2023-09-23 13:49:34 +08:00
FooIbar 5a97561389 Upgrade gradle wrapper 2023-09-22 16:24:48 +08:00
FooIbar 26701d84f7 Cleanup redundant .gitignore 2023-09-22 15:56:27 +08:00
FooIbar d13b09aaf3 Fix swipe-to-refresh 2023-09-22 15:46:57 +08:00
FooIbar 6a65b61785 Store SearchLayout state in ViewModel 2023-09-22 15:02:18 +08:00
FooIbar 2b8bfab44b Fix minRating advanced search 2023-09-22 13:41:22 +08:00
FooIbar b9e1d79be6 Switch to branch automerging 2023-09-21 21:33:21 +08:00
renovate[bot] 0f9e1819c1 Update room_version to v2.6.0-rc01 2023-09-21 10:23:31 +00:00
renovate[bot] eda97347fc Update nav_version to v2.7.3 2023-09-21 08:09:21 +00:00
renovate[bot] 2bd24b6a8b Update dependency com.google.android.material:material to v1.11.0-alpha03 2023-09-21 04:56:54 +00:00
renovate[bot] 8306342ab6 Update dependency androidx.fragment:fragment-ktx to v1.7.0-alpha05 2023-09-21 00:45:03 +00:00
renovate[bot] 6b6ba91721 Update dependency androidx.activity:activity-compose to v1.8.0-rc01 2023-09-20 22:32:00 +00:00
FooIbar 13f255529b Release 1.8.9.6-gms
Releases / Build (push) Has been cancelled
2023-09-20 19:51:04 +08:00
FooIbar 16e912c9ae Merge branch '1.8.x.x' into 1.8.9.x-gms 2023-09-20 19:50:40 +08:00
FooIbar d58e08e24c Release 1.8.9.6
Releases / Build (push) Has been cancelled
2023-09-20 19:49:48 +08:00
FooIbar e111ec74be Merge branch '1.8.x.x' into 1.8.9.x 2023-09-20 19:49:25 +08:00
FooIbar 68155e6a6b Refine modify favorites dialog layout 2023-09-16 18:36:44 +08:00
FooIbar bfbceefef2 Fix respectDefaultWidth not working 2023-09-16 17:08:13 +08:00
FooIbar 21b39135fe Tweak modify favorites dialog layout 2023-09-15 21:10:51 +08:00
FooIbar 01742ac6b9 Refine AppUpdater for the gms variant 2023-09-15 12:40:02 +08:00
FooIbar 6adc7f7221 Add option to disable category color harmonization 2023-09-13 20:21:06 +08:00
FooIbar e94424a83e Release 1.8.9.5-gms
Releases / Build (push) Has been cancelled
2023-09-10 21:22:18 +08:00
FooIbar 56d30aa413 Merge branch '1.8.x.x' into 1.8.9.x-gms
# Conflicts:
#	app/build.gradle.kts
2023-09-10 21:21:59 +08:00
FooIbar a6d215a0bf Release 1.8.9.4-gms
Releases / Build (push) Has been cancelled
2023-08-30 16:43:42 +08:00
FooIbar cf9441adb5 Merge branch '1.8.x.x' into 1.8.9.x-gms
# Conflicts:
#	app/build.gradle.kts
2023-08-30 16:43:28 +08:00
FooIbar 36b16d7be8 Release 1.8.9.3-gms
Releases / Build (push) Has been cancelled
2023-08-17 23:00:54 +08:00
FooIbar fab5532407 Revert "Remove embedded Cronet library"
This reverts commit 9c5eddb9
2023-08-17 23:00:08 +08:00
FooIbar 8ad4e8640f Merge branch '1.8.x.x' into 1.8.9.x-gms
# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/com/hippo/ehviewer/util/CronetUtils.kt
2023-08-17 22:59:37 +08:00
FooIbar 5b5a2a9a33 Release 1.8.9.2-gms
Releases / Build (push) Has been cancelled
2023-08-15 17:49:53 +08:00
FooIbar 7719312355 Merge branch '1.8.x.x' into 1.8.9.x-gms 2023-08-15 17:49:46 +08:00
FooIbar 48f1b0a958 Release 1.8.9.1-gms
Releases / Build (push) Has been cancelled
2023-08-14 23:18:57 +08:00
FooIbar 9abeba6b15 Merge branch '1.8.x.x' into 1.8.9.x-gms 2023-08-14 23:18:34 +08:00
FooIbar 75bec4314e Release 1.8.9.0-gms
Releases / Build (push) Has been cancelled
2023-08-11 16:03:44 +08:00
FooIbar b767c041b9 Load Cronet from Google Play services 2023-08-11 15:56:21 +08:00
60 changed files with 386 additions and 606 deletions

No files matched your search

+3 -3
View File
@@ -6,10 +6,10 @@ body:
- type: markdown
attributes:
value: |
感谢您愿意为 Ehviewer-Overhauled 做出贡献!
感谢您愿意为 EhViewer 做出贡献!
提交问题报告前,还请首先完成文末的自查步骤
Thanks for your contribution on Ehviewer-Overhauled Project!
Thanks for your contribution on EhViewer Project!
Please finish verify steps which list in the end first before create bug report
- type: textarea
@@ -141,5 +141,5 @@ body:
- label: 您确保这个 Issue 只提及一个问题。如果您有多个问题报告,烦请发起多个 Issue / Ensure there is only one bug report in this issue. Please make mutiply issue for mutiply bugs
required: true
- label: 您确保已使用最新 CI 版本测试,并且该问题在最新 CI 版本中并未解决 / This bug have not solved in latest CI version
- label: 您确保已使用最新 [CI 版本](https://github.com/FooIbar/EhViewer/actions)测试,并且该问题在最新 CI 版本中并未解决 / This bug have not solved in latest [CI version](https://github.com/FooIbar/EhViewer/actions)
required: true
+25 -12
View File
@@ -4,8 +4,9 @@ on:
push:
branches:
- '*'
tags-ignore:
- "*"
- 'renovate/**'
pull_request:
workflow_dispatch:
jobs:
linux:
@@ -13,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
with:
submodules: 'recursive'
@@ -23,13 +24,14 @@ jobs:
distribution: temurin
java-version: 17
- name: Install NDK
run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;26.0.10636728" --channel=1 --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
- name: Install Rust Toolchain
run: rustup update && rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android && rustup component add rustfmt clippy
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: "./app/src/main/rust"
- name: Rustfmt Check
working-directory: ./app/src/main/rust
run: cargo fmt --all -- --check
@@ -38,14 +40,25 @@ jobs:
working-directory: ./app/src/main/rust
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Ktlint Check
run: ./gradlew ktlintCheck
- name: Gradle Build
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
gradle-home-cache-cleanup: true
arguments: assembleRelease
- name: Spotless Check
run: ./gradlew spotlessCheck
- name: CMake Cache
uses: actions/cache@v3
with:
path: |
app/.cxx
app/src/main/cpp/nettle/nettle
key: ${{ runner.os }}-cmake-${{ github.run_id }}
restore-keys: ${{ runner.os }}-cmake-
- name: Gradle Build
run: ./gradlew assembleRelease
- name: Update ARM64
uses: actions/upload-artifact@v3
-66
View File
@@ -1,66 +0,0 @@
name: Pull Request Check
on: [ pull_request ]
jobs:
linux:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
with:
submodules: 'recursive'
- name: Setup Java 17
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: Install NDK
run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;26.0.10636728" --channel=1 --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
- name: Install Rust Toolchain
run: rustup update && rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android && rustup component add rustfmt clippy
- name: Rustfmt Check
working-directory: ./app/src/main/rust
run: cargo fmt --all -- --check
- name: Clippy Check
working-directory: ./app/src/main/rust
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Ktlint Check
run: ./gradlew ktlintCheck
- name: Gradle Build
uses: gradle/gradle-build-action@v2
with:
arguments: assembleRelease
- name: Update ARM64
uses: actions/upload-artifact@v3
with:
name: arm64-v8a-${{ github.sha }}
path: app/build/outputs/apk/release/app-arm64-v8a-release.apk
- name: Update x86_64
uses: actions/upload-artifact@v3
with:
name: x86_64-${{ github.sha }}
path: app/build/outputs/apk/release/app-x86_64-release.apk
- name: Update ARM32
uses: actions/upload-artifact@v3
with:
name: armeabi-v7a-${{ github.sha }}
path: app/build/outputs/apk/release/app-armeabi-v7a-release.apk
- name: Update x86
uses: actions/upload-artifact@v3
with:
name: x86-${{ github.sha }}
path: app/build/outputs/apk/release/app-x86-release.apk
+15 -5
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
with:
submodules: 'recursive'
@@ -21,13 +21,23 @@ jobs:
distribution: temurin
java-version: 17
- name: Install NDK
run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;26.0.10636728" --channel=1 --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
- name: Install Rust Toolchain
run: rustup update && rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: "./app/src/main/rust"
- name: CMake Cache
uses: actions/cache@v3
with:
path: |
app/.cxx
app/src/main/cpp/nettle/nettle
key: ${{ runner.os }}-cmake-${{ github.run_id }}
restore-keys: ${{ runner.os }}-cmake-
- name: Gradle Build
uses: gradle/gradle-build-action@v2
with:
-3
View File
@@ -1,3 +0,0 @@
[submodule "app/src/main/cpp/nettle/nettle"]
path = app/src/main/cpp/nettle/nettle
url = https://github.com/Ehviewer-Overhauled/nettle
+24 -21
View File
@@ -5,60 +5,60 @@ The project is in maintenance mode, will only receive bugfixes.
<p align="right">
<strong>English</strong>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-cn.md">
简体中文
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-tw.md">
正體中文
</a>
</p>
<h1 align="center">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200" alt="EhViewer">
<br>EhViewer<br>
</h1>
<p align="center">
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml">
<img src="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
<a href="https://github.com/FooIbar/EhViewer/actions/workflows/ci.yml">
<img src="https://github.com/FooIbar/EhViewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/LICENSE">
<img src="https://img.shields.io/github/license/Ehviewer-Overhauled/Ehviewer" alt="LICENSE">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/LICENSE">
<img src="https://img.shields.io/github/license/FooIbar/EhViewer" alt="LICENSE">
</a>
<a href="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer">
<img src="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer/badge" alt="CodeFactor">
<a href="https://www.codefactor.io/repository/github/FooIbar/EhViewer">
<img src="https://www.codefactor.io/repository/github/FooIbar/EhViewer/badge" alt="CodeFactor">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases">
<img src="https://img.shields.io/github/downloads/Ehviewer-Overhauled/EhViewer/total.svg" alt="Downloads">
<a href="https://github.com/FooIbar/EhViewer/releases">
<img src="https://img.shields.io/github/downloads/FooIbar/EhViewer/total.svg" alt="Downloads">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases">
<img src="https://img.shields.io/github/v/release/Ehviewer-Overhauled/ehviewer?include_prereleases" alt="Release">
<a href="https://github.com/FooIbar/EhViewer/releases">
<img src="https://img.shields.io/github/v/release/FooIbar/EhViewer" alt="Release">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/issues">
<img src="https://img.shields.io/github/issues/Ehviewer-Overhauled/ehviewer" alt="Issues">
<a href="https://github.com/FooIbar/EhViewer/issues">
<img src="https://img.shields.io/github/issues/FooIbar/EhViewer" alt="Issues">
</a>
</p>
<div align="center">
<h3>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#description">
<a href="https://github.com/FooIbar/EhViewer#description">
Description
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#download">
<a href="https://github.com/FooIbar/EhViewer#download">
Download
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#screenshot">
<a href="https://github.com/FooIbar/EhViewer#screenshot">
Screenshot
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#thanks">
<a href="https://github.com/FooIbar/EhViewer#thanks">
Thanks
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer#license">
<a href="https://github.com/FooIbar/EhViewer#license">
License
</a>
</h3>
@@ -73,7 +73,9 @@ and [Dynamic Color](https://m3.material.io/styles/color/dynamic-color/overview)
# Download
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Get it on F-Droid" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-fdroid.svg" width="200px"/></a>
<a href="https://github.com/FooIbar/EhViewer/releases">
<img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/>
</a>
# Screenshot
@@ -103,6 +105,7 @@ Specially thanks [Tachiyomi](https://tachiyomi.org/) for its reader implementati
Copyright 2014-2019 Hippo Seven
Copyright 2020-2022 NekoInverter
Copyright 2022-2023 Tarsin Norbin
Copyright 2023 Foolbar
EhViewer is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+42 -17
View File
@@ -13,6 +13,7 @@ plugins {
id("kotlin-parcelize")
kotlin("plugin.serialization")
id("com.google.devtools.ksp")
id("com.diffplug.spotless")
id("com.mikepenz.aboutlibraries.plugin")
id("org.mozilla.rust-android-gradle.rust-android")
id("dev.shreyaspatil.compose-compiler-report-generator")
@@ -21,7 +22,7 @@ plugins {
android {
compileSdk = 34
buildToolsVersion = "34.0.0"
ndkVersion = "26.0.10636728"
ndkVersion = "26.0.10792818"
splits {
abi {
@@ -45,6 +46,10 @@ android {
enableV4Signing = true
}
val branch = providers.exec {
commandLine = "git branch --show-current".split(' ')
}.standardOutput.asText.get().trim()
val commitSha = providers.exec {
commandLine = "git rev-parse --short=7 HEAD".split(' ')
}.standardOutput.asText.get().trim()
@@ -64,7 +69,8 @@ android {
minSdk = 28
targetSdk = 34
versionCode = 180043
versionName = "1.8.9.5"
versionName = "1.8.9.7"
versionNameSuffix = "-gms"
resourceConfigurations.addAll(
listOf(
"zh",
@@ -81,9 +87,10 @@ android {
"nb-rNO",
),
)
buildConfigField("String", "BRANCH", "\"$branch\"")
buildConfigField("String", "COMMIT_SHA", "\"$commitSha\"")
buildConfigField("String", "BUILD_TIME", "\"$buildTime\"")
buildConfigField("String", "REPO_NAME", "\"$repoName\"")
buildConfigField("String", "VERSION_NAME_SUFFIX", "\"$versionNameSuffix\"")
}
externalNativeBuild {
@@ -146,9 +153,11 @@ android {
isShrinkResources = true
proguardFiles("proguard-rules.pro")
signingConfig = signConfig
buildConfigField("String", "BUILD_TIME", "\"$buildTime\"")
}
debug {
applicationIdSuffix = ".debug"
buildConfigField("String", "BUILD_TIME", "\"\"")
}
}
@@ -167,7 +176,7 @@ android {
dependencies {
// https://developer.android.com/jetpack/androidx/releases/activity
implementation("androidx.activity:activity-compose:1.8.0-beta01")
implementation("androidx.activity:activity-compose:1.8.0-rc01")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.biometric:biometric-ktx:1.2.0-alpha05")
implementation("androidx.browser:browser:1.6.0")
@@ -185,15 +194,15 @@ 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-alpha04")
implementation("androidx.fragment:fragment-ktx:1.7.0-alpha05")
// https://developer.android.com/jetpack/androidx/releases/lifecycle
implementation("androidx.lifecycle:lifecycle-process:2.6.2")
// https://developer.android.com/jetpack/androidx/releases/navigation
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")
val navigation = "2.7.3"
implementation("androidx.navigation:navigation-fragment-ktx:$navigation")
implementation("androidx.navigation:navigation-ui-ktx:$navigation")
implementation("androidx.navigation:navigation-compose:$navigation")
// https://developer.android.com/jetpack/androidx/releases/paging
val paging = "3.2.1"
@@ -203,9 +212,9 @@ dependencies {
implementation("androidx.recyclerview:recyclerview-selection:1.2.0-alpha01")
// https://developer.android.com/jetpack/androidx/releases/room
val room_version = "2.6.0-beta01"
ksp("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-paging:$room_version")
val room = "2.6.0-rc01"
ksp("androidx.room:room-compiler:$room")
implementation("androidx.room:room-paging:$room")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01")
implementation("androidx.work:work-runtime-ktx:2.8.1")
@@ -213,10 +222,10 @@ dependencies {
implementation("com.github.chrisbanes:PhotoView:2.3.0") // Dead Dependency
implementation("com.github.tachiyomiorg:DirectionalViewPager:1.0.0") // Dead Dependency
// https://github.com/google/accompanist/releases
val accompanist_version = "0.32.0"
implementation("com.google.accompanist:accompanist-themeadapter-material3:$accompanist_version")
implementation("com.google.accompanist:accompanist-webview:$accompanist_version")
implementation("com.google.android.material:material:1.11.0-alpha02")
val accompanist = "0.32.0"
implementation("com.google.accompanist:accompanist-themeadapter-material3:$accompanist")
implementation("com.google.accompanist:accompanist-webview:$accompanist")
implementation("com.google.android.material:material:1.11.0-alpha03")
val splitties = "3.0.0"
implementation("com.louiscad.splitties:splitties-appctx:$splitties")
@@ -231,7 +240,7 @@ dependencies {
implementation("com.squareup.okio:okio-jvm:3.5.0")
implementation("com.mikepenz:aboutlibraries-core:10.8.3")
implementation("com.mikepenz:aboutlibraries-core:10.9.1")
implementation("dev.chrisbanes.insetter:insetter:0.6.1") // Dead Dependency
implementation("dev.rikka.rikkax.core:core-ktx:1.4.1")
@@ -250,6 +259,9 @@ dependencies {
implementation("io.ktor:ktor-io-jvm:$ktor")
implementation("io.ktor:ktor-utils-jvm:$ktor")
implementation("org.chromium.net:cronet-api:113.5672.61")
implementation("com.google.android.gms:play-services-cronet:18.0.1")
val serialization = "1.6.0"
implementation("org.jetbrains.kotlinx:kotlinx-serialization-cbor:$serialization")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization")
@@ -292,6 +304,19 @@ cargo {
if (isRelease) profile = "release"
}
spotless {
kotlin {
ktlint()
}
kotlinGradle {
ktlint().editorConfigOverride(
mapOf(
"ktlint_standard_multiline-expression-wrapping" to "disabled",
),
)
}
}
tasks.configureEach {
if ((name == "mergeDebugJniLibFolders" || name == "mergeReleaseJniLibFolders")) {
dependsOn("cargoBuild")
@@ -1,34 +0,0 @@
From 2bda36800a5424c44378bbc0cc8bb5d26a0f34fa Mon Sep 17 00:00:00 2001
From: tarsin <yuanqingxiang233@163.com>
Date: Sat, 22 Jul 2023 08:30:20 +0800
Subject: [PATCH] Don't build other binarys
---
CMakeLists.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 55cd358..52b57aa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -962,7 +962,7 @@ check_symbol_exists(getopt_long getopt.h HAVE_GETOPT_LONG)
# xzdec
#############################################################################
-if(HAVE_GETOPT_LONG AND HAVE_DECODERS)
+if(0)
add_executable(xzdec
src/common/sysdefs.h
src/common/tuklib_common.h
@@ -1008,7 +1008,7 @@ endif()
# xz
#############################################################################
-if(NOT MSVC AND HAVE_GETOPT_LONG)
+if(0)
add_executable(xz
src/common/mythread.h
src/common/sysdefs.h
--
2.41.0
-29
View File
@@ -1,29 +0,0 @@
From 57da49f9b0ed8538573f6cfe289f835ee0078eec Mon Sep 17 00:00:00 2001
From: tarsin <yuanqingxiang233@163.com>
Date: Sat, 22 Jul 2023 17:50:08 +0800
Subject: [PATCH] Hide symbols
---
CMakeLists.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 646484b7..67a71272 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2060,10 +2060,10 @@ SET(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fvisibility=hidden -Werror")
CHECK_C_SOURCE_COMPILES("void __attribute__((visibility(\"default\"))) foo(void);
int main() { return 0; }" HAVE_VISIBILITY_ATTR)
-IF (HAVE_VISIBILITY_ATTR)
+IF (0)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
ADD_DEFINITIONS(-D__LIBARCHIVE_ENABLE_VISIBILITY)
-ENDIF(HAVE_VISIBILITY_ATTR)
+ENDIF(0)
SET(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
# Generate "config.h" from "build/cmake/config.h.in"
--
2.41.0
@@ -1,25 +0,0 @@
From c9298fd6dc0a8b04dd4b2247118b9cb895c46e58 Mon Sep 17 00:00:00 2001
From: tarsin <yuanqingxiang233@163.com>
Date: Sat, 23 Jul 2022 16:05:36 +0800
Subject: [PATCH 2/2] Insert link libs
---
CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 713e3bc5..7247640d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -415,7 +415,7 @@ IF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
# # endif
ENDIF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
-SET(ADDITIONAL_LIBS "")
+SET(ADDITIONAL_LIBS ${LIBARCHIVE_CUSTOM_LIBS})
#
# Find ZLIB
#
--
2.39.2
+11 -6
View File
@@ -23,15 +23,21 @@ set(FETCHCONTENT_BASE_DIR ${deps})
set(BUILD_TESTING 0)
FetchContent_Declare(liblzma
GIT_REPOSITORY https://git.tukaani.org/xz.git
GIT_TAG v5.4.3
PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/0001-Don-t-build-other-binarys.patch || cd .
GIT_REPOSITORY https://github.com/FooIbar/xz.git
GIT_TAG v5.4.4
)
FetchContent_MakeAvailable(liblzma)
include_directories(${liblzma_SOURCE_DIR}/src/liblzma/api)
# Build GNUTLS libnettle
FetchContent_Declare(nettle
URL https://ftp.gnu.org/gnu/nettle/nettle-3.9.1.tar.gz
URL_MD5 29fcd2dec6bf5b48e5e3ffb3cbc4779e
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/nettle/nettle
)
FetchContent_MakeAvailable(nettle)
add_subdirectory(nettle)
# Configure libnettle support for libarchive
@@ -62,9 +68,8 @@ option(ENABLE_TEST OFF)
SET(LIBARCHIVE_CUSTOM_LIBS "nettle" "liblzma")
FetchContent_Declare(libarchive
GIT_REPOSITORY https://github.com/libarchive/libarchive
GIT_TAG v3.7.0
PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/0001-Hide-symbols.patch ${CMAKE_CURRENT_LIST_DIR}/0002-Insert-link-libs.patch || cd .
GIT_REPOSITORY https://github.com/FooIbar/libarchive.git
GIT_TAG v3.7.2
)
FetchContent_MakeAvailable(libarchive)
+1
View File
@@ -0,0 +1 @@
/nettle
+1 -2
View File
@@ -32,7 +32,6 @@ set(LIBNETTLE_SOURCES
nettle/aes256-meta.c
nettle/nist-keywrap.c
nettle/arcfour.c
nettle/arcfour-crypt.c
nettle/arctwo.c
nettle/arctwo-meta.c
nettle/blowfish.c
@@ -177,7 +176,7 @@ set(LIBNETTLE_SOURCES
nettle/sha1-compress.c
nettle/sha1-meta.c
nettle/sha256.c
nettle/sha256-compress.c
nettle/sha256-compress-n.c
nettle/sha224-meta.c
nettle/sha256-meta.c
nettle/sha512.c
+25 -20
View File
@@ -4,13 +4,19 @@
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to 1 if using 'alloca.c'. */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to 1 if you have 'alloca', as a function or macro. */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if <alloca.h> works. */
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#define HAVE_ALLOCA_H 1
/* Define if __builtin_bswap64 is available */
@@ -46,6 +52,9 @@
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 each of the following for which a native (ie. CPU specific)
implementation of the corresponding routine exists. */
/* #undef HAVE_NATIVE_memxor3 */
@@ -71,7 +80,7 @@
/* #undef HAVE_NATIVE_cbc_aes256_encrypt */
/* #undef HAVE_NATIVE_chacha_core */
/* #undef HAVE_NATIVE_chacha_2core */
/* #undef HAVE_NATIVE_chacha_3core */
#define HAVE_NATIVE_chacha_3core 1
/* #undef HAVE_NATIVE_chacha_4core */
/* #undef HAVE_NATIVE_fat_chacha_2core */
/* #undef HAVE_NATIVE_fat_chacha_3core */
@@ -88,13 +97,18 @@
/* #undef HAVE_NATIVE_ecc_secp384r1_redc */
/* #undef HAVE_NATIVE_ecc_secp521r1_modp */
/* #undef HAVE_NATIVE_ecc_secp521r1_redc */
/* #undef HAVE_NATIVE_poly1305_set_key */
/* #undef HAVE_NATIVE_poly1305_block */
/* #undef HAVE_NATIVE_poly1305_digest */
/* #undef HAVE_NATIVE_poly1305_blocks */
/* #undef HAVE_NATIVE_fat_poly1305_blocks */
/* #undef HAVE_NATIVE_ghash_set_key */
/* #undef HAVE_NATIVE_ghash_update */
/* #undef HAVE_NATIVE_salsa20_core */
/* #undef HAVE_NATIVE_salsa20_2core */
#define HAVE_NATIVE_salsa20_2core 1
/* #undef HAVE_NATIVE_fat_salsa20_2core */
/* #undef HAVE_NATIVE_sha1_compress */
/* #undef HAVE_NATIVE_sha256_compress */
/* #undef HAVE_NATIVE_sha256_compress_n */
/* #undef HAVE_NATIVE_sha512_compress */
/* #undef HAVE_NATIVE_sha3_permute */
/* #undef HAVE_NATIVE_umac_nh */
@@ -107,14 +121,11 @@
/* #undef HAVE_OPENSSL_EVP_H */
/* Define to 1 if you have the `secure_getenv' function. */
/* #undef HAVE_SECURE_GETENV */
#define HAVE_SECURE_GETENV 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
@@ -130,9 +141,6 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
@@ -149,7 +157,7 @@
#define PACKAGE_NAME "nettle"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "nettle 3.8.1"
#define PACKAGE_STRING "nettle 3.9.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "nettle"
@@ -158,7 +166,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.8.1"
#define PACKAGE_VERSION "3.9.1"
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG __SIZEOF_LONG__
@@ -174,13 +182,10 @@
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. This
macro is obsolete. */
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Defined if public key features are enabled */
+1 -1
View File
@@ -41,7 +41,7 @@ extern "C" {
/* Individual version numbers in decimal */
#define NETTLE_VERSION_MAJOR 3
#define NETTLE_VERSION_MINOR 8
#define NETTLE_VERSION_MINOR 9
#define NETTLE_USE_MINI_GMP 0
@@ -25,6 +25,7 @@ import androidx.lifecycle.coroutineScope
import coil.ImageLoaderFactory
import coil.decode.ImageDecoderDecoder
import coil.util.DebugLogger
import com.google.android.gms.net.CronetProviderInstaller
import com.hippo.ehviewer.client.EhCookieStore
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.client.data.GalleryDetail
@@ -77,6 +78,7 @@ class EhApplication : Application(), ImageLoaderFactory {
handler?.uncaughtException(t, e)
}
super.onCreate()
CronetProviderInstaller.installProvider(appCtx)
System.loadLibrary("ehviewer")
System.loadLibrary("ehviewer_rust")
ReadableTime.initialize(this)
@@ -60,6 +60,7 @@ object Settings : DataStorePreferences(null) {
var removeImageFiles by boolPref("include_pic", true)
var needSignIn by boolPref("need_sign_in", true)
var blackDarkTheme by boolPref("black_dark_theme", false).observed { updateWhenAmoledModeChanges() }
var harmonizeCategoryColor by boolPref("harmonize_category_color", true)
var preloadThumbAggressively by boolPref("preload_thumb_aggressively", false)
var downloadOriginImage by boolPref("download_origin_image", false)
var thumbSizeDp by intPref("thumb_size_", 120)
@@ -126,12 +126,18 @@ object EhUtils {
MISC -> BG_COLOR_MISC
else -> BG_COLOR_UNKNOWN
}.toInt()
return harmonizeWithRole(context, primary)
return if (Settings.harmonizeCategoryColor) {
harmonizeWithRole(context, primary)
} else {
primary
}
}
@Composable
fun getCategoryColor(category: Int) = Color(getCategoryColor(LocalContext.current, category))
val categoryTextColor = Color(0xffe6e0e9)
fun signOut() {
EhCookieStore.signOut()
Settings.avatar = null
@@ -1,12 +1,9 @@
@file:Suppress("BlockingMethodInNonBlockingContext")
@file:RequiresExtension(extension = Build.VERSION_CODES.S, version = 7)
package com.hippo.ehviewer.coil
import android.net.Uri
import android.os.Build
import android.webkit.MimeTypeMap
import androidx.annotation.RequiresExtension
import coil.ComponentRegistry
import coil.ImageLoader
import coil.decode.DataSource
@@ -30,7 +27,7 @@ class CronetHttpUriFetcher(private val data: String, private val options: Option
val diskCache = requireNotNull(imageLoader.diskCache)
val snapshot = diskCache.openSnapshot(diskCacheKey) ?: run {
val success = cronetRequest(data) {
setCacheDisabled(true)
disableCache()
}.execute {
diskCache.suspendEdit(diskCacheKey) {
RandomAccessFile(data.toFile(), "rw").use {
@@ -1,13 +1,5 @@
@file:RequiresExtension(extension = Build.VERSION_CODES.S, version = 7)
package com.hippo.ehviewer.cronet
import android.net.http.HttpEngine
import android.net.http.HttpException
import android.net.http.UrlRequest
import android.net.http.UrlResponseInfo
import android.os.Build
import androidx.annotation.RequiresExtension
import com.hippo.ehviewer.EhApplication
import com.hippo.ehviewer.client.CHROME_ACCEPT
import com.hippo.ehviewer.client.CHROME_ACCEPT_LANGUAGE
@@ -20,6 +12,10 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.HttpUrl.Companion.toHttpUrl
import okio.Path.Companion.toOkioPath
import org.chromium.net.CronetEngine
import org.chromium.net.CronetException
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
import splitties.init.appCtx
import java.nio.ByteBuffer
import java.nio.channels.FileChannel
@@ -32,23 +28,24 @@ import kotlin.coroutines.resumeWithException
private const val TAG = "CronetRequest"
val pool = DirectByteBufferPool(32)
val cronetHttpClient: HttpEngine = HttpEngine.Builder(appCtx).apply {
setEnableBrotli(true)
val cronetHttpClient: CronetEngine = CronetEngine.Builder(appCtx).apply {
enableBrotli(true)
val cache = (appCtx.cacheDir.toOkioPath() / "http_cache").toFile().apply { mkdirs() }
setStoragePath(cache.absolutePath)
setEnableHttpCache(HttpEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 100 * 1024)
enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 100 * 1024)
setUserAgent(CHROME_USER_AGENT)
}.build()
val cronetHttpClientExecutor = EhApplication.baseOkHttpClient.dispatcher.executorService
// TODO: Rewrite this to use android.net.http.HttpEngine and make it Android 14 only when released
class CronetRequest {
lateinit var consumer: (ByteBuffer) -> Unit
lateinit var onResponse: CronetRequest.(UrlResponseInfo) -> Unit
lateinit var request: UrlRequest
lateinit var onError: (Throwable) -> Unit
lateinit var readerCont: Continuation<Unit>
val callback = object : UrlRequest.Callback {
val callback = object : UrlRequest.Callback() {
override fun onRedirectReceived(req: UrlRequest, info: UrlResponseInfo, url: String) {
logcat(tag = TAG) { "Redirected to $url" }
req.followRedirect()
@@ -67,18 +64,14 @@ class CronetRequest {
readerCont.resume(Unit)
}
override fun onFailed(req: UrlRequest, info: UrlResponseInfo?, e: HttpException) {
override fun onFailed(req: UrlRequest, info: UrlResponseInfo?, e: CronetException) {
onError(e)
}
override fun onCanceled(req: UrlRequest, info: UrlResponseInfo?) {
// No-op
}
}
}
inline fun cronetRequest(url: String, referer: String? = null, conf: UrlRequest.Builder.() -> Unit = {}) = CronetRequest().apply {
request = cronetHttpClient.newUrlRequestBuilder(url, cronetHttpClientExecutor, callback).apply {
request = cronetHttpClient.newUrlRequestBuilder(url, callback, cronetHttpClientExecutor).apply {
addHeader("Cookie", EhCookieStore.getCookieHeader(url.toHttpUrl()))
addHeader("Accept", CHROME_ACCEPT)
addHeader("Accept-Language", CHROME_ACCEPT_LANGUAGE)
@@ -135,9 +135,9 @@ class SpiderDen(mGalleryInfo: GalleryInfo) {
): Boolean {
return if (isCronetSupported) {
cronetRequest(url, referer) {
setCacheDisabled(true)
disableCache()
}.execute { info ->
val headers = info.headers.asMap
val headers = info.allHeaders
val type = headers["Content-Type"]?.first()?.toMediaType()?.subtype ?: "jpg"
val length = headers["Content-Length"]!!.first().toLong()
saveResponseMeta(index, type, length) { file ->
@@ -5,10 +5,12 @@ import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.imePadding
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Modifier
import androidx.core.view.WindowCompat
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
@@ -46,6 +48,7 @@ class ConfigureActivity : EhActivity() {
} else {
BASE_SETTINGS_SCREEN
},
modifier = Modifier.imePadding(),
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up, tween(200)) },
exitTransition = { fadeOut(tween(200)) },
popEnterTransition = { fadeIn(tween(200)) },
@@ -8,14 +8,11 @@ import android.util.AttributeSet
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
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.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ElevatedCard
@@ -34,6 +31,10 @@ import androidx.compose.ui.platform.AbstractComposeView
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import androidx.lifecycle.get
import com.google.accompanist.themeadapter.material3.Mdc3Theme
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
@@ -49,120 +50,125 @@ import com.hippo.ehviewer.util.pickVisualMedia
import com.hippo.unifile.UniFile
import kotlinx.coroutines.launch
class SearchViewModel : ViewModel() {
var isNormalMode by mutableStateOf(true) // else ImageSearch mode
var isAdvancedMode by mutableStateOf(false)
var mCategory by mutableIntStateOf(Settings.searchCategory)
var mSearchMode by mutableIntStateOf(1)
var advancedState by mutableStateOf(AdvancedSearchOption())
var uss by mutableStateOf(false)
var osc by mutableStateOf(false)
var path by mutableStateOf("")
}
class SearchLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
) : AbstractComposeView(context, attrs, defStyle) {
private var isNormalMode by mutableStateOf(true) // else ImageSearch mode
private var isAdvancedMode by mutableStateOf(false)
private var mCategory by mutableIntStateOf(Settings.searchCategory)
private var mSearchMode by mutableIntStateOf(1)
private var advancedState by mutableStateOf(AdvancedSearchOption())
private var uss by mutableStateOf(false)
private var osc by mutableStateOf(false)
private var path by mutableStateOf("")
private val vm by lazy {
ViewModelProvider(findViewTreeViewModelStoreOwner()!!).get<SearchViewModel>()
}
@Composable
override fun Content() {
val coroutineScope = rememberCoroutineScope()
fun selectImage() = coroutineScope.launch {
context.pickVisualMedia(ActivityResultContracts.PickVisualMedia.ImageOnly)?.let {
path = it.toString()
vm.path = it.toString()
}
}
Mdc3Theme {
Column(modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.search_layout_margin_h)).imePadding().verticalScroll(rememberScrollState())) {
AnimatedVisibility(visible = isNormalMode) {
Column(modifier = Modifier.imePadding().verticalScroll(rememberScrollState()).navigationBarsPadding().padding(horizontal = dimensionResource(id = R.dimen.search_layout_margin_h))) {
AnimatedVisibility(visible = vm.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))) {
Text(text = stringResource(id = R.string.search_normal), modifier = Modifier.height(dimensionResource(id = R.dimen.search_category_title_height)), fontWeight = FontWeight.Bold, style = MaterialTheme.typography.titleMedium)
NormalSearch(
category = mCategory,
category = vm.mCategory,
onCategoryChanged = {
Settings.searchCategory = it
mCategory = it
vm.mCategory = it
},
searchMode = mSearchMode,
onSearchModeChanged = { mSearchMode = it },
isAdvanced = isAdvancedMode,
onAdvancedChanged = { isAdvancedMode = it },
searchMode = vm.mSearchMode,
onSearchModeChanged = { vm.mSearchMode = it },
isAdvanced = vm.isAdvancedMode,
onAdvancedChanged = { vm.isAdvancedMode = it },
showInfo = { BaseDialogBuilder(context).setMessage(R.string.search_tip).show() },
)
}
}
}
AnimatedVisibility(visible = isNormalMode && isAdvancedMode) {
AnimatedVisibility(visible = vm.isNormalMode && vm.isAdvancedMode) {
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))) {
Text(text = stringResource(id = R.string.search_advance), modifier = Modifier.height(dimensionResource(id = R.dimen.search_category_title_height)), fontWeight = FontWeight.Bold, style = MaterialTheme.typography.titleMedium)
SearchAdvanced(
state = advancedState,
onStateChanged = { advancedState = it },
state = vm.advancedState,
onStateChanged = { vm.advancedState = it },
)
}
}
}
AnimatedVisibility(visible = !isNormalMode) {
AnimatedVisibility(visible = !vm.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))) {
Text(text = stringResource(id = R.string.search_image), modifier = Modifier.height(dimensionResource(id = R.dimen.search_category_title_height)), fontWeight = FontWeight.Bold, style = MaterialTheme.typography.titleMedium)
ImageSearch(
imagePath = path,
imagePath = vm.path,
onSelectImage = ::selectImage,
uss = uss,
onUssChecked = { uss = it },
osc = osc,
onOscChecked = { osc = it },
uss = vm.uss,
onUssChecked = { vm.uss = it },
osc = vm.osc,
onOscChecked = { vm.osc = it },
)
}
}
}
TabRow(
selectedTabIndex = if (isNormalMode) 0 else 1,
selectedTabIndex = if (vm.isNormalMode) 0 else 1,
divider = {},
) {
Tab(
selected = isNormalMode,
onClick = { isNormalMode = true },
selected = vm.isNormalMode,
onClick = { vm.isNormalMode = true },
text = { Text(text = stringResource(id = R.string.keyword_search)) },
)
Tab(
selected = !isNormalMode,
onClick = { isNormalMode = false },
selected = !vm.isNormalMode,
onClick = { vm.isNormalMode = false },
text = { Text(text = stringResource(id = R.string.search_image)) },
)
}
Spacer(modifier = Modifier.height(WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()))
}
}
}
fun setSearchMyTags(isMyTags: Boolean) {
if (isMyTags) mSearchMode = 2
if (isMyTags) vm.mSearchMode = 2
}
fun setCategory(category: Int) {
mCategory = category
vm.mCategory = category
}
fun formatListUrlBuilder(urlBuilder: ListUrlBuilder, query: String?) {
urlBuilder.reset()
when (isNormalMode) {
when (vm.isNormalMode) {
true -> {
when (mSearchMode) {
when (vm.mSearchMode) {
1 -> urlBuilder.mode = ListUrlBuilder.MODE_NORMAL
2 -> urlBuilder.mode = ListUrlBuilder.MODE_SUBSCRIPTION
3 -> urlBuilder.mode = ListUrlBuilder.MODE_UPLOADER
4 -> urlBuilder.mode = ListUrlBuilder.MODE_TAG
}
urlBuilder.keyword = query
urlBuilder.category = mCategory
if (isAdvancedMode) {
urlBuilder.advanceSearch = advancedState.advanceSearch
urlBuilder.minRating = advancedState.minRating
val pageFrom = advancedState.fromPage
val pageTo = advancedState.toPage
urlBuilder.category = vm.mCategory
if (vm.isAdvancedMode) {
urlBuilder.advanceSearch = vm.advancedState.advanceSearch
urlBuilder.minRating = vm.advancedState.minRating
val pageFrom = vm.advancedState.fromPage
val pageTo = vm.advancedState.toPage
if (pageTo != -1 && pageTo < 10) {
throw EhException(context.getString(R.string.search_sp_err1))
} else if (pageFrom != -1 && pageTo != -1 && pageTo - pageFrom < 20) {
@@ -175,15 +181,15 @@ class SearchLayout @JvmOverloads constructor(
false -> {
urlBuilder.mode = ListUrlBuilder.MODE_IMAGE_SEARCH
if (path.isBlank()) throw EhException(context.getString(R.string.select_image_first))
val uri = Uri.parse(path)
if (vm.path.isBlank()) throw EhException(context.getString(R.string.select_image_first))
val uri = Uri.parse(vm.path)
val src = UniFile.fromUri(context, uri)?.imageSource ?: return
val temp = AppConfig.createTempFile() ?: return
val bitmap = ImageDecoder.decodeBitmap(src, Image.imageSearchDecoderSampleListener)
temp.outputStream().use { bitmap.compress(Bitmap.CompressFormat.JPEG, 90, it) }
urlBuilder.imagePath = temp.path
urlBuilder.isUseSimilarityScan = uss
urlBuilder.isOnlySearchCovers = osc
urlBuilder.isUseSimilarityScan = vm.uss
urlBuilder.isOnlySearchCovers = vm.osc
}
}
}
@@ -257,7 +257,7 @@ fun CookieSignInScene(windowSizeClass: WindowSizeClass) {
when (windowSizeClass.widthSizeClass) {
WindowWidthSizeClass.Compact, WindowWidthSizeClass.Medium -> {
Column(
modifier = Modifier.padding(dimensionResource(id = R.dimen.keyline_margin)).padding(padding).fillMaxSize().verticalScroll(rememberScrollState()),
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(padding).padding(dimensionResource(id = R.dimen.keyline_margin)),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
@@ -284,7 +284,7 @@ fun CookieSignInScene(windowSizeClass: WindowSizeClass) {
}
WindowWidthSizeClass.Expanded -> {
Row(
modifier = Modifier.padding(dimensionResource(id = R.dimen.keyline_margin)).padding(padding).verticalScroll(rememberScrollState()),
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(padding).padding(dimensionResource(id = R.dimen.keyline_margin)),
verticalAlignment = Alignment.CenterVertically,
) {
Column(
@@ -5,12 +5,10 @@ import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SegmentedButton
@@ -45,7 +43,7 @@ fun SelectSiteScreen() {
}
Column(
modifier = Modifier.padding(WindowInsets.systemBars.asPaddingValues()).padding(horizontal = dimensionResource(R.dimen.keyline_margin)).padding(top = dimensionResource(R.dimen.keyline_margin)).fillMaxSize(),
modifier = Modifier.systemBarsPadding().padding(horizontal = dimensionResource(R.dimen.keyline_margin)).padding(top = dimensionResource(R.dimen.keyline_margin)).fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState
@@ -181,7 +182,7 @@ fun SignInScreen(windowSizeClass: WindowSizeClass) {
when (windowSizeClass.widthSizeClass) {
WindowWidthSizeClass.Compact, WindowWidthSizeClass.Medium -> {
Column(
modifier = Modifier.padding(dimensionResource(id = R.dimen.keyline_margin)).fillMaxSize().verticalScroll(rememberScrollState()),
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).systemBarsPadding().padding(dimensionResource(id = R.dimen.keyline_margin)),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
@@ -266,7 +267,7 @@ fun SignInScreen(windowSizeClass: WindowSizeClass) {
}
WindowWidthSizeClass.Expanded -> {
Row(
modifier = Modifier.padding(dimensionResource(id = R.dimen.keyline_margin)).fillMaxSize().verticalScroll(rememberScrollState()),
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).systemBarsPadding().padding(dimensionResource(id = R.dimen.keyline_margin)),
verticalAlignment = Alignment.CenterVertically,
) {
Column(
@@ -10,7 +10,7 @@ object AdvanceTable {
data class AdvancedSearchOption(
val advanceSearch: Int = 0,
val minRating: Int = 0,
val minRating: Int = -1,
val fromPage: Int = -1,
val toPage: Int = -1,
)
@@ -59,7 +59,7 @@ fun SearchAdvanced(
OutlinedTextField(
modifier = Modifier.menuAnchor(),
readOnly = true,
value = minRatingItems[state.minRating],
value = minRatingItems[if (state.minRating in 2..5) state.minRating - 1 else 0],
onValueChange = {},
label = { Text(stringResource(id = R.string.search_sr)) },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
@@ -77,7 +77,8 @@ fun SearchAdvanced(
text = { Text(selectionOption) },
onClick = {
expanded = false
onStateChanged(state.copy(minRating = minRatingItems.indexOf(selectionOption)))
val index = minRatingItems.indexOf(selectionOption)
onStateChanged(state.copy(minRating = if (index > 0) index + 1 else -1))
},
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
)
@@ -21,6 +21,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.ShapeDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
@@ -28,12 +29,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.NOT_FAVORITED
@@ -109,6 +112,7 @@ fun GalleryInfoListItem(
start.linkTo(parent.start)
bottom.linkTo(parent.bottom)
}.clip(ShapeDefaults.Small).background(categoryColor).padding(vertical = 2.dp, horizontal = 8.dp),
color = if (Settings.harmonizeCategoryColor) Color.Unspecified else EhUtils.categoryTextColor,
textAlign = TextAlign.Center,
)
Row(
@@ -198,10 +202,11 @@ fun GalleryInfoGridItem(
modifier = Modifier.aspectRatio(aspect).fillMaxWidth(),
contentScale = ContentScale.Crop,
)
val categoryColor = EhUtils.getCategoryColor(info.category)
Badge(
modifier = Modifier.align(Alignment.TopEnd).width(32.dp).height(24.dp),
containerColor = EhUtils.getCategoryColor(info.category),
contentColor = MaterialTheme.colorScheme.onSurface,
containerColor = categoryColor,
contentColor = if (Settings.harmonizeCategoryColor) contentColorFor(categoryColor) else EhUtils.categoryTextColor,
) {
simpleLang?.let {
Text(text = it.uppercase())
@@ -156,7 +156,10 @@ abstract class BaseScene : Fragment() {
}
hideSoftInput()
createDrawerView(savedInstanceState)?.let {
sideSheetDialog = SideSheetDialog(requireContext()).apply {
sideSheetDialog = object : SideSheetDialog(requireContext()) {
// Dirty workaround
override fun cancel() = hide()
}.apply {
window?.decorView?.apply {
val owner = viewLifecycleOwner
setViewTreeLifecycleOwner(owner)
@@ -46,6 +46,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
@@ -809,6 +810,7 @@ class DownloadsScene :
Text(
text = categoryText,
modifier = Modifier.clip(ShapeDefaults.Small).background(categoryColor).padding(vertical = 2.dp, horizontal = 8.dp),
color = if (Settings.harmonizeCategoryColor) Color.Unspecified else EhUtils.categoryTextColor,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.labelLarge,
)
@@ -333,7 +333,7 @@ class FavoritesScene : SearchBarScene() {
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
binding.tip.setCompoundDrawables(null, drawable, null, null)
binding.tip.setOnClickListener { mAdapter?.refresh() }
binding.refreshLayout.setOnRefreshListener { mAdapter?.refresh() }
binding.refreshLayout.setOnRefreshListener { switchFav(urlBuilder.favCat) }
val transition = ViewTransition(binding.refreshLayout, binding.progress, binding.tip)
val empty = getString(R.string.gallery_list_empty_hit)
viewLifecycleOwner.lifecycleScope.launch {
@@ -27,6 +27,7 @@ import android.view.ViewGroup
import android.view.ViewPropertyAnimator
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.material3.Text
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
@@ -39,6 +40,7 @@ import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.lifecycle.viewModelScope
import androidx.paging.LoadState
import androidx.paging.Pager
@@ -284,7 +286,7 @@ class GalleryListScene : SearchBarScene() {
setSearchBarHint(title)
when (mode) {
MODE_NORMAL -> if (category != EhUtils.NONE || !keyword.isNullOrEmpty()) {
MODE_NORMAL, MODE_SUBSCRIPTION -> if (category != EhUtils.NONE || !keyword.isNullOrEmpty()) {
mainActivity?.clearNavCheckedItem()
}
MODE_TAG, MODE_UPLOADER, MODE_IMAGE_SEARCH -> mainActivity?.clearNavCheckedItem()
@@ -331,6 +333,8 @@ class GalleryListScene : SearchBarScene() {
),
)
mViewTransition = BringOutTransition(binding.contentLayout.contentView, binding.searchLayout)
binding.searchLayout.consumeWindowInsets = false
binding.searchLayout.setViewTreeViewModelStoreOwner(this)
binding.fastScroller.setOnDragHandlerListener(object : OnDragHandlerListener {
override fun onStartDragHandler() {}
override fun onEndDragHandler() {
@@ -360,7 +364,11 @@ class GalleryListScene : SearchBarScene() {
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
binding.tip.setCompoundDrawables(null, drawable, null, null)
binding.tip.setOnClickListener { mAdapter?.refresh() }
binding.refreshLayout.setOnRefreshListener { mAdapter?.refresh() }
binding.refreshLayout.setOnRefreshListener {
mUrlBuilder.setIndex(null, true)
mUrlBuilder.mJumpTo = null
mAdapter?.refresh()
}
val transition = ViewTransition(binding.refreshLayout, binding.progress, binding.tip)
val empty = getString(R.string.gallery_list_empty_hit)
launch {
@@ -509,14 +517,15 @@ class GalleryListScene : SearchBarScene() {
tip: TextView,
) {
val context = context ?: return
if (mAdapter!!.itemCount == 0) return
// Can't add image search as quick search
if (MODE_IMAGE_SEARCH == mUrlBuilder.mode) {
showTip(R.string.image_search_not_quick_search, LENGTH_LONG)
return
}
val gi = mAdapter?.peek(binding.recyclerView.layoutManager!!.firstVisibleItemPosition)
val next = gi?.gid?.plus(1)
val gi = mAdapter!!.peek(binding.recyclerView.layoutManager!!.firstVisibleItemPosition)!!
val next = gi.gid + 1
// Check duplicate
for (q in mQuickSearchList) {
@@ -551,7 +560,7 @@ class GalleryListScene : SearchBarScene() {
}
return@launchIO
}
if (checked[0] && next != null) {
if (checked[0]) {
text += "@$next"
Settings.qSSaveProgress = true
} else {
@@ -614,20 +623,22 @@ class GalleryListScene : SearchBarScene() {
drawerBinding.toolbar.setTitle(R.string.toplist)
} else {
drawerBinding.toolbar.setTitle(R.string.quick_search)
}
if (!mIsTopList) drawerBinding.toolbar.inflateMenu(R.menu.drawer_gallery_list)
drawerBinding.toolbar.setOnMenuItemClickListener { item: MenuItem ->
val id = item.itemId
if (id == R.id.action_add) {
showAddQuickSearchDialog(
qsDrawerAdapter,
drawerBinding.recyclerViewDrawer,
drawerBinding.tip,
)
} else if (id == R.id.action_help) {
showQuickSearchTipDialog()
if (mUrlBuilder.mode != MODE_WHATS_HOT) {
drawerBinding.toolbar.inflateMenu(R.menu.drawer_gallery_list)
drawerBinding.toolbar.setOnMenuItemClickListener { item: MenuItem ->
val id = item.itemId
if (id == R.id.action_add) {
showAddQuickSearchDialog(
qsDrawerAdapter,
drawerBinding.recyclerViewDrawer,
drawerBinding.tip,
)
} else if (id == R.id.action_help) {
showQuickSearchTipDialog()
}
true
}
}
true
}
return drawerBinding.root
}
@@ -850,13 +861,17 @@ class GalleryListScene : SearchBarScene() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QsDrawerHolder {
val holder = QsDrawerHolder(ItemDrawerListBinding.inflate(mInflater, parent, false))
holder.itemView.setOnClickListener {
if (!mIsTopList) {
if (mUrlBuilder.mode == MODE_WHATS_HOT) {
val q = mQuickSearchList[holder.bindingAdapterPosition]
// Navigate to galleryListScene to clear nav checked item
navAnimated(R.id.galleryListScene, ListUrlBuilder().apply { set(q) }.toStartArgs())
} else {
mUrlBuilder.keyword = keywords[holder.bindingAdapterPosition].toString()
mUrlBuilder.mJumpTo = null
if (mIsTopList) {
mUrlBuilder.keyword = keywords[holder.bindingAdapterPosition].toString()
mUrlBuilder.mJumpTo = null
} else {
val q = mQuickSearchList[holder.bindingAdapterPosition]
mUrlBuilder.set(q)
}
onUpdateUrlBuilder()
mAdapter?.refresh()
}
@@ -11,6 +11,7 @@ import androidx.annotation.CallSuper
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
@@ -82,6 +83,7 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene {
onApplySearch()
true
}
binding.searchBarList.consumeWindowInsets = false
binding.searchBarList.setMD3Content {
LazyColumn(contentPadding = WindowInsets.navigationBars.asPaddingValues()) {
items(mSuggestionList) {
@@ -140,6 +142,7 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene {
override fun onDestroyView() {
super.onDestroyView()
mSearchViewOnBackPressedCallback.remove()
binding.root.removeAllViews()
_binding = null
}
@@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
@@ -84,7 +83,7 @@ fun AboutScreen() {
},
snackbarHost = { SnackbarHost(snackbarHostState) },
) { paddingValues ->
Column(modifier = Modifier.padding(top = paddingValues.calculateTopPadding()).nestedScroll(scrollBehavior.nestedScrollConnection).verticalScroll(rememberScrollState())) {
Column(modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection).verticalScroll(rememberScrollState()).padding(paddingValues)) {
Preference(
title = stringResource(id = R.string.settings_about_declaration),
summary = stringResource(id = R.string.settings_about_declaration_summary),
@@ -127,7 +126,6 @@ fun AboutScreen() {
launchSnackBar(ExceptionUtils.getReadableString(it))
}
}
Spacer(modifier = Modifier.size(paddingValues.calculateBottomPadding()))
}
}
}
@@ -7,9 +7,7 @@ import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
import android.provider.Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
@@ -70,7 +68,7 @@ fun AdvancedScreen() {
},
snackbarHost = { SnackbarHost(snackbarHostState) },
) { paddingValues ->
Column(modifier = Modifier.padding(top = paddingValues.calculateTopPadding()).nestedScroll(scrollBehavior.nestedScrollConnection).verticalScroll(rememberScrollState())) {
Column(modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection).verticalScroll(rememberScrollState()).padding(paddingValues)) {
SwitchPreference(
title = stringResource(id = R.string.settings_advanced_save_parse_error_body),
summary = stringResource(id = R.string.settings_advanced_save_parse_error_body_summary),
@@ -225,7 +223,6 @@ fun AdvancedScreen() {
}
}
}
Spacer(modifier = Modifier.size(paddingValues.calculateBottomPadding()))
}
}
}
@@ -5,9 +5,7 @@ import android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
@@ -74,7 +72,7 @@ fun DownloadScreen() {
},
snackbarHost = { SnackbarHost(snackbarHostState) },
) { paddingValues ->
Column(modifier = Modifier.padding(top = paddingValues.calculateTopPadding()).nestedScroll(scrollBehavior.nestedScrollConnection).verticalScroll(rememberScrollState())) {
Column(modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection).verticalScroll(rememberScrollState()).padding(paddingValues)) {
var downloadLocationState by ::downloadLocation.observed
val cannotGetDownloadLocation = stringResource(id = R.string.settings_download_cant_get_download_location)
val selectDownloadDirLauncher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocumentTree()) { treeUri ->
@@ -232,7 +230,6 @@ fun DownloadScreen() {
it.printStackTrace()
}
}
Spacer(modifier = Modifier.size(paddingValues.calculateBottomPadding()))
}
}
}
@@ -4,9 +4,7 @@ import android.content.DialogInterface
import android.os.Build
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
@@ -90,7 +88,7 @@ fun EhScreen() {
) { paddingValues ->
val touristMode = stringResource(id = R.string.settings_eh_identity_cookies_tourist)
val copiedToClipboard = stringResource(id = R.string.copied_to_clipboard)
Column(modifier = Modifier.padding(top = paddingValues.calculateTopPadding()).nestedScroll(scrollBehavior.nestedScrollConnection).verticalScroll(rememberScrollState())) {
Column(modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection).verticalScroll(rememberScrollState()).padding(paddingValues)) {
Preference(
title = stringResource(id = R.string.account_name),
summary = Settings.displayName ?: touristMode,
@@ -224,6 +222,10 @@ fun EhScreen() {
title = stringResource(id = R.string.black_dark_theme),
value = Settings::blackDarkTheme,
)
SwitchPreference(
title = stringResource(id = R.string.harmonize_category_color),
value = Settings::harmonizeCategoryColor,
)
SimpleMenuPreferenceInt(
title = stringResource(id = R.string.settings_eh_launch_page),
entry = R.array.launch_page_entries,
@@ -339,7 +341,6 @@ fun EhScreen() {
)
}
}
Spacer(modifier = Modifier.size(paddingValues.calculateBottomPadding()))
}
}
}
@@ -38,7 +38,7 @@ fun MyTagsScreen() {
val state = rememberWebViewState(url = url)
WebView(
state = state,
modifier = Modifier.padding(top = paddingValues.calculateTopPadding()).fillMaxSize(),
modifier = Modifier.padding(paddingValues).fillMaxSize(),
onCreated = {
it.setDefaultSettings()
},
@@ -62,7 +62,7 @@ fun UConfigScreen() {
val state = rememberWebViewState(url = url)
WebView(
state = state,
modifier = Modifier.padding(top = paddingValues.calculateTopPadding()).fillMaxSize(),
modifier = Modifier.padding(paddingValues).fillMaxSize(),
onCreated = {
it.setDefaultSettings()
},
@@ -3,7 +3,6 @@ package com.hippo.ehviewer.ui.tools
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.unit.Dp
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.roundToInt
@@ -15,7 +14,6 @@ private const val QuarterCircle = PI / 2
@Composable
fun CircularLayout(
modifier: Modifier = Modifier,
radius: Dp,
placeFirstItemInCenter: Boolean = false,
content: @Composable () -> Unit,
) {
@@ -23,7 +21,7 @@ fun CircularLayout(
modifier = modifier,
content = content,
) { measurables, constraints ->
val radiusPx = radius.toPx()
val radiusPx = constraints.maxWidth * 0.4
val itemConstraints = constraints.copy(minWidth = 0, minHeight = 0)
val placeables = measurables.map { measurable -> measurable.measure(itemConstraints) }
val outPlaceables = if (placeFirstItemInCenter) placeables.drop(1) else placeables
@@ -41,11 +41,11 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import com.jamal.composeprefs3.ui.ifNotNullThen
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.suspendCancellableCoroutine
@@ -183,6 +183,7 @@ class DialogState {
}
AlertDialog(
onDismissRequest = { cont.cancel() },
properties = DialogProperties(usePlatformDefaultWidth = respectDefaultWidth),
content = {
Surface(
modifier = with(Modifier) { if (!respectDefaultWidth) defaultMinSize(280.dp) else width(280.dp) },
@@ -248,12 +249,10 @@ class DialogState {
@StringRes title: Int,
@StringRes hint: Int,
maxChar: Int,
adjustTextPosition: Boolean = true,
): Pair<Int, String> = showNoButton(false) {
Column {
Text(text = stringResource(id = title), modifier = Modifier.padding(horizontal = 16.dp).padding(top = 16.dp), style = MaterialTheme.typography.titleMedium)
CircularLayout(
radius = 112.dp,
modifier = Modifier.fillMaxWidth().aspectRatio(1F),
placeFirstItemInCenter = true,
) {
@@ -261,8 +260,7 @@ class DialogState {
TextField(
value = note,
onValueChange = { note = it },
modifier = Modifier.width(128.dp),
textStyle = TextStyle(fontFamily = FontFamily.Monospace),
modifier = Modifier.fillMaxWidth(0.45F).aspectRatio(1F),
label = { Text(text = stringResource(id = hint)) },
trailingIcon = {
if (note.isNotEmpty()) {
@@ -278,7 +276,6 @@ class DialogState {
textAlign = TextAlign.End,
)
},
maxLines = 6,
shape = ShapeDefaults.ExtraSmall,
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.Transparent,
@@ -287,16 +284,18 @@ class DialogState {
)
items.forEachIndexed { index, (icon, text) ->
Column(
modifier = Modifier.clip(IconWithTextCorner).clickable { dismissWith(index to note) },
modifier = Modifier.clip(IconWithTextCorner).clickable { dismissWith(index to note) }
.fillMaxWidth(0.2F),
horizontalAlignment = Alignment.CenterHorizontally,
) {
if (index == 0 && adjustTextPosition) {
Text(text = text, style = MaterialTheme.typography.bodySmall)
Icon(imageVector = icon, contentDescription = null, tint = AlertDialogDefaults.iconContentColor)
} else {
Icon(imageVector = icon, contentDescription = null, tint = AlertDialogDefaults.iconContentColor)
Text(text = text, style = MaterialTheme.typography.bodySmall)
}
Icon(imageVector = icon, contentDescription = null, tint = AlertDialogDefaults.iconContentColor)
Text(
text = text,
textAlign = TextAlign.Center,
overflow = TextOverflow.Ellipsis,
maxLines = 2,
style = MaterialTheme.typography.bodySmall,
)
}
}
}
@@ -34,7 +34,7 @@ fun WebViewScreen(url: String, onNavigateUp: () -> Unit) {
) { paddingValues ->
WebView(
state = state,
modifier = Modifier.padding(top = paddingValues.calculateTopPadding()).fillMaxSize(),
modifier = Modifier.padding(paddingValues).fillMaxSize(),
onCreated = { it.setDefaultSettings() },
)
DisposableEffect(Unit) {
@@ -9,7 +9,6 @@ import io.ktor.util.encodeBase64
import moe.tarsin.coroutines.runSuspendCatching
import okhttp3.Request
import okio.sink
import org.json.JSONObject
import tachiyomi.data.release.GithubArtifacts
import tachiyomi.data.release.GithubCommitComparison
import tachiyomi.data.release.GithubRelease
@@ -20,7 +19,8 @@ import java.time.temporal.ChronoUnit
import java.util.zip.ZipInputStream
private const val API_URL = "https://api.github.com/repos/${BuildConfig.REPO_NAME}"
private const val LATEST_RELEASE_URL = "$API_URL/releases/latest"
private const val RELEASE_URL = "$API_URL/releases"
private const val LATEST_RELEASE_URL = "$RELEASE_URL/latest"
object AppUpdater {
suspend fun checkForUpdate(forceCheck: Boolean = false): Release? {
@@ -31,10 +31,7 @@ object AppUpdater {
Settings.lastUpdateDay = now.epochSecond
if (Settings.useCIUpdateChannel) {
val curSha = BuildConfig.COMMIT_SHA
val branch = ghRequest(API_URL).execute {
JSONObject(body.string()).getString("default_branch")
}
val workflowRunsUrl = "$API_URL/actions/workflows/ci.yml/runs?branch=$branch&status=success&per_page=1"
val workflowRunsUrl = "$API_URL/actions/workflows/ci.yml/runs?branch=${BuildConfig.BRANCH}&status=success&per_page=1"
val workflowRun = ghRequest(workflowRunsUrl).executeAndParseAs<GithubWorkflowRuns>().workflowRuns[0]
val shortSha = workflowRun.headSha.take(7)
if (shortSha != curSha) {
@@ -51,10 +48,11 @@ object AppUpdater {
} else {
val curVersion = BuildConfig.VERSION_NAME
val release = ghRequest(LATEST_RELEASE_URL).executeAndParseAs<GithubRelease>()
val latestVersion = release.version
val latestVersion = release.version + BuildConfig.VERSION_NAME_SUFFIX
val description = release.info
val downloadUrl = release.getDownloadLink()
if (latestVersion != curVersion) {
val downloadUrl = ghRequest("$RELEASE_URL/tags/$latestVersion")
.executeAndParseAs<GithubRelease>().getDownloadLink()
return Release(latestVersion, description, downloadUrl)
}
}
@@ -1,8 +1,6 @@
package com.hippo.ehviewer.util
import android.os.Build
import androidx.annotation.ChecksSdkIntAtLeast
import com.google.android.gms.net.CronetProviderInstaller
@get:ChecksSdkIntAtLeast(Build.VERSION_CODES.S, extension = 7)
val isCronetSupported: Boolean
get() = isAtLeastSExtension7
get() = isAtLeastQ && CronetProviderInstaller.isInstalled()
@@ -1,8 +1,5 @@
package com.hippo.ehviewer.util
import android.os.Build
import android.os.ext.SdkExtensions
val isAtLeastQ = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
val isAtLeastR = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
val isAtLeastSExtension7 = isAtLeastR && SdkExtensions.getExtensionVersion(Build.VERSION_CODES.S) >= 7
+2 -1
View File
@@ -419,7 +419,7 @@
<string name="default_favorites_collection">默认收藏夹</string>
<string name="default_favorites_warning">启用此项将无法添加收藏备注</string>
<string name="let_me_select">让我选择</string>
<string name="favorite_note">备注</string>
<string name="favorite_note">收藏备注</string>
<string name="collections">收藏夹</string>
<string name="need_sign_in">需要登录</string>
<!-- Progress Scene -->
@@ -476,6 +476,7 @@
<string name="download_service">下载服务</string>
<string name="favorite_name">收藏画廊</string>
<string name="black_dark_theme">纯黑深色主题</string>
<string name="harmonize_category_color">类别颜色适配动态配色</string>
<string name="use_ci_update_channel">使用持续集成(CI)构建频道更新</string>
<string name="download_filter">过滤</string>
<string name="download_all">全部</string>
+3 -2
View File
@@ -440,7 +440,7 @@
<string name="settings_about_declaration" translatable="false">EhViewer</string>
<string name="settings_about_declaration_summary">EhViewer is not affiliated with E-Hentai.org in any way</string>
<string name="settings_about_author">Author</string>
<string name="settings_about_author_summary" translatable="false">&lt;del&gt;Hippo &amp;lt;ehviewersu$gmail.com&amp;gt;&lt;/del&gt;&lt;br&gt;&lt;del&gt;NekoInverter&lt;/del&gt;&lt;br&gt;飛鳥澪</string>
<string name="settings_about_author_summary" translatable="false">&lt;del&gt;Hippo &amp;lt;ehviewersu$gmail.com&amp;gt;&lt;/del&gt;&lt;br&gt;&lt;del&gt;NekoInverter&lt;/del&gt;&lt;br&gt;&lt;del&gt;飛鳥澪&lt;/del&gt;&lt;br&gt;Foolbar</string>
<string name="settings_about_latest_release">Latest release</string>
<string name="settings_about_source">Source</string>
<string name="settings_about_version">Build version</string>
@@ -477,7 +477,7 @@
<string name="default_favorites_collection">Default favorites collection</string>
<string name="default_favorites_warning">You won\'t be able to add favorite notes if you enable this</string>
<string name="let_me_select">Let me select</string>
<string name="favorite_note">Note</string>
<string name="favorite_note">Favorite Note</string>
<string name="collections">Collections</string>
<string name="need_sign_in">Signing in is required</string>
<!-- Progress Scene -->
@@ -541,6 +541,7 @@
<string name="download_service">Download Service</string>
<string name="favorite_name">Favorite</string>
<string name="black_dark_theme">Black dark theme</string>
<string name="harmonize_category_color">Harmonize category color for Dynamic Color</string>
<string name="download_filter">Filter</string>
<string name="download_all">All</string>
<string name="download_start_all_reversed">Start all (reversed)</string>
-2
View File
@@ -1,2 +0,0 @@
/target
Cargo.lock
@@ -1,2 +0,0 @@
/target
Cargo.lock
-2
View File
@@ -1,2 +0,0 @@
/target
Cargo.lock
+4 -7
View File
@@ -1,23 +1,20 @@
plugins {
id("com.android.application") version "8.1.1" apply false
id("com.android.application") version "8.1.2" apply false
kotlin("android") version "1.9.10" apply false
kotlin("plugin.serialization") version "1.9.10" apply false
id("com.google.devtools.ksp") version "1.9.10-1.0.13" apply false
id("com.mikepenz.aboutlibraries.plugin") version "10.8.3" apply false
id("com.diffplug.spotless") version "6.22.0" apply false
id("com.mikepenz.aboutlibraries.plugin") version "10.9.1" apply false
id("org.mozilla.rust-android-gradle.rust-android") version "0.9.3" apply false
id("dev.shreyaspatil.compose-compiler-report-generator") version "1.1.0" apply false
}
allprojects {
apply(from = "$rootDir/ktlint.gradle.kts")
}
tasks.register("Delete", Delete::class) {
delete(rootProject.layout.buildDirectory)
}
buildscript {
dependencies {
classpath("com.android.tools:r8:8.2.20-dev")
classpath("com.android.tools:r8:8.3.6-dev")
}
}
-103
View File
@@ -1,103 +0,0 @@
<p align="right">
<strong>English</strong>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md">
简体中文
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md">
正體中文
</a>
</p>
<h1 align="center">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200">
<br>EhViewer<br>
</h1>
<p align="center">
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml">
<img src="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/LICENSE">
<img src="https://img.shields.io/github/license/Ehviewer-Overhauled/Ehviewer" alt="LICENSE">
</a>
<a href="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer">
<img src="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer/badge" alt="CodeFactor">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases">
<img src="https://img.shields.io/github/v/release/Ehviewer-Overhauled/ehviewer?include_prereleases" alt="Release">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/issues">
<img src="https://img.shields.io/github/issues/Ehviewer-Overhauled/ehviewer" alt="Issues">
</a>
</p>
<div align="center">
<h3>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/en.md#description">
Description
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/en.md#download">
Download
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/en.md#screenshot">
Screenshot
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/en.md#thanks">
Thanks
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/en.md#license">
License
</a>
</h3>
</div>
# Description
EhViewer fork dedicated to lightweight and high-performance
with Material Design 3 and Dynamic Color Support
# Download
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Get it on F-Droid" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-fdroid.svg" width="200px"/></a>
# Screenshot
![screenshot-01](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-01.png)
![screenshot-02](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-02.png)
# Thanks
Here is the libraries
- [Arrow](https://arrow-kt.io/)
- [AOSP & AndroidX](http://source.android.com/)
- [Kotlin & KotlinX](https://kotlinlang.org/)
- [FullDraggableDrawer](https://github.com/PureWriter/FullDraggableDrawer)
- [MCA](https://github.com/material-components/material-components-android)
- [material-design-icons](https://github.com/google/material-design-icons)
- [Okhttp](https://square.github.io/okhttp/)
- [RikkaX](https://github.com/RikkaApps/RikkaX)
- [Libarchive](http://www.libarchive.org/)
- [Coil](https://coil-kt.github.io/coil/)
- [Jsoup](https://jsoup.org/)
Specially thanks [Tachiyomi](https://tachiyomi.org/) for its reader implementation!
# License
Copyright 2014-2019 Hippo Seven
Copyright 2020-2022 NekoInverter
Copyright 2022-2023 Tarsin Norbin
EhViewer is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
EhViewer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with EhViewer. If not, see <https://www.gnu.org/licenses/>.
+22 -19
View File
@@ -1,57 +1,57 @@
<p align="right">
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/en.md">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/README.md">
English
</a>
<span> | </span>
<strong>简体中文</strong>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-tw.md">
正體中文
</a>
</p>
<h1 align="center">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200" alt="EhViewer">
<br>EhViewer<br>
</h1>
<p align="center">
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml">
<img src="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
<a href="https://github.com/FooIbar/EhViewer/actions/workflows/ci.yml">
<img src="https://github.com/FooIbar/EhViewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/LICENSE">
<img src="https://img.shields.io/github/license/Ehviewer-Overhauled/Ehviewer" alt="LICENSE">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/LICENSE">
<img src="https://img.shields.io/github/license/FooIbar/EhViewer" alt="LICENSE">
</a>
<a href="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer">
<img src="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer/badge" alt="CodeFactor">
<a href="https://www.codefactor.io/repository/github/FooIbar/EhViewer">
<img src="https://www.codefactor.io/repository/github/FooIbar/EhViewer/badge" alt="CodeFactor">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases">
<img src="https://img.shields.io/github/v/release/Ehviewer-Overhauled/ehviewer?include_prereleases" alt="Release">
<a href="https://github.com/FooIbar/EhViewer/releases">
<img src="https://img.shields.io/github/v/release/FooIbar/EhViewer" alt="Release">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/issues">
<img src="https://img.shields.io/github/issues/Ehviewer-Overhauled/ehviewer" alt="Issues">
<a href="https://github.com/FooIbar/EhViewer/issues">
<img src="https://img.shields.io/github/issues/FooIbar/EhViewer" alt="Issues">
</a>
</p>
<div align="center">
<h3>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md#描述">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-cn.md#描述">
描述
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md#下载">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-cn.md#下载">
下载
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md#截图">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-cn.md#截图">
截图
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md#感谢">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-cn.md#感谢">
感谢
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md#许可证">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-cn.md#许可证">
许可证
</a>
</h3>
@@ -65,7 +65,9 @@
# 下载
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Get it on F-Droid" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-fdroid.svg" width="200px"/></a>
<a href="https://github.com/FooIbar/EhViewer/releases">
<img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/>
</a>
# 截图
@@ -95,6 +97,7 @@
Copyright 2014-2019 Hippo Seven
Copyright 2020-2022 NekoInverter
Copyright 2022-2023 Tarsin Norbin
Copyright 2023 Foolbar
EhViewer is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+22 -19
View File
@@ -1,9 +1,9 @@
<p align="right">
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/en.md">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/README.md">
English
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-cn.md">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-cn.md">
简体中文
</a>
<span> | </span>
@@ -11,47 +11,47 @@
</p>
<h1 align="center">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200" alt="EhViewer">
<br>EhViewer<br>
</h1>
<p align="center">
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml">
<img src="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
<a href="https://github.com/FooIbar/EhViewer/actions/workflows/ci.yml">
<img src="https://github.com/FooIbar/EhViewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/LICENSE">
<img src="https://img.shields.io/github/license/Ehviewer-Overhauled/Ehviewer" alt="LICENSE">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/LICENSE">
<img src="https://img.shields.io/github/license/FooIbar/EhViewer" alt="LICENSE">
</a>
<a href="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer">
<img src="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer/badge" alt="CodeFactor">
<a href="https://www.codefactor.io/repository/github/FooIbar/EhViewer">
<img src="https://www.codefactor.io/repository/github/FooIbar/EhViewer/badge" alt="CodeFactor">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases">
<img src="https://img.shields.io/github/v/release/Ehviewer-Overhauled/ehviewer?include_prereleases" alt="Release">
<a href="https://github.com/FooIbar/EhViewer/releases">
<img src="https://img.shields.io/github/v/release/FooIbar/EhViewer" alt="Release">
</a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/issues">
<img src="https://img.shields.io/github/issues/Ehviewer-Overhauled/ehviewer" alt="Issues">
<a href="https://github.com/FooIbar/EhViewer/issues">
<img src="https://img.shields.io/github/issues/FooIbar/EhViewer" alt="Issues">
</a>
</p>
<div align="center">
<h3>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md#說明">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-tw.md#說明">
說明
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md#下載">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-tw.md#下載">
下載
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md#截圖">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-tw.md#截圖">
截圖
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md#感謝">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-tw.md#感謝">
感謝
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.8.x.x/docs/README/zh-tw.md#許可證書">
<a href="https://github.com/FooIbar/EhViewer/blob/1.8.x.x/docs/README/zh-tw.md#許可證書">
許可證書
</a>
</h3>
@@ -65,7 +65,9 @@
# 下載
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Get it on F-Droid" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-fdroid.svg" width="200px"/></a>
<a href="https://github.com/FooIbar/EhViewer/releases">
<img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/>
</a>
# 截圖
@@ -93,6 +95,7 @@
Copyright 2014-2019 Hippo Seven
Copyright 2020-2022 NekoInverter
Copyright 2022-2023 Tarsin Norbin
Copyright 2023 Foolbar
EhViewer is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Binary file not shown.
Vendored
+2 -1
View File
@@ -83,7 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
-38
View File
@@ -1,38 +0,0 @@
val ktlint by configurations.creating
dependencies {
ktlint("com.pinterest:ktlint:0.50.0") {
attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
}
}
// ktlint(project(":custom-ktlint-ruleset")) // in case of custom ruleset
}
val ktlintCheck by tasks.registering(JavaExec::class) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Check Kotlin code style"
classpath = ktlint
mainClass.set("com.pinterest.ktlint.Main")
// see https://pinterest.github.io/ktlint/install/cli/#command-line-usage for more information
args(
"**/*.kt",
"**/*.kts",
"!**/build/**",
)
}
val ktlintFormat by tasks.registering(JavaExec::class) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Check Kotlin code style and format"
classpath = ktlint
mainClass.set("com.pinterest.ktlint.Main")
jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED")
// see https://pinterest.github.io/ktlint/install/cli/#command-line-usage for more information
args(
"-F",
"**/*.kt",
"**/*.kts",
"!**/build/**",
)
}
+1 -2
View File
@@ -4,8 +4,7 @@
],
"automerge": true,
"automergeType": "pr",
"automergeStrategy": "squash",
"automergeType": "branch",
"extends": [
"config:base"