mirror of
https://github.com/fumiama/copymanga.git
synced 2026-06-05 07:20:23 +08:00
v2.2.6
新增 1. 双页切分显示预载进度 2. 阅览漫画标题栏显示漫画名 修复 1. 一次下载过多漫画可能导致的闪退 优化 1. 阅览漫画定位逻辑 2. VM参数传递, 调用方式 3. 登录错误提示
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,4 +0,0 @@
|
||||
<changelist name="Uncommitted_changes_before_Update_at_2024_3_9,_12_23_AM_[Changes]" date="1709911381682" recycled="true" deleted="true">
|
||||
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Update_at_2024_3_9,_12_23_AM_[Changes]/shelved.patch" />
|
||||
<option name="DESCRIPTION" value="Uncommitted changes before Update at 2024/3/9, 12:23 AM [Changes]" />
|
||||
</changelist>
|
||||
@@ -8,8 +8,8 @@ android {
|
||||
applicationId 'top.fumiama.copymanga'
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 34
|
||||
versionCode 53
|
||||
versionName '2.2.5'
|
||||
versionCode 54
|
||||
versionName '2.2.6'
|
||||
resourceConfigurations += ['zh', 'zh-rCN']
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
@@ -24,13 +24,13 @@ class MangaDlTools {
|
||||
PausableDownloader(url.toString(), 1000) { data ->
|
||||
try {
|
||||
Gson().fromJson(data.decodeToString(), Chapter2Return::class.java)?.let {
|
||||
getChapterInfo(it, index, chapterName, group)
|
||||
downloadChapter(it, index, chapterName, group)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
onDownloadedListener?.handleMessage(index, false, e.localizedMessage?:"Gson parsing error")
|
||||
}
|
||||
}.run()
|
||||
}.run().let { if (!it) onDownloadedListener?.handleMessage(index, false, "获取章节信息错误") }
|
||||
}
|
||||
|
||||
@Synchronized private fun prepareDownloadListener() {
|
||||
@@ -57,8 +57,8 @@ class MangaDlTools {
|
||||
indexMap[f] = index
|
||||
}
|
||||
|
||||
private fun getChapterInfo(chapter2Return: Chapter2Return, index: Int, chapterName: CharSequence, group: CharSequence) {
|
||||
if(index >= 0){
|
||||
private fun downloadChapter(chapter2Return: Chapter2Return, index: Int, chapterName: CharSequence, group: CharSequence) {
|
||||
if(index >= 0) {
|
||||
val f = "$chapterName.zip"
|
||||
setPool(chapter2Return.results.comic.name, group)
|
||||
setIndexMap(f, index)
|
||||
|
||||
@@ -5,38 +5,61 @@ import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.core.content.edit
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.button_tbutton.view.*
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.json.VolumeStructure
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity
|
||||
import java.io.File
|
||||
|
||||
object Reader {
|
||||
fun start2viewManga(name: String, pos: Int, urlArray: Array<String>, fromFirstPage: Boolean = false) {
|
||||
var fileArray = arrayOf<File>()
|
||||
fun start2viewManga(name: String?, pos: Int, urlArray: Array<String>, uuidArray: Array<String>, fromFirstPage: Boolean = false) {
|
||||
Log.d("MyR", "viewMangaAt name $name, pos $pos")
|
||||
mainWeakReference?.get()?.apply {
|
||||
getPreferences(Context.MODE_PRIVATE)?.edit {
|
||||
putInt(name, pos)
|
||||
apply()
|
||||
Log.d("MyR", "记录 $name 阅读到第 ${pos+1} 话")
|
||||
}?: Log.d("MyR", "无法获得 main pref")
|
||||
// ViewMangaActivity.dlhandler = null
|
||||
ViewMangaActivity.position = pos
|
||||
ViewMangaActivity.comicName = name
|
||||
val zipf = ViewMangaActivity.fileArray[pos]
|
||||
val intent = Intent(this, ViewMangaActivity::class.java)
|
||||
name?.let { n ->
|
||||
getPreferences(Context.MODE_PRIVATE)?.edit {
|
||||
putInt(n, pos)
|
||||
apply()
|
||||
Log.d("MyR", "记录 $n 阅读到第 ${pos+1} 话")
|
||||
}?: Log.d("MyR", "无法获得 main pref")
|
||||
intent.putExtra("comicName", name)
|
||||
}
|
||||
intent.putExtra("position", pos)
|
||||
intent.putExtra("urlArray", urlArray)
|
||||
if(!fromFirstPage) {
|
||||
intent.putExtra("uuidArray", uuidArray)
|
||||
if (!fromFirstPage) {
|
||||
intent.putExtra("function", "log")
|
||||
ViewMangaActivity.pn = -2
|
||||
intent.putExtra("pn", -2)
|
||||
}
|
||||
if (zipf.exists()) {
|
||||
ViewMangaActivity.zipFile = zipf
|
||||
val zipFile = fileArray[pos]
|
||||
if (zipFile.exists()) {
|
||||
intent.putExtra("zipFile", zipFile.absolutePath)
|
||||
//intent.putExtra("callFrom", "zipFirst")
|
||||
startActivity(intent)
|
||||
} else {
|
||||
ViewMangaActivity.zipFile = null
|
||||
startActivity(intent)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
fun viewOldMangaZipFile(fileArray: Array<File>, name: String, pos: Int, zipFile: File) {
|
||||
Reader.fileArray = fileArray
|
||||
mainWeakReference?.get()?.apply {
|
||||
val intent = Intent(this, ViewMangaActivity::class.java)
|
||||
intent.putExtra("comicName", name)
|
||||
intent.putExtra("position", pos)
|
||||
intent.putExtra("zipFile", zipFile.absolutePath)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
fun viewMangaZipFile(pos: Int, urlArray: Array<String>, uuidArray: Array<String>, zipFile: File) {
|
||||
mainWeakReference?.get()?.apply {
|
||||
val intent = Intent(this, ViewMangaActivity::class.java)
|
||||
intent.putExtra("position", pos)
|
||||
.putExtra("urlArray", urlArray)
|
||||
.putExtra("uuidArray", uuidArray)
|
||||
.putExtra("callFrom", "zipFirst")
|
||||
.putExtra("zipFile", zipFile.absolutePath)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
fun getComicPathWordInFolder(file: File): String {
|
||||
|
||||
@@ -8,12 +8,11 @@ import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.lang.Thread.sleep
|
||||
import kotlin.random.Random
|
||||
|
||||
class PausableDownloader(private val url: String, private val waitMilliseconds: Long = 0, private val isApi: Boolean = true, private val whenFinish: (suspend (result: ByteArray)->Unit)? = null) {
|
||||
var exit = false
|
||||
suspend fun run() = withContext(Dispatchers.IO) {
|
||||
suspend fun run(): Boolean = withContext(Dispatchers.IO) {
|
||||
var c = 0
|
||||
while (!exit && c++ < 3) {
|
||||
try {
|
||||
@@ -23,12 +22,13 @@ class PausableDownloader(private val url: String, private val waitMilliseconds:
|
||||
mainWeakReference?.get()?.getString(R.string.pc_ua)!!
|
||||
))
|
||||
whenFinish?.let { it(data) }
|
||||
break
|
||||
return@withContext true
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (waitMilliseconds > 0) delay(200+Random.nextLong(waitMilliseconds))
|
||||
}
|
||||
}
|
||||
Log.d("MyPD", "found exit = $exit")
|
||||
return@withContext false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package top.fumiama.copymanga.tools.http
|
||||
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
@@ -14,7 +17,7 @@ import java.util.zip.ZipOutputStream
|
||||
import kotlin.random.Random
|
||||
|
||||
class DownloadPool(folder: String) {
|
||||
class Quest(val fileName: String, val imgUrl: Array<String>, val refer: String? = null)
|
||||
class Quest(val fileName: String, val imgUrl: Array<String>)
|
||||
var exit = false
|
||||
set(value) {
|
||||
if(value) {
|
||||
@@ -33,8 +36,9 @@ class DownloadPool(folder: String) {
|
||||
if(!saveFolder.exists()) saveFolder.mkdirs()
|
||||
}
|
||||
|
||||
operator fun plusAssign(quest: Quest) {
|
||||
operator fun plusAssign(quest: Quest): Unit {
|
||||
packZipFile(quest.fileName, quest.imgUrl)
|
||||
Log.d("MyDP", "+= ${quest.fileName}, size: ${quest.imgUrl.size}")
|
||||
}
|
||||
|
||||
fun setOnDownloadListener(onDownloadListener: (String, Boolean, String) -> Unit) {
|
||||
@@ -46,83 +50,81 @@ class DownloadPool(folder: String) {
|
||||
}
|
||||
|
||||
private fun packZipFile(fileName: String, imgUrls: Array<String>) {
|
||||
Thread {
|
||||
File(saveFolder, "$fileName.tmp").let { f ->
|
||||
f.parentFile?.let { if(!it.exists()) it.mkdirs() }
|
||||
var start = 0
|
||||
Log.d("MyDP", "Zip file: ${f.absolutePath}")
|
||||
if(f.exists()) {
|
||||
try {
|
||||
val zipFile = ZipFile(f)
|
||||
start = zipFile.size()
|
||||
zipFile.close()
|
||||
Log.d("MyDP", "next download index: $start")
|
||||
if (start <= 0 || start >= imgUrls.size) { // error or re-download
|
||||
f.delete()
|
||||
f.createNewFile()
|
||||
start = 0
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
File(saveFolder, "$fileName.tmp").let { f ->
|
||||
f.parentFile?.let { if(!it.exists()) it.mkdirs() }
|
||||
var start = 0
|
||||
Log.d("MyDP", "Zip file: ${f.absolutePath}")
|
||||
if(f.exists()) {
|
||||
try {
|
||||
val zipFile = ZipFile(f)
|
||||
start = zipFile.size()
|
||||
zipFile.close()
|
||||
Log.d("MyDP", "next download index: $start")
|
||||
if (start <= 0 || start >= imgUrls.size) { // error or re-download
|
||||
f.delete()
|
||||
f.createNewFile()
|
||||
start = 0
|
||||
}
|
||||
} else f.createNewFile()
|
||||
val zip: ZipOutputStream
|
||||
if (start > 0) {
|
||||
val fromZip = ZipInputStream(f.readBytes().inputStream())
|
||||
zip = ZipOutputStream(CheckedOutputStream(FileOutputStream(f), CRC32()))
|
||||
zip.setLevel(9)
|
||||
fromZip.use { z ->
|
||||
var e = z.nextEntry
|
||||
while (e != null) {
|
||||
zip.putNextEntry(e)
|
||||
z.copyTo(zip)
|
||||
zip.closeEntry()
|
||||
z.closeEntry()
|
||||
e = z.nextEntry
|
||||
}
|
||||
}
|
||||
} else {
|
||||
zip = ZipOutputStream(CheckedOutputStream(FileOutputStream(f), CRC32()))
|
||||
zip.setLevel(9)
|
||||
}
|
||||
var succeed = true
|
||||
var lastIndex = -8
|
||||
try {
|
||||
for(index in start until imgUrls.size) {
|
||||
while (wait && !exit) sleep(100+Random.nextLong(1000))
|
||||
if(exit) break
|
||||
var tryTimes = 3
|
||||
var s = false
|
||||
while (!s && tryTimes-- > 0) {
|
||||
val u = imgUrls[index]
|
||||
s = (DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(u)?:u), -1))?.let {
|
||||
zip.putNextEntry(ZipEntry("$index.${if(imgUrls[index].contains(".webp")) "webp" else "jpg"}"))
|
||||
zip.write(it)
|
||||
zip.closeEntry()
|
||||
true
|
||||
}?:false
|
||||
if(exit) break
|
||||
if (!s) sleep(2000)
|
||||
if(exit) break
|
||||
}
|
||||
if(!s && tryTimes <= 0) {
|
||||
succeed = false
|
||||
mOnPageDownloadListener?.let { it(fileName, index + 1, imgUrls.size, false, "超过最大重试次数") }
|
||||
break
|
||||
} else mOnPageDownloadListener?.let { it(fileName, index + 1, imgUrls.size, true, "") }
|
||||
lastIndex = index
|
||||
}
|
||||
zip.close()
|
||||
if (succeed && lastIndex+1 >= imgUrls.size) f.renameTo(File(saveFolder, fileName))
|
||||
mOnPageDownloadListener?.let { it(fileName, 0, 0, true, "") }
|
||||
mOnDownloadListener?.let { it(fileName, succeed, "") }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
mOnDownloadListener?.let { it(fileName, false, e.localizedMessage?:"packZipFile") }
|
||||
f.delete()
|
||||
f.createNewFile()
|
||||
}
|
||||
} else f.createNewFile()
|
||||
val zip: ZipOutputStream
|
||||
if (start > 0) {
|
||||
val fromZip = ZipInputStream(f.readBytes().inputStream())
|
||||
zip = ZipOutputStream(CheckedOutputStream(FileOutputStream(f), CRC32()))
|
||||
zip.setLevel(9)
|
||||
fromZip.use { z ->
|
||||
var e = z.nextEntry
|
||||
while (e != null) {
|
||||
zip.putNextEntry(e)
|
||||
z.copyTo(zip)
|
||||
zip.closeEntry()
|
||||
z.closeEntry()
|
||||
e = z.nextEntry
|
||||
}
|
||||
}
|
||||
} else {
|
||||
zip = ZipOutputStream(CheckedOutputStream(FileOutputStream(f), CRC32()))
|
||||
zip.setLevel(9)
|
||||
}
|
||||
}.start()
|
||||
var succeed = true
|
||||
var lastIndex = -8
|
||||
try {
|
||||
for(index in start until imgUrls.size) {
|
||||
while (wait && !exit) sleep(100+Random.nextLong(1000))
|
||||
if(exit) break
|
||||
var tryTimes = 3
|
||||
var s = false
|
||||
while (!s && tryTimes-- > 0) {
|
||||
val u = imgUrls[index]
|
||||
s = (DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(u)?:u), -1))?.let {
|
||||
zip.putNextEntry(ZipEntry("$index.${if(imgUrls[index].contains(".webp")) "webp" else "jpg"}"))
|
||||
zip.write(it)
|
||||
zip.closeEntry()
|
||||
true
|
||||
}?:false
|
||||
if(exit) break
|
||||
if (!s) sleep(2000)
|
||||
if(exit) break
|
||||
}
|
||||
if(!s && tryTimes <= 0) {
|
||||
succeed = false
|
||||
mOnPageDownloadListener?.let { it(fileName, index + 1, imgUrls.size, false, "超过最大重试次数") }
|
||||
break
|
||||
} else mOnPageDownloadListener?.let { it(fileName, index + 1, imgUrls.size, true, "") }
|
||||
lastIndex = index
|
||||
}
|
||||
zip.close()
|
||||
if (succeed && lastIndex+1 >= imgUrls.size) f.renameTo(File(saveFolder, fileName))
|
||||
mOnPageDownloadListener?.let { it(fileName, 0, 0, true, "") }
|
||||
mOnDownloadListener?.let { it(fileName, succeed, "") }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
mOnDownloadListener?.let { it(fileName, false, e.localizedMessage?:"packZipFile") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,15 +115,14 @@ object DownloadTools {
|
||||
fun prepare(url: String?): FutureTask<ByteArray?>? =
|
||||
url?.let {
|
||||
Log.d("Mydl", "prepareHttp: $it")
|
||||
var ret: ByteArray? = null
|
||||
val task = FutureTask(Callable {
|
||||
var ret: ByteArray? = null
|
||||
try {
|
||||
val connection = getNormalConnection(it, "GET")
|
||||
|
||||
val ci = connection?.inputStream
|
||||
ret = ci?.readBytes()
|
||||
ci?.close()
|
||||
connection?.disconnect()
|
||||
connection.inputStream?.use { ci ->
|
||||
ret = ci.readBytes()
|
||||
}
|
||||
connection.disconnect()
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
|
||||
@@ -105,8 +105,8 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
i = p
|
||||
}
|
||||
setOnClickListener {
|
||||
mBookHandler?.urlArray?.let {
|
||||
Reader.start2viewManga(name, i, it)
|
||||
mBookHandler?.apply {
|
||||
Reader.start2viewManga(name, i, urlArray, uuidArray)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
|
||||
var chapterNames = arrayOf<String>()
|
||||
var collect: Int = -1
|
||||
var urlArray = arrayOf<String>()
|
||||
var uuidArray = arrayOf<String>()
|
||||
var exit = false
|
||||
|
||||
override fun handleMessage(msg: Message) {
|
||||
@@ -210,7 +211,7 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
|
||||
if (f.exists()) lci.setBackgroundResource(R.drawable.ic_success)
|
||||
Log.d("MyBH", "add last single chapter ${it.name}")
|
||||
val index = i
|
||||
setOnClickListener { Reader.start2viewManga(comicName, index, urlArray) }
|
||||
setOnClickListener { Reader.start2viewManga(comicName, index, urlArray, uuidArray) }
|
||||
}
|
||||
line?.let { l -> addVolumesView(fbl, l) }
|
||||
} else {
|
||||
@@ -219,14 +220,14 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
|
||||
lct.text = it.name
|
||||
if (f.exists()) lci.setBackgroundResource(R.drawable.ic_success)
|
||||
val index = i
|
||||
setOnClickListener { Reader.start2viewManga(comicName, index, urlArray) }
|
||||
setOnClickListener { Reader.start2viewManga(comicName, index, urlArray, uuidArray) }
|
||||
}
|
||||
}
|
||||
} else line?.l2cr?.apply {
|
||||
lct.text = it.name
|
||||
if (f.exists()) lci.setBackgroundResource(R.drawable.ic_success)
|
||||
val index = i
|
||||
setOnClickListener { Reader.start2viewManga(comicName, index, urlArray) }
|
||||
setOnClickListener { Reader.start2viewManga(comicName, index, urlArray, uuidArray) }
|
||||
line?.let { l -> addVolumesView(fbl, l) }
|
||||
line = null
|
||||
}
|
||||
@@ -242,9 +243,9 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
|
||||
that?.apply {
|
||||
book?.apply {
|
||||
val comicName = name?:return@withContext
|
||||
ViewMangaActivity.fileArray = arrayOf()
|
||||
Reader.fileArray = arrayOf()
|
||||
urlArray = arrayOf()
|
||||
ViewMangaActivity.uuidArray = arrayOf()
|
||||
uuidArray = arrayOf()
|
||||
var i = 0
|
||||
var last = -1
|
||||
volumes.forEachIndexed { groupIndex, v ->
|
||||
@@ -256,9 +257,9 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
|
||||
it.uuid
|
||||
)?:""
|
||||
val f = CMApi.getZipFile(context?.getExternalFilesDir(""), comicName, keys[groupIndex], it.name)
|
||||
ViewMangaActivity.fileArray += f
|
||||
Reader.fileArray += f
|
||||
chapterNames += it.name
|
||||
ViewMangaActivity.uuidArray += it.uuid
|
||||
uuidArray += it.uuid
|
||||
that?.isOnPause?.let { isOnPause ->
|
||||
while (isOnPause && !exit) delay(500)
|
||||
if (exit) return@withContext
|
||||
|
||||
@@ -3,7 +3,6 @@ package top.fumiama.copymanga.ui.comicdl
|
||||
import android.animation.ObjectAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
@@ -13,29 +12,31 @@ import android.view.ViewTreeObserver
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.fragment_book.*
|
||||
import kotlinx.android.synthetic.main.line_chapter.view.*
|
||||
import kotlinx.android.synthetic.main.widget_downloadbar.*
|
||||
import kotlinx.android.synthetic.main.fragment_dlcomic.*
|
||||
import kotlinx.android.synthetic.main.line_horizonal_empty.view.*
|
||||
import kotlinx.android.synthetic.main.button_tbutton.*
|
||||
import kotlinx.android.synthetic.main.button_tbutton.view.*
|
||||
import kotlinx.android.synthetic.main.fragment_book.*
|
||||
import kotlinx.android.synthetic.main.fragment_dlcomic.*
|
||||
import kotlinx.android.synthetic.main.line_caption.view.*
|
||||
import kotlinx.android.synthetic.main.line_chapter.view.*
|
||||
import kotlinx.android.synthetic.main.line_horizonal_empty.view.*
|
||||
import kotlinx.android.synthetic.main.widget_downloadbar.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.json.ChapterStructure
|
||||
import top.fumiama.copymanga.json.ComicStructureOld
|
||||
import top.fumiama.copymanga.json.VolumeStructure
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.manga.MangaDlTools
|
||||
import top.fumiama.copymanga.manga.Reader
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.ui.UITools
|
||||
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment.Companion.exit
|
||||
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment.Companion.json
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity
|
||||
import top.fumiama.copymanga.views.ChapterToggleButton
|
||||
import top.fumiama.copymanga.views.LazyScrollView
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.File
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
@@ -62,6 +63,7 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
private var finishMap = arrayOf<Boolean?>()
|
||||
var downloading = false
|
||||
private var urlArray = arrayOf<String>()
|
||||
private var uuidArray = arrayOf<String>()
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun handleMessage(msg: Message) {
|
||||
@@ -111,8 +113,8 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
if(isOld) analyzeOldStructure()
|
||||
else {
|
||||
urlArray = arrayOf()
|
||||
ViewMangaActivity.fileArray = arrayOf()
|
||||
ViewMangaActivity.uuidArray = arrayOf()
|
||||
Reader.fileArray = arrayOf()
|
||||
uuidArray = arrayOf()
|
||||
vols.forEachIndexed { i, vol ->
|
||||
val caption = groupNames?.get(i)?:vol.results.list[0].group_path_word
|
||||
Log.d("MyCDH", "caption: $caption, group name: ${groupNames?.get(i)}")
|
||||
@@ -269,16 +271,14 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
i.isEnabled = false
|
||||
}
|
||||
i.url?.let {
|
||||
Thread {
|
||||
that?.lifecycleScope?.launch {
|
||||
mangaDlTools.downloadChapterInVol(
|
||||
it,
|
||||
i.chapterName,
|
||||
i.caption?:"null",
|
||||
i.index
|
||||
)
|
||||
}
|
||||
}.start()
|
||||
launch {
|
||||
mangaDlTools.downloadChapterInVol(
|
||||
it,
|
||||
i.chapterName,
|
||||
i.caption?:"null",
|
||||
i.index
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,6 +308,7 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
}
|
||||
|
||||
private suspend fun onZipDownloadFailure(index: Int, message: String) = withContext(Dispatchers.Main) {
|
||||
if (exit) return@withContext
|
||||
tbtnlist[index].setBackgroundResource(R.drawable.rndbg_error)
|
||||
tbtnlist[index].isEnabled = true
|
||||
Toast.makeText(that?.context, "下载${tbtnlist[index].chapterName}失败: $message", Toast.LENGTH_SHORT).show()
|
||||
@@ -345,7 +346,7 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
tbtncnt++
|
||||
|
||||
tbv.tbtn.uuid = uuid
|
||||
ViewMangaActivity.uuidArray += uuid
|
||||
uuidArray += uuid
|
||||
tbv.tbtn.chapterName = title
|
||||
tbv.tbtn.url = url
|
||||
//tbv.tbtn.hint = caption
|
||||
@@ -358,7 +359,7 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
withContext(Dispatchers.IO) {
|
||||
val zipf = CMApi.getZipFile(that!!.context?.getExternalFilesDir(""), comicName, caption, title)
|
||||
Log.d("MyCD", "Get zipf: $zipf")
|
||||
ViewMangaActivity.fileArray += zipf
|
||||
Reader.fileArray += zipf
|
||||
if (zipf.exists()) withContext(Dispatchers.Main) {
|
||||
tbv.tbtn.setBackgroundResource(R.drawable.rndbg_checked)
|
||||
tbv.tbtn.isChecked = false
|
||||
@@ -367,13 +368,9 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
if (zipf.exists() && !multiSelect) {
|
||||
it.tbtn.setBackgroundResource(R.drawable.rndbg_checked)
|
||||
it.tbtn.isChecked = false
|
||||
ViewMangaActivity.zipFile = zipf
|
||||
ViewMangaActivity.dlHandler = this@ComicDlHandler
|
||||
ViewMangaActivity.position = it.tbtn.index
|
||||
dl?.show()
|
||||
val intent = Intent(that?.context, ViewMangaActivity::class.java)
|
||||
intent.putExtra("urlArray", urlArray).putExtra("callFrom", "zipFirst")
|
||||
that?.startActivity(intent)
|
||||
Reader.viewMangaZipFile(it.tbtn.index, urlArray, uuidArray, zipf)
|
||||
} else {
|
||||
it.tbtn.setBackgroundResource(R.drawable.toggle_button)
|
||||
if (it.tbtn.isChecked) that?.tdwn?.text = "$dldChapter/${++checkedChapter}"
|
||||
@@ -393,14 +390,9 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
} else {
|
||||
toolsBox.buildInfo("直接观看", "不下载而进行观看", "确定",
|
||||
null, "取消", {
|
||||
ViewMangaActivity.zipFile = null
|
||||
ViewMangaActivity.dlHandler = this@ComicDlHandler
|
||||
ViewMangaActivity.position = it.tbtn.index
|
||||
dl?.show()
|
||||
|
||||
val intent = Intent(that?.context, ViewMangaActivity::class.java)
|
||||
intent.putExtra("urlArray", urlArray)
|
||||
that?.startActivity(intent)
|
||||
Reader.start2viewManga(null, it.tbtn.index, urlArray, uuidArray)
|
||||
}, null, null
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package top.fumiama.copymanga.ui.download
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
@@ -15,10 +14,10 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.manga.Reader
|
||||
import top.fumiama.copymanga.template.general.NoBackRefreshFragment
|
||||
import top.fumiama.copymanga.tools.file.FileUtils
|
||||
import top.fumiama.copymanga.tools.ui.Navigate
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
@@ -64,12 +63,10 @@ class DownloadFragment: NoBackRefreshFragment(R.layout.fragment_download) {
|
||||
}
|
||||
chosenFile.name.endsWith(".zip") -> {
|
||||
Toast.makeText(context, "加载中...", Toast.LENGTH_SHORT).show()
|
||||
ViewMangaActivity.zipFile = chosenFile
|
||||
ViewMangaActivity.comicName = it[position]
|
||||
ViewMangaActivity.position = position
|
||||
ViewMangaActivity.fileArray = it.map { File(cd, it) }.toTypedArray()
|
||||
// ViewMangaActivity.urlArray = Array(it.size) {return@Array ""}
|
||||
startActivity(Intent(context, ViewMangaActivity::class.java))
|
||||
Reader.viewOldMangaZipFile(
|
||||
it.map { File(cd, it) }.toTypedArray(),
|
||||
it[position], position, chosenFile
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package top.fumiama.copymanga.ui.vm
|
||||
|
||||
import android.widget.Toast
|
||||
import top.fumiama.copymanga.manga.Reader
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity.Companion.comicName
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity.Companion.position
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
@@ -38,7 +36,7 @@ class PagesManager(private val w: WeakReference<ViewMangaActivity>) {
|
||||
}
|
||||
return
|
||||
}
|
||||
val chapterPosition = position + if(goNext) 1 else -1
|
||||
val chapterPosition = v.position + if(goNext) 1 else -1
|
||||
if (v.urlArray.isEmpty()) return
|
||||
if(chapterPosition < 0 || chapterPosition >= v.urlArray.size) {
|
||||
Toast.makeText(v.applicationContext, R.string.end_of_chapter, Toast.LENGTH_SHORT).show()
|
||||
@@ -48,7 +46,7 @@ class PagesManager(private val w: WeakReference<ViewMangaActivity>) {
|
||||
//if(v.zipFirst) intent.putExtra("callFrom", "zipFirst")
|
||||
v.tt.canDo = false
|
||||
//ViewMangaActivity.dlhandler = null
|
||||
comicName?.let { Reader.start2viewManga(it, chapterPosition, v.urlArray, goNext) }
|
||||
v.comicName?.let { Reader.start2viewManga(it, chapterPosition, v.urlArray, v.uuidArray, goNext) }
|
||||
v.finish()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -9,10 +9,12 @@ import android.view.View
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.activity_viewmanga.*
|
||||
import kotlinx.android.synthetic.main.dialog_unzipping.*
|
||||
import kotlinx.android.synthetic.main.widget_infodrawer.*
|
||||
import kotlinx.android.synthetic.main.widget_infodrawer.view.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.MainActivity
|
||||
import top.fumiama.copymanga.json.Chapter2Return
|
||||
@@ -20,10 +22,6 @@ import top.fumiama.copymanga.json.ChapterWithContent
|
||||
import top.fumiama.copymanga.json.ComicStructure
|
||||
import top.fumiama.copymanga.template.http.AutoDownloadHandler
|
||||
import top.fumiama.copymanga.template.http.PausableDownloader
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity.Companion.comicName
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity.Companion.pn
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity.Companion.position
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity.Companion.uuidArray
|
||||
import top.fumiama.copymanga.views.ScaleImageView
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.File
|
||||
@@ -97,11 +95,11 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
LOAD_IMAGES_INTO_LINE -> wv.get()?.lifecycleScope?.launch { loadImagesIntoLine() }
|
||||
RESTORE_PAGE_NUMBER -> {
|
||||
sendEmptyMessage(DIALOG_HIDE)
|
||||
wv.get()?.restorePN()
|
||||
wv.get()?.apply { lifecycleScope.launch { restorePN() } }
|
||||
}
|
||||
LOAD_PAGE_FROM_ITEM -> {
|
||||
val verticalMaxCount = wv.get()?.verticalLoadMaxCount?:20
|
||||
val item = (pn - 1) / verticalMaxCount * verticalMaxCount
|
||||
val item = ((wv.get()?.pn?:1) - 1) / verticalMaxCount * verticalMaxCount
|
||||
loadScrollMode(item)
|
||||
Log.d("MyVMH", "Load page from $item")
|
||||
}
|
||||
@@ -130,6 +128,7 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
}
|
||||
DO_LAMBDA -> (msg.obj as? Runnable?)?.run()
|
||||
SET_NET_INFO -> wv.get()?.idtime?.text = SimpleDateFormat("HH:mm").format(Date()) + week + wv.get()?.toolsBox?.netInfo
|
||||
SET_DL_TEXT -> dl.tunz.text = msg.obj as String
|
||||
}
|
||||
}
|
||||
override fun getGsonItem() = manga
|
||||
@@ -159,9 +158,9 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
prepareManga()
|
||||
}
|
||||
|
||||
suspend fun loadFromFile(file: File): Boolean = withContext(Dispatchers.IO) {
|
||||
suspend fun loadFromFile(file: File): Boolean {
|
||||
fakeLoad()
|
||||
return@withContext try {
|
||||
return try {
|
||||
val jsonFile = File(file.parentFile, "${file.nameWithoutExtension}.json")
|
||||
if(jsonFile.exists()) {
|
||||
manga = Gson().fromJson(jsonFile.reader(), Chapter2Return::class.java)
|
||||
@@ -172,13 +171,15 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
manga?.let {
|
||||
it.results = Chapter2Return.Results()
|
||||
it.results.comic = ComicStructure()
|
||||
it.results.comic.name = file.parentFile?.name
|
||||
it.results.comic.name = file.parentFile?.parentFile?.name
|
||||
it.results.chapter = ChapterWithContent()
|
||||
it.results.chapter.name = file.nameWithoutExtension
|
||||
it.results.chapter.uuid = uuidArray[position]
|
||||
wv.get()?.countZipEntries { c ->
|
||||
it.results.chapter.size = c
|
||||
prepareManga()
|
||||
wv.get()?.apply {
|
||||
it.results.chapter.uuid = uuidArray[position]
|
||||
countZipEntries { c ->
|
||||
it.results.chapter.size = c
|
||||
prepareManga()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,19 +191,21 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fakeLoad() = withContext(Dispatchers.IO) {
|
||||
if(MainActivity.member?.hasLogin == true) launch {
|
||||
PausableDownloader(chapterUrl) { _ -> }.run()
|
||||
}
|
||||
private fun fakeLoad() {
|
||||
if (MainActivity.member?.hasLogin == true) Thread {
|
||||
runBlocking { PausableDownloader(chapterUrl) { _ -> }.run() }
|
||||
}.start()
|
||||
}
|
||||
|
||||
private suspend fun prepareManga() = withContext(Dispatchers.Main) {
|
||||
if(comicName == null) {
|
||||
comicName = manga?.results?.comic?.name
|
||||
wv.get()?.apply {
|
||||
if(comicName == null) {
|
||||
comicName = manga?.results?.comic?.name
|
||||
}
|
||||
count = manga?.results?.chapter?.size?:0
|
||||
initManga()
|
||||
vprog?.visibility = View.GONE
|
||||
}
|
||||
wv.get()?.count = manga?.results?.chapter?.size?:0
|
||||
wv.get()?.initManga()
|
||||
wv.get()?.vprog?.visibility = View.GONE
|
||||
}
|
||||
private suspend fun loadImagesIntoLine(item: Int = (wv.get()?.currentItem?:0), doAfter: Runnable? = null) = withContext(Dispatchers.IO) {
|
||||
val maxCount: Int = (wv.get()?.verticalLoadMaxCount?:20)
|
||||
@@ -220,7 +223,7 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
if(notFull) obtainMessage(PREPARE_LAST_PAGE, loadCount + 1, maxCount).sendToTarget()
|
||||
obtainMessage(DO_LAMBDA, Runnable{
|
||||
doAfter?.run()
|
||||
wv.get()?.updateSeekBar(0)
|
||||
wv.get()?.apply { lifecycleScope.launch { updateSeekBar(0) } }
|
||||
}).sendToTarget()
|
||||
}
|
||||
}
|
||||
@@ -283,5 +286,6 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
const val DECREASE_IMAGE_COUNT_AND_RESTORE_PAGE_NUMBER_AT_ZERO = 20
|
||||
const val DO_LAMBDA = 21
|
||||
const val SET_NET_INFO = 22
|
||||
const val SET_DL_TEXT = 23
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,14 @@ import android.graphics.drawable.Drawable
|
||||
import android.media.AudioManager
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.view.*
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowInsetsController
|
||||
import android.widget.SeekBar
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
@@ -115,6 +119,11 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
val realCount get() = if(cut) indexMap.size else count
|
||||
|
||||
var urlArray = arrayOf<String>()
|
||||
var uuidArray = arrayOf<String>()
|
||||
var position = 0
|
||||
var comicName: String? = null
|
||||
private var zipFile: File? = null
|
||||
var pn = 0
|
||||
|
||||
private val loadImgOnWait = AtomicInteger()
|
||||
|
||||
@@ -149,6 +158,11 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
//dlZip2View = intent.getStringExtra("callFrom") == "Dl" || p["dlZip2View"] == "true"
|
||||
//zipFirst = intent.getStringExtra("callFrom") == "zipFirst"
|
||||
intent.getStringArrayExtra("urlArray")?.let { urlArray = it }
|
||||
intent.getStringArrayExtra("uuidArray")?.let { uuidArray = it }
|
||||
position = intent.getIntExtra("position", 0)
|
||||
comicName = intent.getStringExtra("comicName")
|
||||
zipFile = intent.getStringExtra("zipFile")?.let { File(it) }
|
||||
pn = intent.getIntExtra("pn", 0)
|
||||
cut = pb["useCut"]
|
||||
r2l = pb["r2l"]
|
||||
verticalLoadMaxCount = settingsPref?.getInt("settings_cat_vm_sb_vertical_max", 20)?.let { if(it > 0) it else 20 }?:20
|
||||
@@ -221,7 +235,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
)
|
||||
}
|
||||
|
||||
fun restorePN() {
|
||||
suspend fun restorePN() = withContext(Dispatchers.Main) {
|
||||
if (isPnValid) {
|
||||
isInScroll = false
|
||||
pageNum = pn
|
||||
@@ -242,41 +256,51 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
}
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
private fun doPrepareWebImg() = Thread {
|
||||
private suspend fun doPrepareWebImg() = withContext(Dispatchers.IO) {
|
||||
getImgUrlArray()?.apply {
|
||||
if(cut) {
|
||||
Log.d("MyVM", "is cut, load all pages...")
|
||||
handler.sendEmptyMessage(VMHandler.DIALOG_SHOW) //showDl
|
||||
handler.sendEmptyMessage(VMHandler.DIALOG_SHOW) // showDl
|
||||
isCut = BooleanArray(size)
|
||||
val analyzedCnt = BooleanArray(size)
|
||||
forEachIndexed { i, it ->
|
||||
if(it != null) {
|
||||
Thread{
|
||||
DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(it)?:it), 1024)?.inputStream()?.let {
|
||||
isCut[i] = canCut(it)
|
||||
analyzedCnt[i] = true
|
||||
handler.obtainMessage(VMHandler.SET_DL_TEXT, "$i/$size").sendToTarget()
|
||||
if(it != null) try {
|
||||
DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(it)?:it), 1024)?.inputStream()?.let {
|
||||
isCut[i] = canCut(it)
|
||||
}?:run {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(this@ViewMangaActivity, R.string.touch_img_error, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
finish()
|
||||
}
|
||||
}.start()
|
||||
Thread.sleep(22)
|
||||
return@withContext
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(this@ViewMangaActivity, R.string.analyze_img_size_error, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
finish()
|
||||
}
|
||||
return@withContext
|
||||
}
|
||||
}
|
||||
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
|
||||
handler.sendEmptyMessage(15) // hideDl
|
||||
Log.d("MyVM", "load all pages finished")
|
||||
}
|
||||
count = size
|
||||
runOnUiThread { prepareItems() }
|
||||
prepareItems()
|
||||
if (notUseVP) prepareDownloadTasks()
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
fun initManga() {
|
||||
suspend fun initManga() = withContext(Dispatchers.IO) {
|
||||
val uuid = handler.manga?.results?.chapter?.uuid
|
||||
Log.d("MyVM", "initManga, chapter uuid: $uuid")
|
||||
if (uuid != null && uuid != "") {
|
||||
@@ -333,14 +357,13 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
Log.d("MyVM", "setPageNumber($num)")
|
||||
if (r2l && !notUseVP) vp.currentItem = realCount - num
|
||||
else if (notUseVP) {
|
||||
if(isVertical){
|
||||
if(isVertical) {
|
||||
currentItem = num - 1
|
||||
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 {
|
||||
lifecycleScope.launch { updateSeekBar() }
|
||||
} else {
|
||||
currentItem = num - 1
|
||||
try {
|
||||
loadOneImg()
|
||||
@@ -353,23 +376,24 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
}
|
||||
} 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++
|
||||
//var delta = num - 1 - vp.currentItem
|
||||
vp.currentItem = num - 1
|
||||
/*lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
if(delta >= 1) while (delta-- > 0){
|
||||
delay(20)
|
||||
withContext(Dispatchers.Main) {
|
||||
vp.currentItem++
|
||||
}
|
||||
}
|
||||
else if(delta <= -1) while (delta++ < 0){
|
||||
delay(20)
|
||||
withContext(Dispatchers.Main) {
|
||||
vp.currentItem--
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
else if(delta <= -1) Thread{
|
||||
while (delta++ < 0){
|
||||
Thread.sleep(23)
|
||||
runOnUiThread {
|
||||
vp.currentItem--
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +589,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun prepareItems() {
|
||||
private suspend fun prepareItems(): Unit = withContext(Dispatchers.Main) {
|
||||
try {
|
||||
prepareVP()
|
||||
prepareInfoBar()
|
||||
@@ -588,7 +612,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun setProgress() {
|
||||
private suspend fun setProgress() = withContext(Dispatchers.IO) {
|
||||
handler.manga?.results?.chapter?.uuid?.let {
|
||||
getPreferences(MODE_PRIVATE).edit {
|
||||
//it["chapterId"] = hm.chapterId.toString()
|
||||
@@ -653,18 +677,18 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
vp.adapter = ViewData(vp).RecyclerViewAdapter()
|
||||
vp.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
updateSeekBar()
|
||||
super.onPageSelected(position)
|
||||
lifecycleScope.launch { updateSeekBar() }
|
||||
}
|
||||
})
|
||||
if (r2l && !isPnValid) vp.currentItem = realCount - 1
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSeekBar(p: Int = 0) {
|
||||
suspend fun updateSeekBar(p: Int = 0) = withContext(Dispatchers.Main) {
|
||||
if (p > 0) {
|
||||
updateSeekText(p)
|
||||
return
|
||||
return@withContext
|
||||
}
|
||||
if (!isInSeek) hideDrawer()
|
||||
updateSeekText()
|
||||
@@ -677,7 +701,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
oneinfo.alpha = 0F
|
||||
infseek.visibility = View.GONE
|
||||
isearch.visibility = View.GONE
|
||||
inftitle.ttitle.text = handler.manga?.results?.chapter?.name
|
||||
inftitle.ttitle.text = "$comicName ${handler.manga?.results?.chapter?.name}"
|
||||
inftxtprogress.text = "$pageNum/$realCount"
|
||||
infseek.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
var p = 0
|
||||
@@ -726,7 +750,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
} else isInSeek = false
|
||||
}
|
||||
private fun after() {
|
||||
if(manualCount++ < 3) p = pageNum else updateSeekBar(p)
|
||||
if(manualCount++ < 3) p = pageNum else lifecycleScope.launch { updateSeekBar(p) }
|
||||
}
|
||||
})
|
||||
isearch.setImageResource(R.drawable.ic_author)
|
||||
@@ -786,7 +810,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
if(isVertical && (pageNum-1) % verticalLoadMaxCount == 0) {
|
||||
Log.d("MyVM", "Do scroll back, isVertical: $isVertical, pageNum: $pageNum")
|
||||
if (isInSeek) {
|
||||
updateSeekBar(pageNum-1)
|
||||
(pageNum-1).let { lifecycleScope.launch { updateSeekBar(it) } }
|
||||
return
|
||||
}
|
||||
handler.obtainMessage(
|
||||
@@ -805,7 +829,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
pageNum++
|
||||
if(isVertical && (pageNum-1) % verticalLoadMaxCount == 0) {
|
||||
if (isInSeek) {
|
||||
updateSeekBar(pageNum+1)
|
||||
(pageNum+1).let { lifecycleScope.launch { updateSeekBar(it) } }
|
||||
return
|
||||
}
|
||||
handler.sendEmptyMessage(VMHandler.LOAD_SCROLL_MODE)
|
||||
@@ -917,14 +941,8 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
var comicName: String? = null
|
||||
var uuidArray = arrayOf<String>()
|
||||
var fileArray = arrayOf<File>()
|
||||
var position = 0
|
||||
var zipFile: File? = null
|
||||
var dlHandler: Handler? = null
|
||||
var va: WeakReference<ViewMangaActivity>? = null
|
||||
var pn = 0
|
||||
var noCellarAlert = false
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package top.fumiama.copymanga.user
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Base64
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.stream.JsonReader
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.json.LoginInfoStructure
|
||||
@@ -16,35 +15,38 @@ import java.nio.charset.Charset
|
||||
class Member(private val pref: SharedPreferences, private val getString: (Int) -> String) {
|
||||
val hasLogin: Boolean get() = pref.getString("token", "")?.isNotEmpty()?:false
|
||||
suspend fun login(username: String, pwd: String, salt: Int): LoginInfoStructure = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
getLoginConnection(username, pwd, salt).apply {
|
||||
Gson().fromJson<LoginInfoStructure>(
|
||||
JsonReader(inputStream.reader()), LoginInfoStructure::class.java
|
||||
)?.let { data ->
|
||||
disconnect()
|
||||
if(data.code == 200) {
|
||||
pref.edit()?.apply {
|
||||
putString("token", data.results?.token)
|
||||
putString("user_id", data.results?.user_id)
|
||||
putString("username", data.results?.username)
|
||||
putString("nickname", data.results?.nickname)
|
||||
apply()
|
||||
return@withContext info()
|
||||
var err = ""
|
||||
getLoginConnection(username, pwd, salt).apply {
|
||||
inputStream.use {
|
||||
it?.readBytes()?.let { data ->
|
||||
data.inputStream().use { dataIn ->
|
||||
try {
|
||||
Gson().fromJson<LoginInfoStructure>(
|
||||
dataIn.reader(), LoginInfoStructure::class.java
|
||||
)?.let { info ->
|
||||
if(info.code == 200) {
|
||||
pref.edit()?.apply {
|
||||
putString("token", info.results?.token)
|
||||
putString("user_id", info.results?.user_id)
|
||||
putString("username", info.results?.username)
|
||||
putString("nickname", info.results?.nickname)
|
||||
apply()
|
||||
return@withContext info()
|
||||
}
|
||||
}
|
||||
return@withContext info
|
||||
}?: run { err = getString(R.string.login_parse_json_error) }
|
||||
} catch (e: Exception) {
|
||||
err = data.decodeToString()
|
||||
}
|
||||
}
|
||||
return@withContext data
|
||||
}
|
||||
}?: run { err = getString(R.string.login_get_conn_failed) }
|
||||
}
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 400
|
||||
l.message = getString(R.string.login_get_conn_failed)
|
||||
return@withContext l
|
||||
} catch (e: Exception) {
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 400
|
||||
l.message = e.toString()
|
||||
return@withContext l
|
||||
}
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 400
|
||||
l.message = err
|
||||
return@withContext l
|
||||
}
|
||||
|
||||
|
||||
@@ -61,18 +63,25 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
|
||||
l.message = getString(R.string.noLogin)
|
||||
return@withContext l
|
||||
}
|
||||
return@withContext try {
|
||||
val l = Gson().fromJson(DownloadTools.getHttpContent(
|
||||
try {
|
||||
val data = DownloadTools.getHttpContent(
|
||||
getString(R.string.memberInfoApiUrl).format(CMApi.myHostApiUrl).let {
|
||||
CMApi.apiProxy?.wrap(it)?:it
|
||||
}
|
||||
).decodeToString(),
|
||||
LoginInfoStructure::class.java)
|
||||
if(l.code == 200) pref.edit()?.apply {
|
||||
putString("avatar", l.results.avatar)
|
||||
apply()
|
||||
).decodeToString()
|
||||
try {
|
||||
val l = Gson().fromJson(data, LoginInfoStructure::class.java)
|
||||
if(l.code == 200) pref.edit()?.apply {
|
||||
putString("avatar", l.results.avatar)
|
||||
apply()
|
||||
}
|
||||
l
|
||||
} catch (e : Exception) {
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 450
|
||||
l.message = "${getString(R.string.login_get_avatar_failed)}: $data"
|
||||
l
|
||||
}
|
||||
l
|
||||
} catch (e: Exception) {
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 450
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
<string name="load_page_number_error">第%1$d页加载异常</string>
|
||||
<string name="load_chapter_error">加载章节错误</string>
|
||||
<string name="show_image_error_try_lower_resolution">图片加载错误,请尝试下载后使用较低图片质量查看</string>
|
||||
<string name="touch_img_error">预载图片头失败</string>
|
||||
<string name="analyze_img_size_error">读取图片大小失败</string>
|
||||
|
||||
<string name="mainPageApiUrl">https://%1$s/api/v3/h5/homeIndex?platform=3</string>
|
||||
<string name="referUrl">https://%1$s</string>
|
||||
@@ -171,7 +173,8 @@
|
||||
<string name="login_null_username">用户名为空</string>
|
||||
<string name="login_null_pwd">密码为空</string>
|
||||
<string name="login_get_conn_failed">登录失败</string>
|
||||
<string name="login_get_avatar_failed">恢复登录失败</string>
|
||||
<string name="login_parse_json_error">解析返回数据失败</string>
|
||||
<string name="login_get_avatar_failed">获取用户信息失败</string>
|
||||
<string name="login_restart_to_apply">重启应用以彻底退出登录</string>
|
||||
|
||||
<string name="old_download_card_name">前往旧版下载</string>
|
||||
|
||||
Reference in New Issue
Block a user