diff --git a/.idea/misc.xml b/.idea/misc.xml
index 7631aec3..84da703c 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index ea00135a..c7cfaa59 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -41,6 +41,7 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "ru.noties.markwon:core:${markwonVersion}"
implementation 'com.shawnlin:number-picker:2.4.8'
+ implementation 'com.github.clans:fab:1.6.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test:runner:1.1.1'
diff --git a/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt b/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt
index 80471c11..f6e56537 100644
--- a/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt
+++ b/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt
@@ -1,19 +1,23 @@
package xyz.quaver.pupil
import android.os.Bundle
-import android.util.Log
import android.view.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_reader.*
import kotlinx.android.synthetic.main.activity_reader.view.*
import kotlinx.android.synthetic.main.dialog_numberpicker.view.*
import kotlinx.coroutines.*
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonConfiguration
+import kotlinx.serialization.list
import xyz.quaver.hitomi.Reader
+import xyz.quaver.hitomi.ReaderItem
import xyz.quaver.hitomi.getReader
import xyz.quaver.hitomi.getReferer
import xyz.quaver.pupil.adapters.ReaderAdapter
@@ -32,7 +36,10 @@ class ReaderActivity : AppCompatActivity() {
private lateinit var reader: Deferred
private var loadJob: Job? = null
- private lateinit var snapHelper: PagerSnapHelper
+ private var isScroll = true
+ private var isFullscreen = false
+
+ private val snapHelper = PagerSnapHelper()
private var menu: Menu? = null
@@ -48,44 +55,39 @@ class ReaderActivity : AppCompatActivity() {
supportActionBar?.title = intent.getStringExtra("GALLERY_TITLE")
galleryID = intent.getIntExtra("GALLERY_ID", 0)
- CoroutineScope(Dispatchers.Unconfined).launch {
- reader = async(Dispatchers.IO) {
- val preference = PreferenceManager.getDefaultSharedPreferences(this@ReaderActivity)
- if (preference.getBoolean("use_hiyobi", false)) {
- try {
- xyz.quaver.hiyobi.getReader(galleryID)
- } catch (e: Exception) {
+ reader = CoroutineScope(Dispatchers.IO).async {
+ val json = Json(JsonConfiguration.Stable)
+ val serializer = ReaderItem.serializer().list
+ val preference = PreferenceManager.getDefaultSharedPreferences(this@ReaderActivity)
+ val isHiyobi = preference.getBoolean("use_hiyobi", false)
+
+ val cache = when {
+ isHiyobi -> File(cacheDir, "imageCache/$galleryID/reader-hiyobi.json")
+ else -> File(cacheDir, "imageCache/$galleryID/reader.json")
+ }
+
+ if (cache.exists())
+ json.parse(serializer, cache.readText())
+ else {
+ val reader = when {
+ isHiyobi -> {
+ try {
+ xyz.quaver.hiyobi.getReader(galleryID)
+ } catch (e: Exception) {
+ getReader(galleryID)
+ }
+ }
+ else -> {
getReader(galleryID)
}
}
- getReader(galleryID)
+
+ cache.writeText(json.stringify(serializer, reader))
+
+ reader
}
}
- snapHelper = PagerSnapHelper()
-
- val preferences = PreferenceManager.getDefaultSharedPreferences(this)
-
- val attrs = window.attributes
-
- if (preferences.getBoolean("reader_fullscreen", false)) {
- attrs.flags = attrs.flags or WindowManager.LayoutParams.FLAG_FULLSCREEN
- supportActionBar?.hide()
- } else {
- attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv()
- supportActionBar?.show()
- }
-
- window.attributes = attrs
-
- if (preferences.getBoolean("reader_one_by_one", false)) {
- snapHelper.attachToRecyclerView(reader_recyclerview)
- reader_recyclerview.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
- } else {
- snapHelper.attachToRecyclerView(null)
- reader_recyclerview.layoutManager = LinearLayoutManager(this)
- }
-
initView()
loadImages()
}
@@ -138,6 +140,21 @@ class ReaderActivity : AppCompatActivity() {
loadJob?.cancel()
}
+ override fun onBackPressed() {
+ if (isScroll and !isFullscreen)
+ super.onBackPressed()
+
+ if (isFullscreen) {
+ isFullscreen = false
+ fullscreen(false)
+ }
+
+ if (!isScroll) {
+ isScroll = true
+ scrollMode(true)
+ }
+ }
+
private fun initView() {
with(reader_recyclerview) {
adapter = ReaderAdapter(images)
@@ -155,45 +172,61 @@ class ReaderActivity : AppCompatActivity() {
}
})
- val preferences = PreferenceManager.getDefaultSharedPreferences(context)
ItemClickSupport.addTo(this)
.setOnItemClickListener { _, _, _ ->
- val attrs = window.attributes
- val fullscreen = preferences.getBoolean("reader_fullscreen", false)
+ if (isScroll) {
+ isScroll = false
+ isFullscreen = true
- if (fullscreen) {
- attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv()
- supportActionBar?.show()
+ scrollMode(false)
+ fullscreen(true)
} else {
- attrs.flags = attrs.flags or WindowManager.LayoutParams.FLAG_FULLSCREEN
- supportActionBar?.hide()
+ val smoothScroller = object : LinearSmoothScroller(context) {
+ override fun getVerticalSnapPreference() = SNAP_TO_START
+ }.apply {
+ targetPosition = currentPage
+ }
+ (reader_recyclerview.layoutManager as LinearLayoutManager?)?.startSmoothScroll(smoothScroller)
}
-
- window.attributes = attrs
-
- preferences.edit().putBoolean("reader_fullscreen", !fullscreen).apply()
- }.setOnItemLongClickListener { _, _, _ ->
- val oneByOne = preferences.getBoolean("reader_one_by_one", false)
- if (oneByOne) {
- snapHelper.attachToRecyclerView(null)
- reader_recyclerview.layoutManager = LinearLayoutManager(context)
- }
- else {
- snapHelper.attachToRecyclerView(reader_recyclerview)
- reader_recyclerview.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
- }
-
- (reader_recyclerview.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(currentPage-1, 0)
-
- preferences.edit().putBoolean("reader_one_by_one", !oneByOne).apply()
-
- true
}
}
+
+ reader_fab_fullscreen.setOnClickListener {
+ isFullscreen = true
+ fullscreen(isFullscreen)
+ }
+ }
+
+ private fun fullscreen(isFullscreen: Boolean) {
+ with(window.attributes) {
+ if (isFullscreen) {
+ flags = flags or WindowManager.LayoutParams.FLAG_FULLSCREEN
+ supportActionBar?.hide()
+ this@ReaderActivity.reader_fab.visibility = View.INVISIBLE
+ } else {
+ flags = flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv()
+ supportActionBar?.show()
+ this@ReaderActivity.reader_fab.visibility = View.VISIBLE
+ }
+
+ window.attributes = this
+ }
+ }
+
+ private fun scrollMode(isScroll: Boolean) {
+ if (isScroll) {
+ snapHelper.attachToRecyclerView(null)
+ reader_recyclerview.layoutManager = LinearLayoutManager(this)
+ } else {
+ snapHelper.attachToRecyclerView(reader_recyclerview)
+ reader_recyclerview.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
+ }
+
+ (reader_recyclerview.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(currentPage-1, 0)
}
private fun loadImages() {
- fun webpUrlFromUrl(url: URL) = URL(url.toString().replace("/galleries/", "/webp/") + ".webp")
+ fun webpUrlFromUrl(url: String) = url.replace("/galleries/", "/webp/") + ".webp"
loadJob = CoroutineScope(Dispatchers.Default).launch {
val reader = reader.await()
@@ -213,18 +246,18 @@ class ReaderActivity : AppCompatActivity() {
reader.chunked(8).forEach { chunked ->
chunked.map {
async(Dispatchers.IO) {
- val url = if (it.second?.haswebp == 1) webpUrlFromUrl(it.first) else it.first
+ val url = if (it.galleryInfo?.haswebp == 1) webpUrlFromUrl(it.url) else it.url
val fileName: String
- with(url.path) {
+ with(url) {
fileName = substring(lastIndexOf('/')+1)
}
val cache = File(cacheDir, "/imageCache/$galleryID/$fileName")
if (!cache.exists())
- with(url.openConnection() as HttpsURLConnection) {
+ with(URL(url).openConnection() as HttpsURLConnection) {
setRequestProperty("Referer", getReferer(galleryID))
if (!cache.parentFile.exists())
diff --git a/app/src/main/res/drawable-anydpi/ic_fullscreen.xml b/app/src/main/res/drawable-anydpi/ic_fullscreen.xml
new file mode 100644
index 00000000..f9831623
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_fullscreen.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable-hdpi/ic_fullscreen.png b/app/src/main/res/drawable-hdpi/ic_fullscreen.png
new file mode 100644
index 00000000..c72a9b9e
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_fullscreen.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_fullscreen.png b/app/src/main/res/drawable-mdpi/ic_fullscreen.png
new file mode 100644
index 00000000..f19ccbfa
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_fullscreen.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_fullscreen.png b/app/src/main/res/drawable-xhdpi/ic_fullscreen.png
new file mode 100644
index 00000000..6caba05d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_fullscreen.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_fullscreen.png b/app/src/main/res/drawable-xxhdpi/ic_fullscreen.png
new file mode 100644
index 00000000..4712c6c1
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_fullscreen.png differ
diff --git a/app/src/main/res/drawable/github_circle.xml b/app/src/main/res/drawable/github_circle.xml
new file mode 100644
index 00000000..7df41959
--- /dev/null
+++ b/app/src/main/res/drawable/github_circle.xml
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_reader.xml b/app/src/main/res/layout/activity_reader.xml
index a77f48e5..f77b8d6b 100644
--- a/app/src/main/res/layout/activity_reader.xml
+++ b/app/src/main/res/layout/activity_reader.xml
@@ -6,12 +6,18 @@
android:layout_height="match_parent"
tools:context=".ReaderActivity">
-
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical">
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index d9519336..a0018929 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -43,4 +43,5 @@
メールを送る
準備中
準備中です。
+ フルスクリーン
\ No newline at end of file
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 1ecefb30..a4de07d9 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -43,4 +43,5 @@
문의
준비 중
준비중입니다.\n만화 화면에서 사진을 길게 누르면 스크롤 방식이 바뀝니다. 알고 계셨나요? :)
+ 전체 화면
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 551b9f54..97f25378 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -48,6 +48,7 @@
Language: %1$s
Go to page
+ Fullscreen
Settings
Search Settings
diff --git a/libpupil/src/main/java/xyz/quaver/hitomi/readers.kt b/libpupil/src/main/java/xyz/quaver/hitomi/readers.kt
index 5fee483d..f2a06ec1 100644
--- a/libpupil/src/main/java/xyz/quaver/hitomi/readers.kt
+++ b/libpupil/src/main/java/xyz/quaver/hitomi/readers.kt
@@ -16,7 +16,12 @@ data class GalleryInfo(
val name: String,
val height: Int
)
-typealias Reader = List>
+@Serializable
+data class ReaderItem(
+ val url: String,
+ val galleryInfo: GalleryInfo?
+)
+typealias Reader = List
//Set header `Referer` to reader url to avoid 403 error
fun getReader(galleryID: Int) : Reader {
val readerUrl = "https://hitomi.la/reader/$galleryID.html"
@@ -25,7 +30,7 @@ fun getReader(galleryID: Int) : Reader {
val doc = Jsoup.connect(readerUrl).get()
val images = doc.select(".img-url").map {
- URL(protocol + urlFromURL(it.text()))
+ protocol + urlFromURL(it.text())
}
val galleryInfo = ArrayList()
@@ -42,5 +47,7 @@ fun getReader(galleryID: Int) : Reader {
if (images.size > galleryInfo.size)
galleryInfo.addAll(arrayOfNulls(images.size - galleryInfo.size))
- return images zip galleryInfo
+ return (images zip galleryInfo).map {
+ ReaderItem(it.first, it.second)
+ }
}
\ No newline at end of file
diff --git a/libpupil/src/main/java/xyz/quaver/hiyobi/reader.kt b/libpupil/src/main/java/xyz/quaver/hiyobi/reader.kt
index dfd289bb..47f766b4 100644
--- a/libpupil/src/main/java/xyz/quaver/hiyobi/reader.kt
+++ b/libpupil/src/main/java/xyz/quaver/hiyobi/reader.kt
@@ -4,6 +4,7 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.json.content
import xyz.quaver.hitomi.Reader
+import xyz.quaver.hitomi.ReaderItem
import java.net.URL
import javax.net.ssl.HttpsURLConnection
@@ -42,6 +43,6 @@ fun getReader(galleryId: Int) : Reader {
return json.jsonArray.map {
val name = it.jsonObject["name"]!!.content
- Pair(URL("https://$hiyobi/data/$galleryId/$name"), null)
+ ReaderItem("https://$hiyobi/data/$galleryId/$name", null)
}
}
\ No newline at end of file