diff --git a/.idea/dictionaries/rumia.xml b/.idea/dictionaries/rumia.xml
index dff7651..b4964f2 100644
--- a/.idea/dictionaries/rumia.xml
+++ b/.idea/dictionaries/rumia.xml
@@ -4,6 +4,7 @@
copymanga
fileprovider
fumiama
+ statuscardflow
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index e01d39c..34788ed 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -28,8 +28,8 @@ android {
applicationId 'top.fumiama.copymanga'
minSdkVersion 23
targetSdkVersion 30
- versionCode 16
- versionName '2.0.beta5'
+ versionCode 17
+ versionName '2.0.beta6'
resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/app/src/main/java/top/fumiama/copymanga/template/ui/StatusCardFlow.kt b/app/src/main/java/top/fumiama/copymanga/template/ui/StatusCardFlow.kt
new file mode 100644
index 0000000..cde09bf
--- /dev/null
+++ b/app/src/main/java/top/fumiama/copymanga/template/ui/StatusCardFlow.kt
@@ -0,0 +1,75 @@
+package top.fumiama.copymanga.template.ui
+
+import android.animation.ObjectAnimator
+import android.view.View
+import kotlinx.android.synthetic.main.anchor_popular.view.*
+import kotlinx.android.synthetic.main.line_finish.*
+import kotlinx.android.synthetic.main.line_lazybooklines.*
+import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
+import top.fumiama.dmzj.copymanga.R
+
+@ExperimentalStdlibApi
+open class StatusCardFlow(private val api: Int, nav: Int) : InfoCardLoader(R.layout.fragment_statuscardflow, nav) {
+ val sortWay = listOf("datetime_updated", "-datetime_updated", "popular", "-popular")
+ var sortValue = 0
+
+ override fun getApiUrl() =
+ getString(api).let {
+ String.format(
+ it,
+ page * 21,
+ sortWay[sortValue]
+ )
+ }
+
+ override fun setListeners() {
+ super.setListeners()
+ setUpdate(line_finish_time)
+ setHot(line_finish_pop)
+ }
+
+ override fun onLoadFinish() {
+ super.onLoadFinish()
+ mainWeakReference?.get()?.runOnUiThread {
+ mypl.visibility = View.GONE
+ }
+ }
+
+ open fun setUpdate(that: View) {
+ that.apply {
+ apt.setText(R.string.menu_update_time)
+ setOnClickListener {
+ sortValue = if(apim.rotation == 0f) {
+ ObjectAnimator.ofFloat(apim, "rotation", 0f, 180f).setDuration(233).start()
+ 1
+ }else{
+ ObjectAnimator.ofFloat(apim, "rotation", 180f, 0f).setDuration(233).start()
+ 0
+ }
+ Thread{
+ Thread.sleep(400)
+ mh?.sendEmptyMessage(4)
+ }.start()
+ }
+ }
+ }
+
+ open fun setHot(that: View) {
+ that.apply {
+ apt.setText(R.string.menu_hot)
+ setOnClickListener {
+ sortValue = if (apim.rotation == 0f) {
+ ObjectAnimator.ofFloat(apim, "rotation", 0f, 180f).setDuration(233).start()
+ 1
+ } else {
+ ObjectAnimator.ofFloat(apim, "rotation", 180f, 0f).setDuration(233).start()
+ 0
+ }
+ Thread {
+ Thread.sleep(400)
+ mh?.sendEmptyMessage(4)
+ }.start()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/top/fumiama/copymanga/template/ui/ThemeCardFlow.kt b/app/src/main/java/top/fumiama/copymanga/template/ui/ThemeCardFlow.kt
new file mode 100644
index 0000000..eaf590d
--- /dev/null
+++ b/app/src/main/java/top/fumiama/copymanga/template/ui/ThemeCardFlow.kt
@@ -0,0 +1,36 @@
+package top.fumiama.copymanga.template.ui
+
+import android.os.Bundle
+import kotlinx.android.synthetic.main.app_bar_main.*
+import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
+
+@ExperimentalStdlibApi
+open class ThemeCardFlow(private val api: Int, nav: Int) : StatusCardFlow(0, nav) {
+ private var theme = ""
+ override fun getApiUrl() =
+ getString(api).let {
+ String.format(
+ it,
+ page * 21,
+ sortWay[sortValue],
+ theme
+ )
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ arguments?.apply {
+ getString("path")?.apply { theme = this }
+ getString("name")?.apply {
+ mainWeakReference?.get()?.toolbar?.title = this
+ }
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ arguments?.getString("name")?.apply {
+ mainWeakReference?.get()?.toolbar?.title = this
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/top/fumiama/copymanga/tools/http/DownloadTools.kt b/app/src/main/java/top/fumiama/copymanga/tools/http/DownloadTools.kt
index c4d46de..46359e1 100644
--- a/app/src/main/java/top/fumiama/copymanga/tools/http/DownloadTools.kt
+++ b/app/src/main/java/top/fumiama/copymanga/tools/http/DownloadTools.kt
@@ -3,7 +3,6 @@ package top.fumiama.copymanga.tools.http
import android.util.Log
import top.fumiama.copymanga.tools.ssl.AllTrustManager
import top.fumiama.copymanga.tools.ssl.IgnoreHostNameVerifier
-import java.io.File
import java.net.HttpURLConnection
import java.net.URL
import java.security.SecureRandom
@@ -25,24 +24,31 @@ object DownloadTools {
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.socketFactory)
}
+ private fun getConnection(url: String?, method: String = "GET") =
+ url?.let {
+ val connection = URL(url).openConnection() as HttpURLConnection
+ connection.requestMethod = method
+ connection.connectTimeout = 20000
+ connection.readTimeout = 20000
+ connection
+ }
+
fun getHttpContent(Url: String, refer: String? = null, ua: String? = null): ByteArray? {
Log.d("Mydl", "getHttp: $Url")
var ret: ByteArray? = null
val task = FutureTask(Callable {
try {
- val connection = URL(Url).openConnection() as HttpURLConnection
- connection.requestMethod = "GET"
- connection.connectTimeout = 20000
- connection.readTimeout = 20000
- refer?.let { connection.setRequestProperty("referer", it) }
- connection.setRequestProperty("source", "copyApp")
- connection.setRequestProperty("webp", "1")
- connection.setRequestProperty("region", "1")
- connection.setRequestProperty("platform", "3")
- ua?.let { connection.setRequestProperty("User-agent", it) }
+ getConnection(Url)?.apply {
+ refer?.let { setRequestProperty("referer", it) }
+ setRequestProperty("source", "copyApp")
+ setRequestProperty("webp", "1")
+ setRequestProperty("region", "1")
+ setRequestProperty("platform", "3")
+ ua?.let { setRequestProperty("User-agent", it) }
- ret = connection.inputStream.readBytes()
- connection.disconnect()
+ ret = inputStream.readBytes()
+ disconnect()
+ }
} catch (ex: Exception) {
ex.printStackTrace()
}
@@ -56,78 +62,17 @@ object DownloadTools {
null
}
}
- fun downloadUsingUrlRet(Url: String?, f: File): Boolean {
- Log.d("Mydl", "Ret Get Url: $Url, File: $f")
- val task = FutureTask(Callable {
- try {
- val connection = URL(Url).openConnection() as HttpURLConnection
- connection.requestMethod = "GET"
- connection.connectTimeout = 20000
- connection.readTimeout = 20000
- connection.setRequestProperty("source", "copyApp")
- connection.setRequestProperty("webp", "1")
- connection.setRequestProperty("region", "1")
- connection.setRequestProperty("platform", "3")
-
- if (f.exists()) f.delete()
- else f.parentFile?.mkdirs()
- f.parentFile?.let {
- if (!it.canRead()) it.setReadable(true)
- if (!it.canWrite()) it.setWritable(true)
- }
- connection.inputStream.buffered().copyTo(f.outputStream())
- connection.disconnect()
- return@Callable true
- } catch (ex: Exception) {
- ex.printStackTrace()
- return@Callable false
- }
- })
- Thread(task).start()
- return try {
- task.get()
- } catch (ex: Exception) {
- ex.printStackTrace()
- false
- }
- }
- fun downloadUsingUrl(Url: String?, f: File, refer: String? = null) {
- Log.d("Mydl", "Get Url: $Url, File: $f")
- Thread(Runnable {
- try {
- val connection = URL(Url).openConnection() as HttpURLConnection
- connection.requestMethod = "GET"
- connection.connectTimeout = 20000
- connection.readTimeout = 20000
- refer?.let { connection.setRequestProperty("referer", it) }
-
- if (f.exists()) f.delete()
- else f.parentFile?.mkdirs()
- f.parentFile?.let {
- if (!it.canRead()) it.setReadable(true)
- if (!it.canWrite()) it.setWritable(true)
- }
- connection.inputStream.buffered().copyTo(f.outputStream())
- connection.disconnect()
- } catch (ex: Exception) {
- ex.printStackTrace()
- }
- }).start()
- }
fun getHttpContent(Url: String, refer: String? = null): ByteArray? {
Log.d("Mydl", "getHttp: $Url")
var ret: ByteArray? = null
val task = FutureTask(Callable {
try {
- val connection = URL(Url).openConnection() as HttpURLConnection
- connection.requestMethod = "GET"
- connection.connectTimeout = 20000
- connection.readTimeout = 20000
- refer?.let { connection.setRequestProperty("referer", it) }
+ val connection = getConnection(Url)
+ refer?.let { connection?.setRequestProperty("referer", it) }
- ret = connection.inputStream.readBytes()
- connection.disconnect()
+ ret = connection?.inputStream?.readBytes()
+ connection?.disconnect()
} catch (ex: Exception) {
ex.printStackTrace()
}
@@ -141,4 +86,55 @@ object DownloadTools {
null
}
}
+
+ fun getHttpContent(Url: String, readSize: Int? = null, refer: String? = "https://api.copymanga.com"): ByteArray? {
+ Log.d("Mydl", "getHttp: $Url")
+ var ret: ByteArray? = null
+ val task = FutureTask(Callable {
+ try {
+ val connection = getConnection(Url)
+ refer?.let { connection?.setRequestProperty("referer", it) }
+
+ val ci = connection?.inputStream
+ if(readSize != null) {
+ ret = ByteArray(readSize)
+ ci?.read(ret, 0, readSize)
+ } else ret = ci?.readBytes()
+ ci?.close()
+ connection?.disconnect()
+ } catch (ex: Exception) {
+ ex.printStackTrace()
+ }
+ return@Callable ret
+ })
+ Thread(task).start()
+ return try {
+ task.get()
+ } catch (ex: Exception) {
+ ex.printStackTrace()
+ null
+ }
+ }
+
+ fun touch(url: String?, refer: String? = "https://www.dmzj1.com"): FutureTask? =
+ url?.let {
+ Log.d("Mydl", "touchHttp: $it")
+ var ret: ByteArray? = null
+ val task = FutureTask(Callable {
+ try {
+ val connection = getConnection(it)
+ refer?.let { connection?.setRequestProperty("referer", it) }
+
+ val ci = connection?.inputStream
+ ret = ci?.readBytes()
+ ci?.close()
+ connection?.disconnect()
+ } catch (ex: Exception) {
+ ex.printStackTrace()
+ }
+ return@Callable ret
+ })
+ Thread(task).start()
+ task
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/top/fumiama/copymanga/tools/http/MangaDlTools.kt b/app/src/main/java/top/fumiama/copymanga/tools/http/MangaDlTools.kt
index 33177f3..6d82d20 100644
--- a/app/src/main/java/top/fumiama/copymanga/tools/http/MangaDlTools.kt
+++ b/app/src/main/java/top/fumiama/copymanga/tools/http/MangaDlTools.kt
@@ -19,6 +19,7 @@ class MangaDlTools {
private var comicFileRelative: String? = null
var size = 0
var complete = false
+ var wait = false
fun downloadChapterInVol(url: CharSequence, chapterName: CharSequence, group: CharSequence, index: Int){
comicFileRelative = "$group/$chapterName.zip"
@@ -72,6 +73,8 @@ class MangaDlTools {
zip.setLevel(9)
var succeed = true
for (i in urls.indices) {
+ while (wait && !exit) sleep(1000)
+ if (exit) break
zip.putNextEntry(ZipEntry("$i.webp"))
var tryTimes = 3
var s = false
@@ -89,7 +92,6 @@ class MangaDlTools {
if (!s && tryTimes <= 0) succeed = false
onDownloadedListener?.handleMessage(s, i + 1)
zip.flush()
- if (exit) break
}
zip.close()
onDownloadedListener?.handleMessage(succeed)
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/book/BookFragment.kt b/app/src/main/java/top/fumiama/copymanga/ui/book/BookFragment.kt
index ce0edd1..ce5dc3c 100644
--- a/app/src/main/java/top/fumiama/copymanga/ui/book/BookFragment.kt
+++ b/app/src/main/java/top/fumiama/copymanga/ui/book/BookFragment.kt
@@ -5,6 +5,7 @@ import android.util.Log
import android.view.Menu
import android.view.View
import androidx.navigation.Navigation
+import kotlinx.android.synthetic.main.app_bar_main.*
import top.fumiama.dmzj.copymanga.R
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.template.general.NoBackRefreshFragment
@@ -28,7 +29,10 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
override fun onResume() {
super.onResume()
- mainWeakReference?.get()?.menuMain?.let { setMenuVisible(it) }
+ mainWeakReference?.get()?.apply {
+ menuMain?.let { setMenuVisible(it) }
+ toolbar.title = bookHandler.book?.results?.comic?.name
+ }
}
override fun onDestroy() {
@@ -37,6 +41,11 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
bookHandler.destroy()
}
+ override fun onPause() {
+ super.onPause()
+ mainWeakReference?.get()?.menuMain?.let { setMenuInvisible(it) }
+ }
+
private fun setMenuInvisible(menu: Menu){
menu.findItem(R.id.action_download)?.isVisible = false
}
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/book/BookHandler.kt b/app/src/main/java/top/fumiama/copymanga/ui/book/BookHandler.kt
index 1e3d085..21694aa 100644
--- a/app/src/main/java/top/fumiama/copymanga/ui/book/BookHandler.kt
+++ b/app/src/main/java/top/fumiama/copymanga/ui/book/BookHandler.kt
@@ -17,6 +17,7 @@ import kotlinx.android.synthetic.main.fragment_book.*
import kotlinx.android.synthetic.main.line_2chapters.view.*
import kotlinx.android.synthetic.main.line_bookinfo.*
import kotlinx.android.synthetic.main.line_bookinfo_text.*
+import kotlinx.android.synthetic.main.line_caption.view.*
import kotlinx.android.synthetic.main.line_chapter.view.*
import top.fumiama.dmzj.copymanga.R
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
@@ -52,7 +53,7 @@ class BookHandler(that: WeakReference, path: String)
1 -> setCover()
2 -> setTexts()
3 -> fbibinfo?.let { setInfoHeight(it) }
- //4 -> setThemes()
+ 4 -> setThemes()
5 -> setOverScale()
6 -> endSetLayouts()
}
@@ -147,44 +148,60 @@ class BookHandler(that: WeakReference, path: String)
}
}
- private fun setThemes(){
- book?.results?.groups?.let {
- val keyIterator = it.keys.iterator()
- for(i in 0 until it.size){
- if(i % 2 == 0){
- that?.fbl?.addView(if(i < it.size - 1){
- val line = that.layoutInflater.inflate(R.layout.line_2chapters, that.fbl, false)
- val leftKey = keyIterator.next()
- line?.l2cl?.lct?.text = it[leftKey]?.name
- line?.l2cl?.setOnClickListener { _->
- loadVolume(it[leftKey]?.path_word?:"null")
+ private fun setTheme(caption: String, themeStructure: Array, nav: Int) {
+ that?.apply {
+ val t = layoutInflater.inflate(R.layout.line_caption, fbl, false)
+ t.tcptn.text = caption
+ fbl.addView(t)
+ fbl.addView(layoutInflater.inflate(R.layout.div_h, fbl, false))
+ }
+ var line: View? = null
+ val last = themeStructure.size - 1
+ themeStructure.onEachIndexed { i, it ->
+ if(line == null) {
+ if(i == last) {
+ line = that?.layoutInflater?.inflate(R.layout.line_chapter, that.fbl, false)
+ line?.lcc?.apply {
+ lct.text = it.name
+ setOnClickListener { _ ->
+ loadVolume(it.name, it.path_word, nav)
}
- val rightKey = keyIterator.next()
- line?.l2cr?.lct?.text = it[rightKey]?.name
- line?.l2cr?.setOnClickListener { _->
- loadVolume(it[rightKey]?.path_word?:"null")
+ }
+ that?.fbl?.addView(line)
+ } else {
+ line = that?.layoutInflater?.inflate(R.layout.line_2chapters, that.fbl, false)
+ line?.l2cl?.apply {
+ lct.text = it.name
+ setOnClickListener { _ ->
+ loadVolume(it.name, it.path_word, nav)
}
- line
- }else{
- //Log.d("MyBH", "Add chapter: ${vol[i].volume_name}")
- val line = that.layoutInflater.inflate(R.layout.line_chapter, that.fbl, false)
- val key = keyIterator.next()
- line?.lct?.text = it[key]?.name
- line?.lcc?.setOnClickListener { _->
- loadVolume(it[key]?.path_word?:"null")
- }
- line
- })
+ }
}
+ } else line?.l2cr?.apply {
+ lct.text = it.name
+ setOnClickListener { _ ->
+ loadVolume(it.name, it.path_word, nav)
+ }
+ that?.fbl?.addView(line)
+ line = null
}
}
}
- private fun loadVolume(gpw: String){
+ private fun setThemes(){
+ that?.apply {
+ book?.results?.comic?.apply {
+ author?.let { setTheme(getString(R.string.author), it, R.id.action_nav_book_to_nav_author) }
+ theme?.let { setTheme(getString(R.string.caption), it, R.id.action_nav_book_to_nav_caption) }
+ }
+ }
+ }
+
+ private fun loadVolume(name: String, path: String, nav: Int){
Log.d("MyBH", "start to load chapter")
val bundle = Bundle()
- bundle.putString("group", gpw)
- book?.results?.comic?.path_word?.let { bundle.putString("path", it) }
- that?.rootView?.let { Navigation.findNavController(it).navigate(R.id.action_nav_book_to_nav_chapter, bundle) }
+ bundle.putString("name", name)
+ bundle.putString("path", path)
+ that?.rootView?.let { Navigation.findNavController(it).navigate(nav, bundle) }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/cardflow/author/AuthorFragment.kt b/app/src/main/java/top/fumiama/copymanga/ui/cardflow/author/AuthorFragment.kt
new file mode 100644
index 0000000..9abb65e
--- /dev/null
+++ b/app/src/main/java/top/fumiama/copymanga/ui/cardflow/author/AuthorFragment.kt
@@ -0,0 +1,7 @@
+package top.fumiama.copymanga.ui.cardflow.author
+
+import top.fumiama.copymanga.template.ui.ThemeCardFlow
+import top.fumiama.dmzj.copymanga.R
+
+@ExperimentalStdlibApi
+class AuthorFragment : ThemeCardFlow(R.string.authorApiUrl, R.id.action_nav_author_to_nav_book)
\ No newline at end of file
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/cardflow/caption/CaptionFragment.kt b/app/src/main/java/top/fumiama/copymanga/ui/cardflow/caption/CaptionFragment.kt
new file mode 100644
index 0000000..da3e4bd
--- /dev/null
+++ b/app/src/main/java/top/fumiama/copymanga/ui/cardflow/caption/CaptionFragment.kt
@@ -0,0 +1,7 @@
+package top.fumiama.copymanga.ui.cardflow.caption
+
+import top.fumiama.copymanga.template.ui.ThemeCardFlow
+import top.fumiama.dmzj.copymanga.R
+
+@ExperimentalStdlibApi
+class CaptionFragment : ThemeCardFlow(R.string.captionApiUrl, R.id.action_nav_caption_to_nav_book)
\ No newline at end of file
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/cardflow/finish/FinishFragment.kt b/app/src/main/java/top/fumiama/copymanga/ui/cardflow/finish/FinishFragment.kt
index 62352ba..1b77baf 100644
--- a/app/src/main/java/top/fumiama/copymanga/ui/cardflow/finish/FinishFragment.kt
+++ b/app/src/main/java/top/fumiama/copymanga/ui/cardflow/finish/FinishFragment.kt
@@ -1,77 +1,7 @@
package top.fumiama.copymanga.ui.cardflow.finish
-import android.animation.ObjectAnimator
-import android.view.View
-import kotlinx.android.synthetic.main.anchor_popular.view.*
-import kotlinx.android.synthetic.main.line_finish.*
-import kotlinx.android.synthetic.main.line_lazybooklines.*
-import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
-import top.fumiama.copymanga.template.ui.InfoCardLoader
+import top.fumiama.copymanga.template.ui.StatusCardFlow
import top.fumiama.dmzj.copymanga.R
-import java.lang.Thread.sleep
@ExperimentalStdlibApi
-class FinishFragment : InfoCardLoader(R.layout.fragment_finish, R.id.action_nav_finish_to_nav_book) {
- private val sortWay = listOf("datetime_updated", "-datetime_updated", "popular", "-popular")
- private var sortValue = 0
-
- override fun getApiUrl() =
- getString(R.string.finishApiUrl).let {
- String.format(
- it,
- page * 21,
- sortWay[sortValue]
- )
- }
-
- override fun setListeners() {
- super.setListeners()
- setUpdate()
- setHot()
- }
-
- override fun onLoadFinish() {
- super.onLoadFinish()
- mainWeakReference?.get()?.runOnUiThread {
- mypl.visibility = View.GONE
- }
- }
-
- private fun setUpdate() {
- line_finish_time.apply {
- apt.setText(R.string.menu_update_time)
- setOnClickListener {
- sortValue = if(apim.rotation == 0f) {
- ObjectAnimator.ofFloat(apim, "rotation", 0f, 180f).setDuration(233).start()
- 1
- }else{
- ObjectAnimator.ofFloat(apim, "rotation", 180f, 0f).setDuration(233).start()
- 0
- }
- Thread{
- sleep(400)
- mh?.sendEmptyMessage(4)
- }.start()
- }
- }
- }
-
- private fun setHot() {
- line_finish_pop.apply {
- apt.setText(R.string.menu_hot)
- setOnClickListener {
- sortValue = if (apim.rotation == 0f) {
- ObjectAnimator.ofFloat(apim, "rotation", 0f, 180f).setDuration(233).start()
- 1
- } else {
- ObjectAnimator.ofFloat(apim, "rotation", 180f, 0f).setDuration(233).start()
- 0
- }
- Thread {
- sleep(400)
- mh?.sendEmptyMessage(4)
- }.start()
- }
- }
- }
-}
\ No newline at end of file
+class FinishFragment : StatusCardFlow(R.string.finishApiUrl, R.id.action_nav_finish_to_nav_book)
\ No newline at end of file
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlHandler.kt b/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlHandler.kt
index d4e23f8..58b697f 100644
--- a/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlHandler.kt
+++ b/app/src/main/java/top/fumiama/copymanga/ui/comicdl/ComicDlHandler.kt
@@ -60,7 +60,6 @@ class ComicDlHandler(looper: Looper, that: WeakReference, priva
private var checkedChapter = 0
private var dldChapter = 0
private var haveDlStarted = false
- private var canDl = false
private var tbtnlist: Array = arrayOf()
private var tbtncnt = 0
private var isNewTitle = false
@@ -215,10 +214,12 @@ class ComicDlHandler(looper: Looper, that: WeakReference, priva
setProgress2(dldChapter * 100 / checkedChapter, 233)
}
private fun updateProgressBar(pageNow: Int, size: Int) {
- val delta = 100 / checkedChapter
- val start = dldChapter * delta
- val now = pageNow * delta / size
- setProgress2(start + now, 64)
+ if(checkedChapter > 0) {
+ val delta = 100 / checkedChapter
+ val start = dldChapter * delta
+ val now = pageNow * delta / size
+ setProgress2(start + now, 64)
+ }
}
private fun setProgress2(end: Int, duration: Long) {
ObjectAnimator.ofInt(
@@ -259,10 +260,10 @@ class ComicDlHandler(looper: Looper, that: WeakReference, priva
else if(checkedChapter == 0) hideDlCard()
else{
that.pdwn.progress = 0
- if (canDl || checkedChapter == 0) canDl = false
+ if(haveDlStarted && checkedChapter != 0) mangaDlTools.wait = !mangaDlTools.wait
else {
haveDlStarted = true
- canDl = true
+ mangaDlTools.wait = false
Thread{
sendEmptyMessage(9) //set dl card color to green
downloadMangas()
@@ -291,16 +292,8 @@ class ComicDlHandler(looper: Looper, that: WeakReference, priva
private fun downloadMangas(){
for (i in tbtnlist) {
if (i.isChecked) downloadChapterPages(i)
- if (!canDl) {
- checkedChapter -= dldChapter
- dldChapter = 0
- break
- }
- }
- if (canDl) {
- haveDlStarted = false
- canDl = false
}
+ haveDlStarted = false
}
private fun downloadChapterPages(i: ChapterToggleButton) {
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/home/HomeHandler.kt b/app/src/main/java/top/fumiama/copymanga/ui/home/HomeHandler.kt
index d10766f..b01458a 100644
--- a/app/src/main/java/top/fumiama/copymanga/ui/home/HomeHandler.kt
+++ b/app/src/main/java/top/fumiama/copymanga/ui/home/HomeHandler.kt
@@ -310,7 +310,9 @@ class HomeHandler(that: WeakReference) : AutoDownloadHandler(
private fun setCards(cv: CardView, pw: String, name: String, img: String, isFinal: Boolean, isTopic: Boolean) {
cv.tic.text = name
homeF?.let {
- Glide.with(it).load(GlideUrl(img, CMApi.myGlideHeaders)).timeout(20000).into(cv.imic)
+ if(img.startsWith("http")) {
+ Glide.with(it).load(GlideUrl(img, CMApi.myGlideHeaders)).timeout(20000).into(cv.imic)
+ }
}
if (isFinal) cv.sgnic.visibility = View.VISIBLE
cv.setOnClickListener {
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/vm/PagesManager.kt b/app/src/main/java/top/fumiama/copymanga/ui/vm/PagesManager.kt
index 02c3a63..843d09a 100644
--- a/app/src/main/java/top/fumiama/copymanga/ui/vm/PagesManager.kt
+++ b/app/src/main/java/top/fumiama/copymanga/ui/vm/PagesManager.kt
@@ -21,7 +21,7 @@ class PagesManager(w: WeakReference) {
toPage(v?.r2l!=true)
}
private fun judgePrevious() = v?.pageNum?:0 > 1
- private fun judgeNext() = v?.pageNum?:0 < v?.count?:0
+ private fun judgeNext() = v?.pageNum?:0 < v?.realCount?:0
@ExperimentalStdlibApi
fun toPage(goNext:Boolean){
if (v?.clicked == false) {
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/vm/VMHandler.kt b/app/src/main/java/top/fumiama/copymanga/ui/vm/VMHandler.kt
index df650cc..02a4ed0 100644
--- a/app/src/main/java/top/fumiama/copymanga/ui/vm/VMHandler.kt
+++ b/app/src/main/java/top/fumiama/copymanga/ui/vm/VMHandler.kt
@@ -78,19 +78,19 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
}
4 -> {
val simg = msg.obj as ScaleImageView
- wv.get()?.loadImgOn(simg, msg.arg1)
- simg.setHeight2FitImgWidth()
- if(msg.arg2 == 1) sendEmptyMessage(8)
+ wv.get()?.loadImgOn(simg, msg.arg1, msg.arg2)
+ //simg.setHeight2FitImgWidth()
+ //if(msg.arg2 == 1) sendEmptyMessage(8)
}
5 -> wv.get()?.clearImgOn(msg.obj as ScaleImageView)
6 -> wv.get()?.prepareLastPage(msg.arg1, msg.arg2)
7 -> dl?.show()
8 -> Thread{
- sleep(233)
- sendEmptyMessage(13)
- }.start()
- 9 -> loadThread(msg.arg1)
- 10 -> loadThread()
+ sleep(233)
+ sendEmptyMessage(13)
+ }.start()
+ 9 -> loadScrollMode(msg.arg1)
+ 10 -> loadScrollMode()
11 -> loadImgsIntoLine(msg.arg1)
12 -> loadImgsIntoLine()
13 -> {
@@ -98,10 +98,12 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
wv.get()?.restorePN()
}
14 -> {
- val item = (pn - 1) / (wv.get()?.verticalLoadMaxCount?:40) * (wv.get()?.verticalLoadMaxCount?:40)
- loadThread(item)
+ val item = (pn - 1) / (wv.get()?.verticalLoadMaxCount?:20) * (wv.get()?.verticalLoadMaxCount?:20)
+ loadScrollMode(item)
Log.d("MyVMH", "Load page from $item")
}
+ 15 -> dl?.hide()
+ //16 -> wv.get()?.prepareItems()
22 -> wv.get()?.idtime?.text = SimpleDateFormat("HH:mm").format(Date()) + week + wv.get()?.toolsBox?.netinfo
}
}
@@ -128,7 +130,10 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
fun loadFromFile(file: File): Boolean {
return try {
val jsonFile = File(file.parentFile, "${file.nameWithoutExtension}.json")
- if(jsonFile.exists()) manga = Gson().fromJson(jsonFile.reader(), Chapter2Return::class.java)
+ if(jsonFile.exists()) {
+ manga = Gson().fromJson(jsonFile.reader(), Chapter2Return::class.java)
+ prepareManga()
+ }
else{
manga = Chapter2Return()
manga?.let {
@@ -137,10 +142,12 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
it.results.comic.name = file.parentFile?.name
it.results.chapter = ChapterWithContent()
it.results.chapter.name = file.nameWithoutExtension
- it.results.chapter.size = countZipEntries(file)
+ wv.get()?.countZipEntries { c ->
+ it.results.chapter.size = c
+ prepareManga()
+ }
}
}
- prepareManga()
true
}catch (e: Exception){
e.printStackTrace()
@@ -149,23 +156,6 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
}
}
- private fun countZipEntries(file: File): Int{
- var count = 0
- try {
- val zip = ZipInputStream(file.inputStream().buffered())
- var entry = zip.nextEntry
- while (entry != null) {
- if (!entry.isDirectory) count++
- entry = zip.nextEntry
- }
- zip.closeEntry()
- zip.close()
- } catch (e: Exception) {
- wv.get()?.toolsBox?.toastError("统计zip图片数错误!")
- }
- return count
- }
-
@ExperimentalStdlibApi
private fun prepareManga(){
comicName = manga?.results?.comic?.name
@@ -174,29 +164,33 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
wv.get()?.initManga()
wv.get()?.vprog?.visibility = View.GONE
}
- private fun loadImgsIntoLine(item: Int = (wv.get()?.currentItem?:0), maxCount: Int = (wv.get()?.verticalLoadMaxCount?:40)){
- Log.d("MyVMH", "Fun: loadImgsIntoLine($item)")
- val count = wv.get()?.count?.minus(1)?:0
- val notFull = item + maxCount > count
- val loadCount = (if(notFull) count - item else maxCount) - 1
- Log.d("MyVMH", "loadCount: $loadCount")
- if(loadCount >= 0) for(i in 0..loadCount) obtainMessage(4,item + i, if(i == loadCount - 1)1 else 0, wv.get()?.scrollImages?.get(i)).sendToTarget()
- else sendEmptyMessage(8)
- if(notFull) obtainMessage(6, loadCount + 1, maxCount).sendToTarget()
- }
+ private fun loadImgsIntoLine(item: Int = (wv.get()?.currentItem?:0), maxCount: Int = (wv.get()?.verticalLoadMaxCount?:20)) /*= Thread*/{
+ Log.d("MyVMH", "Fun: loadImgsIntoLine($item, $maxCount)")
+ wv.get()?.realCount?.let { count ->
+ if(count > 0){
+ val notFull = item + maxCount > count
+ val loadCount = (if(notFull) count - item else maxCount) - 1
+ Log.d("MyVMH", "count: $count, loadCount: $loadCount, notFull: $notFull")
+ if(loadCount >= 0) for(i in 0..loadCount) obtainMessage(4,item + i, if(i == loadCount - 1) 1 else 0, wv.get()?.scrollImages?.get(i)).sendToTarget()
+ else sendEmptyMessage(8)
+ if(notFull) obtainMessage(6, loadCount + 1, maxCount).sendToTarget()
+ wv.get()?.updateSeekBar()
+ }
+ }
+ }//.start()
- private fun loadThread() = Thread{
+ private fun loadScrollMode() {
sendEmptyMessage(7)
//sleep(233)
sendEmptyMessage(12)
- }.start()
+ }
- private fun loadThread(item: Int) = Thread{
+ private fun loadScrollMode(item: Int) {
sendEmptyMessage(7)
//sleep(233)
Log.d("MyVMH", "loadImgsIntoLine($item)")
obtainMessage(11, item, 0).sendToTarget()
- }.start()
+ }
private fun showInfCard() {
Log.d("MyVMH", "Read info drawer delta: $delta")
diff --git a/app/src/main/java/top/fumiama/copymanga/ui/vm/ViewMangaActivity.kt b/app/src/main/java/top/fumiama/copymanga/ui/vm/ViewMangaActivity.kt
index b6f9086..b0e1959 100644
--- a/app/src/main/java/top/fumiama/copymanga/ui/vm/ViewMangaActivity.kt
+++ b/app/src/main/java/top/fumiama/copymanga/ui/vm/ViewMangaActivity.kt
@@ -2,8 +2,10 @@ package top.fumiama.copymanga.ui.vm
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
+import android.app.Service
import android.graphics.Bitmap
import android.graphics.BitmapFactory
+import android.media.AudioManager
import android.os.Bundle
import android.os.Handler
import android.util.Log
@@ -14,6 +16,8 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
+import com.bumptech.glide.request.target.SimpleTarget
+import com.bumptech.glide.request.transition.Transition
import com.liaoinstan.springview.widget.SpringView
import kotlinx.android.synthetic.main.activity_viewmanga.*
import kotlinx.android.synthetic.main.line_header.view.*
@@ -28,6 +32,7 @@ import kotlinx.android.synthetic.main.widget_titlebar.view.*
import kotlinx.android.synthetic.main.widget_viewmangainfo.*
import top.fumiama.dmzj.copymanga.R
import top.fumiama.copymanga.template.general.TitleActivityTemplate
+import top.fumiama.copymanga.template.http.AutoDownloadThread
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.copymanga.tools.thread.TimeThread
@@ -35,8 +40,10 @@ import top.fumiama.copymanga.views.ScaleImageView
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
+import java.io.InputStream
import java.lang.ref.WeakReference
import java.util.*
+import java.util.concurrent.FutureTask
import java.util.zip.ZipFile
class ViewMangaActivity : TitleActivityTemplate() {
@@ -49,23 +56,32 @@ class ViewMangaActivity : TitleActivityTemplate() {
//private var progressLog: PropertiesTools? = null
var scrollImages = arrayOf()
//var zipFirst = false
- private var useFullScreen = false
+ //private var useFullScreen = false
var r2l = true
var currentItem = 0
- var verticalLoadMaxCount = 40
+ var verticalLoadMaxCount = 20
private var notUseVP = true
private var isVertical = false
- private var q = 90
- private val size get() = if(count / verticalLoadMaxCount > currentItem / verticalLoadMaxCount) verticalLoadMaxCount else count % verticalLoadMaxCount
+ private var q = 100
+ private val size get() = if(realCount / verticalLoadMaxCount > currentItem / verticalLoadMaxCount) verticalLoadMaxCount else realCount % verticalLoadMaxCount
var infoDrawerDelta = 0f
var pageNum: Int
get() = getPageNumber()
set(value) = setPageNumber(value)
//var pn = 0
private val isPnValid: Boolean get(){
- if(pn == -2) pn = count
+ if(pn == -2) pn = realCount
return intent.getStringExtra("function") == "log" && pn > 0
}
+ private var tasks: Array?>? = null
+ private var destroy = false
+ private var cut = false
+ private var isCut = booleanArrayOf()
+ private var indexMap = intArrayOf()
+ private var volTurnPage = false
+ private var am: AudioManager? = null
+ private var pm: PagesManager? = null
+ val realCount get() = if(cut) indexMap.size else count
@ExperimentalStdlibApi
@SuppressLint("SetTextI18n")
@@ -76,17 +92,19 @@ class ViewMangaActivity : TitleActivityTemplate() {
//progressLog = PropertiesTools(File("$filesDir/progress/${chapter2Return?.results?.chapter?.comic_id}"))
//dlZip2View = intent.getStringExtra("callFrom") == "Dl" || p["dlZip2View"] == "true"
//zipFirst = intent.getStringExtra("callFrom") == "zipFirst"
- useFullScreen = p["useFullScreen"] != "true"
+ cut = p["useCut"] == "true"
r2l = p["r2l"] == "true"
+ verticalLoadMaxCount = if (p["verticalMax"] != "null") p["verticalMax"].toInt() else 20
isVertical = p["vertical"] == "true"
notUseVP = p["noVP"] == "true" || isVertical
//url = intent.getStringExtra("url")
handler = VMHandler(this, if(urlArray.isNotEmpty()) urlArray[position] else "")
if (p["quality"] != "null") q = p["quality"].toInt()
- if (p["verticalMax"] != "null") verticalLoadMaxCount = p["verticalMax"].toInt()
tt = TimeThread(handler, 22)
tt.canDo = true
tt.start()
+ volTurnPage = p["volturn"] == "true"
+ am = getSystemService(Service.AUDIO_SERVICE) as AudioManager
Log.d("MyVM", "Now ZipFile is $zipFile")
try {
@@ -101,15 +119,33 @@ class ViewMangaActivity : TitleActivityTemplate() {
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
- if(useFullScreen) {
- if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R)
- window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
- else {
- window.setDecorFitsSystemWindows(false)
- window.insetsController?.hide(WindowInsets.Type.statusBars())
- //window.insetsController?.hide(WindowInsets.Type.navigationBars())
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R)
+ window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ else {
+ window.setDecorFitsSystemWindows(false)
+ window.insetsController?.hide(WindowInsets.Type.statusBars())
+ //window.insetsController?.hide(WindowInsets.Type.navigationBars())
+ }
+ }
+
+ @ExperimentalStdlibApi
+ override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
+ var flag = false
+ if(volTurnPage) when(keyCode) {
+ KeyEvent.KEYCODE_VOLUME_UP -> {
+ pm?.toPage(false)
+ flag = true
+ }
+ KeyEvent.KEYCODE_VOLUME_DOWN -> {
+ pm?.toPage(true)
+ flag = true
}
}
+ return if(flag) true else super.onKeyDown(keyCode, event)
+ }
+
+ private fun alertCellar() {
+ toolsBox.buildInfo("注意", "要使用使用流量观看吗?", "确定", null, "取消", {handler.startLoad()}, null, {finish()})
}
fun restorePN(){
@@ -121,30 +157,122 @@ class ViewMangaActivity : TitleActivityTemplate() {
sendProgress()
}
+ private fun preDownloadChapterPages() {
+ getImgUrlArray()?.let {
+ val mid = (if(pn in 1 until realCount) (if(cut) Math.abs(indexMap[pn]) else pn) else if(pn == -2 || pn >= realCount) it.size else 1) - 1
+ val left = if(isVertical && mid > verticalLoadMaxCount) (mid / verticalLoadMaxCount) * verticalLoadMaxCount else (mid-1)
+ val right = if(isVertical) (mid / verticalLoadMaxCount + 1) * verticalLoadMaxCount else mid
+ tasks = arrayOfNulls(it.size)
+ Thread{
+ for (i in right until it.size) {
+ if(destroy) break
+ tasks?.let { tasks ->
+ tasks[i] = DownloadTools.touch(it[i])
+ Thread.sleep(1000)
+ }
+ }
+ }.start()
+ Thread.sleep(500)
+ Thread{
+ for (i in left downTo 0) {
+ if(destroy) break
+ tasks?.let { tasks ->
+ tasks[i] = DownloadTools.touch(it[i])
+ Thread.sleep(1000)
+ }
+ }
+ }.start()
+ }
+ }
+
+ @ExperimentalStdlibApi
+ private fun doPrepareWebImg() {
+ getImgUrlArray()?.apply {
+ if(cut) {
+ handler.sendEmptyMessage(7) //showDl
+ isCut = BooleanArray(size)
+ val analyzedCnt = BooleanArray(size)
+ forEachIndexed{ i, it ->
+ if(it != null) {
+ Thread{
+ DownloadTools.getHttpContent(it, 1024)?.inputStream()?.let {
+ isCut[i] = canCut(it)
+ analyzedCnt[i] = true
+ }
+ }.start()
+ Thread.sleep(22)
+ }
+ }
+ while (analyzedCnt.count { it } != size) Thread.sleep(233)
+ isCut.forEachIndexed { index, b ->
+ Log.d("MyVM", "[$index] cut: $b")
+ indexMap += index+1
+ if(b) indexMap += -(index+1)
+ }
+ handler.sendEmptyMessage(15) //hideDl
+ }
+ count = size
+ runOnUiThread { prepareItems() }
+ preDownloadChapterPages()
+ }
+ }
+
@ExperimentalStdlibApi
fun initManga(){
- prepareItems(count)
+ if (zipFile?.exists() != true) doPrepareWebImg()
+ else prepareItems()
if (!isVertical) restorePN()
}
@ExperimentalStdlibApi
private fun prepareImgFromWeb() {
- handler.startLoad()
+ if(toolsBox.netinfo == "移动数据") alertCellar()
+ else handler.startLoad()
}
+ private fun canCut(inputStream: InputStream): Boolean{
+ val op = BitmapFactory.Options()
+ op.inJustDecodeBounds = true
+ BitmapFactory.decodeStream(inputStream, null, op)
+ Log.d("MyVM", "w: ${op.outWidth}, h: ${op.outHeight}")
+ return op.outWidth.toFloat() / op.outHeight.toFloat() > 1
+ }
+
+ @ExperimentalStdlibApi
+ fun countZipEntries(doWhenFinish : (count: Int) -> Unit) = Thread{
+ if (zipFile != null) try {
+ Log.d("Myvm", "zip: $zipFile")
+ val zip = ZipFile(zipFile)
+ count = zip.size()
+ if(cut) zip.entries().toList().sortedBy{it.name.substringBefore('.').toInt()}.forEachIndexed { i, it ->
+ val useCut = canCut(zip.getInputStream(it))
+ isCut += useCut
+ indexMap += i + 1
+ if (useCut) indexMap += -(i + 1)
+ Log.d("Myvm", "[$i] 分析: ${it.name}, cut: $useCut")
+ }
+ } catch (e: Exception) {
+ runOnUiThread { toolsBox.toastError("统计zip图片数错误!") }
+ }
+ runOnUiThread {
+ Log.d("Myvm", "开始加载控件")
+ doWhenFinish(count)
+ }
+ }.start()
+
private fun getPageNumber(): Int {
- return if (r2l && !notUseVP) count - vp.currentItem
+ return if (r2l && !notUseVP) realCount - vp.currentItem
else (if (notUseVP) currentItem else vp.currentItem) + 1
}
private fun setPageNumber(num: Int) {
- if (r2l && !notUseVP) vp.currentItem = count - num
+ if (r2l && !notUseVP) vp.currentItem = realCount - num
else if (notUseVP) {
if(isVertical){
currentItem = num - 1
- val delta = currentItem % verticalLoadMaxCount
- Log.d("MyVM", "Height: ${psivl.height}, scrollY: ${psivs.scrollY}")
- if (!isInScroll || isInSeek) psivs.scrollY = psivl.height / size * delta
+ val offset = currentItem % verticalLoadMaxCount
+ Log.d("MyVM", "Current: $currentItem, Height: ${psivl.height}, scrollY: ${psivs.scrollY}")
+ if (!isInScroll || isInSeek) psivs.scrollY = psivl.height * offset / size
updateSeekBar()
}
else {
@@ -156,31 +284,86 @@ class ViewMangaActivity : TitleActivityTemplate() {
toolsBox.toastError("页数${currentItem}不合法")
}
}
- } else vp.currentItem = num - 1
+ } else {
+ Log.d("MyVM", "Set vp current: ${num-1}")
+ var delta = num - 1 - vp.currentItem
+ if(delta >= 1) Thread{
+ while (delta-- > 0){
+ Thread.sleep(23)
+ runOnUiThread {
+ vp.currentItem++
+ }
+ }
+ }.start()
+ else if(delta <= -1) Thread{
+ while (delta++ < 0){
+ Thread.sleep(23)
+ runOnUiThread {
+ vp.currentItem--
+ }
+ }
+ }.start()
+ }
}
fun clearImgOn(imgView: ScaleImageView){
imgView.visibility = View.GONE
}
- private fun getTempFile(position: Int) = File(cacheDir, "$position")
+ //private fun getTempFile(position: Int) = File(cacheDir, "$position")
private fun getImgUrl(position: Int) = handler.manga?.results?.chapter?.let {
it.contents[it.words.indexOf(position)].url
}
- fun loadImgOn(imgView: ScaleImageView, position: Int){
- if (zipFile?.exists() == true) imgView.setImageBitmap(getImgBitmap(position))
- else if(isVertical) {
- val f = getTempFile(position)
- if(DownloadTools.downloadUsingUrlRet(getImgUrl(position), f))
- imgView.setImageBitmap(BitmapFactory.decodeFile(f.path))
- else Toast.makeText(this, "下载第${position}页失败", Toast.LENGTH_SHORT).show()
+ private fun getImgUrlArray() = handler.manga?.results?.chapter?.let{
+ val re = arrayOfNulls(it.contents.size)
+ for(i in it.contents.indices) {
+ re[i] = getImgUrl(i)
+ }
+ re
+ }
+
+ private fun cutBitmap(bitmap: Bitmap, isEnd: Boolean) = Bitmap.createBitmap(bitmap, if(!isEnd) 0 else (bitmap.width/2), 0, bitmap.width/2, bitmap.height)
+
+ private fun loadImg(imgView: ScaleImageView, bitmap: Bitmap, isLast: Int = 0, useCut: Boolean, isLeft: Boolean){
+ val bitmap2load = if(useCut) cutBitmap(bitmap, isLeft) else bitmap
+ runOnUiThread {
+ imgView.setImageBitmap(bitmap2load)
+ if(isVertical){
+ imgView.setHeight2FitImgWidth()
+ if (isLast == 1) handler.sendEmptyMessage(8)
+ }
+ }
+ }
+
+ private fun loadImgUrlInto(imgView: ScaleImageView, url: String, isLast: Int = 0, useCut: Boolean, isLeft: Boolean){
+ Log.d("MyVM", "Load from adt: $url")
+ AutoDownloadThread(url) {
+ it?.let { loadImg(imgView, BitmapFactory.decodeByteArray(it, 0, it.size), isLast, useCut, isLeft) }
+ }.start()
+ }
+
+ fun loadImgOn(imgView: ScaleImageView, position: Int, isLast: Int = 0){
+ Log.d("MyVM", "Load img: $position")
+ val index2load = if(cut) Math.abs(indexMap[position]) -1 else position
+ val useCut = cut && isCut[index2load]
+ val isLeft = cut && indexMap[position] > 0
+ if (zipFile?.exists() == true) getImgBitmap(index2load)?.let {
+ loadImg(imgView, it, isLast, useCut, isLeft)
+ }
+ else {
+ val re = tasks?.get(index2load)
+ if (re != null) Thread{
+ val data = re.get()
+ if(data != null) {
+ loadImg(imgView, BitmapFactory.decodeByteArray(data, 0, data.size), isLast, useCut, isLeft)
+ Log.d("MyVM", "Load from task")
+ }
+ else getImgUrl(index2load)?.let { loadImgUrlInto(imgView, it, isLast, useCut, isLeft) }
+ }.start()
+ else getImgUrl(index2load)?.let { loadImgUrlInto(imgView, it, isLast, useCut, isLeft) }
}
- else Glide.with(this)
- .load(GlideUrl(getImgUrl(position), CMApi.myGlideHeaders))
- .timeout(10000)
- .into(imgView)
imgView.visibility = View.VISIBLE
}
@@ -190,7 +373,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
}
private fun initImgList(){
- for (i in 0..39) {
+ for (i in 0 until verticalLoadMaxCount) {
val newImg = ScaleImageView(this)
scrollImages += newImg
psivl.addView(newImg)
@@ -202,24 +385,21 @@ class ViewMangaActivity : TitleActivityTemplate() {
handler.dl?.hide()
}
- private fun getImgBitmap(position: Int): Bitmap? {
- Log.d("MyVM", "Get bitmap @$position, count is $count")
- if (position >= count || position < 0) return null
- else {
+ private fun getImgBitmap(position: Int): Bitmap? =
+ if (position >= count || position < 0) null
+ else try {
val zip = ZipFile(zipFile)
- if (q == 100) return BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.jpg")))
+ if (q == 100) BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.webp")))
else {
val out = ByteArrayOutputStream()
- try {
- BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.webp")))
- } catch (e: Exception) {
- e.printStackTrace()
- return null
- }?.compress(Bitmap.CompressFormat.JPEG, q, out)
- return BitmapFactory.decodeStream(ByteArrayInputStream(out.toByteArray()))
+ BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.webp")))?.compress(Bitmap.CompressFormat.JPEG, q, out)
+ BitmapFactory.decodeStream(ByteArrayInputStream(out.toByteArray()))
}
+ } catch (e: Exception) {
+ e.printStackTrace()
+ Toast.makeText(this, "加载zip的${position}.webp错误", Toast.LENGTH_SHORT).show()
+ null
}
- }
private fun setIdPosition(position: Int) {
infoDrawerDelta = position.toFloat()
@@ -229,19 +409,24 @@ class ViewMangaActivity : TitleActivityTemplate() {
@ExperimentalStdlibApi
@SuppressLint("SetTextI18n")
- private fun prepareItems(size: Int) {
- ttitle.text = handler.manga?.results?.chapter?.name
- prepareVP()
- prepareInfoBar(size)
- if (notUseVP && !isVertical) loadOneImg()
- prepareIdBtVH()
- toolsBox.dp2px(67)?.let { setIdPosition(it) }
- prepareIdBtFullScreen()
- prepareIdBtVP()
- prepareIdBtLR()
- handler.progressLog?.let {
- //it["uuid"] = handler.manga?.results?.comic?.uuid
- it["name"] = inftitle.ttitle.text
+ private fun prepareItems() {
+ try {
+ prepareVP()
+ //if (!isVertical) restorePN()
+ prepareInfoBar()
+ if (notUseVP && !isVertical && !isPnValid) loadOneImg()
+ prepareIdBtVH()
+ toolsBox.dp2px(67)?.let { setIdPosition(it) }
+ prepareIdBtCut()
+ prepareIdBtVP()
+ prepareIdBtLR()
+ /*progressLog?.let {
+ it["chapterId"] = hm.chapterId.toString()
+ it["name"] = inftitle.ttitle.text
+ }*/
+ }catch (e: Exception) {
+ e.printStackTrace()
+ toolsBox.toastError("准备控件错误")
}
}
@@ -253,6 +438,14 @@ class ViewMangaActivity : TitleActivityTemplate() {
}
}
+ private fun prepareIdBtCut() {
+ idtbcut.isChecked = cut
+ idtbcut.setOnClickListener {
+ p["useCut"] = if (idtbcut.isChecked) "true" else "false"
+ Toast.makeText(this, "下次浏览生效", Toast.LENGTH_SHORT).show()
+ }
+ }
+
private fun prepareIdBtLR() {
idtblr.isChecked = r2l
idtblr.setOnClickListener {
@@ -285,11 +478,11 @@ class ViewMangaActivity : TitleActivityTemplate() {
super.onPageSelected(position)
}
})
- if (r2l) vp.currentItem = count - 1
+ if (r2l && !isPnValid) vp.currentItem = realCount - 1
}
}
- private fun updateSeekBar() {
+ fun updateSeekBar() {
if (!isInSeek) hideObjs()
updateSeekText()
updateSeekProgress()
@@ -297,17 +490,18 @@ class ViewMangaActivity : TitleActivityTemplate() {
}
@SuppressLint("SetTextI18n")
- private fun prepareInfoBar(size: Int) {
+ private fun prepareInfoBar() {
oneinfo.alpha = 0F
infseek.visibility = View.GONE
isearch.visibility = View.GONE
inftitle.ttitle.text = handler.manga?.results?.chapter?.name
- inftxtprogress.text = "$pageNum/$size"
+ inftxtprogress.text = "$pageNum/$realCount"
infseek.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, isHuman: Boolean) {
+ Log.d("MyVM", "seek to ${p1 * realCount / 100}")
if (isHuman) {
- if (p1 >= (pageNum + 1) * 100 / size) scrollForward()
- else if (p1 < (pageNum - 1) * 100 / size) scrollBack()
+ if (p1 >= (pageNum + 1) * 100 / realCount) scrollForward()
+ else if (p1 < (pageNum - 1) * 100 / realCount) scrollBack()
}
}
override fun onStartTrackingTouch(p0: SeekBar?) {
@@ -318,6 +512,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
isInSeek = false
}
})
+ isearch.setImageResource(R.drawable.ic_author)
isearch.setOnClickListener {
handler.sendEmptyMessage(3)
}
@@ -330,16 +525,16 @@ class ViewMangaActivity : TitleActivityTemplate() {
val vsps = vsp as SpringView
vsps.footerView.lht.text = "更多"
vsps.headerView.lht.text = "更多"
- val pm = PagesManager(WeakReference(this))
+ pm = PagesManager(WeakReference(this))
vsps.setListener(object :SpringView.OnFreshListener{
override fun onLoadmore() {
//scrollForward()
- pm.toPage(true)
+ pm?.toPage(true)
vsps.onFinishFreshAndLoad()
}
override fun onRefresh() {
//scrollBack()
- pm.toPage(false)
+ pm?.toPage(false)
vsps.onFinishFreshAndLoad()
}
})
@@ -350,8 +545,11 @@ class ViewMangaActivity : TitleActivityTemplate() {
psivs.setOnScrollChangeListener { _, _, scrollY, _, _ ->
isInScroll = true
if(!isInSeek){
- val newCurrent = (scrollY.toFloat() * size.toFloat() / psivl.height.toFloat() + 0.5).toInt()
- pageNum += newCurrent - currentItem % verticalLoadMaxCount
+ val delta = (scrollY.toFloat() * size.toFloat() / psivl.height.toFloat() + 0.5).toInt() - currentItem % verticalLoadMaxCount
+ if(delta != 0 && !(delta > 0 && pageNum == size)) {
+ pageNum += delta
+ Log.d("MyVM", "Scroll to offset $delta")
+ }
}
}
}
@@ -361,14 +559,6 @@ class ViewMangaActivity : TitleActivityTemplate() {
}
}
- private fun prepareIdBtFullScreen() {
- idtbfullscreen.isChecked = !useFullScreen
- idtbfullscreen.setOnClickListener {
- p["useFullScreen"] = if (idtbfullscreen.isChecked) "true" else "false"
- Toast.makeText(this, "下次浏览生效", Toast.LENGTH_SHORT).show()
- }
- }
-
fun scrollBack() {
isInScroll = false
if(isVertical && (pageNum-1) % verticalLoadMaxCount == 0){
@@ -384,20 +574,19 @@ class ViewMangaActivity : TitleActivityTemplate() {
if(isVertical && (pageNum-1) % verticalLoadMaxCount == 0) handler.sendEmptyMessage(10)
}
-
-
@SuppressLint("SetTextI18n")
private fun updateSeekText() {
- inftxtprogress.text = "$pageNum/$count"
+ inftxtprogress.text = "$pageNum/$realCount"
}
private fun updateSeekProgress() {
- infseek.progress = pageNum * 100 / count
+ infseek.progress = pageNum * 100 / realCount
}
override fun onDestroy() {
dlhandler?.sendEmptyMessage(0)
tt.canDo = false
+ destroy = true
dlhandler = null
handler.destroy()
super.onDestroy()
@@ -415,22 +604,30 @@ class ViewMangaActivity : TitleActivityTemplate() {
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
override fun onBindViewHolder(holder: ViewData, position: Int) {
- val pos = if (r2l) count - position - 1 else position
- if (zipFile?.exists() == true) getImgBitmap(pos)?.let {
- Glide.with(this@ViewMangaActivity).load(it)
- //.thumbnail(Glide.with(this@ViewMangaActivity).load(R.drawable.load))
- .into(holder.itemView.onei)
- //holder.itemView.onei.setImageBitmap(it)
+ val pos = if (r2l) realCount - position - 1 else position
+ val index2load = if(cut) Math.abs(indexMap[pos]) -1 else pos
+ val useCut = cut && isCut[index2load]
+ val isLeft = cut && indexMap[pos] > 0
+ if (zipFile?.exists() == true) getImgBitmap(index2load)?.let {
+ //Glide.with(this@ViewMangaActivity).load(if(useCut) cutBitmap(it, isLeft) else it).into(holder.itemView.onei)
+ holder.itemView.onei.setImageBitmap(if(useCut) cutBitmap(it, isLeft) else it)
+ }
+ else getImgUrl(index2load)?.let{
+ if(useCut){
+ val thisOneI = holder.itemView.onei
+ Glide.with(this@ViewMangaActivity)
+ .asBitmap()
+ .load(GlideUrl(it, CMApi.myGlideHeaders)
+ ).into(object : SimpleTarget() {
+ override fun onResourceReady(resource: Bitmap, transition: Transition?) {
+ thisOneI.setImageBitmap(cutBitmap(resource, isLeft))
+ } })
+ } else Glide.with(this@ViewMangaActivity).load(GlideUrl(it, CMApi.myGlideHeaders)).into(holder.itemView.onei)
}
- else Glide.with(this@ViewMangaActivity).load(
- GlideUrl(getImgUrl(pos), CMApi.myGlideHeaders))
- .timeout(10000)
- //.thumbnail(Glide.with(this@ViewMangaActivity).load(R.drawable.load))
- .into(holder.itemView.onei)
}
override fun getItemCount(): Int {
- return count
+ return realCount
}
}
}
diff --git a/app/src/main/res/layout/fragment_finish.xml b/app/src/main/res/layout/fragment_statuscardflow.xml
similarity index 100%
rename from app/src/main/res/layout/fragment_finish.xml
rename to app/src/main/res/layout/fragment_statuscardflow.xml
diff --git a/app/src/main/res/layout/widget_infodrawer.xml b/app/src/main/res/layout/widget_infodrawer.xml
index 1cb0dcd..3f10e48 100644
--- a/app/src/main/res/layout/widget_infodrawer.xml
+++ b/app/src/main/res/layout/widget_infodrawer.xml
@@ -39,7 +39,7 @@
app:layout_constraintVertical_bias="0.0" />
+ app:layout_constraintStart_toEndOf="@+id/idtbcut"
+ app:layout_constraintTop_toTopOf="@+id/idtbcut" />
+ app:layout_constraintTop_toTopOf="@+id/idtbcut" />
+ app:layout_constraintTop_toTopOf="@+id/idtbcut" />
\ No newline at end of file
diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml
index 9937e66..1c36912 100644
--- a/app/src/main/res/navigation/mobile_navigation.xml
+++ b/app/src/main/res/navigation/mobile_navigation.xml
@@ -134,6 +134,20 @@
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/>
+
+
+ tools:layout="@layout/fragment_statuscardflow" >
+
+
+
+
+
+
+
+
https://api.copymanga.com/api/v3/recs?pos=3200102&limit=21&offset=%1$d&platform=3
https://api.copymanga.com/api/v3/update/newest?limit=21&offset=%1$d&platform=3
https://api.copymanga.com/api/v3/comics?limit=21&offset=%1$d&ordering=%2$s&top=finish&platform=3
+ https://api.copymanga.com/api/v3/comics?limit=21&offset=%1$d&ordering=%2$s&author=%3$s&platform=3
+ https://api.copymanga.com/api/v3/comics?limit=21&offset=%1$d&ordering=%2$s&theme=%3$s&platform=3
已完结
@@ -75,4 +77,7 @@
近七天
近三十天
总榜单
+
+ 作者
+ 标签
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 8dc9e1f..cca0720 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ buildscript {
maven { url 'https://maven.google.com' }
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.2.0'
+ classpath 'com.android.tools.build:gradle:4.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.21'