mirror of
https://github.com/fumiama/copymanga.git
synced 2026-06-09 17:50:28 +08:00
2.0.beta6
1. 修复漫画封面为空导致的主页闪退 2. 增加详情页导航到作者、标签 3. 增加阅览缓存、音量键页、双页切分 4. 优化卷轴模式、下载逻辑
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<ByteArray?>? =
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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<BookFragment>, 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<BookFragment>, 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<ThemeStructure>, 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) }
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class FinishFragment : StatusCardFlow(R.string.finishApiUrl, R.id.action_nav_finish_to_nav_book)
|
||||
@@ -60,7 +60,6 @@ class ComicDlHandler(looper: Looper, that: WeakReference<ComicDlFragment>, priva
|
||||
private var checkedChapter = 0
|
||||
private var dldChapter = 0
|
||||
private var haveDlStarted = false
|
||||
private var canDl = false
|
||||
private var tbtnlist: Array<ChapterToggleButton> = arrayOf()
|
||||
private var tbtncnt = 0
|
||||
private var isNewTitle = false
|
||||
@@ -215,10 +214,12 @@ class ComicDlHandler(looper: Looper, that: WeakReference<ComicDlFragment>, 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<ComicDlFragment>, 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<ComicDlFragment>, 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) {
|
||||
|
||||
@@ -310,7 +310,9 @@ class HomeHandler(that: WeakReference<HomeFragment>) : 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 {
|
||||
|
||||
@@ -21,7 +21,7 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
|
||||
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) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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<ScaleImageView>()
|
||||
//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<FutureTask<ByteArray?>?>? = 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<String>(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<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
app:layout_constraintVertical_bias="0.0" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/idtbfullscreen"
|
||||
android:id="@+id/idtbcut"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
@@ -47,8 +47,8 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/toggle_button"
|
||||
android:textOff="全屏开"
|
||||
android:textOn="全屏关"
|
||||
android:textOff="切分关闭"
|
||||
android:textOn="双页切分"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/idtbvh"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -64,8 +64,8 @@
|
||||
android:textOff="横向"
|
||||
android:textOn="竖向"
|
||||
app:layout_constraintEnd_toStartOf="@id/idtbvp"
|
||||
app:layout_constraintStart_toEndOf="@+id/idtbfullscreen"
|
||||
app:layout_constraintTop_toTopOf="@+id/idtbfullscreen" />
|
||||
app:layout_constraintStart_toEndOf="@+id/idtbcut"
|
||||
app:layout_constraintTop_toTopOf="@+id/idtbcut" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/idtbvp"
|
||||
@@ -77,7 +77,7 @@
|
||||
android:textOn="动画关"
|
||||
app:layout_constraintEnd_toStartOf="@+id/idtblr"
|
||||
app:layout_constraintStart_toEndOf="@id/idtbvh"
|
||||
app:layout_constraintTop_toTopOf="@+id/idtbfullscreen" />
|
||||
app:layout_constraintTop_toTopOf="@+id/idtbcut" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/idtblr"
|
||||
@@ -89,7 +89,7 @@
|
||||
android:textOn="←后 前→"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/idtbvp"
|
||||
app:layout_constraintTop_toTopOf="@+id/idtbfullscreen" />
|
||||
app:layout_constraintTop_toTopOf="@+id/idtbcut" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -134,6 +134,20 @@
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_out_left_exit"
|
||||
app:popExitAnim="@anim/slide_in_right_exit"/>
|
||||
<action
|
||||
android:id="@+id/action_nav_book_to_nav_author"
|
||||
app:destination="@id/nav_author"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_out_left_exit"
|
||||
app:popExitAnim="@anim/slide_in_right_exit"/>
|
||||
<action
|
||||
android:id="@+id/action_nav_book_to_nav_caption"
|
||||
app:destination="@id/nav_caption"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_out_left_exit"
|
||||
app:popExitAnim="@anim/slide_in_right_exit"/>
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
@@ -189,7 +203,7 @@
|
||||
android:id="@+id/nav_finish"
|
||||
android:name="top.fumiama.copymanga.ui.cardflow.finish.FinishFragment"
|
||||
android:label="@string/complete"
|
||||
tools:layout="@layout/fragment_newest" >
|
||||
tools:layout="@layout/fragment_statuscardflow" >
|
||||
<action
|
||||
android:id="@+id/action_nav_finish_to_nav_book"
|
||||
app:destination="@id/nav_book"
|
||||
@@ -199,6 +213,34 @@
|
||||
app:popExitAnim="@anim/slide_in_right_exit"/>
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_author"
|
||||
android:name="top.fumiama.copymanga.ui.cardflow.author.AuthorFragment"
|
||||
android:label="@string/author"
|
||||
tools:layout="@layout/fragment_statuscardflow" >
|
||||
<action
|
||||
android:id="@+id/action_nav_author_to_nav_book"
|
||||
app:destination="@id/nav_book"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_out_left_exit"
|
||||
app:popExitAnim="@anim/slide_in_right_exit"/>
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_caption"
|
||||
android:name="top.fumiama.copymanga.ui.cardflow.caption.CaptionFragment"
|
||||
android:label="@string/caption"
|
||||
tools:layout="@layout/fragment_statuscardflow" >
|
||||
<action
|
||||
android:id="@+id/action_nav_caption_to_nav_book"
|
||||
app:destination="@id/nav_book"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_out_left_exit"
|
||||
app:popExitAnim="@anim/slide_in_right_exit"/>
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_group"
|
||||
android:name="top.fumiama.copymanga.ui.comicdl.ComicDlFragment"
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
<string name="recommendApiUrl">https://api.copymanga.com/api/v3/recs?pos=3200102&limit=21&offset=%1$d&platform=3</string>
|
||||
<string name="newestApiUrl">https://api.copymanga.com/api/v3/update/newest?limit=21&offset=%1$d&platform=3</string>
|
||||
<string name="finishApiUrl">https://api.copymanga.com/api/v3/comics?limit=21&offset=%1$d&ordering=%2$s&top=finish&platform=3</string>
|
||||
<string name="authorApiUrl">https://api.copymanga.com/api/v3/comics?limit=21&offset=%1$d&ordering=%2$s&author=%3$s&platform=3</string>
|
||||
<string name="captionApiUrl">https://api.copymanga.com/api/v3/comics?limit=21&offset=%1$d&ordering=%2$s&theme=%3$s&platform=3</string>
|
||||
|
||||
<string name="complete">已完结</string>
|
||||
|
||||
@@ -75,4 +77,7 @@
|
||||
<string name="rank_week">近七天</string>
|
||||
<string name="rank_month">近三十天</string>
|
||||
<string name="rank_all">总榜单</string>
|
||||
|
||||
<string name="author">作者</string>
|
||||
<string name="caption">标签</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user