Compare commits

...
104 Commits
Author SHA1 Message Date
txyyh 6f3476895e Rel 1.7.31.0-alpha02
Releases / Build (push) Has been cancelled
2022-11-03 15:56:49 +00:00
tarsin 98af874e83 Don't parse found in common path 2022-11-03 15:12:55 +00:00
tarsin 02bd5badb9 Fix tag search page load 2022-11-03 15:02:54 +00:00
tarsin 605f86483b Fix favourite scene data restore 2022-11-03 15:00:45 +00:00
tarsin f0d6ad9848 Fix uploader page request 2022-11-03 14:51:35 +00:00
tarsin 7677498e0c Relax founds limit
We will calculate accurately later
2022-11-03 14:51:14 +00:00
tarsin d115af60b3 Fix restore state 2022-11-03 14:50:55 +00:00
tarsin b07ab230e9 Code clean and allow refresh pages 2022-11-03 14:50:32 +00:00
tarsin 760ca8d6fb Minimal changes to rework Favourite grabs
TODO: Reimpl goto, refresh pages
And take care of per page counts by user
2022-11-03 05:39:36 +00:00
tarsin 4f0acb465a Minimal changes to rework new exhentai page load
TODO: Reimpl Favourite grab, goto, refresh pages
2022-11-03 05:39:22 +00:00
renovate[bot] f1ddc6c3aa Update lifecycle_version to v2.6.0-alpha03 (1.7.x.x) (#346)
Update lifecycle_version to v2.6.0-alpha03

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-25 17:28:50 +00:00
renovate[bot] 3b955cc9a9 Update fragment_version to v1.5.4 (1.7.x.x) (#345)
Update fragment_version to v1.5.4

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-25 14:30:30 +00:00
renovate[bot] 652f503635 Update dependency com.google.android.material:material to v1.8.0-alpha02 (1.7.x.x) (#344)
Update dependency com.google.android.material:material to v1.8.0-alpha02

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-25 11:05:23 +00:00
renovate[bot] 5f6d2e8dbd Update activity_version to v1.6.1 (1.7.x.x) (#343)
Update activity_version to v1.6.1

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-25 07:22:55 +00:00
renovate[bot] 4925312c4a Update plugin com.android.application to v7.3.1 (1.7.x.x) (#328)
Update plugin com.android.application to v7.3.1

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-13 20:41:56 +00:00
renovate[bot] c58bad59e2 Update plugin org.jetbrains.kotlin.android to v1.7.20 (1.7.x.x) (#315)
Update plugin org.jetbrains.kotlin.android to v1.7.20

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-29 14:52:04 +00:00
renovate[bot] 7aa318890d Update dependency androidx.annotation:annotation to v1.5.0 (1.7.x.x) (#306)
Update dependency androidx.annotation:annotation to v1.5.0

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-22 19:42:22 +08:00
renovate[bot] 066500f2f8 Update fragment_version to v1.5.3 (1.7.x.x) (#304)
Update fragment_version to v1.5.3

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-22 13:34:46 +08:00
renovate[bot] d37752a6db Update dependency androidx.recyclerview:recyclerview to v1.3.0-rc01 (1.7.x.x) (#303)
Update dependency androidx.recyclerview:recyclerview to v1.3.0-rc01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-22 13:34:32 +08:00
renovate[bot] cd81a10d28 Update dependency androidx.customview:customview to v1.2.0-alpha02 (1.7.x.x) (#301)
Update dependency androidx.customview:customview to v1.2.0-alpha02

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-22 10:44:48 +08:00
renovate[bot] 812018af06 Update dependency androidx.constraintlayout:constraintlayout to v2.2.0-alpha04 (1.7.x.x) (#300)
Update dependency androidx.constraintlayout:constraintlayout to v2.2.0-alpha04

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-22 10:44:36 +08:00
renovate[bot] ee1ddeec12 Update activity_version to v1.6.0 (1.7.x.x) (#298)
Update activity_version to v1.6.0

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-22 10:30:44 +08:00
renovate[bot] 8a3ce0e5ef Update dependency androidx.biometric:biometric-ktx to v1.2.0-alpha05 (1.7.x.x) (#299)
Update dependency androidx.biometric:biometric-ktx to v1.2.0-alpha05

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-22 10:30:34 +08:00
LaLucid 8b9a3a0274 Add Gradle cache clean (#287) 2022-09-18 10:05:57 +00:00
txyyh 08f8f6cc75 Use example version code in issue template 2022-09-17 08:53:21 +00:00
txyyh 1052ac5fc5 Apply format to all docs 2022-09-16 12:43:49 +00:00
tarsin b62b6f95a8 Update README.md 2022-09-16 12:43:38 +00:00
renovate[bot] ffd719a104 Update plugin com.android.application to v7.3.0 (1.7.x.x) (#280)
Update plugin com.android.application to v7.3.0

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-15 22:37:41 +00:00
txyyh 2f787ca94b Add thanks to issue template (#272)
* Add thanks

* Shorten description
2022-09-12 14:44:09 +00:00
renovate[bot] 990c8ed9c9 Update dependency androidx.annotation:annotation-experimental to v1.3.0 (1.7.x.x) (#270)
Update dependency androidx.annotation:annotation-experimental to v1.3.0

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-09 08:51:39 +08:00
renovate[bot] 3492593a06 Update lifecycle_version to v2.6.0-alpha02 (1.7.x.x) (#269)
Update lifecycle_version to v2.6.0-alpha02

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-09 08:51:23 +08:00
renovate[bot] 2bea46b15b Update core_version to v1.9.0 (1.7.x.x) (#267)
Update core_version to v1.9.0

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-09 07:09:08 +08:00
renovate[bot] f0903fa8b2 Update dependency androidx.appcompat:appcompat to v1.6.0-rc01 (1.7.x.x) (#268)
Update dependency androidx.appcompat:appcompat to v1.6.0-rc01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-09 07:08:39 +08:00
renovate[bot] 60caa099e2 Update activity_version to v1.6.0-rc02 (1.7.x.x) (#266)
Update activity_version to v1.6.0-rc02

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-08 20:16:00 +00:00
txyyh 586fba4221 Add additional context textarea (#255)
* Use other word

* Add additional context to bug report
2022-09-07 16:20:06 +08:00
EdwardWu 80faa9a2db Ehviewer: Translate: Update zh-rTW Translate (09/06) (#254)
* Update string from d2fc2e
* Update some strings translate

Signed-off-by: Edward Wu <bluehome.wu@gmail.com>
2022-09-06 05:48:24 +00:00
LittleLoli 54fea2929f add backup remote favorite list to local. (#252) 2022-09-06 00:47:02 +00:00
EdwardWu 4599ed88ee Ehviewer: Translate: Update zh-rTW Translate (09/04) (#250)
* Update string from a5161bb

Signed-off-by: Edward Wu <bluehome.wu@gmail.com>
2022-09-04 16:00:26 +00:00
txyyh 60d75fd780 Update material-components (#249) 2022-09-03 11:14:53 +00:00
tarsin 896d71b867 Fix #246 2022-08-31 08:50:07 +08:00
renovate[bot] 6d440730fd Update dependency com.google.android.material:material to v1.7.0-rc01 (1.7.x.x) (#248)
Update dependency com.google.android.material:material to v1.7.0-rc01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-31 08:43:27 +08:00
txyyh 77a6960e90 Use label on info card (#243) 2022-08-29 08:26:52 +00:00
txyyh 215eb267fe Use LabelLarge on CardMessage (#244) 2022-08-29 08:26:38 +00:00
txyyh 2c86e8b898 Use title small on comment (#242) 2022-08-29 08:26:23 +00:00
tarsin d7daa47c73 Make download card takes proper round corner 2022-08-26 07:00:27 +00:00
tarsin 3c488916bf Drop unused code 2022-08-26 07:00:27 +00:00
tarsin ba09fcdc3c Drop unused color res
* Color should be dynamic most time
2022-08-26 07:00:27 +00:00
tarsin 385101a729 Make swiperefreshlayout and ProgressIndicator follow dyncolor 2022-08-26 07:00:27 +00:00
renovate[bot] 002c3cf1d5 Update dependency androidx.webkit:webkit to v1.5.0 (1.7.x.x) (#239)
Update dependency androidx.webkit:webkit to v1.5.0

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-25 19:27:40 +00:00
renovate[bot] 84064549ac Update core_version to v1.9.0-rc01 (1.7.x.x) (#238)
Update core_version to v1.9.0-rc01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-25 15:46:28 +00:00
renovate[bot] 8c52ad212e Update activity_version to v1.6.0-rc01 (1.7.x.x) (#237)
Update activity_version to v1.6.0-rc01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-25 14:40:24 +08:00
renovate[bot] 23e6f78067 Update dependency org.jsoup:jsoup to v1.15.3 (1.7.x.x) (#226)
Update dependency org.jsoup:jsoup to v1.15.3

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-24 05:56:58 +00:00
tarsin d5fcb06e8f Allow universal apk build
Releases / Build (push) Has been cancelled
2022-08-24 02:52:04 +00:00
txyyh 562d1f9a0d Make release 2022-08-24 01:51:21 +00:00
tarsin 03f29288ad Fix a wrong place res 2022-08-23 07:35:18 +00:00
tarsin eb84320225 Support resize thumb, Implement #193 2022-08-23 07:34:57 +00:00
tarsin 10d73ab639 IsLightStatusBar always follow night mode, Fix #199 2022-08-23 07:34:28 +00:00
tarsin cac8f6361a Rename .java to .kt 2022-08-23 07:34:10 +00:00
tarsin 32d0758fdc Fix #196 2022-08-23 02:12:18 +00:00
tarsin c382c9c896 Add back doh 2022-08-23 02:12:18 +00:00
tarsin e772a52bf2 Fix thumb card margin 2022-08-22 10:00:38 +00:00
tarsin edda52159e Make default label removable 2022-08-22 09:58:27 +00:00
tarsin 00c2e683bd Make downloadList qs drawer drag to rearrange position and swipe to remove 2022-08-22 09:58:27 +00:00
tarsin a88766db56 Make gallerylist qs drawer drag to rearrange position and swipe to remove 2022-08-22 09:58:27 +00:00
tarsin f6c1092cba Reimplement history swipe-to-remove 2022-08-22 09:58:27 +00:00
tarsin a15b92333a Clean up readme 2022-08-22 09:58:27 +00:00
tarsin 21fc20a0f4 Drop android-advancedrecyclerview
* Actually this library is unmaintained for above a year, and drag feature we used is totally broken on Android 12 and above https://github.com/h6ah4i/android-advancedrecyclerview/issues/516 https://github.com/Ehviewer-Overhauled/Ehviewer/issues/54
2022-08-22 09:58:27 +00:00
txyyh bf72d772b5 Describe CI pages 2022-08-15 15:34:49 +00:00
txyyh 76d8575398 Rename apks on releases 2022-08-15 15:34:02 +00:00
renovate[bot] 029dc7ac61 Update dependency com.google.android.material:material to v1.7.0-beta01 2022-08-11 22:02:38 +00:00
renovate[bot] 0b6f8d1d6f Update fragment_version to v1.5.2 (1.7.x.x) (#189)
Update fragment_version to v1.5.2

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-11 13:33:21 +08:00
renovate[bot] 0b283bb333 Update dependency androidx.recyclerview:recyclerview to v1.3.0-beta02 (1.7.x.x) (#187)
Update dependency androidx.recyclerview:recyclerview to v1.3.0-beta02

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-11 13:21:34 +08:00
renovate[bot] c74ee2b5cb Update dependency androidx.webkit:webkit to v1.5.0-rc01 (1.7.x.x) (#188)
Update dependency androidx.webkit:webkit to v1.5.0-rc01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-11 13:21:19 +08:00
renovate[bot] 8263dce3ca Update core_version to v1.9.0-beta01 (1.7.x.x) (#185)
Update core_version to v1.9.0-beta01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-11 12:53:03 +08:00
renovate[bot] a37e5e1ab3 Update dependency androidx.appcompat:appcompat to v1.6.0-beta01 (1.7.x.x) (#186)
Update dependency androidx.appcompat:appcompat to v1.6.0-beta01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-11 12:52:47 +08:00
txyyh 0baad6c042 Disable blank issue 2022-08-11 01:33:03 +00:00
renovate[bot] a2da9ffea6 Update activity_version to v1.6.0-beta01 (1.7.x.x) (#184)
Update activity_version to v1.6.0-beta01

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-11 09:10:51 +08:00
txyyh 4f3668dae4 Fix submodule error 2022-08-10 12:57:58 +00:00
txyyh 2598b68b97 Add LICENSE header 2022-08-10 12:44:56 +00:00
txyyh 7d065fb5c5 Use ic_launcher_foreground on scene_login (#174) 2022-08-10 17:10:47 +08:00
txyyh c4cc089eca Use new icon (#173)
* Use new icon

* Add monochrome icon

* Add LICENSE header
2022-08-10 17:10:47 +08:00
txyyh 85c377713d Only build CI on branches (#171) 2022-08-08 01:05:14 +08:00
renovate[bot] 3e7a1d9d35 Update dependency gradle to v7.5.1 (1.7.x.x) (#168)
Update dependency gradle to v7.5.1

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-06 07:42:36 +08:00
txyyh b0e9d8ec66 Fix wrong thanks 2022-08-05 18:33:18 +08:00
txyyh c25163b3c4 Revert "Use O3 optimization"
This reverts commit d396cae207.
2022-08-05 18:31:19 +08:00
txyyh 12d5aa9e08 Fix wrong TOC 2022-08-05 16:33:34 +08:00
txyyh 9fe1743dd9 Fix wrong Download section 2022-08-05 16:25:55 +08:00
txyyh e178880eb4 Add mult-language README and markdown TOC (#165)
* Add mult-language README

* Add markdown TOC

* Add language selection to README

* Fix wrong branch name in README
2022-08-05 15:48:17 +08:00
txyyh 0abab346ab Delete useless string (#161) 2022-08-05 15:25:16 +08:00
EdwardWuandtarsin 63d355ad95 fixup! Ehviewer: Add Chinese(Traditional) Translate (#160)
* Ehviewer: Add Chinese(Traditional) Translate

Signed-off-by: Edward Wu <bluehome.wu@gmail.com>

* fixup! Ehviewer: Add Chinese(Traditional) Translate

Signed-off-by: Edward Wu <bluehome.wu@gmail.com>

Co-authored-by: tarsin <43900799+asuka-mio@users.noreply.github.com>
2022-08-05 15:25:03 +08:00
renovate[bot] 17ab6c7532 Update plugin com.android.application to v7.2.2 (1.7.x.x) (#163)
Update plugin com.android.application to v7.2.2

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-04 04:59:20 +08:00
txyyhandEdwardWu 8d82fc39f6 Ehviewer: Add Chinese(Traditional) Translate (#158)
Signed-off-by: Edward Wu <bluehome.wu@gmail.com>

Co-authored-by: EdwardWu <56945729+bluehomewu@users.noreply.github.com>
2022-08-03 21:30:14 +08:00
tarsin d396cae207 Use O3 optimization 2022-08-02 14:21:41 +08:00
tarsin ec96ca2d7c Update README.md 2022-08-02 14:13:29 +08:00
LaLucid fa2279e480 update CI (#155)
* update CI

* do not need setup-android
2022-08-02 14:13:20 +08:00
txyyh de5b77cc96 Rewrite download section in README (#151)
* Delete CI Download in README

* Add Chinese NOTE

* Add English NOTE

* Use icon for github download
2022-07-31 12:34:41 +08:00
txyyh 41a54b76bf Release 1.7.29.3
CI / Build (push) Has been cancelled
Releases / Build (push) Has been cancelled
2022-07-31 00:16:18 +08:00
txyyh a09940eb86 Turn app link dialog to acquire update (#147) 2022-07-30 23:49:57 +08:00
txyyh 159b8c13b0 Fix archive open error (#145)
This reverts commit d2aecb5eb5 and use https://github.com/Ehviewer-Overhauled/Ehviewer/commit/d2aecb5eb5e25fd5a50726485fd53de178d45aa9#r79616069
2022-07-28 14:54:49 +08:00
renovate[bot] 498d51ec22 Update fragment_version to v1.5.1 (#141)
Update fragment_version to v1.5.1

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-28 04:25:44 +08:00
renovate[bot] 24e50da7c9 Update collection_version to v1.3.0-alpha02 (#140)
Update collection_version to v1.3.0-alpha02

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-28 04:25:05 +08:00
tarsin fcc595d9a3 Drop taptargetview
* Not MD3
2022-07-25 23:13:27 +08:00
tarsin d2aecb5eb5 Log tweaks 2022-07-25 23:09:50 +08:00
txyyh e2cfa30052 Release 1.7.29.2
CI / Build (push) Has been cancelled
Releases / Build (push) Has been cancelled
2022-07-25 14:54:18 +08:00
79 changed files with 1219 additions and 1168 deletions

No files matched your search

+26 -4
View File
@@ -1,8 +1,17 @@
name: Bug 反馈 / Bug report name: Bug 反馈 / Bug report
description: 提交一个问题报告 / Create a bug report to help us improve description: 提交一个问题报告 / Create a bug report
labels: labels:
- "bug" - "bug"
body: body:
- type: markdown
attributes:
value: |
感谢您愿意为 Ehviewer-Overhauled 做出贡献!
提交问题报告前,还请首先完成文末的自查步骤
Thanks for your contribution on Ehviewer-Overhauled Project!
Please finish verify steps which list in the end first before create bug report
- type: textarea - type: textarea
id: reproduce id: reproduce
attributes: attributes:
@@ -44,12 +53,25 @@ body:
validations: validations:
required: true required: true
- type: textarea
id: more
attributes:
label: 备注 / Addition details
description: |
在此处写下其他您想说的内容
Describe addition details here
placeholder: |
其他有用的信息与附件
Additional details and attachments
validations:
required: false
- type: input - type: input
id: version id: version
attributes: attributes:
label: EhViewer 版本号 / EhViewer version code label: EhViewer 版本号 / EhViewer version code
description: 您可以在设置 - 关于处找到版本号 / You can get version code in Settings - About description: 您可以在设置 - 关于处找到版本号 / You can get version code in Settings - About
placeholder: 四位版本号 / 4 digits version code placeholder: 1.6.9.13
validations: validations:
required: true required: true
@@ -57,7 +79,7 @@ body:
id: ci id: ci
attributes: attributes:
label: EhViewer CI 版本 / EhViewer CI Version label: EhViewer CI 版本 / EhViewer CI Version
description: 直接将对应 CI 下载页面网址填入即可 / Simply drop CI download page url here description: 直接将对应 GitHub Action CI 下载页面网址填入即可 / Simply drop GitHub Action CI download page url here
placeholder: https://github.com/Ehviewer-Overhauled/Ehviewer/actions/runs/XXXXXXXXXX placeholder: https://github.com/Ehviewer-Overhauled/Ehviewer/actions/runs/XXXXXXXXXX
validations: validations:
required: true required: true
@@ -119,4 +141,4 @@ body:
required: true required: true
- label: 您确保已使用最新 CI 版本测试,并且该问题在最新 CI 版本中并未解决 / This bug have not solved in latest CI version - label: 您确保已使用最新 CI 版本测试,并且该问题在最新 CI 版本中并未解决 / This bug have not solved in latest CI version
required: true required: true
+1
View File
@@ -1,3 +1,4 @@
blank_issues_enabled: false
contact_links: contact_links:
- name: 所有其他问题 / All other questions - name: 所有其他问题 / All other questions
url: https://github.com/Ehviewer-Overhauled/Ehviewer/discussions url: https://github.com/Ehviewer-Overhauled/Ehviewer/discussions
+14 -5
View File
@@ -1,8 +1,17 @@
name: 功能请求 / Feature request name: 功能请求 / Feature request
description: 提出一个功能建议 / Suggest an idea for this project description: 提出一个功能建议 / Suggest an idea
labels: labels:
- "enhancement" - "enhancement"
body: body:
- type: markdown
attributes:
value: |
感谢您愿意为 Ehviewer-Overhauled 做出贡献!
提交功能建议前,还请首先完成文末的自查步骤
Thanks for your contribution on Ehviewer-Overhauled Project!
Please finish verify steps which list in the end first before suggest an idea
- type: textarea - type: textarea
id: request id: request
attributes: attributes:
@@ -33,7 +42,7 @@ body:
- type: textarea - type: textarea
id: more id: more
attributes: attributes:
label: 其他细节 / Addition details label: 备注 / Addition details
description: | description: |
在此处写下其他您想说的内容 在此处写下其他您想说的内容
Describe addition details here Describe addition details here
@@ -48,7 +57,7 @@ body:
attributes: attributes:
label: EhViewer 版本号 / EhViewer version code label: EhViewer 版本号 / EhViewer version code
description: 您可以在设置 - 关于处找到版本号 / You can get version code in Settings - About description: 您可以在设置 - 关于处找到版本号 / You can get version code in Settings - About
placeholder: 四位版本号 / 4 digits version code placeholder: 1.6.9.13
validations: validations:
required: true required: true
@@ -56,7 +65,7 @@ body:
id: ci id: ci
attributes: attributes:
label: EhViewer CI 版本 / EhViewer CI Version label: EhViewer CI 版本 / EhViewer CI Version
description: 直接将对应 CI 下载页面网址填入即可 / Simply drop CI download page url here description: 直接将对应 GitHub Action CI 下载页面网址填入即可 / Simply drop GitHub Action CI download page url here
placeholder: https://github.com/Ehviewer-Overhauled/Ehviewer/actions/runs/XXXXXXXXXX placeholder: https://github.com/Ehviewer-Overhauled/Ehviewer/actions/runs/XXXXXXXXXX
validations: validations:
required: true required: true
@@ -82,4 +91,4 @@ body:
required: true required: true
- label: 您确保已使用最新 CI 版本测试,并且该功能在最新 CI 版本中并未按照预期实现 / This feature don't implement correctly in latest CI version - label: 您确保已使用最新 CI 版本测试,并且该功能在最新 CI 版本中并未按照预期实现 / This feature don't implement correctly in latest CI version
required: true required: true
+11 -7
View File
@@ -1,6 +1,11 @@
name: CI name: CI
on: [push] on:
push:
branches:
- '*'
tags-ignore:
- "*"
jobs: jobs:
linux: linux:
@@ -9,6 +14,8 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Setup Java 11 - name: Setup Java 11
uses: actions/setup-java@v3 uses: actions/setup-java@v3
@@ -16,18 +23,15 @@ jobs:
distribution: temurin distribution: temurin
java-version: 11 java-version: 11
- name: Setup Android SDK Tools
uses: android-actions/setup-android@v2
- name: Install NDK - name: Install NDK
run: | run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.0.8775105" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.0.8775105" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
- name: Gradle Build - name: Gradle Build
uses: gradle/gradle-build-action@v2 uses: gradle/gradle-build-action@v2
- run: | with:
git submodule update --init --recursive gradle-home-cache-cleanup: true
gradle assembleRelease arguments: assembleRelease
- name: Update ARM64 - name: Update ARM64
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
+4 -6
View File
@@ -9,6 +9,8 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Setup Java 11 - name: Setup Java 11
uses: actions/setup-java@v3 uses: actions/setup-java@v3
@@ -16,18 +18,14 @@ jobs:
distribution: temurin distribution: temurin
java-version: 11 java-version: 11
- name: Setup Android SDK Tools
uses: android-actions/setup-android@v2
- name: Install NDK - name: Install NDK
run: | run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.0.8775105" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.0.8775105" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
- name: Gradle Build - name: Gradle Build
uses: gradle/gradle-build-action@v2 uses: gradle/gradle-build-action@v2
- run: | with:
git submodule update --init --recursive arguments: assembleRelease
gradle assembleRelease
- name: Update ARM64 - name: Update ARM64
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
+18 -11
View File
@@ -12,6 +12,8 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Setup Java 11 - name: Setup Java 11
uses: actions/setup-java@v3 uses: actions/setup-java@v3
@@ -19,26 +21,31 @@ jobs:
distribution: temurin distribution: temurin
java-version: 11 java-version: 11
- name: Setup Android SDK Tools
uses: android-actions/setup-android@v2
- name: Install NDK - name: Install NDK
run: | run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.0.8775105" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;25.0.8775105" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
- name: Gradle Build - name: Gradle Build
uses: gradle/gradle-build-action@v2 uses: gradle/gradle-build-action@v2
- run: | with:
git submodule update --init --recursive arguments: assembleRelease
gradle assembleRelease
- name: Rename Apks
run: |
cp app/build/outputs/apk/release/app-universal-release.apk app/build/outputs/apk/release/EhViewer-universal-A11-.apk
cp app/build/outputs/apk/release/app-arm64-v8a-release.apk app/build/outputs/apk/release/EhViewer-arm64-v8a-A11-.apk
cp app/build/outputs/apk/release/app-x86_64-release.apk app/build/outputs/apk/release/EhViewer-x86_64-A11-.apk
cp app/build/outputs/apk/release/app-x86-release.apk app/build/outputs/apk/release/EhViewer-x86-A11-.apk
cp app/build/outputs/apk/release/app-armeabi-v7a-release.apk app/build/outputs/apk/release/EhViewer-armeabi-v7a-A11-.apk
- name: Releases - name: Releases
uses: softprops/action-gh-release@v0.1.14 uses: softprops/action-gh-release@v1
with: with:
body: Bump Version body: Bump Version
discussion_category_name: Announcements discussion_category_name: Announcements
files: | files: |
app/build/outputs/apk/release/app-arm64-v8a-release.apk app/build/outputs/apk/release/EhViewer-universal-A11-.apk
app/build/outputs/apk/release/app-x86_64-release.apk app/build/outputs/apk/release/EhViewer-arm64-v8a-A11-.apk
app/build/outputs/apk/release/app-x86-release.apk app/build/outputs/apk/release/EhViewer-x86_64-A11-.apk
app/build/outputs/apk/release/app-armeabi-v7a-release.apk app/build/outputs/apk/release/EhViewer-x86-A11-.apk
app/build/outputs/apk/release/EhViewer-armeabi-v7a-A11-.apk
+44 -14
View File
@@ -1,5 +1,17 @@
<p align="right">
<strong>English<strong>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-cn.md">
简体中文
</a>
<span> | <span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-tw.md">
正體中文
</a>
</p>
<h1 align="center"> <h1 align="center">
<img src="art/launcher_icon-web.png" width="200"> <img src="art/launcher_icon-web.svg" width="200">
<br>EhViewer<br> <br>EhViewer<br>
</h1> </h1>
@@ -7,7 +19,7 @@
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml"> <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"> <img src="https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml/badge.svg" alt="Github Actions">
</a> </a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/master/LICENSE"> <a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/LICENSE">
<img src="https://img.shields.io/github/license/Ehviewer-Overhauled/Ehviewer" alt="LICENSE"> <img src="https://img.shields.io/github/license/Ehviewer-Overhauled/Ehviewer" alt="LICENSE">
</a> </a>
<a href="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer"> <a href="https://www.codefactor.io/repository/github/Ehviewer-Overhauled/ehviewer">
@@ -21,22 +33,42 @@
</a> </a>
</p> </p>
<div align="center">
<h3>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/tree/1.7.x.x#description">
Description
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/tree/1.7.x.x#download">
Download
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/tree/1.7.x.x#screenshot">
Screenshot
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/tree/1.7.x.x#thanks">
Thanks
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/tree/1.7.x.x#license">
License
</a>
</h3>
</div>
# Description # Description
致力于轻量化与良好性能表现的 EhViewer 分支
已针对性适配 Material Design 3 及其动态取色系统
EhViewer fork dedicated to lightweight and high-performance EhViewer fork dedicated to lightweight and high-performance
with Material Design 3 and Dynamic Color Support with Material Design 3 and Dynamic Color Support
# Download # Download
[Github 下载](https://github.com/Ehviewer-Overhauled/Ehviewer/releases) <a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on Github" src="art/get-it-on-github.svg" width="200px"/></a>
[CI 版本下载(需登录)](https://github.com/Ehviewer-Overhauled/Ehviewer/actions/workflows/ci.yml) App is divided into two versions: 1.7 and 1.8 . Version 1.8 support Android 12 and above, also the develop mainline. Version 1.7 support Android 11 and below, drop down some spicetify functions for Android 12 to make app useable on lower Android System
# Screenshot # Screenshot
@@ -45,12 +77,11 @@ with Material Design 3 and Dynamic Color Support
# Thanks # Thanks
本项目受到了诸多开源项目的帮助
Here is the libraries Here is the libraries
- [AOSP](http://source.android.com/) - [AOSP & AndroidX](http://source.android.com/)
- [android-advancedrecyclerview](https://github.com/h6ah4i/android-advancedrecyclerview) - [FullDraggableDrawer](https://github.com/PureWriter/FullDraggableDrawer)
- [GnuTLS](https://gnutls.org/)
- [material-components-android](https://github.com/material-components/material-components-android) - [material-components-android](https://github.com/material-components/material-components-android)
- [material-design-icons](https://github.com/google/material-design-icons) - [material-design-icons](https://github.com/google/material-design-icons)
- [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/) - [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/)
@@ -62,7 +93,6 @@ Here is the libraries
- [libpng](http://www.libpng.org/pub/png/libpng.html) - [libpng](http://www.libpng.org/pub/png/libpng.html)
- [okhttp](https://github.com/square/okhttp) - [okhttp](https://github.com/square/okhttp)
- [roaster](https://github.com/forge/roaster) - [roaster](https://github.com/forge/roaster)
- [TapTargetView](https://github.com/KeepSafe/TapTargetView)
- [libarchive](http://www.libarchive.org/) - [libarchive](http://www.libarchive.org/)
- [XZ Utils](https://tukaani.org/xz/) - [XZ Utils](https://tukaani.org/xz/)
+25 -21
View File
@@ -18,6 +18,7 @@ android {
enable = true enable = true
reset() reset()
include 'arm64-v8a', 'x86_64', 'armeabi-v7a', 'x86' include 'arm64-v8a', 'x86_64', 'armeabi-v7a', 'x86'
universalApk = true
} }
} }
@@ -34,8 +35,8 @@ android {
applicationId "moe.tarsin.ehviewer" applicationId "moe.tarsin.ehviewer"
minSdkVersion 26 minSdkVersion 26
targetSdkVersion 33 targetSdkVersion 33
versionCode 114533 versionCode 114537
versionName "1.7.29.1" versionName "1.7.31.0-alpha02"
resConfigs 'zh', 'zh-rCN', 'zh-rHK', 'zh-rTW', 'es', 'ja', 'ko', 'fr', 'de', 'th' resConfigs 'zh', 'zh-rCN', 'zh-rHK', 'zh-rTW', 'es', 'ja', 'ko', 'fr', 'de', 'th'
} }
@@ -92,42 +93,42 @@ tasks.withType(JavaCompile) {
} }
dependencies { dependencies {
def activity_version = "1.6.0-alpha05" def activity_version = "1.6.1"
implementation "androidx.activity:activity:$activity_version" implementation "androidx.activity:activity:$activity_version"
implementation "androidx.activity:activity-ktx:$activity_version" implementation "androidx.activity:activity-ktx:$activity_version"
implementation "androidx.annotation:annotation:1.4.0" implementation "androidx.annotation:annotation:1.5.0"
implementation "androidx.annotation:annotation-experimental:1.2.0" implementation "androidx.annotation:annotation-experimental:1.3.0"
implementation "androidx.appcompat:appcompat:1.6.0-alpha05" implementation "androidx.appcompat:appcompat:1.6.0-rc01"
def arch_core_version = "2.1.0" def arch_core_version = "2.1.0"
implementation "androidx.arch.core:core-common:$arch_core_version" implementation "androidx.arch.core:core-common:$arch_core_version"
implementation "androidx.arch.core:core-runtime:$arch_core_version" implementation "androidx.arch.core:core-runtime:$arch_core_version"
implementation "androidx.biometric:biometric-ktx:1.2.0-alpha04" implementation "androidx.biometric:biometric-ktx:1.2.0-alpha05"
implementation "androidx.browser:browser:1.4.0" implementation "androidx.browser:browser:1.4.0"
def collection_version = "1.3.0-alpha01" def collection_version = "1.3.0-alpha02"
implementation "androidx.collection:collection:$collection_version" implementation "androidx.collection:collection:$collection_version"
implementation "androidx.collection:collection-ktx:$collection_version" implementation "androidx.collection:collection-ktx:$collection_version"
implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha03" implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha04"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0" implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
def core_version = "1.9.0-alpha05" def core_version = "1.9.0"
implementation "androidx.core:core:$core_version" implementation "androidx.core:core:$core_version"
implementation "androidx.core:core-ktx:$core_version" implementation "androidx.core:core-ktx:$core_version"
implementation "androidx.customview:customview:1.2.0-alpha01" implementation "androidx.customview:customview:1.2.0-alpha02"
implementation "androidx.documentfile:documentfile:1.1.0-alpha01" implementation "androidx.documentfile:documentfile:1.1.0-alpha01"
implementation "androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03" implementation "androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03"
def fragment_version = "1.5.0" def fragment_version = "1.5.4"
implementation "androidx.fragment:fragment:$fragment_version" implementation "androidx.fragment:fragment:$fragment_version"
implementation "androidx.fragment:fragment-ktx:$fragment_version" implementation "androidx.fragment:fragment-ktx:$fragment_version"
def lifecycle_version = "2.6.0-alpha01" def lifecycle_version = "2.6.0-alpha03"
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-core-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-livedata-core-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
@@ -136,7 +137,7 @@ dependencies {
implementation "androidx.loader:loader:1.1.0" implementation "androidx.loader:loader:1.1.0"
implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.preference:preference:1.2.0'
implementation 'androidx.recyclerview:recyclerview:1.3.0-beta01' implementation 'androidx.recyclerview:recyclerview:1.3.0-rc01'
implementation 'androidx.startup:startup-runtime:1.2.0-alpha01' implementation 'androidx.startup:startup-runtime:1.2.0-alpha01'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01'
implementation "androidx.transition:transition-ktx:1.4.1" implementation "androidx.transition:transition-ktx:1.4.1"
@@ -144,20 +145,23 @@ dependencies {
implementation "androidx.vectordrawable:vectordrawable-animated:1.1.0" implementation "androidx.vectordrawable:vectordrawable-animated:1.1.0"
implementation 'androidx.viewpager:viewpager:1.1.0-alpha01' implementation 'androidx.viewpager:viewpager:1.1.0-alpha01'
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01' implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
implementation 'androidx.webkit:webkit:1.5.0-beta01' implementation 'androidx.webkit:webkit:1.5.0'
implementation 'com.drakeet.drawer:drawer:1.0.3' implementation 'com.drakeet.drawer:drawer:1.0.3'
implementation 'com.google.android.material:material:1.7.0-alpha03' implementation 'com.google.android.material:material:1.8.0-alpha02'
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.3'
implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0' implementation 'com.squareup.okhttp3:okhttp-bom:5.0.0-alpha.10'
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.10' implementation 'com.squareup.okhttp3:okhttp'
implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps'
implementation 'dev.rikka.rikkax.core:core-ktx:1.4.1' implementation 'dev.rikka.rikkax.core:core-ktx:1.4.1'
implementation 'dev.rikka.rikkax.insets:insets:1.3.0' implementation 'dev.rikka.rikkax.insets:insets:1.3.0'
implementation 'dev.rikka.rikkax.layoutinflater:layoutinflater:1.2.0' implementation 'dev.rikka.rikkax.layoutinflater:layoutinflater:1.2.0'
implementation 'dev.rikka.rikkax.preference:simplemenu-preference:1.0.3' implementation 'dev.rikka.rikkax.preference:simplemenu-preference:1.0.3'
implementation 'dev.rikka.rikkax.material:material-preference:2.0.0' implementation 'dev.rikka.rikkax.material:material-preference:2.0.0'
implementation 'org.greenrobot:greendao:3.3.0' implementation 'org.greenrobot:greendao:3.3.0'
implementation 'org.jsoup:jsoup:1.15.2' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'org.jsoup:jsoup:1.15.3'
implementation projects.native implementation projects.native
} }
@@ -51,7 +51,6 @@ public final class ConacoTask<V> {
private final WeakReference<Unikery<V>> mUnikeryWeakReference; private final WeakReference<Unikery<V>> mUnikeryWeakReference;
private final String mKey; private final String mKey;
private final String mUrl; private final String mUrl;
private final DataContainer mDataContainer;
private final boolean mUseMemoryCache; private final boolean mUseMemoryCache;
private final boolean mUseDiskCache; private final boolean mUseDiskCache;
private final boolean mUseNetwork; private final boolean mUseNetwork;
@@ -73,7 +72,6 @@ public final class ConacoTask<V> {
mUnikeryWeakReference = new WeakReference<>(builder.mUnikery); mUnikeryWeakReference = new WeakReference<>(builder.mUnikery);
mKey = builder.mKey; mKey = builder.mKey;
mUrl = builder.mUrl; mUrl = builder.mUrl;
mDataContainer = builder.mDataContainer;
mUseMemoryCache = builder.mUseMemoryCache; mUseMemoryCache = builder.mUseMemoryCache;
mUseDiskCache = builder.mUseDiskCache; mUseDiskCache = builder.mUseDiskCache;
mUseNetwork = builder.mUseNetwork; mUseNetwork = builder.mUseNetwork;
@@ -85,42 +83,6 @@ public final class ConacoTask<V> {
mConaco = builder.mConaco; mConaco = builder.mConaco;
} }
private static void putFromDiskCacheToDataContainer(String key, ValueCache cache, DataContainer container) {
SimpleDiskCache diskCache = cache.getDiskCache();
if (diskCache != null) {
InputStreamPipe pipe = diskCache.getInputStreamPipe(key);
if (pipe != null) {
try {
pipe.obtain();
container.save(pipe.open(), -1L, null, null);
} catch (IOException e) {
Log.d(TAG, "Can't save value from disk cache to data container");
e.printStackTrace();
container.remove();
} finally {
pipe.close();
pipe.release();
}
}
}
}
private static void putFromDataContainerToDiskCache(String key, ValueCache cache, DataContainer container) {
InputStreamPipe pipe = container.get();
if (pipe != null) {
try {
pipe.obtain();
cache.putRawToDisk(key, pipe.open());
} catch (IOException e) {
Log.w(TAG, "Can't save value from data container to disk cache", e);
cache.removeFromDisk(key);
} finally {
pipe.close();
pipe.release();
}
}
}
int getId() { int getId() {
return mId; return mId;
} }
@@ -219,7 +181,6 @@ public final class ConacoTask<V> {
private Unikery<T> mUnikery; private Unikery<T> mUnikery;
private String mKey; private String mKey;
private String mUrl; private String mUrl;
private DataContainer mDataContainer;
private boolean mUseMemoryCache = true; private boolean mUseMemoryCache = true;
private boolean mUseDiskCache = true; private boolean mUseDiskCache = true;
private boolean mUseNetwork = true; private boolean mUseNetwork = true;
@@ -262,11 +223,6 @@ public final class ConacoTask<V> {
return this; return this;
} }
public Builder<T> setDataContainer(DataContainer dataContainer) {
mDataContainer = dataContainer;
return this;
}
boolean isUseMemoryCache() { boolean isUseMemoryCache() {
return mUseMemoryCache; return mUseMemoryCache;
} }
@@ -332,7 +288,7 @@ public final class ConacoTask<V> {
if (mUnikery == null) { if (mUnikery == null) {
throw new IllegalStateException("Must set unikery"); throw new IllegalStateException("Must set unikery");
} }
if (mKey == null && mUrl == null && mDataContainer == null) { if (mKey == null && mUrl == null) {
throw new IllegalStateException("At least one of mKey and mUrl and mDataContainer have to not be null"); throw new IllegalStateException("At least one of mKey and mUrl and mDataContainer have to not be null");
} }
} }
@@ -352,26 +308,13 @@ public final class ConacoTask<V> {
} else { } else {
V value = null; V value = null;
// First check data container
if (mDataContainer != null && mDataContainer.isEnabled()) {
InputStreamPipe isp = mDataContainer.get();
if (isp != null) {
value = mHelper.decode(isp);
}
}
// Then check disk cache // Then check disk cache
if (mKey != null) { if (mKey != null) {
if (value == null && mUseDiskCache) { if (value == null && mUseDiskCache) {
value = mCache.getFromDisk(mKey); value = mCache.getFromDisk(mKey);
// Put back to data container
if (value != null && mDataContainer != null && mDataContainer.isEnabled()) {
putFromDiskCacheToDataContainer(mKey, mCache, mDataContainer);
}
} }
if (value != null && mUseMemoryCache && mHelper.useMemoryCache(mKey, value)) { if (value != null && mUseMemoryCache && mHelper.useMemoryCache(mKey, value)) {
// Put it to memory
mCache.putToMemory(mKey, value); mCache.putToMemory(mKey, value);
} }
} }
@@ -451,18 +394,6 @@ public final class ConacoTask<V> {
} }
} }
private boolean putToDataContainer(InputStream is, ResponseBody body) {
// Get media type
String mediaType;
MediaType mt = body.contentType();
if (mt != null) {
mediaType = mt.type() + '/' + mt.subtype();
} else {
mediaType = null;
}
return mDataContainer.save(is, body.contentLength(), mediaType, this);
}
@Override @Override
protected V doInBackground(Void... params) { protected V doInBackground(Void... params) {
if (isNotNecessary(this)) { if (isNotNecessary(this)) {
@@ -489,7 +420,7 @@ public final class ConacoTask<V> {
return null; return null;
} }
if ((mDataContainer == null || !mDataContainer.isEnabled()) && mKey != null) { if (mKey != null) {
if (putToDiskCache(is, body.contentLength())) { if (putToDiskCache(is, body.contentLength())) {
// Get object from disk cache // Get object from disk cache
value = mCache.getFromDisk(mKey); value = mCache.getFromDisk(mKey);
@@ -506,37 +437,6 @@ public final class ConacoTask<V> {
mCache.removeFromDisk(mKey); mCache.removeFromDisk(mKey);
return null; return null;
} }
} else if (mDataContainer != null && mDataContainer.isEnabled()) {
// Check url Moved
HttpUrl requestHttpUrl = request.url();
HttpUrl responseHttpUrl = response.request().url();
if (!responseHttpUrl.equals(requestHttpUrl)) {
mDataContainer.onUrlMoved(mUrl, responseHttpUrl.url().toString());
}
// Put to data container
if (!putToDataContainer(is, body)) {
return null;
}
// Get value from data container
InputStreamPipe isp = mDataContainer.get();
if (isp == null) {
return null;
}
value = mHelper.decode(isp);
if (value == null) {
mDataContainer.remove();
} else if (mKey != null) {
// Put to disk cache
putFromDataContainerToDiskCache(mKey, mCache, mDataContainer);
if (mUseMemoryCache && mHelper.useMemoryCache(mKey, value)) {
// Put it to memory
mCache.putToMemory(mKey, value);
}
}
return value;
} else { } else {
return null; return null;
} }
@@ -1,52 +0,0 @@
/*
* Copyright 2015-2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.conaco;
import androidx.annotation.Nullable;
import com.hippo.streampipe.InputStreamPipe;
import java.io.InputStream;
public interface DataContainer {
/**
* Returns the enabled status for this DataContainer.
*/
boolean isEnabled();
/**
* Get 304 or something like that
*/
void onUrlMoved(String requestUrl, String responseUrl);
/**
* Save the {@code InputStream}
*/
boolean save(InputStream is, long length, @Nullable String mediaType, @Nullable ProgressNotifier notify);
/**
* Get {@code InputStreamPipe} for saved before
*/
@Nullable
InputStreamPipe get();
/**
* Remove saved stuff
*/
void remove();
}
@@ -100,6 +100,11 @@ public class Settings {
private static final int DEFAULT_VERSION_CODE = 0; private static final int DEFAULT_VERSION_CODE = 0;
private static final String KEY_DISPLAY_NAME = "display_name"; private static final String KEY_DISPLAY_NAME = "display_name";
private static final String DEFAULT_DISPLAY_NAME = null; private static final String DEFAULT_DISPLAY_NAME = null;
public static final String KEY_LIST_THUMB_SIZE = "list_tile_size";
private static final int DEFAULT_LIST_THUMB_SIZE = 40;
private static int LIST_THUMB_SIZE = 40;
public static boolean LIST_THUMB_SIZE_INITED = false;
private static final String KEY_AVATAR = "avatar"; private static final String KEY_AVATAR = "avatar";
private static final String DEFAULT_AVATAR = null; private static final String DEFAULT_AVATAR = null;
private static final String KEY_SHOW_WARNING = "show_warning"; private static final String KEY_SHOW_WARNING = "show_warning";
@@ -1168,4 +1173,14 @@ public class Settings {
public static void putPasswdToArchivePasswds(String value) { public static void putPasswdToArchivePasswds(String value) {
putStringToStringSet(KEY_ARCHIVE_PASSWDS, value); putStringToStringSet(KEY_ARCHIVE_PASSWDS, value);
} }
public static int getListThumbSize() {
if (LIST_THUMB_SIZE_INITED) {
return LIST_THUMB_SIZE;
}
int size = 3 * getInt(KEY_LIST_THUMB_SIZE, DEFAULT_LIST_THUMB_SIZE);
LIST_THUMB_SIZE = size;
LIST_THUMB_SIZE_INITED = true;
return size;
}
} }
@@ -44,7 +44,7 @@ public class FavListUrlBuilder implements Parcelable {
} }
}; };
private static final String TAG = FavListUrlBuilder.class.getSimpleName(); private static final String TAG = FavListUrlBuilder.class.getSimpleName();
private int mIndex; private String mNext;
private String mKeyword; private String mKeyword;
private int mFavCat = FAV_CAT_ALL; private int mFavCat = FAV_CAT_ALL;
@@ -52,7 +52,7 @@ public class FavListUrlBuilder implements Parcelable {
} }
protected FavListUrlBuilder(Parcel in) { protected FavListUrlBuilder(Parcel in) {
this.mIndex = in.readInt(); this.mNext = in.readString();
this.mKeyword = in.readString(); this.mKeyword = in.readString();
this.mFavCat = in.readInt(); this.mFavCat = in.readInt();
} }
@@ -61,8 +61,8 @@ public class FavListUrlBuilder implements Parcelable {
return favCat >= 0 && favCat <= 9; return favCat >= 0 && favCat <= 9;
} }
public void setIndex(int index) { public void setNext(String next) {
mIndex = index; mNext = next;
} }
public String getKeyword() { public String getKeyword() {
@@ -105,8 +105,8 @@ public class FavListUrlBuilder implements Parcelable {
Log.e(TAG, "Can't URLEncoder.encode " + mKeyword); Log.e(TAG, "Can't URLEncoder.encode " + mKeyword);
} }
} }
if (mIndex > 0) { if (mNext != null && !mNext.isEmpty()) {
ub.addQuery("page", Integer.toString(mIndex)); ub.addQuery("next", mNext);
} }
return ub.build(); return ub.build();
} }
@@ -118,7 +118,7 @@ public class FavListUrlBuilder implements Parcelable {
@Override @Override
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.mIndex); dest.writeString(this.mNext);
dest.writeString(this.mKeyword); dest.writeString(this.mKeyword);
dest.writeInt(this.mFavCat); dest.writeInt(this.mFavCat);
} }
@@ -64,7 +64,8 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
@Mode @Mode
private int mMode = MODE_NORMAL; private int mMode = MODE_NORMAL;
private int mPageIndex = 0; private int mNextGid = 0;
private int mPrevGid = 0;
private int mCategory = EhUtils.NONE; private int mCategory = EhUtils.NONE;
private String mKeyword = null; private String mKeyword = null;
@@ -86,7 +87,8 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
@SuppressWarnings("WrongConstant") @SuppressWarnings("WrongConstant")
protected ListUrlBuilder(Parcel in) { protected ListUrlBuilder(Parcel in) {
this.mMode = in.readInt(); this.mMode = in.readInt();
this.mPageIndex = in.readInt(); this.mNextGid = in.readInt();
this.mPrevGid = in.readInt();
this.mCategory = in.readInt(); this.mCategory = in.readInt();
this.mKeyword = in.readString(); this.mKeyword = in.readString();
this.mAdvanceSearch = in.readInt(); this.mAdvanceSearch = in.readInt();
@@ -105,7 +107,8 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
*/ */
public void reset() { public void reset() {
mMode = MODE_NORMAL; mMode = MODE_NORMAL;
mPageIndex = 0; mNextGid = 0;
mPrevGid = 0;
mCategory = EhUtils.NONE; mCategory = EhUtils.NONE;
mKeyword = null; mKeyword = null;
mAdvanceSearch = -1; mAdvanceSearch = -1;
@@ -137,12 +140,12 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
mMode = mode; mMode = mode;
} }
public int getPageIndex() { public void setNextGid(int nextGid) {
return mPageIndex; mNextGid = nextGid;
} }
public void setPageIndex(int pageIndex) { public void setPrevGid(int prevGid) {
mPageIndex = pageIndex; mPrevGid = prevGid;
} }
public int getCategory() { public int getCategory() {
@@ -233,7 +236,8 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
*/ */
public void set(ListUrlBuilder lub) { public void set(ListUrlBuilder lub) {
mMode = lub.mMode; mMode = lub.mMode;
mPageIndex = lub.mPageIndex; mNextGid = lub.mNextGid;
mPrevGid = lub.mPrevGid;
mCategory = lub.mCategory; mCategory = lub.mCategory;
mKeyword = lub.mKeyword; mKeyword = lub.mKeyword;
mAdvanceSearch = lub.mAdvanceSearch; mAdvanceSearch = lub.mAdvanceSearch;
@@ -524,9 +528,11 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
if (mSHash != null) { if (mSHash != null) {
ub.addQuery("f_shash", mSHash); ub.addQuery("f_shash", mSHash);
} }
// Page index if (mNextGid != 0) {
if (mPageIndex != 0) { ub.addQuery("next", mNextGid);
ub.addQuery("page", mPageIndex); }
if (mPrevGid != 0) {
ub.addQuery("prev", mPrevGid);
} }
// Advance search // Advance search
if (mAdvanceSearch != -1) { if (mAdvanceSearch != -1) {
@@ -570,8 +576,8 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
// Empty // Empty
} }
if (mPageIndex != 0) { if (mNextGid != 0) {
sb.append('/').append(mPageIndex); sb.append("?next=").append(mNextGid);
} }
return sb.toString(); return sb.toString();
} }
@@ -583,8 +589,8 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
// Empty // Empty
} }
if (mPageIndex != 0) { if (mNextGid != 0) {
sb.append('/').append(mPageIndex); sb.append("?next=").append(mNextGid);
} }
return sb.toString(); return sb.toString();
} }
@@ -600,8 +606,8 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
// Empty // Empty
} }
if (mPageIndex != 0) { if (mNextGid != 0) {
sb.append("&p=").append(mPageIndex); sb.append("&p=").append(mNextGid);
} }
return sb.toString(); return sb.toString();
} }
@@ -615,7 +621,8 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
@Override @Override
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.mMode); dest.writeInt(this.mMode);
dest.writeInt(this.mPageIndex); dest.writeInt(this.mNextGid);
dest.writeInt(this.mPrevGid);
dest.writeInt(this.mCategory); dest.writeInt(this.mCategory);
dest.writeString(this.mKeyword); dest.writeString(this.mKeyword);
dest.writeInt(this.mAdvanceSearch); dest.writeInt(this.mAdvanceSearch);
@@ -31,8 +31,10 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
public class FavoritesParser { public class FavoritesParser {
private static final Pattern PATTERN_NEXT_PAGE = Pattern.compile("next=(\\d+-\\d+)");
public static Result parse(String body) throws Exception { public static Result parse(String body) throws Exception {
if (body.contains("This page requires you to log on.</p>")) { if (body.contains("This page requires you to log on.</p>")) {
@@ -59,14 +61,25 @@ public class FavoritesParser {
e.printStackTrace(); e.printStackTrace();
throw new ParseException("Parse favorites error", body); throw new ParseException("Parse favorites error", body);
} }
Result re = new Result();
try {
var d = Jsoup.parse(body);
var snv = d.getElementsByClass("searchnav").first();
assert snv != null;
var href = snv.child(3).child(0).attr("href");
var matcher = PATTERN_NEXT_PAGE.matcher(href);
if (matcher.find()) {
re.nextPage = matcher.group(1);
}
} catch (Throwable e) {
e.printStackTrace();
}
GalleryListParser.Result result = GalleryListParser.parse(body); GalleryListParser.Result result = GalleryListParser.parse(body);
Result re = new Result();
re.catArray = catArray; re.catArray = catArray;
re.countArray = countArray; re.countArray = countArray;
re.pages = result.pages;
re.nextPage = result.nextPage;
re.galleryInfoList = result.galleryInfoList; re.galleryInfoList = result.galleryInfoList;
return re; return re;
@@ -75,8 +88,7 @@ public class FavoritesParser {
public static class Result { public static class Result {
public String[] catArray; // Size 10 public String[] catArray; // Size 10
public int[] countArray; // Size 10 public int[] countArray; // Size 10
public int pages; public String nextPage;
public int nextPage;
public List<GalleryInfo> galleryInfoList; public List<GalleryInfo> galleryInfoList;
} }
} }
@@ -51,7 +51,8 @@ public class GalleryListParser {
private static final Pattern PATTERN_THUMB_SIZE = Pattern.compile("height:(\\d+)px;width:(\\d+)px"); private static final Pattern PATTERN_THUMB_SIZE = Pattern.compile("height:(\\d+)px;width:(\\d+)px");
private static final Pattern PATTERN_FAVORITE_SLOT = Pattern.compile("background-color:rgba\\((\\d+),(\\d+),(\\d+),"); private static final Pattern PATTERN_FAVORITE_SLOT = Pattern.compile("background-color:rgba\\((\\d+),(\\d+),(\\d+),");
private static final Pattern PATTERN_PAGES = Pattern.compile("(\\d+) page"); private static final Pattern PATTERN_PAGES = Pattern.compile("(\\d+) page");
private static final Pattern PATTERN_NEXT_PAGE = Pattern.compile("page=(\\d+)");
private static final Pattern PATTERN_GETINT = Pattern.compile("[^0-9]");
private static final String[][] FAVORITE_SLOT_RGB = new String[][]{ private static final String[][] FAVORITE_SLOT_RGB = new String[][]{
new String[]{"0", "0", "0"}, new String[]{"0", "0", "0"},
@@ -297,39 +298,21 @@ public class GalleryListParser {
return gi; return gi;
} }
private static int getInt(String str) {
var m = PATTERN_GETINT.matcher(str);
return Integer.parseInt(m.replaceAll("").trim());
}
public static Result parse(@NonNull String body) throws Exception { public static Result parse(@NonNull String body) throws Exception {
Result result = new Result(); Result result = new Result();
Document d = Jsoup.parse(body); Document d = Jsoup.parse(body);
try { result.founds = Integer.MAX_VALUE;
Element ptt = d.getElementsByClass("ptt").first(); result.noWatchedTags = body.contains("<p>You do not have any watched tags");
Elements es = ptt.child(0).child(0).children(); if (body.contains("No hits found</p>")) {
result.pages = Integer.parseInt(es.get(es.size() - 2).text().trim()); result.founds = 0;
result.galleryInfoList = Collections.EMPTY_LIST;
Element e = es.get(es.size() - 1); return result;
if (e != null) {
e = e.children().first();
if (e != null) {
String href = e.attr("href");
Matcher matcher = PATTERN_NEXT_PAGE.matcher(href);
if (matcher.find()) {
result.nextPage = NumberUtils.parseIntSafely(matcher.group(1), 0);
}
}
}
} catch (Throwable e) {
ExceptionUtils.throwIfFatal(e);
result.noWatchedTags = body.contains("<p>You do not have any watched tags");
if (body.contains("No hits found</p>")) {
result.pages = 0;
//noinspection unchecked
result.galleryInfoList = Collections.EMPTY_LIST;
return result;
} else if (d.getElementsByClass("ptt").isEmpty()) {
result.pages = 1;
} else {
result.pages = Integer.MAX_VALUE;
}
} }
try { try {
@@ -364,8 +347,7 @@ public class GalleryListParser {
} }
public static class Result { public static class Result {
public int pages; public int founds;
public int nextPage;
public boolean noWatchedTags; public boolean noWatchedTags;
public List<GalleryInfo> galleryInfoList; public List<GalleryInfo> galleryInfoList;
} }
@@ -45,6 +45,10 @@ import java.util.List;
public final class CommonOperations { public final class CommonOperations {
public static int getPagesForFounds(int founds, int per) {
return (int)Math.ceil((double) founds/per);
}
private static void doAddToFavorites(Activity activity, GalleryInfo galleryInfo, private static void doAddToFavorites(Activity activity, GalleryInfo galleryInfo,
int slot, EhClient.Callback<Void> listener) { int slot, EhClient.Callback<Void> listener) {
if (slot == -1) { if (slot == -1) {
@@ -394,17 +394,22 @@ public class GalleryActivity extends EhActivity implements SeekBar.OnSeekBarChan
} }
switch (event.getAction()) { switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL: case MotionEvent.ACTION_SCROLL:
if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f) { float scroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL) * 300;
if (scroll < 0.0f) {
if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) { if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) {
mGalleryView.pageLeft(); mGalleryView.pageLeft();
} else { } else if (mLayoutMode == GalleryView.LAYOUT_LEFT_TO_RIGHT){
mGalleryView.pageRight(); mGalleryView.pageRight();
} else if (mLayoutMode == GalleryView.LAYOUT_TOP_TO_BOTTOM) {
mGalleryView.onScroll(0, -scroll, 0, -scroll, 0, -scroll);
} }
} else { } else {
if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) { if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) {
mGalleryView.pageRight(); mGalleryView.pageRight();
} else { } else if (mLayoutMode == GalleryView.LAYOUT_LEFT_TO_RIGHT) {
mGalleryView.pageLeft(); mGalleryView.pageLeft();
} else if (mLayoutMode == GalleryView.LAYOUT_TOP_TO_BOTTOM) {
mGalleryView.onScroll(0, -scroll, 0, -scroll, 0, -scroll);
} }
} }
} }
@@ -307,7 +307,6 @@ public final class MainActivity extends StageActivity
mStageLayout = (EhStageLayout) ViewUtils.$$(this, R.id.fragment_container); mStageLayout = (EhStageLayout) ViewUtils.$$(this, R.id.fragment_container);
mDrawerLayout = (DrawerLayout) ViewUtils.$$(this, R.id.draw_view); mDrawerLayout = (DrawerLayout) ViewUtils.$$(this, R.id.draw_view);
mDrawerLayout.setStatusBarBackgroundColor(0);
mNavView = (NavigationView) ViewUtils.$$(this, R.id.nav_view); mNavView = (NavigationView) ViewUtils.$$(this, R.id.nav_view);
mRightDrawer = (DrawerView) ViewUtils.$$(this, R.id.right_drawer); mRightDrawer = (DrawerView) ViewUtils.$$(this, R.id.right_drawer);
@@ -1,68 +0,0 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.ui;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.snackbar.Snackbar;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.fragment.SettingsFragment;
import com.hippo.ehviewer.ui.scene.BaseScene;
public final class SettingsActivity extends EhActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preference);
setSupportActionBar(findViewById(R.id.toolbar));
ActionBar bar = getSupportActionBar();
if (bar != null) {
bar.setDisplayHomeAsUpEnabled(true);
}
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_MATCH_ACTIVITY_OPEN)
.replace(R.id.fragment, new SettingsFragment())
.commitAllowingStateLoss();
}
}
public void showTip(@StringRes int id, int length) {
showTip(getString(id), length);
}
public void showTip(CharSequence message, int length) {
Snackbar.make(findViewById(R.id.snackbar), message,
length == BaseScene.LENGTH_LONG ? Snackbar.LENGTH_LONG : Snackbar.LENGTH_SHORT).show();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}
@@ -0,0 +1,64 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.ui
import android.content.res.Configuration
import android.os.Bundle
import android.view.MenuItem
import androidx.annotation.StringRes
import androidx.core.view.WindowCompat
import androidx.fragment.app.FragmentTransaction
import com.google.android.material.snackbar.Snackbar
import com.hippo.ehviewer.R
import com.hippo.ehviewer.ui.fragment.SettingsFragment
import com.hippo.ehviewer.ui.scene.BaseScene
class SettingsActivity : EhActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_preference)
setSupportActionBar(findViewById(R.id.toolbar))
val bar = supportActionBar
bar?.setDisplayHomeAsUpEnabled(true)
WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES) <= 0
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_MATCH_ACTIVITY_OPEN)
.replace(R.id.fragment, SettingsFragment())
.commitAllowingStateLoss()
}
}
fun showTip(@StringRes id: Int, length: Int) {
showTip(getString(id), length)
}
fun showTip(message: CharSequence?, length: Int) {
Snackbar.make(
findViewById(R.id.snackbar), message!!,
if (length == BaseScene.LENGTH_LONG) Snackbar.LENGTH_LONG else Snackbar.LENGTH_SHORT
).show()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
}
}
@@ -17,12 +17,13 @@
package com.hippo.ehviewer.ui.fragment; package com.hippo.ehviewer.ui.fragment;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.util.Log;
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts;
@@ -39,6 +40,11 @@ import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.EhDB; import com.hippo.ehviewer.EhDB;
import com.hippo.ehviewer.GetText; import com.hippo.ehviewer.GetText;
import com.hippo.ehviewer.R; import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.ehviewer.client.EhClient;
import com.hippo.ehviewer.client.EhRequest;
import com.hippo.ehviewer.client.data.FavListUrlBuilder;
import com.hippo.ehviewer.client.parser.FavoritesParser;
import com.hippo.ehviewer.ui.scene.BaseScene; import com.hippo.ehviewer.ui.scene.BaseScene;
import com.hippo.util.ExceptionUtils; import com.hippo.util.ExceptionUtils;
import com.hippo.util.IoThreadPoolExecutor; import com.hippo.util.IoThreadPoolExecutor;
@@ -53,6 +59,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
@@ -64,6 +71,7 @@ public class AdvancedFragment extends BasePreferenceFragment {
private static final String KEY_IMPORT_DATA = "import_data"; private static final String KEY_IMPORT_DATA = "import_data";
private static final String KEY_EXPORT_DATA = "export_data"; private static final String KEY_EXPORT_DATA = "export_data";
private static final String KEY_OPEN_BY_DEFAULT = "open_by_default"; private static final String KEY_OPEN_BY_DEFAULT = "open_by_default";
private static final String KEY_BACKUP_FAVORITE = "backup_favorite";
ActivityResultLauncher<String> exportLauncher = registerForActivityResult( ActivityResultLauncher<String> exportLauncher = registerForActivityResult(
new ActivityResultContracts.CreateDocument(), new ActivityResultContracts.CreateDocument(),
@@ -231,6 +239,7 @@ public class AdvancedFragment extends BasePreferenceFragment {
Preference importData = findPreference(KEY_IMPORT_DATA); Preference importData = findPreference(KEY_IMPORT_DATA);
Preference exportData = findPreference(KEY_EXPORT_DATA); Preference exportData = findPreference(KEY_EXPORT_DATA);
Preference openByDefault = findPreference(KEY_OPEN_BY_DEFAULT); Preference openByDefault = findPreference(KEY_OPEN_BY_DEFAULT);
Preference backupFavorite = findPreference(KEY_BACKUP_FAVORITE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
openByDefault.setVisible(false); openByDefault.setVisible(false);
@@ -242,6 +251,7 @@ public class AdvancedFragment extends BasePreferenceFragment {
clearMemoryCache.setOnPreferenceClickListener(this); clearMemoryCache.setOnPreferenceClickListener(this);
importData.setOnPreferenceClickListener(this); importData.setOnPreferenceClickListener(this);
exportData.setOnPreferenceClickListener(this); exportData.setOnPreferenceClickListener(this);
backupFavorite.setOnPreferenceClickListener(this);
appLanguage.setOnPreferenceChangeListener(this); appLanguage.setOnPreferenceChangeListener(this);
} }
@@ -288,10 +298,62 @@ public class AdvancedFragment extends BasePreferenceFragment {
startActivity(intent); startActivity(intent);
} }
return true; return true;
} else if (KEY_BACKUP_FAVORITE.equals(key)) {
try {
showTip(R.string.backup_favorite_start, BaseScene.LENGTH_SHORT);
backupFavorite();
} catch (Exception e) {
ExceptionUtils.throwIfFatal(e);
showTip(R.string.backup_favorite_failed, BaseScene.LENGTH_SHORT);
}
return true;
} }
return false; return false;
} }
private void backupFavorite() {
AtomicInteger page = new AtomicInteger(0);
Context context = requireContext();
Activity activity = requireActivity();
EhClient mClient = EhApplication.getEhClient(context);
FavListUrlBuilder favListUrlBuilder = new FavListUrlBuilder();
// favListUrlBuilder.setNext(page.get());
EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_GET_FAVORITES);
request.setCallback(new EhClient.Callback() {
@Override
public void onSuccess(Object result) {
try {
FavoritesParser.Result result1 = (FavoritesParser.Result) result;
EhDB.putLocalFavorites(result1.galleryInfoList);
Log.d("LocalFavorites", "now backup page " + page.get());
if (!result1.galleryInfoList.isEmpty()) {
// favListUrlBuilder.setNext(page.incrementAndGet());
request.setArgs(favListUrlBuilder.build(), Settings.getShowJpnTitle());
mClient.execute(request);
} else {
showTip(R.string.backup_favorite_success, BaseScene.LENGTH_SHORT);
}
} catch (Exception e) {
showTip(R.string.backup_favorite_failed, BaseScene.LENGTH_SHORT);
}
}
@Override
public void onFailure(Exception e) {
showTip(R.string.backup_favorite_failed, BaseScene.LENGTH_SHORT);
}
@Override
public void onCancel() {
showTip(R.string.backup_favorite_failed, BaseScene.LENGTH_SHORT);
}
});
request.setArgs(favListUrlBuilder.build(), Settings.getShowJpnTitle());
mClient.execute(request);
}
@Override @Override
public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceChange(Preference preference, Object newValue) {
String key = preference.getKey(); String key = preference.getKey();
@@ -38,6 +38,7 @@ public class EhFragment extends BasePreferenceFragment {
Preference blackDarkTheme = findPreference(Settings.KEY_BLACK_DARK_THEME); Preference blackDarkTheme = findPreference(Settings.KEY_BLACK_DARK_THEME);
Preference gallerySite = findPreference(Settings.KEY_GALLERY_SITE); Preference gallerySite = findPreference(Settings.KEY_GALLERY_SITE);
Preference listMode = findPreference(Settings.KEY_LIST_MODE); Preference listMode = findPreference(Settings.KEY_LIST_MODE);
Preference listThumbSize = findPreference(Settings.KEY_LIST_THUMB_SIZE);
Preference detailSize = findPreference(Settings.KEY_DETAIL_SIZE); Preference detailSize = findPreference(Settings.KEY_DETAIL_SIZE);
Preference thumbSize = findPreference(Settings.KEY_THUMB_SIZE); Preference thumbSize = findPreference(Settings.KEY_THUMB_SIZE);
Preference showTagTranslations = findPreference(Settings.KEY_SHOW_TAG_TRANSLATIONS); Preference showTagTranslations = findPreference(Settings.KEY_SHOW_TAG_TRANSLATIONS);
@@ -46,6 +47,7 @@ public class EhFragment extends BasePreferenceFragment {
theme.setOnPreferenceChangeListener(this); theme.setOnPreferenceChangeListener(this);
gallerySite.setOnPreferenceChangeListener(this); gallerySite.setOnPreferenceChangeListener(this);
listMode.setOnPreferenceChangeListener(this); listMode.setOnPreferenceChangeListener(this);
listThumbSize.setOnPreferenceChangeListener(this);
detailSize.setOnPreferenceChangeListener(this); detailSize.setOnPreferenceChangeListener(this);
thumbSize.setOnPreferenceChangeListener(this); thumbSize.setOnPreferenceChangeListener(this);
showTagTranslations.setOnPreferenceChangeListener(this); showTagTranslations.setOnPreferenceChangeListener(this);
@@ -70,6 +72,10 @@ public class EhFragment extends BasePreferenceFragment {
} else if (Settings.KEY_LIST_MODE.equals(key)) { } else if (Settings.KEY_LIST_MODE.equals(key)) {
requireActivity().setResult(Activity.RESULT_OK); requireActivity().setResult(Activity.RESULT_OK);
return true; return true;
} else if (Settings.KEY_LIST_THUMB_SIZE.equals(key)) {
Settings.LIST_THUMB_SIZE_INITED = false;
requireActivity().setResult(Activity.RESULT_OK);
return true;
} else if (Settings.KEY_DETAIL_SIZE.equals(key)) { } else if (Settings.KEY_DETAIL_SIZE.equals(key)) {
requireActivity().setResult(Activity.RESULT_OK); requireActivity().setResult(Activity.RESULT_OK);
} else if (Settings.KEY_THUMB_SIZE.equals(key)) { } else if (Settings.KEY_THUMB_SIZE.equals(key)) {
@@ -56,7 +56,6 @@ public abstract class BaseScene extends SceneFragment {
private View drawerView; private View drawerView;
@Nullable @Nullable
private SparseArray<Parcelable> drawerViewState; private SparseArray<Parcelable> drawerViewState;
private boolean needWhiteStatusBar = needWhiteStatusBar();
public void addAboveSnackView(View view) { public void addAboveSnackView(View view) {
FragmentActivity activity = getActivity(); FragmentActivity activity = getActivity();
@@ -118,10 +117,6 @@ public abstract class BaseScene extends SceneFragment {
return true; return true;
} }
public boolean needWhiteStatusBar() {
return true;
}
public int getNavCheckedItem() { public int getNavCheckedItem() {
return 0; return 0;
} }
@@ -176,14 +171,6 @@ public abstract class BaseScene extends SceneFragment {
drawerView = null; drawerView = null;
} }
public void setLightStatusBar(boolean set) {
var insetsController = getInsetsController();
if (insetsController != null) {
insetsController.setAppearanceLightStatusBars(set && (requireActivity().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) <= 0);
}
needWhiteStatusBar = set;
}
public void onDestroyDrawerView() { public void onDestroyDrawerView() {
} }
@@ -213,7 +200,11 @@ public abstract class BaseScene extends SceneFragment {
// Hide soft ime // Hide soft ime
hideSoftInput(); hideSoftInput();
setLightStatusBar(needWhiteStatusBar);
insetsController = getInsetsController();
if (insetsController != null) {
insetsController.setAppearanceLightStatusBars((requireActivity().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) <= 0);
}
} }
@Nullable @Nullable
@@ -22,21 +22,17 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
import android.view.Display;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@@ -45,30 +41,20 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator; import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.recyclerview.widget.StaggeredGridLayoutManager; import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.getkeepsafe.taptargetview.TapTarget;
import com.getkeepsafe.taptargetview.TapTargetView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter;
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange;
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableItemViewHolder;
import com.hippo.app.CheckBoxDialogBuilder; import com.hippo.app.CheckBoxDialogBuilder;
import com.hippo.app.EditTextDialogBuilder; import com.hippo.app.EditTextDialogBuilder;
import com.hippo.conaco.DataContainer;
import com.hippo.conaco.ProgressNotifier;
import com.hippo.easyrecyclerview.EasyRecyclerView; import com.hippo.easyrecyclerview.EasyRecyclerView;
import com.hippo.easyrecyclerview.FastScroller; import com.hippo.easyrecyclerview.FastScroller;
import com.hippo.easyrecyclerview.HandlerDrawable; import com.hippo.easyrecyclerview.HandlerDrawable;
@@ -85,7 +71,6 @@ import com.hippo.ehviewer.download.DownloadManager;
import com.hippo.ehviewer.download.DownloadService; import com.hippo.ehviewer.download.DownloadService;
import com.hippo.ehviewer.spider.SpiderDen; import com.hippo.ehviewer.spider.SpiderDen;
import com.hippo.ehviewer.ui.GalleryActivity; import com.hippo.ehviewer.ui.GalleryActivity;
import com.hippo.ehviewer.ui.MainActivity;
import com.hippo.ehviewer.widget.SimpleRatingView; import com.hippo.ehviewer.widget.SimpleRatingView;
import com.hippo.io.UniFileInputStreamPipe; import com.hippo.io.UniFileInputStreamPipe;
import com.hippo.scene.Announcer; import com.hippo.scene.Announcer;
@@ -99,7 +84,6 @@ import com.hippo.widget.recyclerview.AutoStaggeredGridLayoutManager;
import com.hippo.yorozuya.AssertUtils; import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.FileUtils; import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.IOUtils; import com.hippo.yorozuya.IOUtils;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.ObjectUtils; import com.hippo.yorozuya.ObjectUtils;
import com.hippo.yorozuya.ViewUtils; import com.hippo.yorozuya.ViewUtils;
import com.hippo.yorozuya.collect.LongList; import com.hippo.yorozuya.collect.LongList;
@@ -390,90 +374,9 @@ public class DownloadsScene extends ToolbarScene
updateView(); updateView();
guide();
return view; return view;
} }
private void guide() {
if (Settings.getGuideDownloadThumb() && null != mRecyclerView) {
mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Settings.getGuideDownloadThumb()) {
guideDownloadThumb();
}
if (null != mRecyclerView) {
ViewUtils.removeOnGlobalLayoutListener(mRecyclerView.getViewTreeObserver(), this);
}
}
});
} else {
guideDownloadLabels();
}
}
private void guideDownloadThumb() {
MainActivity activity = getMainActivity();
if (null == activity || !Settings.getGuideDownloadThumb() || null == mLayoutManager || null == mRecyclerView) {
guideDownloadLabels();
return;
}
int position = mLayoutManager.findFirstCompletelyVisibleItemPositions(null)[0];
if (position < 0) {
guideDownloadLabels();
return;
}
RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(position);
if (null == holder) {
guideDownloadLabels();
return;
}
TapTargetView.showFor(requireActivity(),
TapTarget.forView(((DownloadHolder) holder).thumb,
getString(R.string.guide_download_thumb_title),
getString(R.string.guide_download_thumb_text))
.transparentTarget(true),
new TapTargetView.Listener() {
@Override
public void onTargetDismissed(TapTargetView view, boolean userInitiated) {
super.onTargetDismissed(view, userInitiated);
Settings.putGuideDownloadThumb(false);
guideDownloadLabels();
}
});
}
private void guideDownloadLabels() {
MainActivity activity = getMainActivity();
if (null == activity || !Settings.getGuideDownloadLabels()) {
return;
}
Display display = activity.getWindowManager().getDefaultDisplay();
Point point = new Point();
display.getSize(point);
Rect bounds = new Rect(point.x + LayoutUtils.dp2pix(requireContext(), 20),
point.y / 3 + LayoutUtils.dp2pix(requireContext(), 20),
point.x - LayoutUtils.dp2pix(requireContext(), 20),
point.y / 3 - LayoutUtils.dp2pix(requireContext(), 20));
TapTargetView.showFor(requireActivity(),
TapTarget.forBounds(bounds,
getString(R.string.guide_download_labels_title),
getString(R.string.guide_download_labels_text))
.transparentTarget(true),
new TapTargetView.Listener() {
@Override
public void onTargetDismissed(TapTargetView view, boolean userInitiated) {
super.onTargetClick(view);
Settings.puttGuideDownloadLabels(false);
openDrawer(Gravity.RIGHT);
}
});
}
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
@@ -639,20 +542,13 @@ public class DownloadsScene extends ToolbarScene
initLabels(); initLabels();
RecyclerViewDragDropManager dragDropManager = new RecyclerViewDragDropManager();
dragDropManager.setInitiateOnLongPress(true);
dragDropManager.setInitiateOnTouch(false);
dragDropManager.setDraggingItemAlpha(0.8f);
mLabelAdapter = new DownloadLabelAdapter(inflater); mLabelAdapter = new DownloadLabelAdapter(inflater);
final EasyRecyclerView recyclerView = view.findViewById(R.id.recycler_view_drawer); final EasyRecyclerView recyclerView = view.findViewById(R.id.recycler_view_drawer);
recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setLayoutManager(new LinearLayoutManager(context));
mLabelAdapter.setHasStableIds(true); mLabelAdapter.setHasStableIds(true);
final GeneralItemAnimator animator = new DraggableItemAnimator(); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new DownloadLabelItemTouchHelperCallback());
recyclerView.setItemAnimator(animator); itemTouchHelper.attachToRecyclerView(recyclerView);
recyclerView.setAdapter(dragDropManager.createWrappedAdapter(mLabelAdapter)); recyclerView.setAdapter(mLabelAdapter);
dragDropManager.attachRecyclerView(recyclerView);
return view; return view;
} }
@@ -975,7 +871,7 @@ public class DownloadsScene extends ToolbarScene
holder.speed.setText(FileUtils.humanReadableByteCount(speed, false) + "/S"); holder.speed.setText(FileUtils.humanReadableByteCount(speed, false) + "/S");
} }
private static class DownloadLabelHolder extends AbstractDraggableItemViewHolder { private static class DownloadLabelHolder extends RecyclerView.ViewHolder {
private final TextView label; private final TextView label;
private final ImageView option; private final ImageView option;
@@ -987,74 +883,7 @@ public class DownloadsScene extends ToolbarScene
} }
} }
private static class ThumbDataContainer implements DataContainer { private class DownloadLabelAdapter extends RecyclerView.Adapter<DownloadLabelHolder> {
private final DownloadInfo mInfo;
@Nullable
private UniFile mFile;
public ThumbDataContainer(@NonNull DownloadInfo info) {
mInfo = info;
}
private void ensureFile() {
if (mFile == null) {
UniFile dir = SpiderDen.getGalleryDownloadDir(mInfo);
if (dir != null && dir.isDirectory()) {
mFile = dir.createFile(".thumb");
}
}
}
@Override
public boolean isEnabled() {
ensureFile();
return mFile != null;
}
@Override
public void onUrlMoved(String requestUrl, String responseUrl) {
}
@Override
public boolean save(InputStream is, long length, String mediaType, ProgressNotifier notify) {
ensureFile();
if (mFile == null) {
return false;
}
OutputStream os = null;
try {
os = mFile.openOutputStream();
IOUtils.copy(is, os);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
IOUtils.closeQuietly(os);
}
}
@Override
public InputStreamPipe get() {
ensureFile();
if (mFile != null) {
return new UniFileInputStreamPipe(mFile);
} else {
return null;
}
}
@Override
public void remove() {
if (mFile != null) {
mFile.delete();
}
}
}
private class DownloadLabelAdapter extends RecyclerView.Adapter<DownloadLabelHolder> implements DraggableItemAdapter<DownloadLabelHolder> {
private final LayoutInflater mInflater; private final LayoutInflater mInflater;
@@ -1108,36 +937,15 @@ public class DownloadsScene extends ToolbarScene
}); });
if (position > 0) { if (position > 0) {
holder.option.setVisibility(View.VISIBLE); holder.option.setVisibility(View.VISIBLE);
holder.itemView.setOnLongClickListener(v -> { holder.option.setOnClickListener(v -> {
if (context != null) { if (context != null) {
PopupMenu popupMenu = new PopupMenu(context, holder.option); EditTextDialogBuilder builder = new EditTextDialogBuilder(
popupMenu.inflate(R.menu.download_label_option); context, label, getString(R.string.download_labels));
popupMenu.show(); builder.setTitle(R.string.rename_label_title);
popupMenu.setOnMenuItemClickListener(item -> { builder.setPositiveButton(android.R.string.ok, null);
int itemId = item.getItemId(); AlertDialog dialog = builder.show();
if (itemId == R.id.menu_label_rename) { new RenameLabelDialogHelper(builder, dialog, label);
EditTextDialogBuilder builder = new EditTextDialogBuilder(
context, label, getString(R.string.download_labels));
builder.setTitle(R.string.rename_label_title);
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.show();
new RenameLabelDialogHelper(builder, dialog, label);
} else if (itemId == R.id.menu_label_remove) {
new MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.delete_label_title))
.setMessage(getString(R.string.delete_label_message, label))
.setPositiveButton(R.string.delete, (dialog, which) -> {
mDownloadManager.deleteLabel(label);
mLabels.remove(position);
notifyDataSetChanged();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
return false;
});
} }
return true;
}); });
} else { } else {
holder.option.setVisibility(View.GONE); holder.option.setVisibility(View.GONE);
@@ -1154,43 +962,6 @@ public class DownloadsScene extends ToolbarScene
public int getItemCount() { public int getItemCount() {
return mLabels != null ? mLabels.size() : 0; return mLabels != null ? mLabels.size() : 0;
} }
@Override
public boolean onCheckCanStartDrag(@NonNull DownloadLabelHolder holder, int position, int x, int y) {
return position != 0 && x > holder.option.getX() && y > holder.option.getY();
}
@Override
public ItemDraggableRange onGetItemDraggableRange(@NonNull DownloadLabelHolder holder, int position) {
return new ItemDraggableRange(1, getItemCount() - 1);
}
@Override
public void onMoveItem(int fromPosition, int toPosition) {
Context context = getContext();
if (null == context || fromPosition == toPosition || toPosition == 0) {
return;
}
EhApplication.getDownloadManager(context).moveLabel(fromPosition - 1, toPosition - 1);
final String item = mLabels.remove(fromPosition);
mLabels.add(toPosition, item);
}
@Override
public boolean onCheckCanDrop(int draggingPosition, int dropPosition) {
return dropPosition != 0;
}
@Override
public void onItemDragStarted(int position) {
notifyDataSetChanged();
}
@Override
public void onItemDragFinished(int fromPosition, int toPosition, boolean result) {
notifyDataSetChanged();
}
} }
private class DeleteRangeDialogHelper implements DialogInterface.OnClickListener { private class DeleteRangeDialogHelper implements DialogInterface.OnClickListener {
@@ -1390,8 +1161,7 @@ public class DownloadsScene extends ToolbarScene
return; return;
} }
DownloadInfo info = mList.get(position); DownloadInfo info = mList.get(position);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(info.gid), info.thumb, holder.thumb.load(EhCacheKeyFactory.getThumbKey(info.gid), info.thumb, true);
new ThumbDataContainer(info), true);
holder.title.setText(EhUtils.getSuitableTitle(info)); holder.title.setText(EhUtils.getSuitableTitle(info));
holder.uploader.setText(info.uploader); holder.uploader.setText(info.uploader);
holder.rating.setRating(info.rating); holder.rating.setRating(info.rating);
@@ -1528,4 +1298,43 @@ public class DownloadsScene extends ToolbarScene
} }
} }
} }
private class DownloadLabelItemTouchHelperCallback extends ItemTouchHelper.Callback {
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT);
}
@SuppressLint("NotifyDataSetChanged")
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getBindingAdapterPosition();
int toPosition = target.getBindingAdapterPosition();
Context context = getContext();
if (null == context || fromPosition == toPosition || toPosition == 0 || fromPosition == 0) {
return false;
}
EhApplication.getDownloadManager(context).moveLabel(fromPosition - 1, toPosition - 1);
final String item = mLabels.remove(fromPosition);
mLabels.add(toPosition, item);
mLabelAdapter.notifyDataSetChanged();
return true;
}
@SuppressLint("NotifyDataSetChanged")
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getBindingAdapterPosition();
if (mDownloadManager == null)
return;
if (position != 0) {
String label = mLabels.get(position);
mDownloadManager.deleteLabel(label);
}
mLabels.remove(position);
mLabelAdapter.notifyDataSetChanged();
}
}
} }
@@ -24,6 +24,7 @@ import android.content.res.Resources;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable;
import android.text.InputType; import android.text.InputType;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
@@ -45,8 +46,6 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.getkeepsafe.taptargetview.TapTarget;
import com.getkeepsafe.taptargetview.TapTargetView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.hippo.annotation.Implemented; import com.hippo.annotation.Implemented;
@@ -311,40 +310,9 @@ public class FavoritesScene extends BaseScene implements
mHelper.firstRefresh(); mHelper.firstRefresh();
} }
guideCollections();
return view; return view;
} }
private void guideCollections() {
Activity activity = getMainActivity();
if (null == activity || !Settings.getGuideCollections()) {
return;
}
Display display = activity.getWindowManager().getDefaultDisplay();
Point point = new Point();
display.getSize(point);
Rect bounds = new Rect(point.x + LayoutUtils.dp2pix(requireContext(), 20),
point.y / 3 + LayoutUtils.dp2pix(requireContext(), 20),
point.x - LayoutUtils.dp2pix(requireContext(), 20),
point.y / 3 - LayoutUtils.dp2pix(requireContext(), 20));
TapTargetView.showFor(requireActivity(),
TapTarget.forBounds(bounds,
getString(R.string.guide_collections_title),
getString(R.string.guide_collections_text))
.transparentTarget(true),
new TapTargetView.Listener() {
@Override
public void onTargetDismissed(TapTargetView view, boolean userInitiated) {
super.onTargetClick(view);
Settings.putGuideCollections(false);
openDrawer(Gravity.RIGHT);
}
});
}
// keyword of mUrlBuilder, fav cat of mUrlBuilder, mFavCatArray. // keyword of mUrlBuilder, fav cat of mUrlBuilder, mFavCatArray.
// They changed, call it // They changed, call it
private void updateSearchBar() { private void updateSearchBar() {
@@ -887,7 +855,14 @@ public class FavoritesScene extends BaseScene implements
} }
updateSearchBar(); updateSearchBar();
mHelper.onGetPageData(taskId, result.pages, result.nextPage, result.galleryInfoList); int pages = 0;
assert mUrlBuilder != null;
if (FavListUrlBuilder.isValidFavCat(mUrlBuilder.getFavCat()))
pages = CommonOperations.getPagesForFounds(mFavCountArray[mUrlBuilder.getFavCat()], 50);
else if (mUrlBuilder.getFavCat() == FavListUrlBuilder.FAV_CAT_ALL)
pages = CommonOperations.getPagesForFounds(mFavCountSum, 50);
mHelper.nextPg = result.nextPage;
mHelper.onGetPageData(taskId, pages, mHelper.pgCounter + 1, result.galleryInfoList);
if (mDrawerAdapter != null) { if (mDrawerAdapter != null) {
mDrawerAdapter.notifyDataSetChanged(); mDrawerAdapter.notifyDataSetChanged();
@@ -1206,6 +1181,8 @@ public class FavoritesScene extends BaseScene implements
} }
private class FavoritesHelper extends GalleryInfoContentHelper { private class FavoritesHelper extends GalleryInfoContentHelper {
public int pgCounter = 0;
public String nextPg = null;
@Override @Override
protected void getPageData(final int taskId, int type, int page) { protected void getPageData(final int taskId, int type, int page) {
@@ -1213,6 +1190,7 @@ public class FavoritesScene extends BaseScene implements
if (null == activity || null == mUrlBuilder || null == mClient) { if (null == activity || null == mUrlBuilder || null == mClient) {
return; return;
} }
pgCounter = page;
if (mEnableModify) { if (mEnableModify) {
mEnableModify = false; mEnableModify = false;
@@ -1252,7 +1230,7 @@ public class FavoritesScene extends BaseScene implements
url = mUrlBuilder.build(); url = mUrlBuilder.build();
} }
mUrlBuilder.setIndex(page); mUrlBuilder.setNext(nextPg);
EhRequest request = new EhRequest(); EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_MODIFY_FAVORITES); request.setMethod(EhClient.METHOD_MODIFY_FAVORITES);
request.setCallback(new GetFavoritesListener(getContext(), request.setCallback(new GetFavoritesListener(getContext(),
@@ -1265,7 +1243,7 @@ public class FavoritesScene extends BaseScene implements
final String keyword = mUrlBuilder.getKeyword(); final String keyword = mUrlBuilder.getKeyword();
SimpleHandler.getInstance().post(() -> onGetFavoritesLocal(keyword, taskId)); SimpleHandler.getInstance().post(() -> onGetFavoritesLocal(keyword, taskId));
} else { } else {
mUrlBuilder.setIndex(page); mUrlBuilder.setNext(nextPg);
String url = mUrlBuilder.build(); String url = mUrlBuilder.build();
EhRequest request = new EhRequest(); EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_GET_FAVORITES); request.setMethod(EhClient.METHOD_GET_FAVORITES);
@@ -1328,5 +1306,25 @@ public class FavoritesScene extends BaseScene implements
} }
} }
} }
@Override
protected void onClearData() {
super.onClearData();
nextPg = null;
}
@Override
protected Parcelable saveInstanceState(Parcelable superState) {
Bundle bundle = (Bundle) super.saveInstanceState(superState);
bundle.putString(KEY_NEXT_PAGE, nextPg);
return bundle;
}
@Override
protected Parcelable restoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
nextPg = bundle.getString(KEY_NEXT_PAGE);
return super.restoreInstanceState(state);
}
} }
} }
@@ -184,14 +184,7 @@ public final class GalleryCommentsScene extends ToolbarScene
mEditPanel, mEditPanel,
mFabLayout mFabLayout
)); ));
mRefreshLayout.setColorSchemeColors(ResourcesKt.resolveColor(getTheme(), androidx.appcompat.R.attr.colorPrimary));
mRefreshLayout.setColorSchemeResources(
R.color.loading_indicator_red,
R.color.loading_indicator_purple,
R.color.loading_indicator_blue,
R.color.loading_indicator_cyan,
R.color.loading_indicator_green,
R.color.loading_indicator_yellow);
mRefreshLayout.setOnRefreshListener(this); mRefreshLayout.setOnRefreshListener(this);
Context context = requireContext(); Context context = requireContext();
@@ -559,12 +559,6 @@ public class GalleryDetailScene extends ToolbarScene implements View.OnClickList
ViewGroup main = (ViewGroup) ViewUtils.$$(view, R.id.main); ViewGroup main = (ViewGroup) ViewUtils.$$(view, R.id.main);
ScrollView mainView = (ScrollView) ViewUtils.$$(main, R.id.scroll_view); ScrollView mainView = (ScrollView) ViewUtils.$$(main, R.id.scroll_view);
mainView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if (mActionGroup != null && mHeader != null) {
//noinspection IntegerDivisionInFloatingPointContext
setLightStatusBar(mActionGroup.getY() - mHeader.findViewById(R.id.header_content).getPaddingTop() / 2 < scrollY);
}
});
View progressView = ViewUtils.$$(main, R.id.progress_view); View progressView = ViewUtils.$$(main, R.id.progress_view);
mTip = (TextView) ViewUtils.$$(main, R.id.tip); mTip = (TextView) ViewUtils.$$(main, R.id.tip);
mViewTransition = new ViewTransition(mainView, progressView, mTip); mViewTransition = new ViewTransition(mainView, progressView, mTip);
@@ -668,11 +662,6 @@ public class GalleryDetailScene extends ToolbarScene implements View.OnClickList
return view; return view;
} }
@Override
public boolean needWhiteStatusBar() {
return false;
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -841,19 +830,16 @@ public class GalleryDetailScene extends ToolbarScene implements View.OnClickList
switch (state) { switch (state) {
case STATE_NORMAL: case STATE_NORMAL:
setLightStatusBar(false);
// Show mMainView // Show mMainView
mViewTransition.showView(0, animation); mViewTransition.showView(0, animation);
// Show mBelowHeader // Show mBelowHeader
mViewTransition2.showView(0, animation); mViewTransition2.showView(0, animation);
break; break;
case STATE_REFRESH: case STATE_REFRESH:
setLightStatusBar(true);
// Show mProgressView // Show mProgressView
mViewTransition.showView(1, animation); mViewTransition.showView(1, animation);
break; break;
case STATE_REFRESH_HEADER: case STATE_REFRESH_HEADER:
setLightStatusBar(false);
// Show mMainView // Show mMainView
mViewTransition.showView(0, animation); mViewTransition.showView(0, animation);
// Show mProgress // Show mProgress
@@ -862,7 +848,6 @@ public class GalleryDetailScene extends ToolbarScene implements View.OnClickList
default: default:
case STATE_INIT: case STATE_INIT:
case STATE_FAILED: case STATE_FAILED:
setLightStatusBar(true);
// Show mFailedView // Show mFailedView
mViewTransition.showView(2, animation); mViewTransition.showView(2, animation);
break; break;
@@ -18,13 +18,10 @@ package com.hippo.ehviewer.ui.scene;
import android.animation.Animator; import android.animation.Animator;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@@ -33,10 +30,8 @@ import android.text.Spannable;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.ImageSpan; import android.text.style.ImageSpan;
import android.view.Display;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -50,25 +45,17 @@ import androidx.annotation.IntDef;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsAnimationCompat; import androidx.core.view.WindowInsetsAnimationCompat;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.getkeepsafe.taptargetview.TapTarget;
import com.getkeepsafe.taptargetview.TapTargetView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter;
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange;
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableItemViewHolder;
import com.hippo.app.EditTextDialogBuilder; import com.hippo.app.EditTextDialogBuilder;
import com.hippo.drawable.AddDeleteDrawable; import com.hippo.drawable.AddDeleteDrawable;
import com.hippo.drawable.DrawerArrowDrawable; import com.hippo.drawable.DrawerArrowDrawable;
@@ -111,7 +98,6 @@ import com.hippo.widget.FabLayout;
import com.hippo.widget.SearchBarMover; import com.hippo.widget.SearchBarMover;
import com.hippo.yorozuya.AnimationUtils; import com.hippo.yorozuya.AnimationUtils;
import com.hippo.yorozuya.AssertUtils; import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.MathUtils; import com.hippo.yorozuya.MathUtils;
import com.hippo.yorozuya.SimpleAnimatorListener; import com.hippo.yorozuya.SimpleAnimatorListener;
import com.hippo.yorozuya.StringUtils; import com.hippo.yorozuya.StringUtils;
@@ -634,40 +620,9 @@ public final class GalleryListScene extends BaseScene
mHelper.firstRefresh(); mHelper.firstRefresh();
} }
guideQuickSearch();
return view; return view;
} }
private void guideQuickSearch() {
Activity activity = getMainActivity();
if (null == activity || !Settings.getGuideQuickSearch()) {
return;
}
Display display = activity.getWindowManager().getDefaultDisplay();
Point point = new Point();
display.getSize(point);
Rect bounds = new Rect(point.x + LayoutUtils.dp2pix(requireContext(), 20),
point.y / 3 + LayoutUtils.dp2pix(requireContext(), 20),
point.x - LayoutUtils.dp2pix(requireContext(), 20),
point.y / 3 - LayoutUtils.dp2pix(requireContext(), 20));
TapTargetView.showFor(requireActivity(),
TapTarget.forBounds(bounds,
getString(R.string.guide_quick_search_title),
getString(R.string.guide_quick_search_text))
.transparentTarget(true),
new TapTargetView.Listener() {
@Override
public void onTargetDismissed(TapTargetView view, boolean userInitiated) {
super.onTargetClick(view);
Settings.putGuideQuickSearch(false);
openDrawer(Gravity.RIGHT);
}
});
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -786,19 +741,13 @@ public final class GalleryListScene extends BaseScene
Context context = getContext(); Context context = getContext();
AssertUtils.assertNotNull(context); AssertUtils.assertNotNull(context);
RecyclerViewDragDropManager dragDropManager = new RecyclerViewDragDropManager();
dragDropManager.setInitiateOnLongPress(true);
dragDropManager.setInitiateOnTouch(false);
dragDropManager.setDraggingItemAlpha(0.8f);
final EasyRecyclerView recyclerView = view.findViewById(R.id.recycler_view_drawer); final EasyRecyclerView recyclerView = view.findViewById(R.id.recycler_view_drawer);
recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setLayoutManager(new LinearLayoutManager(context));
final QsDrawerAdapter qsDrawerAdapter = new QsDrawerAdapter(inflater); final QsDrawerAdapter qsDrawerAdapter = new QsDrawerAdapter(inflater);
qsDrawerAdapter.setHasStableIds(true); qsDrawerAdapter.setHasStableIds(true);
final GeneralItemAnimator animator = new DraggableItemAnimator(); recyclerView.setAdapter(qsDrawerAdapter);
recyclerView.setItemAnimator(animator); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new GalleryListQSItemTouchHelperCallback(qsDrawerAdapter));
recyclerView.setAdapter(dragDropManager.createWrappedAdapter(qsDrawerAdapter)); itemTouchHelper.attachToRecyclerView(recyclerView);
dragDropManager.attachRecyclerView(recyclerView);
mQuickSearchList = EhDB.getAllQuickSearch(); mQuickSearchList = EhDB.getAllQuickSearch();
tip.setText(R.string.quick_search_tip); tip.setText(R.string.quick_search_tip);
if (mIsTopList) { if (mIsTopList) {
@@ -1422,7 +1371,7 @@ public final class GalleryListScene extends BaseScene
? R.string.gallery_list_empty_hit_subscription ? R.string.gallery_list_empty_hit_subscription
: R.string.gallery_list_empty_hit); : R.string.gallery_list_empty_hit);
mHelper.setEmptyString(emptyString); mHelper.setEmptyString(emptyString);
mHelper.onGetPageData(taskId, result.pages, result.nextPage, result.galleryInfoList); mHelper.onGetPageData(taskId, CommonOperations.getPagesForFounds(result.founds, 25), mHelper.pgCounter + 1, result.galleryInfoList);
} }
} }
@@ -1525,7 +1474,7 @@ public final class GalleryListScene extends BaseScene
} }
} }
private static class QsDrawerHolder extends AbstractDraggableItemViewHolder { private static class QsDrawerHolder extends RecyclerView.ViewHolder {
private final TextView key; private final TextView key;
private final ImageView option; private final ImageView option;
@@ -1570,7 +1519,7 @@ public final class GalleryListScene extends BaseScene
} }
} }
private class QsDrawerAdapter extends RecyclerView.Adapter<QsDrawerHolder> implements DraggableItemAdapter<QsDrawerHolder> { private class QsDrawerAdapter extends RecyclerView.Adapter<QsDrawerHolder> {
private final LayoutInflater mInflater; private final LayoutInflater mInflater;
@@ -1595,40 +1544,12 @@ public final class GalleryListScene extends BaseScene
} }
mUrlBuilder.set(mQuickSearchList.get(position)); mUrlBuilder.set(mQuickSearchList.get(position));
mUrlBuilder.setPageIndex(0); mUrlBuilder.setNextGid(0);
onUpdateUrlBuilder(); onUpdateUrlBuilder();
mHelper.refresh(); mHelper.refresh();
setState(STATE_NORMAL); setState(STATE_NORMAL);
closeDrawer(Gravity.RIGHT); closeDrawer(Gravity.RIGHT);
}); });
holder.itemView.setOnLongClickListener(v -> {
PopupMenu popupMenu = new PopupMenu(requireContext(), holder.option);
popupMenu.inflate(R.menu.quicksearch_option);
popupMenu.show();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
final QuickSearch quickSearch = mQuickSearchList.get(position);
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.menu_qs_remove) {
new MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.delete_quick_search_title))
.setMessage(getString(R.string.delete_quick_search_message, quickSearch.name))
.setPositiveButton(R.string.delete, (dialog, which) -> {
EhDB.deleteQuickSearch(quickSearch);
mQuickSearchList.remove(position);
notifyDataSetChanged();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
return true;
}
return false;
}
});
return true;
});
} else { } else {
int[] keywords = {11, 12, 13, 15}; int[] keywords = {11, 12, 13, 15};
int[] toplists = {R.string.toplist_alltime, R.string.toplist_pastyear, R.string.toplist_pastmonth, R.string.toplist_yesterday}; int[] toplists = {R.string.toplist_alltime, R.string.toplist_pastyear, R.string.toplist_pastmonth, R.string.toplist_yesterday};
@@ -1640,7 +1561,7 @@ public final class GalleryListScene extends BaseScene
} }
mUrlBuilder.setKeyword(String.valueOf(keywords[position])); mUrlBuilder.setKeyword(String.valueOf(keywords[position]));
mUrlBuilder.setPageIndex(0); mUrlBuilder.setNextGid(0);
onUpdateUrlBuilder(); onUpdateUrlBuilder();
mHelper.refresh(); mHelper.refresh();
setState(STATE_NORMAL); setState(STATE_NORMAL);
@@ -1664,44 +1585,6 @@ public final class GalleryListScene extends BaseScene
public int getItemCount() { public int getItemCount() {
return !mIsTopList ? mQuickSearchList != null ? mQuickSearchList.size() : 0 : 4; return !mIsTopList ? mQuickSearchList != null ? mQuickSearchList.size() : 0 : 4;
} }
@Override
public boolean onCheckCanStartDrag(@NonNull QsDrawerHolder holder, int position, int x, int y) {
return !mIsTopList && x > holder.option.getX() && y > holder.option.getY();
}
@Override
public ItemDraggableRange onGetItemDraggableRange(@NonNull QsDrawerHolder holder, int position) {
return null;
}
@Override
public void onMoveItem(int fromPosition, int toPosition) {
if (fromPosition == toPosition) {
return;
}
if (null == mQuickSearchList) {
return;
}
EhDB.moveQuickSearch(fromPosition, toPosition);
final QuickSearch item = mQuickSearchList.remove(fromPosition);
mQuickSearchList.add(toPosition, item);
}
@Override
public boolean onCheckCanDrop(int draggingPosition, int dropPosition) {
return true;
}
@Override
public void onItemDragStarted(int position) {
notifyDataSetChanged();
}
@Override
public void onItemDragFinished(int fromPosition, int toPosition, boolean result) {
notifyDataSetChanged();
}
} }
private abstract class UrlSuggestion extends SearchBar.Suggestion { private abstract class UrlSuggestion extends SearchBar.Suggestion {
@@ -1808,15 +1691,20 @@ public final class GalleryListScene extends BaseScene
} }
private class GalleryListHelper extends GalleryInfoContentHelper { private class GalleryListHelper extends GalleryInfoContentHelper {
public int pgCounter = 0;
@Override @Override
protected void getPageData(int taskId, int type, int page) { protected void getPageData(int taskId, int type, int page) {
pgCounter = page;
MainActivity activity = getMainActivity(); MainActivity activity = getMainActivity();
if (null == activity || null == mClient || null == mUrlBuilder) { if (null == activity || null == mClient || null == mUrlBuilder) {
return; return;
} }
mUrlBuilder.setPageIndex(page); if (page != 0)
mUrlBuilder.setNextGid(minGid);
else
mUrlBuilder.setNextGid(0);
if (ListUrlBuilder.MODE_IMAGE_SEARCH == mUrlBuilder.getMode()) { if (ListUrlBuilder.MODE_IMAGE_SEARCH == mUrlBuilder.getMode()) {
EhRequest request = new EhRequest(); EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_IMAGE_SEARCH); request.setMethod(EhClient.METHOD_IMAGE_SEARCH);
@@ -1886,4 +1774,47 @@ public final class GalleryListScene extends BaseScene
} }
} }
} }
private class GalleryListQSItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final QsDrawerAdapter mAdapter;
public GalleryListQSItemTouchHelperCallback(QsDrawerAdapter adapter) {
mAdapter = adapter;
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT);
}
@SuppressLint("NotifyDataSetChanged")
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getBindingAdapterPosition();
int toPosition = target.getBindingAdapterPosition();
if (fromPosition == toPosition) {
return false;
}
if (null == mQuickSearchList) {
return false;
}
EhDB.moveQuickSearch(fromPosition, toPosition);
final QuickSearch item = mQuickSearchList.remove(fromPosition);
mQuickSearchList.add(toPosition, item);
mAdapter.notifyDataSetChanged();
return true;
}
@SuppressLint("NotifyDataSetChanged")
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
if (mQuickSearchList == null)
return;
int position = viewHolder.getBindingAdapterPosition();
final QuickSearch quickSearch = mQuickSearchList.get(position);
EhDB.deleteQuickSearch(quickSearch);
mQuickSearchList.remove(position);
mAdapter.notifyDataSetChanged();
}
}
} }
@@ -36,20 +36,11 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager; import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemAdapter;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAction;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionDefault;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem;
import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager;
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractSwipeableItemViewHolder;
import com.hippo.easyrecyclerview.EasyRecyclerView; import com.hippo.easyrecyclerview.EasyRecyclerView;
import com.hippo.easyrecyclerview.FastScroller; import com.hippo.easyrecyclerview.FastScroller;
import com.hippo.easyrecyclerview.HandlerDrawable; import com.hippo.easyrecyclerview.HandlerDrawable;
@@ -206,17 +197,9 @@ public class HistoryScene extends ToolbarScene {
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mTip.setCompoundDrawables(null, drawable, null, null); mTip.setCompoundDrawables(null, drawable, null, null);
RecyclerViewTouchActionGuardManager guardManager = new RecyclerViewTouchActionGuardManager();
guardManager.setInterceptVerticalScrollingWhileAnimationRunning(true);
guardManager.setEnabled(true);
RecyclerViewSwipeManager swipeManager = new RecyclerViewSwipeManager();
mAdapter = new HistoryAdapter(); mAdapter = new HistoryAdapter();
mAdapter.setHasStableIds(true); mAdapter.setHasStableIds(true);
mAdapter = swipeManager.createWrappedAdapter(mAdapter);
mRecyclerView.setAdapter(mAdapter); mRecyclerView.setAdapter(mAdapter);
final GeneralItemAnimator animator = new SwipeDismissItemAnimator();
animator.setSupportsChangeAnimations(false);
mRecyclerView.setItemAnimator(animator);
AutoStaggeredGridLayoutManager layoutManager = new AutoStaggeredGridLayoutManager( AutoStaggeredGridLayoutManager layoutManager = new AutoStaggeredGridLayoutManager(
0, StaggeredGridLayoutManager.VERTICAL); 0, StaggeredGridLayoutManager.VERTICAL);
layoutManager.setColumnSize(resources.getDimensionPixelOffset(Settings.getDetailSizeResId())); layoutManager.setColumnSize(resources.getDimensionPixelOffset(Settings.getDetailSizeResId()));
@@ -229,9 +212,8 @@ public class HistoryScene extends ToolbarScene {
int paddingV = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_v); int paddingV = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_v);
MarginItemDecoration decoration = new MarginItemDecoration(interval, paddingH, paddingV, paddingH, paddingV); MarginItemDecoration decoration = new MarginItemDecoration(interval, paddingH, paddingV, paddingH, paddingV);
mRecyclerView.addItemDecoration(decoration); mRecyclerView.addItemDecoration(decoration);
guardManager.attachRecyclerView(mRecyclerView); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new HistoryItemTouchHelperCallback());
swipeManager.attachRecyclerView(mRecyclerView); itemTouchHelper.attachToRecyclerView(mRecyclerView);
mFastScroller.attachToRecyclerView(mRecyclerView); mFastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable handlerDrawable = new HandlerDrawable(); HandlerDrawable handlerDrawable = new HandlerDrawable();
handlerDrawable.setColor(ResourcesKt.resolveColor(getTheme(), com.google.android.material.R.attr.colorPrimary)); handlerDrawable.setColor(ResourcesKt.resolveColor(getTheme(), com.google.android.material.R.attr.colorPrimary));
@@ -502,7 +484,7 @@ public class HistoryScene extends ToolbarScene {
} }
} }
private static class HistoryHolder extends AbstractSwipeableItemViewHolder { private static class HistoryHolder extends RecyclerView.ViewHolder {
public final View card; public final View card;
public final LoadImageView thumb; public final LoadImageView thumb;
@@ -529,12 +511,6 @@ public class HistoryScene extends ToolbarScene {
pages = itemView.findViewById(R.id.pages); pages = itemView.findViewById(R.id.pages);
downloaded = itemView.findViewById(R.id.downloaded); downloaded = itemView.findViewById(R.id.downloaded);
} }
@NonNull
@Override
public View getSwipeableContainerView() {
return card;
}
} }
private class MoveDialogHelper implements DialogInterface.OnClickListener { private class MoveDialogHelper implements DialogInterface.OnClickListener {
@@ -570,8 +546,7 @@ public class HistoryScene extends ToolbarScene {
} }
} }
private class HistoryAdapter extends RecyclerView.Adapter<HistoryHolder> private class HistoryAdapter extends RecyclerView.Adapter<HistoryHolder> {
implements SwipeableItemAdapter<HistoryHolder> {
private final LayoutInflater mInflater; private final LayoutInflater mInflater;
private final int mListThumbWidth; private final int mListThumbWidth;
@@ -649,55 +624,30 @@ public class HistoryScene extends ToolbarScene {
public int getItemCount() { public int getItemCount() {
return null != mLazyList ? mLazyList.size() : 0; return null != mLazyList ? mLazyList.size() : 0;
} }
@Override
public int onGetSwipeReactionType(@NonNull HistoryHolder holder, int position, int x, int y) {
return SwipeableItemConstants.REACTION_CAN_SWIPE_LEFT;
}
@Override
public void onSwipeItemStarted(@NonNull HistoryHolder holder, int position) {
}
@Override
public void onSetSwipeBackground(@NonNull HistoryHolder holder, int position, int type) {
}
@Override
public SwipeResultAction onSwipeItem(@NonNull HistoryHolder holder, int position, int result) {
switch (result) {
case SwipeableItemConstants.RESULT_SWIPED_LEFT:
return new SwipeResultActionClear(position);
case SwipeableItemConstants.RESULT_SWIPED_RIGHT:
case SwipeableItemConstants.RESULT_CANCELED:
case SwipeableItemConstants.RESULT_NONE:
case SwipeableItemConstants.RESULT_SWIPED_DOWN:
case SwipeableItemConstants.RESULT_SWIPED_UP:
default:
return new SwipeResultActionDefault();
}
}
} }
private class SwipeResultActionClear extends SwipeResultActionRemoveItem { private class HistoryItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final int mPosition; @Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
protected SwipeResultActionClear(int position) { return makeMovementFlags(0, ItemTouchHelper.LEFT);
mPosition = position;
} }
@Override @Override
protected void onPerformAction() { public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
super.onPerformAction(); return false;
if (null == mLazyList || null == mAdapter) { }
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int mPosition = viewHolder.getBindingAdapterPosition();
if (null == mLazyList || mAdapter == null) {
return; return;
} }
HistoryInfo info = mLazyList.get(mPosition); HistoryInfo info = mLazyList.get(mPosition);
EhDB.deleteHistoryInfo(info); EhDB.deleteHistoryInfo(info);
updateLazyList(); updateLazyList();
mAdapter.notifyDataSetChanged(); mAdapter.notifyItemRemoved(mPosition);
updateView(true); updateView(true);
} }
} }
@@ -87,12 +87,6 @@ public abstract class ToolbarScene extends BaseScene {
} }
} }
@Override
public boolean needWhiteStatusBar() {
return false;
}
public int getMenuResId() { public int getMenuResId() {
return 0; return 0;
} }
@@ -53,11 +53,6 @@ public class FixedThumb extends LoadImageView {
a.recycle(); a.recycle();
} }
public void setFix(float minAspect, float maxAspect) {
this.minAspect = minAspect;
this.maxAspect = maxAspect;
}
@Override @Override
public void onPreSetImageDrawable(Drawable drawable, boolean isTarget) { public void onPreSetImageDrawable(Drawable drawable, boolean isTarget) {
if (alwaysCutAndScale) { if (alwaysCutAndScale) {
@@ -31,8 +31,14 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelper<GalleryInfo> { public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelper<GalleryInfo> {
public int maxGid = -1;
public int minGid = -1;
private static final String KEY_DATA_MAP = "data_map"; private static final String KEY_DATA_MAP = "data_map";
private static final String KEY_MAX_GID = "max_gid";
private static final String KEY_MIN_GID = "min_gid";
public static final String KEY_NEXT_PAGE = "next_page";
private final FavouriteStatusRouter.Listener listener; private final FavouriteStatusRouter.Listener listener;
@SuppressLint("UseSparseArrays") @SuppressLint("UseSparseArrays")
private Map<Long, GalleryInfo> map = new HashMap<>(); private Map<Long, GalleryInfo> map = new HashMap<>();
@@ -59,6 +65,12 @@ public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelp
@Override @Override
protected void onAddData(List<GalleryInfo> data) { protected void onAddData(List<GalleryInfo> data) {
for (GalleryInfo info : data) { for (GalleryInfo info : data) {
if (maxGid == -1)
maxGid = (int) info.gid;
if (minGid == -1)
minGid = (int) info.gid;
maxGid = (int) Math.max(maxGid, info.gid);
minGid = (int) Math.min(minGid, info.gid);
map.put(info.gid, info); map.put(info.gid, info);
} }
} }
@@ -78,6 +90,8 @@ public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelp
@Override @Override
protected void onClearData() { protected void onClearData() {
map.clear(); map.clear();
maxGid = -1;
minGid = -1;
} }
@Override @Override
@@ -88,6 +102,8 @@ public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelp
FavouriteStatusRouter router = EhApplication.getFavouriteStatusRouter(); FavouriteStatusRouter router = EhApplication.getFavouriteStatusRouter();
int id = router.saveDataMap(map); int id = router.saveDataMap(map);
bundle.putInt(KEY_DATA_MAP, id); bundle.putInt(KEY_DATA_MAP, id);
bundle.putInt(KEY_MIN_GID, minGid);
bundle.putInt(KEY_MAX_GID, maxGid);
return bundle; return bundle;
} }
@@ -104,6 +120,8 @@ public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelp
this.map = map; this.map = map;
} }
} }
minGid = bundle.getInt(KEY_MIN_GID);
maxGid = bundle.getInt(KEY_MAX_GID);
return super.restoreInstanceState(state); return super.restoreInstanceState(state);
} }
@@ -0,0 +1,13 @@
package com.hippo.ehviewer.widget
import android.content.Context
import android.util.AttributeSet
import com.hippo.ehviewer.Settings
class ResizeableFixedThumb @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : FixedThumb(context, attrs) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
setMeasuredDimension(Settings.getListThumbSize() * 2, Settings.getListThumbSize() * 3)
}
}
@@ -1,27 +0,0 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.scene;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
public interface TransitionHelper {
boolean onTransition(Context context, FragmentTransaction transaction, Fragment exit, Fragment enter);
}
@@ -102,27 +102,11 @@ public class ContentLayout extends FrameLayout {
mFastScroller = mContentView.findViewById(R.id.fast_scroller); mFastScroller = mContentView.findViewById(R.id.fast_scroller);
mRecyclerView = mRefreshLayout.findViewById(R.id.recycler_view); mRecyclerView = mRefreshLayout.findViewById(R.id.recycler_view);
mRefreshLayout.setColorSchemeColors(ResourcesKt.resolveColor(context.getTheme(), androidx.appcompat.R.attr.colorPrimary));
mFastScroller.attachToRecyclerView(mRecyclerView); mFastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable drawable = new HandlerDrawable(); HandlerDrawable drawable = new HandlerDrawable();
drawable.setColor(ResourcesKt.resolveColor(context.getTheme(), androidx.appcompat.R.attr.colorPrimary)); drawable.setColor(ResourcesKt.resolveColor(context.getTheme(), androidx.appcompat.R.attr.colorPrimary));
mFastScroller.setHandlerDrawable(drawable); mFastScroller.setHandlerDrawable(drawable);
mRefreshLayout.setColorSchemeResources(
R.color.loading_indicator_red,
R.color.loading_indicator_purple,
R.color.loading_indicator_blue,
R.color.loading_indicator_cyan,
R.color.loading_indicator_green,
R.color.loading_indicator_yellow);
Resources resources = getResources();
mBottomProgress.setIndicatorColor(
resources.getColor(R.color.loading_indicator_red),
resources.getColor(R.color.loading_indicator_blue),
resources.getColor(R.color.loading_indicator_green),
resources.getColor(R.color.loading_indicator_orange));
mBottomProgress.setIndeterminateAnimationType(LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS);
mRecyclerViewOriginBottom = mRecyclerView.getPaddingBottom(); mRecyclerViewOriginBottom = mRecyclerView.getPaddingBottom();
mFastScrollerOriginBottom = mFastScroller.getPaddingBottom(); mFastScrollerOriginBottom = mFastScroller.getPaddingBottom();
} }
@@ -467,48 +451,22 @@ public class ContentLayout extends FrameLayout {
switch (mCurrentTaskType) { switch (mCurrentTaskType) {
case TYPE_REFRESH: case TYPE_REFRESH:
mStartPage = 0;
mEndPage = 1;
mPages = pages; mPages = pages;
mNextPage = nextPage; mNextPage = nextPage;
mPageDivider.clear();
mPageDivider.add(data.size()); mPageDivider.add(data.size());
if (data.isEmpty()) { if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged(); notifyDataSetChanged();
mRefreshLayout.setRefreshing(false);
if (true || mEndPage >= mPages) { // Not found mBottomProgress.hide();
// Ui change, show empty string showEmptyString();
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else { } else {
mData.clear();
onClearData();
mData.addAll(data); mData.addAll(data);
onAddData(data); onAddData(data);
notifyDataSetChanged(); notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setRefreshing(false); mRefreshLayout.setRefreshing(false);
mBottomProgress.hide(); mBottomProgress.hide();
showContent(); showContent();
// RecyclerView scroll
if (mRecyclerView.isAttachedToWindow()) { if (mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll(); mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0); LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
@@ -529,33 +487,24 @@ public class ContentLayout extends FrameLayout {
// assert mStartPage >= 0 // assert mStartPage >= 0
if (data.isEmpty()) { if (data.isEmpty()) {
if (true || mStartPage <= 0) { // OK, that's all // OK, that's all
if (mData.isEmpty()) { if (mData.isEmpty()) {
// Ui change, show empty string // Ui change, show empty string
mRefreshLayout.setRefreshing(false); mRefreshLayout.setRefreshing(false);
mBottomProgress.hide(); mBottomProgress.hide();
showEmptyString(); showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll, to top
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
} else { } else {
// Keep UI // Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// Get previous if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
mCurrentTaskId = mIdGenerator.nextId(); // RecyclerView scroll, to top
// Keep mCurrentTaskType mRecyclerView.stopScroll();
mCurrentTaskPage = mStartPage - 1; LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage); onScrollToPosition(0);
}
} }
} else { } else {
mData.addAll(0, data); mData.addAll(0, data);
@@ -592,33 +541,24 @@ public class ContentLayout extends FrameLayout {
mPages = Math.max(mEndPage, pages); mPages = Math.max(mEndPage, pages);
if (data.isEmpty()) { if (data.isEmpty()) {
if (true || mEndPage >= mPages) { // OK, that's all // OK, that's all
if (mData.isEmpty()) { if (mData.isEmpty()) {
// Ui change, show empty string // Ui change, show empty string
mRefreshLayout.setRefreshing(false); mRefreshLayout.setRefreshing(false);
mBottomProgress.hide(); mBottomProgress.hide();
showEmptyString(); showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
} else { } else {
// Keep UI // Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// Get next page if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
mCurrentTaskId = mIdGenerator.nextId(); // RecyclerView scroll
// Keep mCurrentTaskType mRecyclerView.stopScroll();
mCurrentTaskPage = mEndPage; LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage); onScrollToPosition(oldDataSize);
}
} }
} else { } else {
mData.addAll(data); mData.addAll(data);
@@ -655,23 +595,11 @@ public class ContentLayout extends FrameLayout {
onClearData(); onClearData();
notifyDataSetChanged(); notifyDataSetChanged();
if (true || mEndPage >= mPages) { // Not found // Not found
// Ui change, show empty string // Ui change, show empty string
mRefreshLayout.setRefreshing(false); mRefreshLayout.setRefreshing(false);
mBottomProgress.hide(); mBottomProgress.hide();
showEmptyString(); showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else { } else {
mData.clear(); mData.clear();
onClearData(); onClearData();
@@ -820,6 +748,12 @@ public class ContentLayout extends FrameLayout {
} }
private void doRefresh() { private void doRefresh() {
mStartPage = 0;
mEndPage = 1;
mPages = 0;
mPageDivider.clear();
mData.clear();
onClearData();
mCurrentTaskId = mIdGenerator.nextId(); mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH; mCurrentTaskType = TYPE_REFRESH;
mCurrentTaskPage = 0; mCurrentTaskPage = 0;
@@ -34,7 +34,6 @@ import androidx.core.content.ContextCompat;
import com.hippo.conaco.Conaco; import com.hippo.conaco.Conaco;
import com.hippo.conaco.ConacoTask; import com.hippo.conaco.ConacoTask;
import com.hippo.conaco.DataContainer;
import com.hippo.conaco.Unikery; import com.hippo.conaco.Unikery;
import com.hippo.drawable.PreciselyClipDrawable; import com.hippo.drawable.PreciselyClipDrawable;
import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.EhApplication;
@@ -56,7 +55,6 @@ public class LoadImageView extends FixedAspectImageView implements Unikery<Image
private Conaco<ImageBitmap> mConaco; private Conaco<ImageBitmap> mConaco;
private String mKey; private String mKey;
private String mUrl; private String mUrl;
private DataContainer mContainer;
private boolean mUseNetwork; private boolean mUseNetwork;
private int mOffsetX = Integer.MIN_VALUE; private int mOffsetX = Integer.MIN_VALUE;
private int mOffsetY = Integer.MIN_VALUE; private int mOffsetY = Integer.MIN_VALUE;
@@ -109,7 +107,7 @@ public class LoadImageView extends FixedAspectImageView implements Unikery<Image
if (mFailed) { if (mFailed) {
onFailure(); onFailure();
} else if (mConaco.isLoading(this)) { } else if (mConaco.isLoading(this)) {
load(mKey, mUrl, mContainer, mUseNetwork); load(mKey, mUrl, mUseNetwork);
} }
} }
} }
@@ -209,15 +207,11 @@ public class LoadImageView extends FixedAspectImageView implements Unikery<Image
} }
public void load(String key, String url) { public void load(String key, String url) {
load(key, url, null, true); load(key, url, true);
} }
public void load(String key, String url, boolean useNetwork) { public void load(String key, String url, boolean useNetwork) {
load(key, url, null, useNetwork); if (url == null || (key == null)) {
}
public void load(String key, String url, DataContainer container, boolean useNetwork) {
if (url == null || (key == null && container == null)) {
return; return;
} }
@@ -226,14 +220,12 @@ public class LoadImageView extends FixedAspectImageView implements Unikery<Image
mKey = key; mKey = key;
mUrl = url; mUrl = url;
mContainer = container;
mUseNetwork = useNetwork; mUseNetwork = useNetwork;
ConacoTask.Builder<ImageBitmap> builder = new ConacoTask.Builder<ImageBitmap>() ConacoTask.Builder<ImageBitmap> builder = new ConacoTask.Builder<ImageBitmap>()
.setUnikery(this) .setUnikery(this)
.setKey(key) .setKey(key)
.setUrl(url) .setUrl(url)
.setDataContainer(container)
.setUseNetwork(useNetwork); .setUseNetwork(useNetwork);
mConaco.load(builder); mConaco.load(builder);
} }
@@ -255,7 +247,6 @@ public class LoadImageView extends FixedAspectImageView implements Unikery<Image
mConaco.cancel(this); mConaco.cancel(this);
mKey = null; mKey = null;
mUrl = null; mUrl = null;
mContainer = null;
clearDrawable(); clearDrawable();
} }
@@ -326,7 +317,6 @@ public class LoadImageView extends FixedAspectImageView implements Unikery<Image
// Can't retry, so release // Can't retry, so release
mKey = null; mKey = null;
mUrl = null; mUrl = null;
mContainer = null;
} }
} }
@@ -363,12 +353,12 @@ public class LoadImageView extends FixedAspectImageView implements Unikery<Image
@Override @Override
public void onClick(@NonNull View v) { public void onClick(@NonNull View v) {
load(mKey, mUrl, mContainer, true); load(mKey, mUrl, true);
} }
@Override @Override
public boolean onLongClick(@NonNull View v) { public boolean onLongClick(@NonNull View v) {
load(mKey, mUrl, mContainer, true); load(mKey, mUrl, true);
return true; return true;
} }
@@ -21,18 +21,49 @@
android:height="108dp" android:height="108dp"
android:viewportWidth="108" android:viewportWidth="108"
android:viewportHeight="108"> android:viewportHeight="108">
<group <group android:scaleX="0.7425"
android:scaleX="0.37947997" android:scaleY="0.7425"
android:scaleY="0.37947997" android:translateX="30.68"
android:translateX="35.1" android:translateY="30.68">
android:translateY="39.584126"> <path
<path android:pathData="M11,9H34"
android:fillColor="@color/ic_launcher_foreground" android:strokeWidth="8"
android:fillType="evenOdd" android:fillColor="#00000000"
android:pathData="M39.893,68.066L39.893,75.977L0,75.977L0,4.59L39.893,4.59L39.893,12.5L8.984,12.5L8.984,34.766L38.086,34.766L38.086,42.578L8.984,42.578L8.984,68.066L39.893,68.066Z" /> android:strokeColor="#FBBD06"
<path android:strokeLineCap="round"/>
android:fillColor="@color/ic_launcher_foreground" <path
android:fillType="evenOdd" android:pathData="M11,54H23"
android:pathData="M99.609,75.977L90.918,75.977L90.918,41.699A23.436,23.436 0,0 0,90.662 38.109Q90.055,34.207 88.013,31.958Q85.629,29.334 81.028,28.863A20.84,20.84 0,0 0,78.906 28.76A23.134,23.134 0,0 0,74.45 29.16Q71.926,29.656 69.994,30.767A11.122,11.122 0,0 0,66.968 33.301A13.32,13.32 0,0 0,64.756 37.276Q63.399,40.971 63.213,46.495A53.517,53.517 0,0 0,63.184 48.291L63.184,75.977L54.395,75.977L54.395,0L63.184,0L63.184,22.266A66.935,66.935 0,0 1,63.115 25.383Q63.043,26.914 62.897,28.251A33.547,33.547 0,0 1,62.695 29.785L63.281,29.785A16.11,16.11 0,0 1,69.394 24.035A19.448,19.448 0,0 1,70.068 23.682A20.88,20.88 0,0 1,77.292 21.622A25.763,25.763 0,0 1,79.98 21.484A32.643,32.643 0,0 1,85.483 21.917Q91.249,22.905 94.678,26.147Q98.472,29.735 99.347,36.631A35.274,35.274 0,0 1,99.609 41.064L99.609,75.977Z" /> android:strokeWidth="8"
</group> android:fillColor="#00000000"
android:strokeColor="#FBBD06"
android:strokeLineCap="round"/>
<path
android:pathData="M11,9L11,54"
android:strokeWidth="8"
android:fillColor="#00000000"
android:strokeColor="#35AA53"
android:strokeLineCap="round"/>
<path
android:pathData="M11,31L52,31"
android:strokeWidth="8"
android:fillColor="#00000000"
android:strokeColor="#FBBD06"
android:strokeLineCap="round"/>
<path
android:pathData="M52,31L52,54"
android:strokeWidth="8"
android:fillColor="#00000000"
android:strokeColor="#4586F3"
android:strokeLineCap="round"/>
<path
android:pathData="M34,21L34,54"
android:strokeWidth="8"
android:fillColor="#00000000"
android:strokeColor="#EB4334"
android:strokeLineCap="round"/>
<path
android:pathData="M15,35H11C8.791,35 7,33.209 7,31C7,28.791 8.791,27 11,27H15V35Z"
android:fillColor="#FBBD06"
android:fillType="evenOdd"/>
</group>
</vector> </vector>
@@ -42,7 +42,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:padding="@dimen/keyline_margin" android:padding="@dimen/keyline_margin"
app:srcCompat="@mipmap/ic_launcher" /> app:srcCompat="@drawable/ic_launcher_foreground" />
</LinearLayout> </LinearLayout>
@@ -77,10 +77,11 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<com.hippo.widget.LoadImageView <com.hippo.ehviewer.widget.FixedThumb
android:id="@+id/thumb" android:id="@+id/thumb"
android:layout_width="@dimen/gallery_detail_thumb_width" android:layout_width="@dimen/gallery_detail_thumb_width"
android:layout_height="@dimen/gallery_detail_thumb_height" /> android:layout_height="@dimen/gallery_detail_thumb_height"
app:alwaysCutAndScale="true"/>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
@@ -104,7 +105,7 @@
<TextView <TextView
android:id="@+id/language" android:id="@+id/language"
style="@style/TextAppearance.Material3.BodySmall" style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="start" android:gravity="start"
@@ -114,7 +115,7 @@
<TextView <TextView
android:id="@+id/size" android:id="@+id/size"
style="@style/TextAppearance.Material3.BodySmall" style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@@ -128,7 +129,7 @@
<TextView <TextView
android:id="@+id/favoredTimes" android:id="@+id/favoredTimes"
style="@style/TextAppearance.Material3.BodySmall" style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@@ -139,7 +140,7 @@
<TextView <TextView
android:id="@+id/pages" android:id="@+id/pages"
style="@style/TextAppearance.Material3.BodySmall" style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@@ -153,7 +154,7 @@
<TextView <TextView
android:id="@+id/posted" android:id="@+id/posted"
style="@style/TextAppearance.Material3.BodySmall" style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
+17 -9
View File
@@ -29,12 +29,20 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.hippo.ehviewer.widget.FixedThumb <com.google.android.material.card.MaterialCardView
android:id="@+id/thumb" android:id="@+id/thumb_card"
android:layout_width="@dimen/gallery_list_thumb_width" style="@style/Widget.Material3.CardView.Filled"
android:layout_height="@dimen/gallery_list_thumb_height" android:layout_width="wrap_content"
app:alwaysCutAndScale="true" android:layout_height="wrap_content">
app:retryType="longClick" />
<com.hippo.ehviewer.widget.ResizeableFixedThumb
android:id="@+id/thumb"
android:layout_width="0dp"
android:layout_height="0dp"
app:alwaysCutAndScale="true"
app:retryType="click"/>
</com.google.android.material.card.MaterialCardView>
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
@@ -45,7 +53,7 @@
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:layout_toEndOf="@id/thumb" /> android:layout_toEndOf="@id/thumb_card" />
<TextView <TextView
android:id="@+id/uploader" android:id="@+id/uploader"
@@ -70,7 +78,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignStart="@id/title" android:layout_alignStart="@id/title"
android:layout_alignBottom="@id/thumb" android:layout_alignBottom="@id/thumb_card"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingTop="2dp" android:paddingTop="2dp"
@@ -83,7 +91,7 @@
android:id="@+id/actions" android:id="@+id/actions"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignBottom="@+id/thumb" android:layout_alignBottom="@+id/thumb_card"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:paddingEnd="8dp"> android:paddingEnd="8dp">
@@ -35,12 +35,14 @@
<TextView <TextView
android:id="@+id/user" android:id="@+id/user"
style="@style/TextAppearance.Material3.TitleSmall"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?selectableItemBackground" /> android:background="?selectableItemBackground" />
<TextView <TextView
android:id="@+id/time" android:id="@+id/time"
style="@style/TextAppearance.Material3.TitleSmall"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" /> android:layout_alignParentEnd="true" />
@@ -15,6 +15,7 @@
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" <com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card" android:id="@+id/card"
style="@style/Widget.Material3.CardView.Elevated" style="@style/Widget.Material3.CardView.Elevated"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -31,15 +32,15 @@
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/thumb_card" android:id="@+id/thumb_card"
style="@style/Widget.Material3.CardView.Filled" style="@style/Widget.Material3.CardView.Filled"
android:layout_width="@dimen/gallery_list_thumb_width" android:layout_width="wrap_content"
android:layout_height="@dimen/gallery_list_thumb_height"> android:layout_height="wrap_content">
<com.hippo.ehviewer.widget.FixedThumb <com.hippo.ehviewer.widget.ResizeableFixedThumb
android:id="@+id/thumb" android:id="@+id/thumb"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="0dp"
app:alwaysCutAndScale="true" app:alwaysCutAndScale="true"
app:retryType="click" /> app:retryType="click"/>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
+1 -1
View File
@@ -38,7 +38,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:padding="@dimen/keyline_margin" android:padding="@dimen/keyline_margin"
app:srcCompat="@mipmap/ic_launcher" /> app:srcCompat="@drawable/ic_launcher_foreground" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/username_layout" android:id="@+id/username_layout"
@@ -60,6 +60,7 @@
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:indeterminate="true" android:indeterminate="true"
android:visibility="gone" android:visibility="gone"
app:fitsSystemWindowsInsets="end"
app:hideAnimationBehavior="inward" app:hideAnimationBehavior="inward"
app:showAnimationBehavior="outward" /> app:showAnimationBehavior="outward" />
@@ -15,7 +15,8 @@
~ You should have received a copy of the GNU General Public License along with EhViewer. ~ You should have received a copy of the GNU General Public License along with EhViewer.
~ If not, see <https://www.gnu.org/licenses/>. ~ If not, see <https://www.gnu.org/licenses/>.
--> -->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" /> <background android:drawable="@android:color/white"/>
<foreground android:drawable="@drawable/ic_launcher_foreground" /> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon> </adaptive-icon>
@@ -15,7 +15,8 @@
~ You should have received a copy of the GNU General Public License along with EhViewer. ~ You should have received a copy of the GNU General Public License along with EhViewer.
~ If not, see <https://www.gnu.org/licenses/>. ~ If not, see <https://www.gnu.org/licenses/>.
--> -->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" /> <background android:drawable="@android:color/white"/>
<foreground android:drawable="@drawable/ic_launcher_foreground" /> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon> </adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 B

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

-4
View File
@@ -15,10 +15,6 @@
--> -->
<resources> <resources>
<!-- divider -->
<color name="divider">#20ffffff</color> <color name="divider">#20ffffff</color>
<color name="navigation_bar_divider">#1fffffff</color> <color name="navigation_bar_divider">#1fffffff</color>
<!-- Lock pattern view -->
</resources> </resources>
+8 -3
View File
@@ -106,7 +106,6 @@
<string name="content_layout_restore_tip">点击重试</string> <string name="content_layout_restore_tip">点击重试</string>
<string name="write_rationale">EhViewer 将申请设备存储空间访问权限以便下载画廊。您愿意授权吗?</string> <string name="write_rationale">EhViewer 将申请设备存储空间访问权限以便下载画廊。您愿意授权吗?</string>
<string name="you_rejected_me">好痛</string> <string name="you_rejected_me">好痛</string>
<string name="analytics_explain">您同意让开发者收集您的设备信息与使用情况吗?这将对开发有很大帮助并将为您启用应用内更新。&lt;br&gt;&lt;br&gt;数据统计服务由 Microsoft AppCenter 提供,其隐私政策可在 &lt;a href=&quot;https://privacy.microsoft.com/zh-cn/privacystatement&quot;&gt;https://privacy.microsoft.com/zh-cn/privacystatement&lt;/a&gt; 查看。&lt;br&gt;&lt;br&gt;若您同意参与数据统计,您的设备信息与应用使用情况将会被记录,其包括但不限于:Android API 版本、设备型号、语言所在地、本应用版本号、会话时长、应用功能使用次数。开发者承诺以下信息并不会被记录:电话号码、电子邮件地址、IMEI。&lt;br&gt;&lt;br&gt;在您同意参与数据统计之前,您的信息不会被记录。&lt;br&gt;&lt;br&gt;被记录的数据会由 Microsoft AppCenter 进行分析,分析报表仅可被本应用开发者访问。</string>
<string name="get_it">知道了</string> <string name="get_it">知道了</string>
<string name="accept">接受</string> <string name="accept">接受</string>
<string name="reject">拒绝</string> <string name="reject">拒绝</string>
@@ -756,8 +755,8 @@
<string name="pick_new_download_location">选择新路径</string> <string name="pick_new_download_location">选择新路径</string>
<string name="dont_show_again">不再显示</string> <string name="dont_show_again">不再显示</string>
<string name="open_settings">打开设置</string> <string name="open_settings">打开设置</string>
<string name="app_link_not_verified_message">对于 Android 12 及更新的版本,您需要手动添加链接到已验证链接才能在 EhViewer 中打开 E-Hentai 链接。</string> <string name="app_link_not_verified_message">对于您的设备,我们强烈建议您使用 1.8 版本。1.7 版本仅为 Android 11 及以下版本设计</string>
<string name="app_link_not_verified_title">应用链接未验证</string> <string name="app_link_not_verified_title">升级 App 版本</string>
<string name="open_by_default">默认打开</string> <string name="open_by_default">默认打开</string>
<string name="show_library_version">依赖库之版本</string> <string name="show_library_version">依赖库之版本</string>
@@ -769,4 +768,10 @@
<string name="archive_need_passwd">归档文件需要密码</string> <string name="archive_need_passwd">归档文件需要密码</string>
<string name="passwd_wrong">密码错误</string> <string name="passwd_wrong">密码错误</string>
<string name="passwd_cannot_be_empty">密码不能为空</string> <string name="passwd_cannot_be_empty">密码不能为空</string>
<string name="list_tile_thumb_size">详情模式下缩略图大小</string>
<string name="backup_favorite">备份收藏列表</string>
<string name="backup_favorite_summary">备份云端收藏列表到本地</string>
<string name="backup_favorite_failed">备份收藏列表失败</string>
<string name="backup_favorite_success">备份收藏列表成功</string>
<string name="backup_favorite_start">正在备份收藏列表</string>
</resources> </resources>
+79 -9
View File
@@ -19,8 +19,8 @@
<string name="app_name">EhViewer</string> <string name="app_name">EhViewer</string>
<!-- Theme --> <!-- Theme -->
<string name="theme_light">亮色主題</string> <string name="theme_light">淺色主題</string>
<string name="theme_dark">暗色主題</string> <string name="theme_dark">深色主題</string>
<string name="theme_black">黑色主題</string> <string name="theme_black">黑色主題</string>
<string name="homepage">首頁</string> <string name="homepage">首頁</string>
@@ -144,7 +144,7 @@
<string name="search_specify_tag">指定標籤</string> <string name="search_specify_tag">指定標籤</string>
<string name="search_enable_advance">啟用進階選項</string> <string name="search_enable_advance">啟用進階選項</string>
<string name="search_tip">一般搜尋:就是搜尋。\n\n訂閱搜素:在訂閱中搜索。\n\n指定上傳者:列出該上傳者上傳的圖庫。其他選項會被忽略。\n\n指定標籤:列出含有該標籤的圖庫。其他選項會被忽略。</string> <string name="search_tip">一般搜尋:就是搜尋。\n\n訂閱搜尋:在訂閱中搜尋。\n\n指定上傳者:列出該上傳者上傳的圖庫。其他選項會被忽略。\n\n指定標籤:列出含有該標籤的圖庫。其他選項會被忽略。</string>
<string name="search_sname">搜尋圖庫</string> <string name="search_sname">搜尋圖庫</string>
<string name="search_stags">搜尋圖庫的標籤</string> <string name="search_stags">搜尋圖庫的標籤</string>
@@ -183,7 +183,7 @@
<string name="delete_quick_search_message">刪除“%s”嗎?</string> <string name="delete_quick_search_message">刪除“%s”嗎?</string>
<string name="no_quick_search">快速搜尋會顯示在這裡</string> <string name="no_quick_search">快速搜尋會顯示在這裡</string>
<string name="add_quick_search_tip">圖庫列表的狀態將被儲存為快速搜尋。如果你想儲存搜尋面板的狀態,請先進行搜尋。</string> <string name="add_quick_search_tip">圖庫列表的狀態將被儲存為快速搜尋。如果你想儲存搜尋面板的狀態,請先進行搜尋。</string>
<string name="readme">讀我檔</string> <string name="readme">ReadMe</string>
<string name="image_search_not_quick_search">無法將圖片搜尋加入快速搜尋</string> <string name="image_search_not_quick_search">無法將圖片搜尋加入快速搜尋</string>
<string name="duplicate_quick_search">已存在相同的快速搜尋,名稱為“%s”。</string> <string name="duplicate_quick_search">已存在相同的快速搜尋,名稱為“%s”。</string>
<string name="duplicate_name">已經由重複的名稱了</string> <string name="duplicate_name">已經由重複的名稱了</string>
@@ -234,7 +234,10 @@
<string name="add_to_favorite_failure">無法新增至收藏</string> <string name="add_to_favorite_failure">無法新增至收藏</string>
<string name="remove_from_favorite_failure">無法從收藏中移除</string> <string name="remove_from_favorite_failure">無法從收藏中移除</string>
<string name="filter_the_uploader">把上傳者“%s”加入濾除列表?</string> <string name="filter_the_uploader">把上傳者“%s”加入濾除列表?</string>
<string name="filter_the_tag">隱藏標籤“%s”?</string>
<string name="filter_added">已經新增篩選條件</string> <string name="filter_added">已經新增篩選條件</string>
<string name="newer_version_avaliable">此圖庫有新版本可以使用。</string>
<string name="newer_version_title">%1$s, 增加於 %2$s</string>
<!-- Rating --> <!-- Rating -->
<string name="rating10">太神啦!</string> <string name="rating10">太神啦!</string>
@@ -349,6 +352,7 @@
<string name="rename_label_title">重新命名標籤</string> <string name="rename_label_title">重新命名標籤</string>
<string name="delete_label_title">刪除標籤</string> <string name="delete_label_title">刪除標籤</string>
<string name="delete_label_message">將 “%s”刪除?</string> <string name="delete_label_message">將 “%s”刪除?</string>
<string name="rename_label">重新命名</string>
<!-- History --> <!-- History -->
<string name="no_history">歷史紀錄將會顯示在這裡</string> <string name="no_history">歷史紀錄將會顯示在這裡</string>
@@ -373,6 +377,7 @@
<string name="set_pattern_protection">設定圖形解鎖</string> <string name="set_pattern_protection">設定圖形解鎖</string>
<string name="set_pattern_protection_tip">繪製圖案來設定繪圖解鎖\n留白以取消圖案保護</string> <string name="set_pattern_protection_tip">繪製圖案來設定繪圖解鎖\n留白以取消圖案保護</string>
<string name="set">設定</string> <string name="set">設定</string>
<string name="enable_biometric">允許使用生物識別解鎖</string>
<!-- UConfig Activity --> <!-- UConfig Activity -->
<string name="u_config">EHentai 設定</string> <string name="u_config">EHentai 設定</string>
@@ -400,6 +405,7 @@
<string name="page_menu_refresh">@string/refresh</string> <string name="page_menu_refresh">@string/refresh</string>
<string name="page_menu_share">@string/share</string> <string name="page_menu_share">@string/share</string>
<string name="page_menu_save">儲存</string> <string name="page_menu_save">儲存</string>
<string name="page_menu_save_to">儲存到…</string>
<string name="page_menu_add_bookmark">新增書籤</string> <string name="page_menu_add_bookmark">新增書籤</string>
<string name="gallery_menu_title">選單</string> <string name="gallery_menu_title">選單</string>
<string name="share_image">分享圖片</string> <string name="share_image">分享圖片</string>
@@ -422,8 +428,8 @@
<string name="settings_my_tags">我的標籤</string> <string name="settings_my_tags">我的標籤</string>
<string name="settings_my_tags_summary">EHentai 網站上的我的標籤</string> <string name="settings_my_tags_summary">EHentai 網站上的我的標籤</string>
<string name="settings_eh_theme">主題</string> <string name="settings_eh_theme">主題</string>
<string name="settings_eh_theme_light">亮色</string> <string name="settings_eh_theme_light">淺色</string>
<string name="settings_eh_theme_dark">暗色</string> <string name="settings_eh_theme_dark">深色</string>
<string name="settings_eh_theme_black">黑色</string> <string name="settings_eh_theme_black">黑色</string>
<string name="settings_eh_apply_nav_bar_theme_color">導航欄應用主題配色</string> <string name="settings_eh_apply_nav_bar_theme_color">導航欄應用主題配色</string>
<string name="settings_eh_gallery_site">圖庫站台</string> <string name="settings_eh_gallery_site">圖庫站台</string>
@@ -465,6 +471,7 @@
<string name="settings_read_screen_rotation_default">系統預設</string> <string name="settings_read_screen_rotation_default">系統預設</string>
<string name="settings_read_screen_rotation_portrait">直向</string> <string name="settings_read_screen_rotation_portrait">直向</string>
<string name="settings_read_screen_rotation_landscape">橫向</string> <string name="settings_read_screen_rotation_landscape">橫向</string>
<string name="settings_read_screen_rotation_sensor">自動旋轉</string>
<string name="settings_read_reading_direction">閱讀方向</string> <string name="settings_read_reading_direction">閱讀方向</string>
<string name="settings_read_reading_direction_left_to_right">由左到右</string> <string name="settings_read_reading_direction_left_to_right">由左到右</string>
<string name="settings_read_reading_direction_right_to_Left">由右到左</string> <string name="settings_read_reading_direction_right_to_Left">由右到左</string>
@@ -490,6 +497,7 @@
<string name="settings_read_reading_fullscreen">全螢幕</string> <string name="settings_read_reading_fullscreen">全螢幕</string>
<string name="settings_read_custom_screen_lightness">自訂螢幕亮度</string> <string name="settings_read_custom_screen_lightness">自訂螢幕亮度</string>
<string name="settings_read_screen_lightness">螢幕亮度</string> <string name="settings_read_screen_lightness">螢幕亮度</string>
<string name="settings_read_reverse_volume">翻轉音量鍵</string>
<string name="settings_download">下載</string> <string name="settings_download">下載</string>
<string name="settings_download_download_location">下載路徑</string> <string name="settings_download_download_location">下載路徑</string>
@@ -525,7 +533,7 @@
<string name="settings_advanced">進階</string> <string name="settings_advanced">進階</string>
<string name="settings_advanced_save_parse_error_body">解析失敗時儲存網頁的內容</string> <string name="settings_advanced_save_parse_error_body">解析失敗時儲存網頁的內容</string>
<string name="settings_advanced_save_parse_error_body_summary">網頁內容可能含有敏感的隱私資料</string> <string name="settings_advanced_save_parse_error_body_summary">網頁內容可能含有敏感的隱私資料</string>
<string name="settings_advanced_save_crash_log">應用崩潰時儲存錯誤日誌</string> <string name="settings_advanced_save_crash_log">應用程式崩潰時儲存錯誤日誌</string>
<string name="settings_advanced_save_crash_log_summary">錯誤日誌可以幫助開發者修正問題</string> <string name="settings_advanced_save_crash_log_summary">錯誤日誌可以幫助開發者修正問題</string>
<string name="settings_advanced_dump_logcat">傾印log</string> <string name="settings_advanced_dump_logcat">傾印log</string>
<string name="settings_advanced_dump_logcat_summary">儲存log紀錄至外接儲存裝置中</string> <string name="settings_advanced_dump_logcat_summary">儲存log紀錄至外接儲存裝置中</string>
@@ -591,7 +599,7 @@
<string name="rewrite">改寫</string> <string name="rewrite">改寫</string>
<string name="language_japanese">日語</string> <string name="language_japanese">日語</string>
<string name="language_english">英語</string> <string name="language_english">英語</string>
<string name="language_chinese">漢語</string> <string name="language_chinese">中文</string>
<string name="language_dutch">荷蘭語</string> <string name="language_dutch">荷蘭語</string>
<string name="language_french">法語</string> <string name="language_french">法語</string>
<string name="language_german">德語</string> <string name="language_german">德語</string>
@@ -702,6 +710,68 @@
<string name="settings_privacy">隱私</string> <string name="settings_privacy">隱私</string>
<string name="settings_privacy_secure">不允許螢幕擷取</string> <string name="settings_privacy_secure">不允許螢幕擷取</string>
<string name="settings_privacy_secure_summary">啟用後,將無法對本程式進行螢幕擷取,同時,將不會在系統任務切換器中顯示該程式的預覽內容,重新啟動本程式以套用此變更</string> <string name="settings_privacy_secure_summary">啟用後,將無法對本程式進行螢幕擷取,同時,將不會在系統任務切換器中顯示該程式的預覽內容,重新啟動本程式以套用此變更</string>
<string name="favorite_name">收藏圖庫</string>
<string name="download_service">下載服務</string>
<string name="favorite_name">收藏圖庫</string>
<string name="black_dark_theme">純黑深色主題</string>
<string name="download_filter">過濾</string>
<string name="download_all">全部</string>
<string name="download_start_all_reversed">全部開始(倒序)</string>
<string name="settings_download_download_delay">下載延時</string>
<string name="settings_download_download_delay_summary">每次下載延時 %s 毫秒</string>
<string name="no_browser_installed">請安裝一個瀏覽器。</string>
<string name="toplist_alltime">從始至終</string>
<string name="toplist_pastyear">過去一年</string>
<string name="toplist_pastmonth">過去一個月</string>
<string name="toplist_yesterday">昨日</string>
<string name="toplist">排行</string>
<string name="tag_vote_down">不,這不是</string>
<string name="tag_vote_up">是的,這很正確</string>
<string name="tag_vote_successfully">投票成功</string>
<string name="from_clipboard">從剪貼板匯入</string>
<string name="from_clipboard_error">未在剪貼板中發現 Cookies。</string>
<string name="delete_search_history">從搜索記錄中刪除“%s”?</string>
<string name="settings_advanced_dns_over_http_title">安全 DNS(DoH)</string>
<string name="settings_advanced_dns_over_http_summary">解決某些地區的 DNS 汙染問題</string>
<string name="settings_advanced_domain_fronting_title">域名前綴</string>
<string name="settings_advanced_domain_fronting_summary">繞過 SNI 封鎖</string>
<string name="read_theme">色彩主題</string>
<string name="follow_app">跟隨應用</string>
<string name="settings_e_ink_mode_title">墨水屏模式</string>
<string name="settings_e_ink_mode_summary">為墨水屏做一些最佳化</string>
<string name="settings_advanced_clear_memory_cache_done">完成記憶體快取清理</string>
<string name="action_add_tag">增加標籤</string>
<string name="action_add_tag_tip">增加新標籤,用逗號「,」分割</string>
<string name="error_no_webview">WebView 不可用</string>
<string name="comment_user_uploader">%s (上傳者)</string>
<string name="settings_eh_metered_network_warning">流量計費網路警告</string>
<string name="metered_network_warning">正在使用流量計費網路</string>
<string name="read_from">從第 %d 頁閱讀</string>
<string name="settings_request_news_title">啟動時請求新聞頁面</string>
<string name="copy_trans">複製翻譯</string>
<string name="reset_download_location">恢復預設路徑</string>
<string name="pick_new_download_location">選擇新路徑</string>
<string name="dont_show_again">不再顯示</string>
<string name="open_settings">打開設定</string>
<string name="app_link_not_verified_message">對於 Android 12 及更新的版本,您需要手動增加連結到已驗證連結才能在 EhViewer 中打開 E-Hentai 連結。</string>
<string name="app_link_not_verified_title">應用連結未驗證</string>
<string name="open_by_default">預設打開</string>
<string name="show_library_version">依賴庫之版本</string>
<string name="settings_privacy_require_unlock">需要解鎖</string>
<string name="proxy_type_name">代理類型</string>
<string name="filter_label">隱藏項類型</string>
<string name="archive_passwd">封存文件密碼</string>
<string name="archive_need_passwd">封存文件需要密碼</string>
<string name="passwd_wrong">密碼錯誤</string>
<string name="passwd_cannot_be_empty">密碼不能為空</string>
<string name="list_tile_thumb_size">詳情模式下縮圖大小</string>
<string name="backup_favorite">備份收藏列表</string>
<string name="backup_favorite_summary">備份雲端收藏列表到本機</string>
<string name="backup_favorite_failed">備份收藏列表失敗</string>
<string name="backup_favorite_success">備份收藏列表成功</string>
<string name="backup_favorite_start">正在備份收藏列表</string>
</resources> </resources>
-4
View File
@@ -134,10 +134,6 @@
<attr name="url" format="string" /> <attr name="url" format="string" />
</declare-styleable> </declare-styleable>
<declare-styleable name="SeekBarPreference">
<attr name="max" format="integer" />
</declare-styleable>
<declare-styleable name="FastScroller"> <declare-styleable name="FastScroller">
<attr name="handler" format="reference" /> <attr name="handler" format="reference" />
<attr name="draggable" format="boolean" /> <attr name="draggable" format="boolean" />
@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2022 Tarsin Norbin
~
~ This file is part of EhViewer
~
~ EhViewer is free software: you can redistribute it and/or modify it
~ under the terms of the GNU GeneralPublic 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/>.
-->
<resources>
<color name="ic_launcher_background">#E2E0D0</color>
<color name="ic_launcher_foreground">#5C0D11</color>
</resources>
-33
View File
@@ -18,43 +18,10 @@
<color name="primary_drawable_black">#ccffffff</color> <color name="primary_drawable_black">#ccffffff</color>
<color name="secondary_drawable_black">#3dffffff</color> <color name="secondary_drawable_black">#3dffffff</color>
<color name="red_500">#fff44336</color> <color name="red_500">#fff44336</color>
<color name="purple_a700">#ffaa00ff</color>
<color name="cyan_600">#ff00acc1</color>
<color name="light_green_600">#ff7cb342</color>
<color name="yellow_800">#fff9a825</color> <color name="yellow_800">#fff9a825</color>
<color name="deep_orange_400">#ffff7043</color>
<color name="brown_500">#ff795548</color> <color name="brown_500">#ff795548</color>
<color name="loading_indicator_red">#ffe53935</color>
<color name="loading_indicator_purple">@color/purple_a700</color>
<color name="loading_indicator_blue">#ff1d87e4</color>
<color name="loading_indicator_cyan">@color/cyan_600</color>
<color name="loading_indicator_green">@color/light_green_600</color>
<color name="loading_indicator_yellow">@color/yellow_800</color>
<color name="loading_indicator_orange">@color/deep_orange_400</color>
<color name="navigation_bar_divider">#1f000000</color> <color name="navigation_bar_divider">#1f000000</color>
<!-- Red -->
<!-- Orange -->
<!-- Yellow 700 -->
<!-- Green -->
<!-- Light Green -->
<!-- Blue -->
<!-- Indigo -->
<!-- Purple -->
<!-- Deep Purple 300 -->
<!-- Pink 300 -->
<!-- divider -->
<color name="divider">#20000000</color> <color name="divider">#20000000</color>
<color name="divider_black">#20ffffff</color> <color name="divider_black">#20ffffff</color>
<!-- shadow -->
<!-- Gallery Activity -->
<!-- Lock pattern view -->
<!--Shortcut background-->
<color name="shortcut_bg">#F5F5F5</color> <color name="shortcut_bg">#F5F5F5</color>
</resources> </resources>
-2
View File
@@ -31,8 +31,6 @@
<dimen name="rating_size">16dp</dimen> <dimen name="rating_size">16dp</dimen>
<dimen name="rating_interval">1dp</dimen> <dimen name="rating_interval">1dp</dimen>
<dimen name="gallery_list_thumb_height">120dp</dimen>
<dimen name="gallery_list_thumb_width">80dp</dimen>
<!-- 4dp - 4dp, 4dp for card padding --> <!-- 4dp - 4dp, 4dp for card padding -->
<dimen name="gallery_list_interval">0dp</dimen> <dimen name="gallery_list_interval">0dp</dimen>
<!-- 8dp - 4dp, 4dp for card padding --> <!-- 8dp - 4dp, 4dp for card padding -->
-3
View File
@@ -60,13 +60,10 @@
<string name="pd_file_image" translatable="false">M13,9H18.5L13,3.5V9M6,2H14L20,8V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V4C4,2.89 4.89,2 6,2M6,20H15L18,20V12L14,16L12,14L6,20M8,9A2,2 0 0,0 6,11A2,2 0 0,0 8,13A2,2 0 0,0 10,11A2,2 0 0,0 8,9Z</string> <string name="pd_file_image" translatable="false">M13,9H18.5L13,3.5V9M6,2H14L20,8V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V4C4,2.89 4.89,2 6,2M6,20H15L18,20V12L14,16L12,14L6,20M8,9A2,2 0 0,0 6,11A2,2 0 0,0 8,13A2,2 0 0,0 10,11A2,2 0 0,0 8,9Z</string>
<string name="pd_eh_subscription" translatable="false">M20,8H4V6h16V8 M18,2H6v2h12V2 M20,10H4c-1.1,0-2,0.9-2,2v8c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2v-8C22,10.9,21.1,10,20,10zM11,14H7v1h4v2H7v1h4v2H5v-8h6V14z M19,20h-2v-3h-2v3h-2v-8h2v3h2v-3h2V20z</string> <string name="pd_eh_subscription" translatable="false">M20,8H4V6h16V8 M18,2H6v2h12V2 M20,10H4c-1.1,0-2,0.9-2,2v8c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2v-8C22,10.9,21.1,10,20,10zM11,14H7v1h4v2H7v1h4v2H5v-8h6V14z M19,20h-2v-3h-2v3h-2v-8h2v3h2v-3h2V20z</string>
<string name="pd_pencil" translatable="false">M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z</string> <string name="pd_pencil" translatable="false">M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z</string>
<string name="pd_big_history" translatable="false">M5.5,2H22V0H5C3.3,0,2,1.3,2,3V21C2,22.7,3.3,24,5,24H22V4H5.5C4.1,4,4.1,2,5.5,2ZM20,6V22H6V6H20M12.5,11.8V14.4L14.9,15.8L15.3,15.2L13.3,14V11.9M13.3,9.3C11.5,9.3,10,10.3,9.2,11.7L8,10.5V13.8H11.3L9.9,12.4C10.5,11.1,11.8,10.3,13.3,10.3C15.4,10.3,17.1,12,17.1,14.1S15.4,17.9,13.3,17.9C11.7,17.9,10.3,16.9,9.8,15.4H8.7C9.3,17.4,11.1,18.9,13.3,18.9C15.9,18.9,18.1,16.8,18.1,14.1C18,11.4,15.9,9.3,13.3,9.3Z</string> <string name="pd_big_history" translatable="false">M5.5,2H22V0H5C3.3,0,2,1.3,2,3V21C2,22.7,3.3,24,5,24H22V4H5.5C4.1,4,4.1,2,5.5,2ZM20,6V22H6V6H20M12.5,11.8V14.4L14.9,15.8L15.3,15.2L13.3,14V11.9M13.3,9.3C11.5,9.3,10,10.3,9.2,11.7L8,10.5V13.8H11.3L9.9,12.4C10.5,11.1,11.8,10.3,13.3,10.3C15.4,10.3,17.1,12,17.1,14.1S15.4,17.9,13.3,17.9C11.7,17.9,10.3,16.9,9.8,15.4H8.7C9.3,17.4,11.1,18.9,13.3,18.9C15.9,18.9,18.1,16.8,18.1,14.1C18,11.4,15.9,9.3,13.3,9.3Z</string>
<string name="pd_big_download" translatable="false">M0,19V24H24V19H0ZM16,22H15V21H16V22ZM19,22H18V21H19V22ZM22,22H21V21H22V22M15,11L15,0L9,0L9,11L5,11L12,18L19,11Z</string> <string name="pd_big_download" translatable="false">M0,19V24H24V19H0ZM16,22H15V21H16V22ZM19,22H18V21H19V22ZM22,22H21V21H22V22M15,11L15,0L9,0L9,11L5,11L12,18L19,11Z</string>
<string name="pd_big_filter" translatable="false">M22.9,2.84C24,0.44,15.08,0,12,0C9.06,0,0,0.43,1.1,2.84C1.6,3.94,10,15.76,10,15.76V21L14,24V15.76S22.4,3.96,22.9,2.84ZM12,1.94C16.25,1.94,20.15,2.51,20.15,3.17S16.25,4.34,12,4.34S3.97,3.8,3.97,3.17S7.76,1.94,12,1.94Z</string> <string name="pd_big_filter" translatable="false">M22.9,2.84C24,0.44,15.08,0,12,0C9.06,0,0,0.43,1.1,2.84C1.6,3.94,10,15.76,10,15.76V21L14,24V15.76S22.4,3.96,22.9,2.84ZM12,1.94C16.25,1.94,20.15,2.51,20.15,3.17S16.25,4.34,12,4.34S3.97,3.8,3.97,3.17S7.76,1.94,12,1.94Z</string>
<string name="pd_slider_bubble" translatable="false">M13,0C20.2,0,26,5.9,26,13.2,26,16.9,24,20.8,18.7,26.1L13,32,7.2,26.2C2,20.8,0,16.9,0,13.3,0,5.9,5.8,0,13,0Z</string> <string name="pd_slider_bubble" translatable="false">M13,0C20.2,0,26,5.9,26,13.2,26,16.9,24,20.8,18.7,26.1L13,32,7.2,26.2C2,20.8,0,16.9,0,13.3,0,5.9,5.8,0,13,0Z</string>
<string name="pd_sad_panda" translatable="false">M21.1,7.8C22.2,7.4,23,6.3,23,5C23,3.3,21.7,2,20,2C18.9,2,17.9,2.6,17.4,3.6L21.1,7.8M6.6,3.6C6.1,2.6,5.1,2,4,2C2.3,2,1,3.3,1,5C1,6.3,1.8,7.4,2.9,7.8L6.6,3.6M10.1,13L8,15.1C7.4,15.7,6.5,15.7,5.9,15.1L5.9,15.1C5.3,14.5,5.3,13.6,5.9,13L8,10.9C8.6,10.3,9.5,10.3,10.1,10.9L10.1,10.9C10.7,11.5,10.7,12.4,10.1,13M16,15.1L13.9,13C13.3,12.4,13.3,11.5,13.9,10.9L13.9,10.9C14.5,10.3,15.4,10.3,16,10.9L18.1,13C18.7,13.6,18.7,14.5,18.1,15.1L18.1,15.1C17.5,15.7,16.6,15.7,16,15.1M12,17C12.8,17,13.5,17.4,13.5,18S12.8,19,12,19S10.5,18.6,10.5,18S11.2,17,12,17Z</string> <string name="pd_sad_panda" translatable="false">M21.1,7.8C22.2,7.4,23,6.3,23,5C23,3.3,21.7,2,20,2C18.9,2,17.9,2.6,17.4,3.6L21.1,7.8M6.6,3.6C6.1,2.6,5.1,2,4,2C2.3,2,1,3.3,1,5C1,6.3,1.8,7.4,2.9,7.8L6.6,3.6M10.1,13L8,15.1C7.4,15.7,6.5,15.7,5.9,15.1L5.9,15.1C5.3,14.5,5.3,13.6,5.9,13L8,10.9C8.6,10.3,9.5,10.3,10.1,10.9L10.1,10.9C10.7,11.5,10.7,12.4,10.1,13M16,15.1L13.9,13C13.3,12.4,13.3,11.5,13.9,10.9L13.9,10.9C14.5,10.3,15.4,10.3,16,10.9L18.1,13C18.7,13.6,18.7,14.5,18.1,15.1L18.1,15.1C17.5,15.7,16.6,15.7,16,15.1M12,17C12.8,17,13.5,17.4,13.5,18S12.8,19,12,19S10.5,18.6,10.5,18S11.2,17,12,17Z</string>
<string name="pd_archive" translatable="false">M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM10,17l-3.5,-3.5 1.41,-1.41L10,14.17 15.18,9l1.41,1.41L10,17z</string> <string name="pd_archive" translatable="false">M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM10,17l-3.5,-3.5 1.41,-1.41L10,14.17 15.18,9l1.41,1.41L10,17z</string>
+8 -3
View File
@@ -148,7 +148,6 @@
<string name="content_layout_restore_tip">Tap to retry</string> <string name="content_layout_restore_tip">Tap to retry</string>
<string name="write_rationale">EhViewer will request WRITE_EXTERNAL_STORAGE permission for downloading gallery. Do you want to grant the permission?</string> <string name="write_rationale">EhViewer will request WRITE_EXTERNAL_STORAGE permission for downloading gallery. Do you want to grant the permission?</string>
<string name="you_rejected_me">It hurts</string> <string name="you_rejected_me">It hurts</string>
<string name="analytics_explain">Would you mind if the developer collected your device information and your usage? It will help the developer a lot.&lt;br&gt;&lt;br&gt;Data analysis service is provided by Microsoft AppCenter. Its privacy policy can be found at &lt;a href=&quot;https://privacy.microsoft.com/zh-cn/privacystatement&quot;&gt;https://privacy.microsoft.com/zh-cn/privacystatement&lt;/a&gt;.&lt;br&gt;&lt;br&gt;If you agree to join data analysis, your device information and your usage will be collected, including but not limited to Android API version, equipment model, language residence, the application version, conversion time, function times. The developer promise that these information will NOT be collected, including phone number, e-mail address, IMEI.&lt;br&gt;&lt;br&gt;Your information will not be collected until you agree to join data analysis.&lt;br&gt;&lt;br&gt;The collected information will be analyzed by Microsoft AppCenter. The analysis report can only be viewed by the developer of this application.</string>
<string name="get_it">Got it</string> <string name="get_it">Got it</string>
<string name="accept">Accept</string> <string name="accept">Accept</string>
<string name="reject">Reject</string> <string name="reject">Reject</string>
@@ -820,8 +819,8 @@
<string name="pick_new_download_location">Pick a new location</string> <string name="pick_new_download_location">Pick a new location</string>
<string name="dont_show_again">Don\'t show again</string> <string name="dont_show_again">Don\'t show again</string>
<string name="open_settings">Open settings</string> <string name="open_settings">Open settings</string>
<string name="app_link_not_verified_message">For Android 12 and newer, you need to manually add link to verified links in order to open E-Hentai links in EhViewer.</string> <string name="app_link_not_verified_message">For you device, We strongly recommend you to use version 1.8. version 1.7 is only made for Android 11 and below .</string>
<string name="app_link_not_verified_title">App links not verified</string> <string name="app_link_not_verified_title">Update App Version</string>
<string name="open_by_default">Open by default</string> <string name="open_by_default">Open by default</string>
<string name="show_library_version">Library Version</string> <string name="show_library_version">Library Version</string>
@@ -833,4 +832,10 @@
<string name="archive_need_passwd">Archive need password</string> <string name="archive_need_passwd">Archive need password</string>
<string name="passwd_wrong">Password Wrong</string> <string name="passwd_wrong">Password Wrong</string>
<string name="passwd_cannot_be_empty">Password can\'t be empty</string> <string name="passwd_cannot_be_empty">Password can\'t be empty</string>
<string name="list_tile_thumb_size">Thumb size in thumb mode</string>
<string name="backup_favorite">Backup favorite list</string>
<string name="backup_favorite_summary">Backup remote favorite list to local</string>
<string name="backup_favorite_failed">Backup favorite list failed</string>
<string name="backup_favorite_success">backup favorite list success</string>
<string name="backup_favorite_start">Now starting backup favorite list</string>
</resources> </resources>
+1 -3
View File
@@ -18,8 +18,6 @@
<style name="AppTheme" parent="Base.AppTheme" /> <style name="AppTheme" parent="Base.AppTheme" />
<!-- TextAppearance -->
<!-- Progress View --> <!-- Progress View -->
<style name="ProgressView"> <style name="ProgressView">
<item name="android:indeterminate">true</item> <item name="android:indeterminate">true</item>
@@ -34,7 +32,7 @@
</style> </style>
<style name="CardMessage"> <style name="CardMessage">
<item name="android:textAppearance">@style/TextAppearance.Material3.BodyMedium</item> <item name="android:textAppearance">@style/TextAppearance.Material3.LabelLarge</item>
<item name="android:ellipsize">end</item> <item name="android:ellipsize">end</item>
<item name="android:singleLine">true</item> <item name="android:singleLine">true</item>
<item name="android:maxLines">1</item> <item name="android:maxLines">1</item>
@@ -109,4 +109,10 @@
android:title="@string/open_by_default" android:title="@string/open_by_default"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<Preference
android:key="backup_favorite"
android:summary="@string/backup_favorite_summary"
android:title="@string/backup_favorite"
app:iconSpaceReserved="false" />
</PreferenceScreen> </PreferenceScreen>
+9
View File
@@ -82,6 +82,15 @@
app:entryValues="@array/list_mode_entry_values" app:entryValues="@array/list_mode_entry_values"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SeekBarPreference
android:defaultValue="40"
android:key="list_tile_size"
android:title="@string/list_tile_thumb_size"
android:max="60"
app:iconSpaceReserved="false"
app:min="20"
app:showSeekBarValue="true" />
<rikka.preference.SimpleMenuPreference <rikka.preference.SimpleMenuPreference
android:defaultValue="0" android:defaultValue="0"
android:key="detail_size" android:key="detail_size"
+1 -1
View File
@@ -122,8 +122,8 @@
android:dependency="custom_screen_lightness" android:dependency="custom_screen_lightness"
android:key="screen_lightness" android:key="screen_lightness"
android:title="@string/settings_read_screen_lightness" android:title="@string/settings_read_screen_lightness"
android:max="200"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:max="200"
app:showSeekBarValue="true" /> app:showSeekBarValue="true" />
</PreferenceScreen> </PreferenceScreen>
+55
View File
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="646" height="250" id="svg8502" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="get-it-on-github.svg" inkscape:export-filename="/home/nixdorf/Lokaler Speicher/Build/andOTP/assets/badges/get-it-on-github.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90">
<defs id="defs8504" />
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.50000001" inkscape:cx="-223.13537" inkscape:cy="546.37524" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1920" inkscape:window-height="1021" inkscape:window-x="0" inkscape:window-y="31" inkscape:window-maximized="1" />
<metadata id="metadata8507">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:creator>
<cc:Agent>
<dc:title>Andrew Nayenko</dc:title>
</cc:Agent>
</dc:creator>
<dc:publisher>
<cc:Agent>
<dc:title>https://f-droid.org</dc:title>
</cc:Agent>
</dc:publisher>
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
<dc:contributor>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-289,-312.36218)">
<rect style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#a6a6a6;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" id="rect3007" width="560" height="164" x="332" y="355.36218" rx="20" ry="20" />
<text sodipodi:linespacing="100%" id="text3013" y="402.36697" x="508.95129" style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.39519119px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';letter-spacing:0px;word-spacing:0px;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate" xml:space="preserve"><tspan y="402.36697" x="508.95129" id="tspan3015" sodipodi:role="line" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:34.125px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans'">GET IT ON</tspan></text>
<text xml:space="preserve" style="color:black;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:29.70882034px;line-height:100%;font-family:Rokkitt;-inkscape-font-specification:'Rokkitt Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate" x="508.21259" y="489.36108" id="text5902" sodipodi:linespacing="100%"><tspan sodipodi:role="line" id="tspan5904" x="508.21259" y="489.36108" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:87.5px;line-height:100%;font-family:'Roboto Slab';-inkscape-font-specification:'Roboto Slab Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:white;fill-opacity:1">GitHub</tspan></text>
<g transform="matrix(1.0017681,0,0,1.0017681,68.770756,92.660249)" id="g5136">
<path style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none" d="m 350.60937,282.4375 c -33.34765,0 -60.38671,27.03516 -60.38671,60.38672 0,26.67969 17.30078,49.3164 41.29687,57.30078 3.01563,0.55859 4.125,-1.30859 4.125,-2.90625 0,-1.4375 -0.0547,-6.19531 -0.082,-11.24219 -16.80078,3.65235 -20.34375,-7.125 -20.34375,-7.125 -2.75,-6.98047 -6.70703,-8.83594 -6.70703,-8.83594 -5.48047,-3.74609 0.41406,-3.67187 0.41406,-3.67187 6.0625,0.42578 9.25781,6.22266 9.25781,6.22266 5.38282,9.23437 14.125,6.5664 17.57032,5.02343 0.54296,-3.90234 2.10937,-6.57031 3.83593,-8.07812 -13.41406,-1.52735 -27.51562,-6.70313 -27.51562,-29.84375 0,-6.59375 2.35937,-11.98047 6.22265,-16.20703 -0.625,-1.52344 -2.6914,-7.66407 0.58594,-15.98047 0,0 5.07031,-1.625 16.60938,6.1875 4.82031,-1.33594 9.98437,-2.00781 15.11718,-2.03125 5.13282,0.0234 10.30079,0.69531 15.12891,2.03125 11.52344,-7.8125 16.58984,-6.1875 16.58984,-6.1875 3.28516,8.3164 1.21875,14.45703 0.58985,15.98047 3.87109,4.22656 6.21484,9.61328 6.21484,16.20703 0,23.19531 -14.125,28.30078 -27.57422,29.79687 2.16797,1.875 4.09766,5.55078 4.09766,11.1836 0,8.07812 -0.0703,14.58203 -0.0703,16.57031 0,1.60937 1.08593,3.49219 4.14843,2.89844 23.98047,-7.9961 41.26172,-30.6211 41.26172,-57.29297 0,-33.35156 -27.03515,-60.38672 -60.38672,-60.38672" id="path4937" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 313.09375,369.14062 c -0.13281,0.30079 -0.60547,0.38672 -1.03516,0.1836 -0.4375,-0.19922 -0.68359,-0.60547 -0.54297,-0.91016 0.12891,-0.30859 0.60157,-0.39062 1.03907,-0.1875 0.4414,0.19922 0.6914,0.61328 0.53906,0.91406" id="path4939" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 315.53906,371.86719 c -0.28906,0.26562 -0.85156,0.14453 -1.23437,-0.27735 -0.39453,-0.42187 -0.46875,-0.98437 -0.17578,-1.25781 0.29687,-0.26562 0.84375,-0.14062 1.23828,0.28125 0.39453,0.42578 0.47265,0.98438 0.17187,1.25391" id="path4941" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 317.92187,375.34375 c -0.37109,0.25781 -0.97656,0.0156 -1.35156,-0.51953 -0.37109,-0.53906 -0.37109,-1.17969 0.008,-1.4375 0.375,-0.25781 0.97266,-0.0274 1.35157,0.5039 0.36718,0.54688 0.36718,1.19141 -0.008,1.45313" id="path4943" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 321.18359,378.70312 c -0.33203,0.36719 -1.03906,0.26954 -1.55468,-0.23046 -0.52735,-0.48438 -0.67579,-1.17579 -0.34375,-1.54297 0.33593,-0.36328 1.04687,-0.26172 1.5664,0.23047 0.52344,0.48828 0.6836,1.18359 0.33203,1.54296" id="path4945-3" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 325.68359,380.65625 c -0.14843,0.47266 -0.82812,0.6875 -1.51172,0.48828 -0.68359,-0.20703 -1.1289,-0.76172 -0.99218,-1.24219 0.14453,-0.47265 0.82422,-0.69922 1.51562,-0.48437 0.67969,0.20703 1.12891,0.75781 0.98828,1.23828" id="path4947-6" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 330.625,381.01953 c 0.0156,0.49609 -0.5625,0.91016 -1.28125,0.91797 -0.72266,0.0156 -1.30859,-0.38672 -1.31641,-0.875 0,-0.50391 0.57032,-0.91406 1.28907,-0.92578 0.71875,-0.0156 1.30859,0.38672 1.30859,0.88281" id="path4949" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 335.22266,380.23437 c 0.0859,0.48829 -0.41407,0.98438 -1.125,1.11719 -0.70313,0.12891 -1.35157,-0.17187 -1.44141,-0.65234 -0.0859,-0.5 0.42187,-0.9961 1.12109,-1.125 0.71485,-0.125 1.35547,0.16797 1.44532,0.66015" id="path4951-7" inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

+10
View File
@@ -0,0 +1,10 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="108" height="108" rx="10" fill="white"/>
<path d="M32 31H55" stroke="#FBBD06" stroke-width="8" stroke-linecap="round"/>
<path d="M32 76H44" stroke="#FBBD06" stroke-width="8" stroke-linecap="round"/>
<line x1="32" y1="31" x2="32" y2="76" stroke="#35AA53" stroke-width="8" stroke-linecap="round"/>
<line x1="32" y1="53" x2="73" y2="53" stroke="#FBBD06" stroke-width="8" stroke-linecap="round"/>
<line x1="73" y1="53" x2="73" y2="76" stroke="#4586F3" stroke-width="8" stroke-linecap="round"/>
<path d="M55 43L55 76" stroke="#EB4334" stroke-width="8" stroke-linecap="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M36 57H32C29.7909 57 28 55.2091 28 53C28 50.7909 29.7909 49 32 49H36V57Z" fill="#FBBD06"/>
</svg>

After

Width:  |  Height:  |  Size: 832 B

+2 -2
View File
@@ -1,6 +1,6 @@
plugins { plugins {
id 'com.android.application' version '7.2.1' apply false id 'com.android.application' version '7.3.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
} }
task clean(type: Delete) { task clean(type: Delete) {
+110
View File
@@ -0,0 +1,110 @@
<p align="right">
<strong>English<strong>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-cn.md">
简体中文
</a>
<span> | <span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-tw.md">
正體中文
</a>
</p>
<h1 align="center">
<img src="../../art/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.7.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.7.x.x/docs/README/en.md#description">
Description
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/en.md#download">
Download
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/en.md#screenshot">
Screenshot
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/en.md#thanks">
Thanks
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.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="../../art/get-it-on-github.svg" width="200px"/></a>
App is divided into two versions: 1.7 and 1.8 . Version 1.8 support Android 12 and above, also the develop mainline. Version 1.7 support Android 11 and below, drop down some spicetify functions for Android 12 to make app useable on lower Android System
# Screenshot
![screenshot-01](../../art/screenshot-01.png)
![screenshot-02](../../art/screenshot-02.png)
# Thanks
Here is the libraries
- [AOSP & AndroidX](http://source.android.com/)
- [FullDraggableDrawer](https://github.com/PureWriter/FullDraggableDrawer)
- [GnuTLS](https://gnutls.org/)
- [material-components-android](https://github.com/material-components/material-components-android)
- [material-design-icons](https://github.com/google/material-design-icons)
- [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/)
- [apng](http://apng.sourceforge.net/)
- [giflib](http://giflib.sourceforge.net)
- [greenDAO](https://github.com/greenrobot/greenDAO)
- [jsoup](https://github.com/jhy/jsoup)
- [libjpeg-turbo](https://libjpeg-turbo.org/)
- [libpng](http://www.libpng.org/pub/png/libpng.html)
- [okhttp](https://github.com/square/okhttp)
- [roaster](https://github.com/forge/roaster)
- [libarchive](http://www.libarchive.org/)
- [XZ Utils](https://tukaani.org/xz/)
# License
Copyright 2014-2019 Hippo Seven
Copyright 2020-2022 NekoInverter
Copyright 2022 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/>.
+110
View File
@@ -0,0 +1,110 @@
<p align="right">
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/en.md">
English
</a>
<span> | </span>
<strong>简体中文<strong>
<span> | <span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-tw.md">
正體中文
</a>
</p>
<h1 align="center">
<img src="../../art/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.7.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.7.x.x/docs/README/zh-cn.md#描述">
描述
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-cn.md#下载">
下载
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-cn.md#截图">
截图
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-cn.md#感谢">
感谢
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-cn.md#许可证">
许可证
</a>
</h3>
</div>
# 描述
致力于轻量化与良好性能表现的 EhViewer 分支
已针对性适配 Material Design 3 及其动态取色系统
# 下载
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on Github" src="../../art/get-it-on-github.svg" width="200px"/></a>
App 分为 1.8 与 1.7 两个版本。1.8 版本适配 Android 12 及以上系统,为开发主线;1.7 版本适配 Android 11 及以下版本,削减了 Android 12 及以上系统的独有功能,使其能在低版本 Android 上正常工作
# 截图
![screenshot-01](../../art/screenshot-01.png)
![screenshot-02](../../art/screenshot-02.png)
# 感谢
本项目受到了诸多开源项目的帮助
- [AOSP & AndroidX](http://source.android.com/)
- [FullDraggableDrawer](https://github.com/PureWriter/FullDraggableDrawer)
- [GnuTLS](https://gnutls.org/)
- [material-components-android](https://github.com/material-components/material-components-android)
- [material-design-icons](https://github.com/google/material-design-icons)
- [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/)
- [apng](http://apng.sourceforge.net/)
- [giflib](http://giflib.sourceforge.net)
- [greenDAO](https://github.com/greenrobot/greenDAO)
- [jsoup](https://github.com/jhy/jsoup)
- [libjpeg-turbo](https://libjpeg-turbo.org/)
- [libpng](http://www.libpng.org/pub/png/libpng.html)
- [okhttp](https://github.com/square/okhttp)
- [roaster](https://github.com/forge/roaster)
- [libarchive](http://www.libarchive.org/)
- [XZ Utils](https://tukaani.org/xz/)
# 许可证
Copyright 2014-2019 Hippo Seven
Copyright 2020-2022 NekoInverter
Copyright 2022 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/>.
+110
View File
@@ -0,0 +1,110 @@
<p align="right">
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/en.md">
English
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-cn.md">
简体中文
</a>
<span> | <span>
<strong>正體中文<strong>
</p>
<h1 align="center">
<img src="../../art/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.7.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.7.x.x/docs/README/zh-tw.md#說明">
說明
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-tw.md#下載">
下載
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-tw.md#截圖">
截圖
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-tw.md#感謝">
感謝
</a>
<span> | </span>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/blob/1.7.x.x/docs/README/zh-tw.md#許可證書">
許可證書
</a>
</h3>
</div>
# 說明
致力於輕量化與良好性能表現的 EhViewer 分支
已針對性適配 Material Design 3 及其動態取色系統
# 下載
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on Github" src="../../art/get-it-on-github.svg" width="200px"/></a>
App 分為 1.8 與 1.7 兩個版本。1.8 版本適配 Android 12 及以上系統,為開發主線;1.7 版本適配 Android 11 及以下版本,削減了 Android 12 及以上系統的獨有功能,使其能在低版本 Android 上正常工作
# 截圖
![screenshot-01](../../art/screenshot-01.png)
![screenshot-02](../../art/screenshot-02.png)
# 感謝
本項目受到了諸多開源項目的幫助
- [AOSP & AndroidX](http://source.android.com/)
- [FullDraggableDrawer](https://github.com/PureWriter/FullDraggableDrawer)
- [GnuTLS](https://gnutls.org/)
- [material-components-android](https://github.com/material-components/material-components-android)
- [material-design-icons](https://github.com/google/material-design-icons)
- [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/)
- [apng](http://apng.sourceforge.net/)
- [giflib](http://giflib.sourceforge.net)
- [greenDAO](https://github.com/greenrobot/greenDAO)
- [jsoup](https://github.com/jhy/jsoup)
- [libjpeg-turbo](https://libjpeg-turbo.org/)
- [libpng](http://www.libpng.org/pub/png/libpng.html)
- [okhttp](https://github.com/square/okhttp)
- [roaster](https://github.com/forge/roaster)
- [libarchive](http://www.libarchive.org/)
- [XZ Utils](https://tukaani.org/xz/)
# 許可證書
Copyright 2014-2019 Hippo Seven
Copyright 2020-2022 NekoInverter
Copyright 2022 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/>.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
+1 -1
View File
@@ -37,5 +37,5 @@ android {
} }
dependencies { dependencies {
compileOnly 'androidx.annotation:annotation:1.4.0' compileOnly 'androidx.annotation:annotation:1.5.0'
} }
-1
View File
@@ -172,7 +172,6 @@ Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *_, jobject thiz, jstri
free(passwd); free(passwd);
passwd = calloc(len, sizeof(char)); passwd = calloc(len, sizeof(char));
strcpy(passwd, (*env)->GetStringUTFChars(env, str, NULL)); strcpy(passwd, (*env)->GetStringUTFChars(env, str, NULL));
LOGI("%s%s", "Passwd is ", passwd);
archive_alloc(); archive_alloc();
while (archive_read_next_header(arc, &entry) == ARCHIVE_OK) { while (archive_read_next_header(arc, &entry) == ARCHIVE_OK) {
if (!filename_is_playable_file(archive_entry_pathname(entry))) if (!filename_is_playable_file(archive_entry_pathname(entry)))