mirror of
https://github.com/fumiama/copymanga.git
synced 2026-06-04 23:10:23 +08:00
v2.2.2
新增 1. API代理(需密钥) 修复 1. 图床代理实际无效 2. 流量阅读时闪退 优化 1. 网络错误时自动停止加载
This commit is contained in:
1
.idea/dictionaries/fumiama.xml
generated
1
.idea/dictionaries/fumiama.xml
generated
@@ -5,6 +5,7 @@
|
||||
<w>grps</w>
|
||||
<w>imgs</w>
|
||||
<w>lowpan</w>
|
||||
<w>mangacopy</w>
|
||||
<w>mangafuna</w>
|
||||
<w>nisi</w>
|
||||
<w>pausable</w>
|
||||
|
||||
@@ -8,8 +8,8 @@ android {
|
||||
applicationId 'top.fumiama.copymanga'
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 34
|
||||
versionCode 49
|
||||
versionName '2.2.1'
|
||||
versionCode 50
|
||||
versionName '2.2.2'
|
||||
resourceConfigurations += ['zh', 'zh-rCN']
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
@@ -55,7 +55,7 @@ class LoginActivity : AppCompatActivity() {
|
||||
finish()
|
||||
return@launch
|
||||
}
|
||||
Toast.makeText(this@LoginActivity, l?.message, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this@LoginActivity, l?.message, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,20 +5,19 @@ import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.card_book.*
|
||||
import kotlinx.android.synthetic.main.line_booktandb.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.json.BookInfoStructure
|
||||
import top.fumiama.copymanga.json.ThemeStructure
|
||||
import top.fumiama.copymanga.json.VolumeStructure
|
||||
import top.fumiama.copymanga.template.http.PausableDownloader
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.File
|
||||
|
||||
class Book(val path: String, private val getString: (Int) -> String, private val exDir: File, private val loadCache: Boolean = false, private val mPassName: String? = null) {
|
||||
private val mBookApiUrl = getString(R.string.bookInfoApiUrl).format(CMApi.myHostApiUrl, path)
|
||||
private val mBookApiUrl = getString(R.string.bookInfoApiUrl).format(CMApi.myHostApiUrl, path).let {
|
||||
CMApi.apiProxy?.wrap(it)?:it
|
||||
}
|
||||
private val mUserAgent = getString(R.string.pc_ua)
|
||||
private var mBook: BookInfoStructure? = null
|
||||
private var mGroupPathWords = arrayOf<String>()
|
||||
@@ -131,7 +130,7 @@ class Book(val path: String, private val getString: (Int) -> String, private val
|
||||
mJsonString = Gson().toJson(volumes)
|
||||
File(mangaFolder, "info.json").writeText(mJsonString)
|
||||
File(mangaFolder, "grps.json").writeText(Gson().toJson(mKeys))
|
||||
(cover?.let { CMApi.proxy?.wrap(it) } ?:cover)?.let {
|
||||
(cover?.let { CMApi.imageProxy?.wrap(it) } ?:cover)?.let {
|
||||
Thread {
|
||||
DownloadTools.getHttpContent(it, -1)?.let { data ->
|
||||
File(mangaFolder, "head.jpg").writeBytes(data)
|
||||
|
||||
@@ -5,15 +5,18 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.json.BookQueryStructure
|
||||
import top.fumiama.copymanga.json.ReturnBase
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
|
||||
class Shelf(private val token: String, getString: (Int) -> String) {
|
||||
private val hostUrl: String = getString(R.string.hostUrl)
|
||||
private val apiUrl: String = getString(R.string.shelfOperateApiUrl).format(hostUrl)
|
||||
private val queryApiUrl = getString(R.string.bookUserQueryApiUrl)
|
||||
private val queryApiUrlTemplate = getString(R.string.bookUserQueryApiUrl)
|
||||
private val referer: String = getString(R.string.referer)
|
||||
private val ua: String = getString(R.string.pc_ua)
|
||||
private val addApiUrl get() = "$apiUrl?platform=3".let { CMApi.apiProxy?.wrap(it)?:it }
|
||||
private val delApiUrl get() = "${apiUrl}s?platform=3".let { CMApi.apiProxy?.wrap(it)?:it }
|
||||
suspend fun add(comicId: String): String = withContext(Dispatchers.IO) {
|
||||
if (comicId.isEmpty()) {
|
||||
return@withContext "空漫画ID"
|
||||
@@ -26,7 +29,7 @@ class Shelf(private val token: String, getString: (Int) -> String) {
|
||||
append(token)
|
||||
}
|
||||
val re = DownloadTools.requestWithBody(
|
||||
"$apiUrl?platform=3", "POST", body.encodeToByteArray(), referer, ua
|
||||
addApiUrl, "POST", body.encodeToByteArray(), referer, ua
|
||||
)?.decodeToString() ?: return@withContext "空回应"
|
||||
return@withContext Gson().fromJson(re, ReturnBase::class.java).message
|
||||
}
|
||||
@@ -45,7 +48,7 @@ class Shelf(private val token: String, getString: (Int) -> String) {
|
||||
append(token)
|
||||
}
|
||||
val re = DownloadTools.requestWithBody(
|
||||
"${apiUrl}s?platform=3", "DELETE", body.encodeToByteArray(), referer, ua
|
||||
delApiUrl, "DELETE", body.encodeToByteArray(), referer, ua
|
||||
)?.decodeToString() ?: return@withContext "空回应"
|
||||
return@withContext Gson().fromJson(re, ReturnBase::class.java).message
|
||||
}
|
||||
@@ -53,7 +56,9 @@ class Shelf(private val token: String, getString: (Int) -> String) {
|
||||
suspend fun query(pathWord: String): BookQueryStructure? = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
Gson().fromJson(DownloadTools.getHttpContent(
|
||||
queryApiUrl.format(hostUrl, pathWord), referer, ua
|
||||
queryApiUrlTemplate.format(hostUrl, pathWord).let {
|
||||
CMApi.apiProxy?.wrap(it)?:it
|
||||
}, referer, ua
|
||||
).decodeToString(), BookQueryStructure::class.java)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
||||
@@ -13,47 +13,39 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.json.ReturnBase
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
||||
import top.fumiama.copymanga.tools.thread.TimeThread
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.File
|
||||
import java.lang.Thread.sleep
|
||||
import java.security.MessageDigest
|
||||
|
||||
open class AutoDownloadHandler(
|
||||
private val url: String, private val jsonClass: Class<*>,
|
||||
private val context: LifecycleOwner?,
|
||||
private val callCheckMsg: Int = -1,
|
||||
private val loadFromCache: Boolean = false,
|
||||
private val customCacheFile: File? = null): Handler(Looper.myLooper()!!) {
|
||||
private var timeThread: TimeThread? = null
|
||||
private var checkTimes = 0
|
||||
var exit = false
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
when(msg.what){
|
||||
callCheckMsg -> check()
|
||||
0 -> setLayouts()
|
||||
MSG_START_LOAD -> setLayouts()
|
||||
}
|
||||
}
|
||||
open fun setGsonItem(gsonObj: Any): Boolean = true
|
||||
open fun getGsonItem(): ReturnBase? = null
|
||||
open fun onError() {}
|
||||
open suspend fun onError() {}
|
||||
open suspend fun doWhenFinishDownload() {}
|
||||
fun startLoad() {
|
||||
sendEmptyMessage(0)
|
||||
sendEmptyMessage(MSG_START_LOAD)
|
||||
}
|
||||
fun destroy() {
|
||||
exit = true
|
||||
}
|
||||
private suspend fun download() = withContext(Dispatchers.IO) {
|
||||
checkTimes = 0
|
||||
TimeThread(this@AutoDownloadHandler, callCheckMsg, 100).let {
|
||||
timeThread = it
|
||||
it.canDo = true
|
||||
it.start()
|
||||
}
|
||||
downloadCoroutine()
|
||||
check()
|
||||
}
|
||||
private fun toHexStr(byteArray: ByteArray) =
|
||||
with(StringBuilder()) {
|
||||
@@ -86,7 +78,10 @@ open class AutoDownloadHandler(
|
||||
var cnt = 0
|
||||
while (cnt++ <= 3) {
|
||||
try {
|
||||
val data = DownloadTools.getHttpContent(url, null, mainWeakReference?.get()?.getString(R.string.pc_ua)!!)
|
||||
val data = DownloadTools.getHttpContent(
|
||||
CMApi.apiProxy?.wrap(url)?:url, null,
|
||||
mainWeakReference?.get()?.getString(R.string.pc_ua)!!
|
||||
)
|
||||
if(exit) return@withContext
|
||||
val fi = data.inputStream()
|
||||
val pass = setGsonItem(Gson().fromJson(fi.reader(), jsonClass))
|
||||
@@ -105,17 +100,18 @@ open class AutoDownloadHandler(
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun check() {
|
||||
val g = getGsonItem()
|
||||
if(g != null) {
|
||||
timeThread?.canDo = false
|
||||
if(g.code == 200) sendEmptyMessage(0)
|
||||
else onError()
|
||||
Log.d("MyADH", "[${g.code}]${g.message}")
|
||||
} else if(checkTimes++ > 1000) timeThread?.canDo = false
|
||||
private suspend fun check() {
|
||||
getGsonItem()?.let {
|
||||
Log.d("MyADH", "[${it.code}]${it.message}")
|
||||
if (it.code == 200) startLoad() else null
|
||||
}?:onError()
|
||||
}
|
||||
private fun setLayouts() = context?.lifecycleScope?.launch {
|
||||
if(getGsonItem() == null) download()
|
||||
else doWhenFinishDownload()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MSG_START_LOAD = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,20 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.withContext
|
||||
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 whenFinish: (suspend (result: ByteArray)->Unit)? = null) {
|
||||
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) {
|
||||
var c = 0
|
||||
while (!exit && c++ < 3) {
|
||||
try {
|
||||
val data = (DownloadTools.getHttpContent(url,
|
||||
val data = (DownloadTools.getHttpContent(
|
||||
(if(isApi) CMApi.apiProxy?.wrap(url) else null)?:url,
|
||||
mainWeakReference?.get()?.getString(R.string.referer)!!,
|
||||
mainWeakReference?.get()?.getString(R.string.pc_ua)!!
|
||||
))
|
||||
|
||||
@@ -114,7 +114,7 @@ class CardList(
|
||||
that?.context?.let { context ->
|
||||
val waitMillis = cardLoadingWaits.getAndIncrement().toLong()*200
|
||||
val g = Glide.with(context).load(
|
||||
GlideUrl(CMApi.proxy?.wrap(head)?:head, CMApi.myGlideHeaders)
|
||||
GlideUrl(CMApi.imageProxy?.wrap(head)?:head, CMApi.myGlideHeaders)
|
||||
).addListener(GlideHideLottieViewListener(WeakReference(it.laic)) {
|
||||
if (exitCardList) return@GlideHideLottieViewListener
|
||||
cardLoadingWaits.decrementAndGet()
|
||||
|
||||
@@ -9,11 +9,26 @@ import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.File
|
||||
|
||||
object CMApi {
|
||||
var proxy = if (Proxy.useImageProxy) Proxy(
|
||||
R.string.imgProxyApiUrl,
|
||||
R.string.imgProxyApiRegex,
|
||||
R.string.imgProxyKeyID
|
||||
) else null
|
||||
var imageProxy: Proxy? = null
|
||||
get() {
|
||||
if (field != null) return field
|
||||
if (Proxy.useImageProxy) field = Proxy(
|
||||
R.string.imgProxyApiUrl,
|
||||
Regex("^https://[0-9a-z-]+\\.mangafuna\\.xyz/"),
|
||||
R.string.imgProxyKeyID
|
||||
)
|
||||
return field
|
||||
}
|
||||
var apiProxy: Proxy? = null
|
||||
get() {
|
||||
if (field != null) return field
|
||||
if (Proxy.useApiProxy) field = Proxy(
|
||||
R.string.apiProxyApiUrl,
|
||||
Regex("^https://api\\.(copymanga|mangacopy)\\.\\w+/api/"),
|
||||
R.string.imgProxyKeyID
|
||||
)
|
||||
return field
|
||||
}
|
||||
var resolution = Resolution(Regex("c\\d+x\\."))
|
||||
var myGlideHeaders: LazyHeaders? = null
|
||||
get() {
|
||||
@@ -68,8 +83,4 @@ object CMApi {
|
||||
fun getChapterInfoApiUrl(arg1: String?, arg2: String?) =
|
||||
MainActivity.mainWeakReference?.get()?.getString(R.string.chapterInfoApiUrl)
|
||||
?.format(myHostApiUrl, arg1, arg2)
|
||||
|
||||
fun getGroupInfoApiUrl(arg1: String?, arg2: String?, arg3: Int? = 0) =
|
||||
MainActivity.mainWeakReference?.get()?.getString(R.string.groupInfoApiUrl)
|
||||
?.format(myHostApiUrl, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ class DownloadPool(folder: String) {
|
||||
var s = false
|
||||
while (!s && tryTimes-- > 0) {
|
||||
val u = imgUrls[index]
|
||||
s = (DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.proxy?.wrap(u)?:u), -1))?.let {
|
||||
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()
|
||||
|
||||
@@ -38,7 +38,7 @@ object DownloadTools {
|
||||
}
|
||||
setRequestProperty("platform", "3")
|
||||
}
|
||||
Log.d("Mydl", "getConnection: ${connection.requestProperties.map { "${it.key}: ${it.value}" }.joinToString("\n")}")
|
||||
Log.d("Mydl", "getConnection: $url\n${connection.requestProperties.map { "${it.key}: ${it.value}" }.joinToString("\n")}")
|
||||
connection
|
||||
}
|
||||
|
||||
|
||||
@@ -6,17 +6,16 @@ import top.fumiama.copymanga.MainActivity
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.Charset
|
||||
|
||||
class Proxy(id: Int, apiRegexID: Int, keyID: Int? = null) {
|
||||
class Proxy(id: Int, private val apiRegex: Regex, keyID: Int? = null) {
|
||||
private val code = keyID?.let { k ->
|
||||
MainActivity.mainWeakReference?.get()?.let {
|
||||
PreferenceManager.getDefaultSharedPreferences(it).getString(it.getString(k), null)
|
||||
}
|
||||
}
|
||||
private val proxyApiUrl = MainActivity.mainWeakReference?.get()?.getString(id)
|
||||
private val apiRegex = Regex(MainActivity.mainWeakReference?.get()?.getString(apiRegexID)?:"<no prefix>")
|
||||
|
||||
fun wrap(u: String): String {
|
||||
if(!apiRegex.matches(u)) {
|
||||
if(!apiRegex.containsMatchIn(u)) {
|
||||
Log.d("MyP", "[N] wrap: $u")
|
||||
return u
|
||||
}
|
||||
@@ -42,7 +41,7 @@ class Proxy(id: Int, apiRegexID: Int, keyID: Int? = null) {
|
||||
}
|
||||
return false
|
||||
}
|
||||
/*val useApiProxy: Boolean
|
||||
val useApiProxy: Boolean
|
||||
get() {
|
||||
MainActivity.mainWeakReference?.get()?.let {
|
||||
PreferenceManager.getDefaultSharedPreferences(it).apply {
|
||||
@@ -52,6 +51,6 @@ class Proxy(id: Int, apiRegexID: Int, keyID: Int? = null) {
|
||||
}
|
||||
}
|
||||
return false
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
||||
import top.fumiama.copymanga.tools.ui.Navigate
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.lang.Thread.sleep
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.myLooper()!!) {
|
||||
@@ -82,7 +81,7 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
|
||||
that?.apply {
|
||||
val load = Glide.with(this).load(
|
||||
if (book?.cover != null)
|
||||
GlideUrl(CMApi.proxy?.wrap(book?.cover!!)?:book?.cover!!, CMApi.myGlideHeaders)
|
||||
GlideUrl(CMApi.imageProxy?.wrap(book?.cover!!)?:book?.cover!!, CMApi.myGlideHeaders)
|
||||
else book?.cachedCover
|
||||
).addListener(GlideHideLottieViewListener(WeakReference(laic)))
|
||||
load.into(imic)
|
||||
|
||||
@@ -37,7 +37,6 @@ import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
||||
import top.fumiama.copymanga.tools.ui.Navigate
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.lang.Thread.sleep
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
@@ -196,7 +195,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
thisBanner?.cover?.let {
|
||||
//Log.d("MyHomeFVP", "Load img: $it")
|
||||
Glide.with(this@HomeFragment).load(
|
||||
GlideUrl(CMApi.proxy?.wrap(it)?:it, CMApi.myGlideHeaders)
|
||||
GlideUrl(CMApi.imageProxy?.wrap(it)?:it, CMApi.myGlideHeaders)
|
||||
).addListener(GlideHideLottieViewListener(WeakReference(holder.itemView.lai))).into(holder.itemView.vpi)
|
||||
}
|
||||
holder.itemView.vpt.text = thisBanner?.brief
|
||||
@@ -255,7 +254,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
holder.itemView.tb.text = popular.toString()
|
||||
context?.let {
|
||||
Glide.with(it)
|
||||
.load(GlideUrl(CMApi.proxy?.wrap(cover)?:cover, CMApi.myGlideHeaders))
|
||||
.load(GlideUrl(CMApi.imageProxy?.wrap(cover)?:cover, CMApi.myGlideHeaders))
|
||||
.addListener(GlideHideLottieViewListener(WeakReference(holder.itemView.laic)))
|
||||
.into(holder.itemView.imic)
|
||||
}
|
||||
|
||||
@@ -35,15 +35,13 @@ import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
||||
import top.fumiama.copymanga.tools.ui.Navigate
|
||||
import top.fumiama.copymanga.tools.ui.UITools
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.lang.Thread.sleep
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadHandler(
|
||||
that.get()?.getString(R.string.mainPageApiUrl)!!.format(CMApi.myHostApiUrl),
|
||||
IndexStructure::class.java,
|
||||
that.get(),
|
||||
9
|
||||
that.get()
|
||||
) {
|
||||
private val homeF get() = that.get()
|
||||
var index: IndexStructure? = null
|
||||
@@ -87,7 +85,6 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
|
||||
homeF?.fhl?.addView(indexLines[msg.arg1])
|
||||
}
|
||||
}
|
||||
//9 -> checkIndex()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,10 +101,14 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
|
||||
index?.results?.banners = banners
|
||||
return pass
|
||||
}
|
||||
override fun onError() {
|
||||
override suspend fun onError() {
|
||||
super.onError()
|
||||
if(exit) return
|
||||
Toast.makeText(homeF?.context, R.string.web_error, Toast.LENGTH_SHORT).show()
|
||||
sendEmptyMessage(2) //setSwipe
|
||||
obtainMessage(-1, false).sendToTarget() //closeLoad
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(homeF?.context, R.string.web_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
override suspend fun doWhenFinishDownload() = withContext(Dispatchers.IO) {
|
||||
super.doWhenFinishDownload()
|
||||
@@ -329,7 +330,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
|
||||
if(img.startsWith("http")) {
|
||||
Log.d("MyHH", "load card image: $img")
|
||||
val waitMillis = cardLoadingWaits.getAndIncrement().toLong()*200
|
||||
val g = Glide.with(it).load(GlideUrl(CMApi.proxy?.wrap(img)?:img, CMApi.myGlideHeaders))
|
||||
val g = Glide.with(it).load(GlideUrl(CMApi.imageProxy?.wrap(img)?:img, CMApi.myGlideHeaders))
|
||||
.addListener(GlideHideLottieViewListener(WeakReference(cv.laic)) {
|
||||
cardLoadingWaits.decrementAndGet()
|
||||
})
|
||||
|
||||
@@ -145,13 +145,11 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
manga = m
|
||||
return true
|
||||
}
|
||||
override fun onError() {
|
||||
override suspend fun onError() {
|
||||
super.onError()
|
||||
if(exit) return
|
||||
wv.get()?.apply {
|
||||
lifecycleScope.launch {
|
||||
toolsBox.toastError(R.string.download_chapter_info_failed)
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
wv.get()?.toolsBox?.toastError(R.string.download_chapter_info_failed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +191,9 @@ class VMHandler(activity: ViewMangaActivity, private val chapterUrl: String, pri
|
||||
}
|
||||
|
||||
private suspend fun fakeLoad() = withContext(Dispatchers.IO) {
|
||||
if(MainActivity.member?.hasLogin == true) PausableDownloader(chapterUrl) { _ -> }.run()
|
||||
if(MainActivity.member?.hasLogin == true) launch {
|
||||
PausableDownloader(chapterUrl) { _ -> }.run()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun prepareManga() = withContext(Dispatchers.Main) {
|
||||
|
||||
@@ -12,6 +12,7 @@ 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.*
|
||||
@@ -217,7 +218,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
return if(flag) true else super.onKeyDown(keyCode, event)
|
||||
}
|
||||
|
||||
private fun alertCellar() {
|
||||
private suspend fun alertCellar() = withContext(Dispatchers.Main) {
|
||||
toolsBox.buildInfo(
|
||||
"注意", "要使用使用流量观看吗?", "确定", "本次阅读不再提醒", "取消",
|
||||
{ handler.startLoad() }, { noCellarAlert = true; handler.startLoad() }, { finish() }
|
||||
@@ -238,7 +239,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
getImgUrlArray()?.let {
|
||||
tasks = Array(it.size) { i ->
|
||||
val u = it[i]?:return@Array null
|
||||
return@Array DownloadTools.prepare(CMApi.resolution.wrap(CMApi.proxy?.wrap(u)?:u))
|
||||
return@Array DownloadTools.prepare(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(u)?:u))
|
||||
}
|
||||
tasksRunStatus = Array(it.size) { return@Array false }
|
||||
}
|
||||
@@ -255,7 +256,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
forEachIndexed { i, it ->
|
||||
if(it != null) {
|
||||
Thread{
|
||||
DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.proxy?.wrap(it)?:it), 1024)?.inputStream()?.let {
|
||||
DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(it)?:it), 1024)?.inputStream()?.let {
|
||||
isCut[i] = canCut(it)
|
||||
analyzedCnt[i] = true
|
||||
}
|
||||
@@ -293,7 +294,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
if (!isVertical) restorePN()
|
||||
}
|
||||
|
||||
private fun prepareImgFromWeb() {
|
||||
private suspend fun prepareImgFromWeb() {
|
||||
if(!noCellarAlert && toolsBox.netInfo == getString(R.string.TRANSPORT_CELLULAR)) alertCellar()
|
||||
else handler.startLoad()
|
||||
}
|
||||
@@ -410,7 +411,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
|
||||
private suspend fun loadImgUrlInto(imgView: ScaleImageView, url: String, useCut: Boolean, isLeft: Boolean){
|
||||
Log.d("MyVM", "Load from adt: $url")
|
||||
PausableDownloader(CMApi.resolution.wrap(CMApi.proxy?.wrap(url)?:url), 1000) {
|
||||
PausableDownloader(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(url)?:url), 1000, false) {
|
||||
it.let { loadImg(imgView, BitmapFactory.decodeByteArray(it, 0, it.size), useCut, isLeft, false) }
|
||||
}.run()
|
||||
}
|
||||
@@ -861,7 +862,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
val thisOneI = holder.itemView.onei
|
||||
Glide.with(this@ViewMangaActivity.applicationContext)
|
||||
.asBitmap()
|
||||
.load(GlideUrl(CMApi.resolution.wrap(CMApi.proxy?.wrap(it)?:it), CMApi.myGlideHeaders))
|
||||
.load(GlideUrl(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(it)?:it), CMApi.myGlideHeaders))
|
||||
.placeholder(BitmapDrawable(resources, getLoadingBitmap(pos)))
|
||||
.into(object : CustomTarget<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
@@ -870,7 +871,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
override fun onLoadCleared(placeholder: Drawable?) { }
|
||||
})
|
||||
} else Glide.with(this@ViewMangaActivity.applicationContext)
|
||||
.load(GlideUrl(CMApi.resolution.wrap(CMApi.proxy?.wrap(it)?:it), CMApi.myGlideHeaders))
|
||||
.load(GlideUrl(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(it)?:it), CMApi.myGlideHeaders))
|
||||
.placeholder(BitmapDrawable(resources, getLoadingBitmap(pos)))
|
||||
.into(holder.itemView.onei)
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
|
||||
}
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 400
|
||||
l.message = getString(R.string.login_get_conn_failed)
|
||||
l.message = getString(R.string.login_get_conn_failed)
|
||||
return@withContext l
|
||||
} catch (e: Exception) {
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 400
|
||||
l.message = e.localizedMessage
|
||||
l.message = e.toString()
|
||||
return@withContext l
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,10 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
|
||||
}
|
||||
return@withContext try {
|
||||
val l = Gson().fromJson(DownloadTools.getHttpContent(
|
||||
getString(R.string.memberInfoApiUrl).format(CMApi.myHostApiUrl)).decodeToString(),
|
||||
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)
|
||||
@@ -91,6 +94,8 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
|
||||
|
||||
private fun getLoginConnection(username: String, pwd: String, salt: Int) =
|
||||
getString(R.string.loginApiUrl).format(CMApi.myHostApiUrl).let {
|
||||
CMApi.apiProxy?.wrap(it)?:it
|
||||
}.let {
|
||||
DownloadTools.getApiConnection(it, "POST").apply {
|
||||
pref.apply {
|
||||
doOutput = true
|
||||
|
||||
@@ -82,12 +82,8 @@
|
||||
<string name="shelfOperateApiUrl">https://%1$s/api/v3/member/collect/comic</string>
|
||||
|
||||
<string name="imgProxyApiUrl">https://copymanga.azurewebsites.net/api/img?code=%1$s&url=%2$s</string>
|
||||
<string name="imgProxyApiRegex" tools:ignore="TypographyDashes">^https://[0-9a-z-]+\.mangafuna\.xyz/</string>
|
||||
<string name="imgProxyKeyID">settings_cat_net_et_img_proxy_code</string>
|
||||
<!--
|
||||
<string name="apiProxyApiUrl">https://copymanga.azurewebsites.net/api/api?url=%1$s</string>
|
||||
<string name="apiProxyApiPrefix">https://api.mangacopy.com/api/</string>
|
||||
-->
|
||||
<string name="apiProxyApiUrl">https://copymanga.azurewebsites.net/api/api?code=%1$s&url=%2$s</string>
|
||||
<string name="imgResolutionKeyID">settings_cat_net_sb_image_resolution</string>
|
||||
|
||||
<string name="complete">已完结</string>
|
||||
@@ -147,8 +143,8 @@
|
||||
<string name="settings_cat_net_sm_use_api_proxy">作者自建的API代理,可缓解国内图书详情加载问题,但不保证100%解决,也不保证一直可用</string>
|
||||
<string name="settings_cat_net_sw_use_img_proxy">使用图床代理(重启生效)</string>
|
||||
<string name="settings_cat_net_sm_use_img_proxy">作者自建的图床代理,可缓解国内图片无法加载问题,但不保证100%解决,也不保证一直可用</string>
|
||||
<string name="settings_cat_net_et_title_img_proxy">图床代理密钥(重启生效)</string>
|
||||
<string name="settings_cat_net_et_summary_img_proxy">为避免滥用,代理密钥需加群(559748702)获得,且随时可能会刷新</string>
|
||||
<string name="settings_cat_net_et_title_img_proxy">代理密钥(重启生效)</string>
|
||||
<string name="settings_cat_net_et_summary_img_proxy">为避免滥用,该密钥需加群(559748702)获得,且随时可能会刷新</string>
|
||||
|
||||
<string name="settings_cat_vm">漫画浏览</string>
|
||||
<string name="settings_cat_vm_sw_always_dark_bg">深色阅读背景</string>
|
||||
|
||||
@@ -37,14 +37,12 @@
|
||||
app:enableCopying="true"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="settings_cat_net_et_api_url" />
|
||||
<!--
|
||||
<SwitchPreferenceCompat
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="settings_cat_net_sw_use_api_proxy"
|
||||
app:selectable="true"
|
||||
app:summary="@string/settings_cat_net_sm_use_api_proxy"
|
||||
app:title="@string/settings_cat_net_sw_use_api_proxy" />
|
||||
-->
|
||||
<SwitchPreferenceCompat
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="settings_cat_net_sw_use_img_proxy"
|
||||
|
||||
Reference in New Issue
Block a user