Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9415ab4ef9 | ||
|
|
647294daf2 | ||
|
|
6ebc386474 |
@@ -20,7 +20,7 @@ android {
|
|||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 57
|
versionCode 57
|
||||||
versionName "4.20"
|
versionName "4.21"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"filters": [],
|
"filters": [],
|
||||||
"properties": [],
|
"properties": [],
|
||||||
"versionCode": 57,
|
"versionCode": 57,
|
||||||
"versionName": "4.20",
|
"versionName": "4.21",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"outputFile": "app-release.apk"
|
"outputFile": "app-release.apk"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
package xyz.quaver.pupil.adapters
|
package xyz.quaver.pupil.adapters
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.PorterDuff
|
||||||
|
import android.graphics.PorterDuffColorFilter
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.SparseBooleanArray
|
import android.util.SparseBooleanArray
|
||||||
@@ -221,12 +224,16 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri
|
|||||||
"male" -> {
|
"male" -> {
|
||||||
setChipBackgroundColorResource(R.color.material_blue_700)
|
setChipBackgroundColorResource(R.color.material_blue_700)
|
||||||
setTextColor(ContextCompat.getColor(context, android.R.color.white))
|
setTextColor(ContextCompat.getColor(context, android.R.color.white))
|
||||||
ContextCompat.getDrawable(context, R.drawable.gender_male)
|
ContextCompat.getDrawable(context, R.drawable.gender_male)?.apply {
|
||||||
|
colorFilter = PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"female" -> {
|
"female" -> {
|
||||||
setChipBackgroundColorResource(R.color.material_pink_600)
|
setChipBackgroundColorResource(R.color.material_pink_600)
|
||||||
setTextColor(ContextCompat.getColor(context, android.R.color.white))
|
setTextColor(ContextCompat.getColor(context, android.R.color.white))
|
||||||
ContextCompat.getDrawable(context, R.drawable.gender_female)
|
ContextCompat.getDrawable(context, R.drawable.gender_female)?.apply {
|
||||||
|
colorFilter = PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import xyz.quaver.pupil.util.download.Cache
|
|||||||
import xyz.quaver.pupil.util.download.DownloadWorker
|
import xyz.quaver.pupil.util.download.DownloadWorker
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.concurrent.schedule
|
import kotlin.concurrent.schedule
|
||||||
|
import kotlin.concurrent.timer
|
||||||
|
|
||||||
class ReaderActivity : AppCompatActivity() {
|
class ReaderActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@@ -71,6 +72,7 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val timer = Timer()
|
private val timer = Timer()
|
||||||
|
private var autoTimer: Timer? = null
|
||||||
|
|
||||||
private val snapHelper = PagerSnapHelper()
|
private val snapHelper = PagerSnapHelper()
|
||||||
|
|
||||||
@@ -380,6 +382,30 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
with(reader_fab_auto) {
|
||||||
|
setImageResource(R.drawable.clock_start)
|
||||||
|
setOnClickListener {
|
||||||
|
if (autoTimer == null) {
|
||||||
|
autoTimer = timer(initialDelay = 10000L, period = 10000L) {
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
with(this@ReaderActivity.reader_recyclerview) {
|
||||||
|
val lastItem =
|
||||||
|
(layoutManager as LinearLayoutManager).findLastCompletelyVisibleItemPosition()
|
||||||
|
|
||||||
|
if (lastItem < adapter!!.itemCount - 1)
|
||||||
|
(layoutManager as LinearLayoutManager).scrollToPosition(lastItem + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setImageResource(R.drawable.clock_end)
|
||||||
|
} else {
|
||||||
|
autoTimer?.cancel()
|
||||||
|
autoTimer = null
|
||||||
|
setImageResource(R.drawable.clock_start)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
with(reader_fab_fullscreen) {
|
with(reader_fab_fullscreen) {
|
||||||
setImageResource(R.drawable.ic_fullscreen)
|
setImageResource(R.drawable.ic_fullscreen)
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
|
|||||||
@@ -79,13 +79,16 @@ class SettingsFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getDirSize(dir: File) : String {
|
private fun getDirSize(dir: File) : String {
|
||||||
return getString(R.string.settings_storage_usage,
|
return if (activity != null)
|
||||||
|
getString(R.string.settings_storage_usage,
|
||||||
Runtime.getRuntime().exec("du -hs " + dir.absolutePath).let {
|
Runtime.getRuntime().exec("du -hs " + dir.absolutePath).let {
|
||||||
BufferedReader(InputStreamReader(it.inputStream)).use { reader ->
|
BufferedReader(InputStreamReader(it.inputStream)).use { reader ->
|
||||||
reader.readLine().split('\t').firstOrNull() ?: "0"
|
reader.readLine()?.split('\t')?.firstOrNull() ?: "0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
else
|
||||||
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPreferenceClick(preference: Preference?): Boolean {
|
override fun onPreferenceClick(preference: Preference?): Boolean {
|
||||||
@@ -106,11 +109,13 @@ class SettingsFragment :
|
|||||||
if (dir.exists())
|
if (dir.exists())
|
||||||
dir.deleteRecursively()
|
dir.deleteRecursively()
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
summary = getString(R.string.settings_storage_usage_loading)
|
summary = getString(R.string.settings_storage_usage_loading)
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
getDirSize(dir).let {
|
||||||
launch(Dispatchers.Main) {
|
launch(Dispatchers.Main) {
|
||||||
this@with.summary = getDirSize(dir)
|
this@with.summary = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,11 +132,13 @@ class SettingsFragment :
|
|||||||
if (dir.exists())
|
if (dir.exists())
|
||||||
dir.deleteRecursively()
|
dir.deleteRecursively()
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
summary = getString(R.string.settings_storage_usage_loading)
|
summary = getString(R.string.settings_storage_usage_loading)
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
getDirSize(dir).let {
|
||||||
launch(Dispatchers.Main) {
|
launch(Dispatchers.Main) {
|
||||||
this@with.summary = getDirSize(dir)
|
this@with.summary = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -298,11 +305,12 @@ class SettingsFragment :
|
|||||||
"delete_cache" -> {
|
"delete_cache" -> {
|
||||||
val dir = File(requireContext().cacheDir, "imageCache")
|
val dir = File(requireContext().cacheDir, "imageCache")
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
summary = getString(R.string.settings_storage_usage_loading)
|
summary = getString(R.string.settings_storage_usage_loading)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
getDirSize(dir).let {
|
||||||
launch(Dispatchers.Main) {
|
launch(Dispatchers.Main) {
|
||||||
this@with.summary = getDirSize(dir)
|
this@with.summary = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,11 +319,12 @@ class SettingsFragment :
|
|||||||
"delete_downloads" -> {
|
"delete_downloads" -> {
|
||||||
val dir = getDownloadDirectory(requireContext())
|
val dir = getDownloadDirectory(requireContext())
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
summary = getString(R.string.settings_storage_usage_loading)
|
summary = getString(R.string.settings_storage_usage_loading)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
getDirSize(dir).let {
|
||||||
launch(Dispatchers.Main) {
|
launch(Dispatchers.Main) {
|
||||||
this@with.summary = getDirSize(dir)
|
this@with.summary = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
8
app/src/main/res/drawable/clock_end.xml
Normal file
8
app/src/main/res/drawable/clock_end.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/clock_end.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#fff" android:pathData="M12,1C8.14,1 5,4.14 5,8A7,7 0 0,0 12,15C15.86,15 19,11.87 19,8C19,4.14 15.86,1 12,1M12,3.15C14.67,3.15 16.85,5.32 16.85,8C16.85,10.68 14.67,12.85 12,12.85A4.85,4.85 0 0,1 7.15,8A4.85,4.85 0 0,1 12,3.15M11,5V8.69L14.19,10.53L14.94,9.23L12.5,7.82V5M15,16V19H3V21H15V24L19,20M19,20V24H21V16H19" />
|
||||||
|
</vector>
|
||||||
8
app/src/main/res/drawable/clock_start.xml
Normal file
8
app/src/main/res/drawable/clock_start.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/clock_start.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#fff" android:pathData="M12,1C8.14,1 5,4.14 5,8A7,7 0 0,0 12,15C15.86,15 19,11.87 19,8C19,4.14 15.86,1 12,1M12,3.15C14.67,3.15 16.85,5.32 16.85,8C16.85,10.68 14.67,12.85 12,12.85A4.85,4.85 0 0,1 7.15,8A4.85,4.85 0 0,1 12,3.15M11,5V8.69L14.19,10.53L14.94,9.23L12.5,7.82V5M4,16V24H6V21H18V24L22,20L18,16V19H6V16" />
|
||||||
|
</vector>
|
||||||
@@ -82,6 +82,13 @@
|
|||||||
app:fab_label="@string/reader_fab_retry"
|
app:fab_label="@string/reader_fab_retry"
|
||||||
app:fab_size="mini"/>
|
app:fab_size="mini"/>
|
||||||
|
|
||||||
|
<com.github.clans.fab.FloatingActionButton
|
||||||
|
android:id="@+id/reader_fab_auto"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:fab_label="@string/reader_fab_auto"
|
||||||
|
app:fab_size="mini"/>
|
||||||
|
|
||||||
<com.github.clans.fab.FloatingActionButton
|
<com.github.clans.fab.FloatingActionButton
|
||||||
android:id="@+id/reader_fab_fullscreen"
|
android:id="@+id/reader_fab_fullscreen"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
@@ -151,4 +151,5 @@
|
|||||||
<string name="settings_user_id_toast">ユーザーIDをクリップボードにコピーしました</string>
|
<string name="settings_user_id_toast">ユーザーIDをクリップボードにコピーしました</string>
|
||||||
<string name="reader_error_retry">ダウンロードエラーが発生しました。リトライしますか?</string>
|
<string name="reader_error_retry">ダウンロードエラーが発生しました。リトライしますか?</string>
|
||||||
<string name="reader_fab_retry">リトライ</string>
|
<string name="reader_fab_retry">リトライ</string>
|
||||||
|
<string name="reader_fab_auto">自動スクロール</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -151,4 +151,5 @@
|
|||||||
<string name="settings_user_id_toast">유저 ID를 클립보드에 복사했습니다</string>
|
<string name="settings_user_id_toast">유저 ID를 클립보드에 복사했습니다</string>
|
||||||
<string name="reader_error_retry">다운로드 에러가 발생했습니. 재시도 하시겠습니까?</string>
|
<string name="reader_error_retry">다운로드 에러가 발생했습니. 재시도 하시겠습니까?</string>
|
||||||
<string name="reader_fab_retry">재시도</string>
|
<string name="reader_fab_retry">재시도</string>
|
||||||
|
<string name="reader_fab_auto">자동 스크롤</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -115,6 +115,7 @@
|
|||||||
<string name="reader_go_to_page">Go to page</string>
|
<string name="reader_go_to_page">Go to page</string>
|
||||||
<string name="reader_fab_fullscreen">Fullscreen</string>>
|
<string name="reader_fab_fullscreen">Fullscreen</string>>
|
||||||
<string name="reader_fab_retry">Retry</string>
|
<string name="reader_fab_retry">Retry</string>
|
||||||
|
<string name="reader_fab_auto">Automatic scroll</string>
|
||||||
<string name="reader_fab_download">Background download</string>
|
<string name="reader_fab_download">Background download</string>
|
||||||
<string name="reader_fab_download_cancel">Cancel background download</string>
|
<string name="reader_fab_download_cancel">Cancel background download</string>
|
||||||
<string name="reader_notification_text">Downloading…</string>
|
<string name="reader_notification_text">Downloading…</string>
|
||||||
|
|||||||
@@ -33,12 +33,11 @@ fun getGalleryInfo(galleryID: Int) =
|
|||||||
|
|
||||||
//common.js
|
//common.js
|
||||||
var adapose = false
|
var adapose = false
|
||||||
const val numberOfFrontends = 3
|
|
||||||
const val domain = "ltn.hitomi.la"
|
const val domain = "ltn.hitomi.la"
|
||||||
const val galleryblockdir = "galleryblock"
|
const val galleryblockdir = "galleryblock"
|
||||||
const val nozomiextension = ".nozomi"
|
const val nozomiextension = ".nozomi"
|
||||||
|
|
||||||
fun subdomainFromGalleryID(g: Int) : String {
|
fun subdomainFromGalleryID(g: Int, numberOfFrontends: Int) : String {
|
||||||
if (adapose)
|
if (adapose)
|
||||||
return "0"
|
return "0"
|
||||||
|
|
||||||
@@ -53,13 +52,20 @@ fun subdomainFromURL(url: String, base: String? = null) : String {
|
|||||||
if (!base.isNullOrBlank())
|
if (!base.isNullOrBlank())
|
||||||
retval = base
|
retval = base
|
||||||
|
|
||||||
|
var numberOfFrontends = 3
|
||||||
val b = 16
|
val b = 16
|
||||||
|
|
||||||
val r = Regex("""/[0-9a-f]/([0-9a-f]{2})/""")
|
val r = Regex("""/[0-9a-f]/([0-9a-f]{2})/""")
|
||||||
val m = r.find(url) ?: return retval
|
val m = r.find(url) ?: return retval
|
||||||
|
|
||||||
val g = m.groupValues[1].toIntOrNull(b) ?: return retval
|
var g = m.groupValues[1].toIntOrNull(b) ?: return retval
|
||||||
|
|
||||||
retval = subdomainFromGalleryID(g) + retval
|
when {
|
||||||
|
g < 0x30 -> numberOfFrontends = 2
|
||||||
|
g < 0x09 -> g = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = subdomainFromGalleryID(g, numberOfFrontends) + retval
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,13 @@ class UnitTest {
|
|||||||
print(reader)
|
print(reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_getImages() {
|
||||||
|
val reader = getReader(1702206)
|
||||||
|
|
||||||
|
print(urlFromUrlFromHash(1702206, reader.galleryInfo.files.first(), "webp"))
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun test_hiyobi() {
|
fun test_hiyobi() {
|
||||||
val reader = xyz.quaver.hiyobi.getReader(1664762)
|
val reader = xyz.quaver.hiyobi.getReader(1664762)
|
||||||
|
|||||||
Reference in New Issue
Block a user