mirror of
https://github.com/fumiama/copymanga.git
synced 2026-06-05 07:20:23 +08:00
v2.0.6
新增 1. 从断点继续下载漫画 2. 封面加载动画 3. 长按下载漫画导航至对应文件夹 修复 1. 部分下载漫画时的闪退 2. 搜索退出后不保留关键词 优化 1. 漫画阅读器代码 2. 每次启动时如未登录则不再刷新用户信息 3. AppBar 不跟随滚动 (fix #40) 4. 标签、作者、已完结默认从新到旧显示 升级 1. 升级支持库版本
This commit is contained in:
1
.idea/dictionaries/fumiama.xml
generated
1
.idea/dictionaries/fumiama.xml
generated
@@ -1,6 +1,7 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="fumiama">
|
||||
<words>
|
||||
<w>imgs</w>
|
||||
<w>lowpan</w>
|
||||
<w>nisi</w>
|
||||
</words>
|
||||
|
||||
@@ -8,8 +8,8 @@ android {
|
||||
applicationId 'top.fumiama.copymanga'
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 34
|
||||
versionCode 41
|
||||
versionName '2.0.5'
|
||||
versionCode 42
|
||||
versionName '2.0.6'
|
||||
resConfigs 'zh', 'zh-rCN'
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
@@ -58,10 +58,10 @@ dependencies {
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.10.0'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.5'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.7.5'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.6'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.7.6'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
implementation "androidx.preference:preference-ktx:1.2.1"
|
||||
implementation 'com.afollestad.material-dialogs:input:3.3.0'
|
||||
@@ -74,5 +74,6 @@ dependencies {
|
||||
implementation 'com.liaoinstan.springview:library:1.7.0'
|
||||
implementation 'com.github.zawadz88.materialpopupmenu:material-popup-menu:4.0.1'
|
||||
implementation 'com.lapism:search:2.4.1@aar'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
|
||||
implementation 'com.airbnb.android:lottie:6.3.0'
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
android:usesCleartextTraffic="true">
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="top.fumiama.copymanga.fileprovider"
|
||||
android:authorities="@string/file_provider_authority"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
|
||||
@@ -19,21 +19,26 @@ class MangaDlTools {
|
||||
get() = pool?.wait
|
||||
set(value) { if (value != null) { pool?.wait = value } }
|
||||
|
||||
fun downloadChapterInVol(url: CharSequence, chapterName: CharSequence, group: CharSequence, index: Int){
|
||||
fun downloadChapterInVol(url: CharSequence, chapterName: CharSequence, group: CharSequence, index: Int) {
|
||||
Log.d("MyMDT", "下载:$url, index:$index")
|
||||
AutoDownloadThread(url.toString()){ data ->
|
||||
Gson().fromJson(data?.decodeToString(), Chapter2Return::class.java)?.let {
|
||||
getChapterInfo(it, index, chapterName, group)
|
||||
AutoDownloadThread(url.toString(), 1000) { data ->
|
||||
try {
|
||||
Gson().fromJson(data?.decodeToString(), Chapter2Return::class.java)?.let {
|
||||
getChapterInfo(it, index, chapterName, group)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
onDownloadedListener?.handleMessage(index, false, e.localizedMessage?:"Gson parsing error")
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
@Synchronized private fun prepareDownloadListener() {
|
||||
pool?.setOnDownloadListener { fileName: String, isSuccess: Boolean ->
|
||||
indexMap[fileName]?.let { onDownloadedListener?.handleMessage(it, isSuccess) }
|
||||
pool?.setOnDownloadListener { fileName: String, isSuccess: Boolean, message: String ->
|
||||
indexMap[fileName]?.let { onDownloadedListener?.handleMessage(it, isSuccess, message) }
|
||||
}
|
||||
pool?.setOnPageDownloadListener { fileName: String, downloaded: Int, total: Int, isSuccess: Boolean ->
|
||||
indexMap[fileName]?.let { onDownloadedListener?.handleMessage(it, downloaded, total, isSuccess) }
|
||||
pool?.setOnPageDownloadListener { fileName: String, downloaded: Int, total: Int, isSuccess: Boolean, message: String ->
|
||||
indexMap[fileName]?.let { onDownloadedListener?.handleMessage(it, downloaded, total, isSuccess, message) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +88,7 @@ class MangaDlTools {
|
||||
|
||||
var onDownloadedListener: OnDownloadedListener? = null
|
||||
interface OnDownloadedListener{
|
||||
fun handleMessage(index: Int, isSuccess: Boolean)
|
||||
fun handleMessage(index: Int, downloaded: Int, total: Int, isSuccess: Boolean)
|
||||
fun handleMessage(index: Int, isSuccess: Boolean, message: String)
|
||||
fun handleMessage(index: Int, downloaded: Int, total: Int, isSuccess: Boolean, message: String)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,16 @@ import android.util.Log
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import kotlin.random.Random
|
||||
|
||||
class AutoDownloadThread(private val url: String, private val whenFinish: (result: ByteArray?)->Unit): Thread() {
|
||||
class AutoDownloadThread(private val url: String, private val waitMilliseconds: Long = 0, private val whenFinish: (result: ByteArray?)->Unit): Thread() {
|
||||
var exit = false
|
||||
override fun run() {
|
||||
super.run()
|
||||
var re: ByteArray? = null
|
||||
var c = 0
|
||||
while (!exit && re == null && c++ < 3){
|
||||
while (!exit && re == null && c++ < 3) {
|
||||
if (waitMilliseconds > 0) sleep(200+Random.nextLong(waitMilliseconds))
|
||||
re = DownloadTools.getHttpContent(url,
|
||||
mainWeakReference?.get()?.getString(R.string.referer)!!,
|
||||
mainWeakReference?.get()?.getString(R.string.pc_ua)!!
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
package top.fumiama.copymanga.template.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import kotlinx.android.synthetic.main.card_book.*
|
||||
import kotlinx.android.synthetic.main.card_book.view.*
|
||||
import kotlinx.android.synthetic.main.line_horizonal_empty.view.*
|
||||
import kotlinx.android.synthetic.main.line_lazybooklines.*
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.File
|
||||
import java.lang.ref.WeakReference
|
||||
@@ -110,14 +117,22 @@ class CardList(
|
||||
that?.context?.let { context ->
|
||||
Glide.with(context).load(
|
||||
GlideUrl(CMApi.proxy?.wrap(head)?:head, CMApi.myGlideHeaders)
|
||||
).into(it.imic)
|
||||
).addListener(GlideHideLottieViewListener(WeakReference(it.laic))).into(it.imic)
|
||||
}
|
||||
} else {
|
||||
it.laic.pauseAnimation()
|
||||
it.laic.visibility = View.GONE
|
||||
it.imic.setImageResource(R.drawable.img_defmask)
|
||||
}
|
||||
} else {
|
||||
val img = File(file, "head.jpg")
|
||||
if(img.exists()) it.imic.setImageURI(Uri.fromFile(img))
|
||||
it.laic.pauseAnimation()
|
||||
it.laic.visibility = View.GONE
|
||||
if(img.exists()) {
|
||||
it.imic.setImageURI(Uri.fromFile(img))
|
||||
} else {
|
||||
it.imic.setImageResource(R.drawable.img_defmask)
|
||||
}
|
||||
}
|
||||
if(card.isFinish) it.sgnic.visibility = View.VISIBLE
|
||||
if(card.isNew) it.sgnnew.visibility = View.VISIBLE
|
||||
|
||||
@@ -10,7 +10,7 @@ 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")
|
||||
val sortWay = listOf("-datetime_updated", "datetime_updated", "popular", "-popular")
|
||||
var sortValue = 0
|
||||
|
||||
override fun getApiUrl() =
|
||||
|
||||
@@ -3,11 +3,14 @@ package top.fumiama.copymanga.tools.http
|
||||
import android.util.Log
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.lang.Thread.sleep
|
||||
import java.util.zip.CRC32
|
||||
import java.util.zip.CheckedOutputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipFile
|
||||
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)
|
||||
@@ -22,9 +25,9 @@ class DownloadPool(folder: String) {
|
||||
var wait = false
|
||||
private val saveFolder = File(folder)
|
||||
//fileName: String, isSuccess: Boolean
|
||||
private var mOnDownloadListener: ((String, Boolean) -> Unit)? = null
|
||||
private var mOnDownloadListener: ((String, Boolean, String) -> Unit)? = null
|
||||
//fileName: String, downloaded: Int, total: Int, isSuccess: Boolean
|
||||
private var mOnPageDownloadListener: ((String, Int, Int, Boolean) -> Unit)? = null
|
||||
private var mOnPageDownloadListener: ((String, Int, Int, Boolean, String) -> Unit)? = null
|
||||
init {
|
||||
if(!saveFolder.exists()) saveFolder.mkdirs()
|
||||
}
|
||||
@@ -37,50 +40,76 @@ class DownloadPool(folder: String) {
|
||||
Thread{
|
||||
quests.forEach { quest ->
|
||||
packZipFile(quest.fileName, quest.imgUrl, quest.refer)
|
||||
sleep(1000)
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
fun setOnDownloadListener(onDownloadListener: (String, Boolean) -> Unit) {
|
||||
fun setOnDownloadListener(onDownloadListener: (String, Boolean, String) -> Unit) {
|
||||
mOnDownloadListener = onDownloadListener
|
||||
}
|
||||
|
||||
fun setOnPageDownloadListener(onPageDownloadListener: (String, Int, Int, Boolean) -> Unit) {
|
||||
fun setOnPageDownloadListener(onPageDownloadListener: (String, Int, Int, Boolean, String) -> Unit) {
|
||||
mOnPageDownloadListener = onPageDownloadListener
|
||||
}
|
||||
|
||||
private fun packZipFile(fileName: String, imgUrls: Array<String>, refer: String?) {
|
||||
Thread{
|
||||
File(saveFolder, fileName).let { f ->
|
||||
File(saveFolder, "$fileName.tmp").let { f ->
|
||||
f.parentFile?.let { if(!it.exists()) it.mkdirs() }
|
||||
if(f.exists()) f.delete()
|
||||
f.createNewFile()
|
||||
var start = 0
|
||||
Log.d("MyDP", "Zip file: ${f.absolutePath}")
|
||||
val zip = ZipOutputStream(CheckedOutputStream(f.outputStream(), CRC32()))
|
||||
if(f.exists()) {
|
||||
try {
|
||||
val zipFile = ZipFile(f)
|
||||
start = zipFile.size() - 1
|
||||
zipFile.close()
|
||||
Log.d("MyDP", "last downloaded index: $start")
|
||||
if (start <= 0 || start >= imgUrls.size) { // error or re-download
|
||||
f.delete()
|
||||
f.createNewFile()
|
||||
start = 0
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
f.delete()
|
||||
f.createNewFile()
|
||||
}
|
||||
} else f.createNewFile()
|
||||
val zip = ZipOutputStream(CheckedOutputStream(FileOutputStream(f, true), CRC32()))
|
||||
zip.setLevel(9)
|
||||
var succeed = true
|
||||
for(index in imgUrls.indices) {
|
||||
while (wait && !exit) sleep(1000)
|
||||
if(exit) break
|
||||
zip.putNextEntry(ZipEntry("$index.${if(imgUrls[index].contains(".webp")) "webp" else "jpg"}"))
|
||||
var tryTimes = 3
|
||||
var s = false
|
||||
while (!s && tryTimes-- > 0){
|
||||
val u = imgUrls[index]
|
||||
s = (DownloadTools.getHttpContent(CMApi.proxy?.wrap(u)?:u, -1))?.let { zip.write(it); true }?:false
|
||||
if (!s) sleep(2000)
|
||||
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.proxy?.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 (!s) sleep(2000)
|
||||
}
|
||||
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
|
||||
}
|
||||
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) }
|
||||
//zip.flush()
|
||||
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") }
|
||||
}
|
||||
zip.close()
|
||||
mOnPageDownloadListener?.let { it(fileName, 0, 0, true) }
|
||||
mOnDownloadListener?.let { it(fileName, succeed) }
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package top.fumiama.copymanga.tools.ui
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class GlideHideLottieViewListener(private val wla: WeakReference<LottieAnimationView>): RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
wla.get()?.apply {
|
||||
pauseAnimation()
|
||||
visibility = View.GONE
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package top.fumiama.copymanga.tools.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
@@ -42,6 +43,10 @@ class UITools(that: Context?, w: WeakReference<Activity>? = null) {
|
||||
Toast.makeText(zis, s, Toast.LENGTH_SHORT).show()
|
||||
if (willFinish) weak?.get()?.finish()
|
||||
}
|
||||
fun toastError(s: Int, willFinish: Boolean = true) {
|
||||
Toast.makeText(zis, s, Toast.LENGTH_SHORT).show()
|
||||
if (willFinish) weak?.get()?.finish()
|
||||
}
|
||||
fun buildInfo(
|
||||
title: String,
|
||||
msg: String,
|
||||
@@ -84,7 +89,7 @@ class UITools(that: Context?, w: WeakReference<Activity>? = null) {
|
||||
fun dp2px(dp:Int):Int?{
|
||||
return zis?.resources?.displayMetrics?.density?.let { (dp * it + 0.5).toInt()}
|
||||
}
|
||||
fun px2dp(px:Int):Int?{
|
||||
private fun px2dp(px:Int):Int?{
|
||||
return zis?.resources?.displayMetrics?.density?.let { (px.toDouble() / it + 0.5).toInt()}
|
||||
}
|
||||
fun calcWidthFromDp(marginLeftDp:Int, widthDp:Int):List<Int>{
|
||||
@@ -124,22 +129,24 @@ class UITools(that: Context?, w: WeakReference<Activity>? = null) {
|
||||
}
|
||||
toString()
|
||||
}
|
||||
@SuppressLint("DiscouragedApi", "InternalInsetResource")
|
||||
fun getNavigationBarHeight(context: Context): Int {
|
||||
val resources = context.resources
|
||||
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
|
||||
return if (resourceId > 0) {
|
||||
resources.getDimensionPixelSize(resourceId)
|
||||
} else {
|
||||
0
|
||||
64
|
||||
}
|
||||
}
|
||||
@SuppressLint("DiscouragedApi", "InternalInsetResource")
|
||||
fun getStatusBarHeight(context: Context): Int {
|
||||
val resources = context.resources
|
||||
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||
return if (resourceId > 0) {
|
||||
resources.getDimensionPixelSize(resourceId)
|
||||
} else {
|
||||
0
|
||||
64
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.lang.ref.WeakReference
|
||||
class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
var fbibinfo: View? = null
|
||||
var fbtinfo: View? = null
|
||||
var isOnPause = false
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
@@ -67,14 +68,21 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
}
|
||||
}
|
||||
|
||||
/*override fun onResume() {
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mainWeakReference?.get()?.apply {
|
||||
isOnPause = false
|
||||
/*mainWeakReference?.get()?.apply {
|
||||
toolbar.title = bookHandler?.book?.results?.comic?.name
|
||||
}
|
||||
setStartRead()
|
||||
fbibinfo?.layoutParams?.height = ((fbibinfo?.width?:0) * 4.0 / 9.0 + 0.5).toInt()
|
||||
}*/
|
||||
*/
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
isOnPause = true
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
@@ -33,6 +33,7 @@ import top.fumiama.copymanga.template.http.AutoDownloadHandler
|
||||
import top.fumiama.copymanga.template.http.AutoDownloadThread
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.ui.GlideBlurTransformation
|
||||
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
||||
import top.fumiama.copymanga.tools.ui.Navigate
|
||||
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment
|
||||
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment.Companion.json
|
||||
@@ -147,7 +148,7 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
book?.results?.comic?.cover?.let { cover ->
|
||||
val load = Glide.with(this).load(
|
||||
GlideUrl(CMApi.proxy?.wrap(cover)?:cover, CMApi.myGlideHeaders)
|
||||
).timeout(10000)
|
||||
).timeout(10000).addListener(GlideHideLottieViewListener(WeakReference(laic)))
|
||||
load.into(imic)
|
||||
context?.let { it1 -> GlideBlurTransformation(it1) }
|
||||
?.let { it2 -> RequestOptions.bitmapTransform(it2) }
|
||||
@@ -286,6 +287,10 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
chapterNames += it.name
|
||||
ViewMangaActivity.uuidArray += it.uuid
|
||||
Log.d("MyBH", "i = $i, last=$last, add chapter ${it.name}, line is null: ${line == null}")
|
||||
that?.isOnPause?.let { isOnPause ->
|
||||
while (isOnPause && !exit) sleep(1000)
|
||||
if (exit) return@Thread
|
||||
}?:return@Thread
|
||||
if(line == null) {
|
||||
if(i == last) {
|
||||
line = layoutInflater.inflate(R.layout.line_chapter, that!!.fbl, false)
|
||||
|
||||
@@ -225,25 +225,27 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
mangaDlTools.onDownloadedListener = object :MangaDlTools.OnDownloadedListener{
|
||||
override fun handleMessage(index: Int, isSuccess: Boolean) {
|
||||
override fun handleMessage(index: Int, isSuccess: Boolean, message: String) {
|
||||
that?.activity?.runOnUiThread {
|
||||
if(isSuccess) onZipDownloadFinish(index)
|
||||
else onZipDownloadFailure(index)
|
||||
else onZipDownloadFailure(index, message)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun handleMessage(
|
||||
index: Int,
|
||||
downloaded: Int,
|
||||
total: Int,
|
||||
isSuccess: Boolean
|
||||
isSuccess: Boolean,
|
||||
message: String
|
||||
) {
|
||||
that?.activity?.runOnUiThread {
|
||||
if(isSuccess) {
|
||||
tbtnlist[index].text = if(downloaded == 0 && total == 0) tbtnlist[index].chapterName else "$downloaded/$total"
|
||||
} else {
|
||||
tbtnlist[index].text = "$downloaded/$total"
|
||||
Toast.makeText(that?.context, "下载${tbtnlist[index].chapterName}的第${downloaded}页失败", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(that?.context, "下载${tbtnlist[index].chapterName}的第${downloaded}页失败: $message", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,6 +285,7 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
updateProgressBar()
|
||||
that?.apply {
|
||||
cdwn.postDelayed({
|
||||
if (mangaDlTools?.exit != false) return@postDelayed
|
||||
if (dldChapter == checkedChapter) {
|
||||
checkedChapter = 0
|
||||
setProgress2(0, 233)
|
||||
@@ -296,9 +299,9 @@ class ComicDlHandler(looper: Looper, private val th: WeakReference<ComicDlFragme
|
||||
}
|
||||
}
|
||||
|
||||
private fun onZipDownloadFailure(index: Int) {
|
||||
private fun onZipDownloadFailure(index: Int, message: String) {
|
||||
tbtnlist[index].setBackgroundResource(R.drawable.rndbg_error)
|
||||
Toast.makeText(that?.context, "下载${tbtnlist[index].chapterName}失败", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(that?.context, "下载${tbtnlist[index].chapterName}失败: $message", Toast.LENGTH_SHORT).show()
|
||||
updateProgressBar()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package top.fumiama.copymanga.ui.download
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.provider.DocumentsContract
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.net.toUri
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
@@ -124,12 +129,12 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
|
||||
AlertDialog.Builder(context)
|
||||
.setIcon(R.drawable.ic_launcher_foreground)
|
||||
.setTitle(R.string.new_download_card_option_hint)
|
||||
.setItems(arrayOf("删除", "前往")) { d, p ->
|
||||
.setItems(arrayOf("删除数据", "前往详情")) { d, p ->
|
||||
d.cancel()
|
||||
when (p) {
|
||||
0 -> {
|
||||
AlertDialog.Builder(context)
|
||||
.setIcon(R.drawable.ic_launcher_foreground).setMessage("删除下载的此漫画吗?")
|
||||
.setIcon(R.drawable.ic_launcher_foreground).setMessage("删除下载的漫画${name}吗?")
|
||||
.setTitle("提示").setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
if (chosenFile.exists()) Thread {
|
||||
FileUtils.recursiveRemove(chosenFile)
|
||||
|
||||
@@ -10,7 +10,6 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ImageButton
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -29,8 +28,8 @@ import top.fumiama.copymanga.json.BookListStructure
|
||||
import top.fumiama.copymanga.template.general.NoBackRefreshFragment
|
||||
import top.fumiama.copymanga.template.http.AutoDownloadThread
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
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
|
||||
@@ -72,13 +71,20 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
}
|
||||
})
|
||||
setTextHint(android.R.string.search_go)
|
||||
|
||||
setOnQueryTextListener(object : SearchLayout.OnQueryTextListener {
|
||||
var lastChangeTime = 0L
|
||||
var lastSearch: String = ""
|
||||
override fun onQueryTextChange(newText: CharSequence): Boolean {
|
||||
if (newText.contentEquals("__notice_focus_change__") || newText.contentEquals(lastSearch)) return true
|
||||
postDelayed({
|
||||
val diff = System.currentTimeMillis() - lastChangeTime
|
||||
if(diff > 500) {
|
||||
if (newText.isNotEmpty()) adapter.refresh(newText)
|
||||
if (newText.isNotEmpty()) {
|
||||
Log.d("MyHF", "new text: $newText")
|
||||
lastSearch = newText.toString()
|
||||
adapter.refresh(newText)
|
||||
}
|
||||
}
|
||||
}, 1024)
|
||||
lastChangeTime = System.currentTimeMillis()
|
||||
@@ -90,6 +96,8 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
val key = query.toString()
|
||||
Toast.makeText(context, key, Toast.LENGTH_SHORT).show()
|
||||
}*/
|
||||
Log.d("MyHF", "recover text: $lastSearch")
|
||||
setTextQuery(lastSearch, false)
|
||||
return true
|
||||
}
|
||||
})
|
||||
@@ -112,9 +120,12 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
setOnFocusChangeListener(object : SearchLayout.OnFocusChangeListener {
|
||||
override fun onFocusChange(hasFocus: Boolean) {
|
||||
Log.d("MyHF", "fhs onFocusChange: $hasFocus")
|
||||
navigationIconSupport = if (hasFocus) SearchLayout.NavigationIconSupport.ARROW
|
||||
navigationIconSupport = if (hasFocus) {
|
||||
setTextQuery("__notice_focus_change__", true)
|
||||
SearchLayout.NavigationIconSupport.ARROW
|
||||
}
|
||||
else {
|
||||
micView.postDelayed({ micView.visibility = View.VISIBLE }, 233)
|
||||
micView.postDelayed({ micView?.visibility = View.VISIBLE }, 233)
|
||||
SearchLayout.NavigationIconSupport.SEARCH
|
||||
}
|
||||
}
|
||||
@@ -171,7 +182,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
//Log.d("MyHomeFVP", "Load img: $it")
|
||||
Glide.with(this@HomeFragment).load(
|
||||
GlideUrl(CMApi.proxy?.wrap(it)?:it, CMApi.myGlideHeaders)
|
||||
).timeout(10000).into(holder.itemView.vpi)
|
||||
).addListener(GlideHideLottieViewListener(WeakReference(holder.itemView.lai))).timeout(10000).into(holder.itemView.vpi)
|
||||
}
|
||||
holder.itemView.vpt.text = thisBanner?.brief
|
||||
holder.itemView.vpc.setOnClickListener {
|
||||
@@ -190,7 +201,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
RecyclerView.Adapter<ListViewHolder>() {
|
||||
private var results: BookListStructure? = null
|
||||
var type = ""
|
||||
private var query: CharSequence? = null
|
||||
private var query: String? = null
|
||||
private var count = 0
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
|
||||
return ListViewHolder(
|
||||
@@ -228,7 +239,10 @@ 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)).into(holder.itemView.imic)
|
||||
Glide.with(it)
|
||||
.load(GlideUrl(CMApi.proxy?.wrap(cover)?:cover, CMApi.myGlideHeaders))
|
||||
.addListener(GlideHideLottieViewListener(WeakReference(holder.itemView.laic)))
|
||||
.into(holder.itemView.imic)
|
||||
}
|
||||
holder.itemView.lwc.setOnClickListener {
|
||||
val bundle = Bundle()
|
||||
@@ -239,10 +253,10 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = (results?.results?.list?.size?:0)+1
|
||||
override fun getItemCount() = (results?.results?.list?.size?:0) + if (query?.isNotEmpty() == true) 1 else 0
|
||||
|
||||
fun refresh(q: CharSequence) {
|
||||
query = q
|
||||
query = q.toString()
|
||||
activity?.apply {
|
||||
AutoDownloadThread(getString(R.string.searchApiUrl).format(CMApi.myHostApiUrl, 0, query, type)) {
|
||||
results = Gson().fromJson(it?.decodeToString(), BookListStructure::class.java)
|
||||
|
||||
@@ -21,13 +21,14 @@ import com.to.aboomy.pager2banner.ScaleInTransformer
|
||||
import kotlinx.android.synthetic.main.card_book.view.*
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
import kotlinx.android.synthetic.main.line_1bookline.view.*
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import top.fumiama.copymanga.json.ComicStructure
|
||||
import top.fumiama.copymanga.json.IndexStructure
|
||||
import top.fumiama.copymanga.template.http.AutoDownloadHandler
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
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
|
||||
|
||||
@@ -310,7 +311,9 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
|
||||
cv.tic.text = name
|
||||
homeF?.let {
|
||||
if(img.startsWith("http")) it.activity?.runOnUiThread {
|
||||
Glide.with(it).load(GlideUrl(CMApi.proxy?.wrap(img)?:img, CMApi.myGlideHeaders)).timeout(20000).into(cv.imic)
|
||||
Glide.with(it).load(GlideUrl(CMApi.proxy?.wrap(img)?:img, CMApi.myGlideHeaders))
|
||||
.addListener(GlideHideLottieViewListener(WeakReference(cv.laic)))
|
||||
.timeout(20000).into(cv.imic)
|
||||
}
|
||||
}
|
||||
if (isFinal) cv.sgnic.visibility = View.VISIBLE
|
||||
|
||||
@@ -4,12 +4,15 @@ 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
|
||||
|
||||
class PagesManager(private val w: WeakReference<ViewMangaActivity>) {
|
||||
val v get() = w.get()
|
||||
private var isEndL = false
|
||||
private var isEndR = false
|
||||
private val canGoPrevious get() = (v?.pageNum ?: 0) > 1
|
||||
private val canGoNext get() = (v?.pageNum ?: 0) < (v?.realCount ?: 0)
|
||||
@ExperimentalStdlibApi
|
||||
fun toPreviousPage(){
|
||||
toPage(v?.r2l==true)
|
||||
@@ -18,16 +21,14 @@ class PagesManager(private val w: WeakReference<ViewMangaActivity>) {
|
||||
fun toNextPage(){
|
||||
toPage(v?.r2l!=true)
|
||||
}
|
||||
private fun judgePrevious() = (v?.pageNum ?: 0) > 1
|
||||
private fun judgeNext() = (v?.pageNum ?: 0) < (v?.realCount ?: 0)
|
||||
@ExperimentalStdlibApi
|
||||
fun toPage(goNext:Boolean) {
|
||||
v?.let { v ->
|
||||
if (v.clicked) {
|
||||
v.hideObjs()
|
||||
v.hideDrawer()
|
||||
return
|
||||
}
|
||||
if (if(goNext)judgeNext() else judgePrevious()) {
|
||||
if (if(goNext) canGoNext else canGoPrevious) {
|
||||
if(goNext) {
|
||||
v.scrollForward()
|
||||
isEndR = false
|
||||
@@ -38,33 +39,26 @@ class PagesManager(private val w: WeakReference<ViewMangaActivity>) {
|
||||
return
|
||||
}
|
||||
val chapterPosition = position + if(goNext) 1 else -1
|
||||
if (v.urlArray.isNotEmpty()) {
|
||||
if(chapterPosition >= 0 && chapterPosition < v.urlArray.size) v.urlArray[chapterPosition].let {
|
||||
if (if(goNext) isEndR else isEndL) {
|
||||
//if(v.zipFirst) intent.putExtra("callFrom", "zipFirst")
|
||||
v.tt.canDo = false
|
||||
//ViewMangaActivity.dlhandler = null
|
||||
comicName?.let { it1 -> Reader.viewMangaAt(it1, chapterPosition, v.urlArray, goNext) }
|
||||
v.finish()
|
||||
return
|
||||
}
|
||||
val hint = if(goNext) '下' else '上'
|
||||
Toast.makeText(
|
||||
v.applicationContext,
|
||||
"再次按下加载${hint}一章",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
if(goNext) isEndR = true
|
||||
else isEndL = true
|
||||
} else Toast.makeText(
|
||||
v.applicationContext,
|
||||
"已经到头了~",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
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()
|
||||
return
|
||||
}
|
||||
if (if(goNext) isEndR else isEndL) {
|
||||
//if(v.zipFirst) intent.putExtra("callFrom", "zipFirst")
|
||||
v.tt.canDo = false
|
||||
//ViewMangaActivity.dlhandler = null
|
||||
comicName?.let { Reader.viewMangaAt(it, chapterPosition, v.urlArray, goNext) }
|
||||
v.finish()
|
||||
return
|
||||
}
|
||||
val hint = if(goNext) R.string.press_again_to_load_next_chapter else R.string.press_again_to_load_previous_chapter
|
||||
Toast.makeText(v.applicationContext, hint, Toast.LENGTH_SHORT).show()
|
||||
if(goNext) isEndR = true
|
||||
else isEndL = true
|
||||
}
|
||||
}
|
||||
fun manageInfo(){
|
||||
if (v?.clicked == false) v?.showObjs() else v?.hideObjs()
|
||||
fun toggleDrawer() {
|
||||
if (v?.clicked == false) v?.showDrawer() else v?.hideDrawer()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.activity_viewmanga.*
|
||||
import kotlinx.android.synthetic.main.widget_infodrawer.*
|
||||
import kotlinx.android.synthetic.main.widget_infodrawer.view.*
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import top.fumiama.copymanga.json.Chapter2Return
|
||||
import top.fumiama.copymanga.json.ChapterWithContent
|
||||
import top.fumiama.copymanga.json.ComicStructure
|
||||
@@ -21,21 +21,20 @@ 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
|
||||
import java.lang.Exception
|
||||
import java.lang.Thread.sleep
|
||||
import java.lang.ref.WeakReference
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
|
||||
url, Chapter2Return::class.java, Looper.myLooper()!!
|
||||
) {
|
||||
var manga: Chapter2Return? = null
|
||||
private val wv = WeakReference(activity)
|
||||
private val infcard = wv.get()?.infcard
|
||||
private var infcShowed = false
|
||||
private val drawer = wv.get()?.infcard
|
||||
private val weeks = wv.get()?.getStringArray(R.array.weeks)
|
||||
private var hasDrawerShown = false
|
||||
val dl = activity.let {
|
||||
val re = Dialog(it)
|
||||
re.setContentView(R.layout.dialog_unzipping)
|
||||
@@ -49,16 +48,9 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
|
||||
private val week: String
|
||||
get() {
|
||||
val cal = Calendar.getInstance()
|
||||
return when (cal[Calendar.DAY_OF_WEEK]) {
|
||||
1 -> "周日"
|
||||
2 -> "周一"
|
||||
3 -> "周二"
|
||||
4 -> "周三"
|
||||
5 -> "周四"
|
||||
6 -> "周五"
|
||||
7 -> "周六"
|
||||
else -> ""
|
||||
}
|
||||
val w = cal[Calendar.DAY_OF_WEEK]
|
||||
if (w > 7 || w <= 0) return ""
|
||||
return weeks?.get(w-1) ?: ""
|
||||
}
|
||||
private var remainingImageCount = 0
|
||||
|
||||
@@ -66,21 +58,22 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
when (msg.what) {
|
||||
HIDE_INFO_CARD -> if (infcShowed) {
|
||||
hideInfCard(); infcShowed = false
|
||||
HIDE_INFO_CARD -> if (hasDrawerShown) {
|
||||
hideInfCard(); hasDrawerShown = false
|
||||
}
|
||||
SHOW_INFO_CARD -> if (!infcShowed) {
|
||||
showInfCard(); infcShowed = true
|
||||
SHOW_INFO_CARD -> if (!hasDrawerShown) {
|
||||
showInfCard(); hasDrawerShown = true
|
||||
}
|
||||
TRIGGER_INFO_CARD -> infcShowed = if (infcShowed) {
|
||||
TRIGGER_INFO_CARD -> hasDrawerShown = if (hasDrawerShown) {
|
||||
hideInfCard(); false
|
||||
} else {
|
||||
showInfCard(); true
|
||||
}
|
||||
LOAD_IMG_ON -> {
|
||||
val simg = msg.obj as ScaleImageView
|
||||
wv.get()?.loadImgOn(simg, msg.arg1, msg.arg2)
|
||||
//simg.setHeight2FitImgWidth()
|
||||
val scaleImageView = msg.obj as ScaleImageView
|
||||
// msg.arg2: isLast
|
||||
wv.get()?.loadImgOn(scaleImageView, msg.arg1)
|
||||
//scaleImageView.setHeight2FitImgWidth()
|
||||
//if(msg.arg2 == 1) sendEmptyMessage(DELAYED_RESTORE_PAGE_NUMBER)
|
||||
}
|
||||
CLEAR_IMG_ON -> {
|
||||
@@ -106,13 +99,13 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
|
||||
Log.d("MyVMH", "Load page from $item")
|
||||
}
|
||||
DIALOG_HIDE -> dl.hide()
|
||||
HIDE_INFO_CARD_FULL -> if (infcShowed) {
|
||||
hideInfCardFull(); infcShowed = false
|
||||
HIDE_INFO_CARD_FULL -> if (hasDrawerShown) {
|
||||
hideInfCardFull(); hasDrawerShown = false
|
||||
}
|
||||
SHOW_INFO_CARD_FULL -> if (!infcShowed) {
|
||||
showInfCardFull(); infcShowed = true
|
||||
SHOW_INFO_CARD_FULL -> if (!hasDrawerShown) {
|
||||
showInfCardFull(); hasDrawerShown = true
|
||||
}
|
||||
TRIGGER_INFO_CARD_FULL -> infcShowed = if (infcShowed) {
|
||||
TRIGGER_INFO_CARD_FULL -> hasDrawerShown = if (hasDrawerShown) {
|
||||
hideInfCardFull(); false
|
||||
} else {
|
||||
showInfCardFull(); true
|
||||
@@ -147,7 +140,7 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
|
||||
override fun onError() {
|
||||
super.onError()
|
||||
if(exit) return
|
||||
wv.get()?.toolsBox?.toastError("下载章节信息失败")
|
||||
wv.get()?.toolsBox?.toastError(R.string.download_chapter_info_failed)
|
||||
}
|
||||
|
||||
override fun doWhenFinishDownload() {
|
||||
@@ -181,7 +174,7 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
|
||||
true
|
||||
} catch (e: Exception){
|
||||
e.printStackTrace()
|
||||
//wv.get()?.toolsBox?.toastError("读取本地章节信息失败")
|
||||
wv.get()?.toolsBox?.toastError(R.string.load_local_chapter_info_failed)
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -225,23 +218,23 @@ class VMHandler(activity: ViewMangaActivity, url: String) : AutoDownloadHandler(
|
||||
|
||||
private fun showInfCard() {
|
||||
Log.d("MyVMH", "Read info drawer delta: $delta")
|
||||
ObjectAnimator.ofFloat(infcard?.idc, "alpha", 0.3F, 0.8F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(infcard, "translationY", delta, 0F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(drawer?.idc, "alpha", 0.3F, 0.8F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(drawer, "translationY", delta, 0F).setDuration(233).start()
|
||||
}
|
||||
|
||||
private fun showInfCardFull() {
|
||||
Log.d("MyVMH", "Read info drawer delta: $delta")
|
||||
ObjectAnimator.ofFloat(infcard?.idc, "alpha", 0.0F, 0.8F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(infcard, "translationY", delta, 0F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(drawer?.idc, "alpha", 0.0F, 0.8F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(drawer, "translationY", delta, 0F).setDuration(233).start()
|
||||
}
|
||||
|
||||
private fun hideInfCard() {
|
||||
ObjectAnimator.ofFloat(infcard?.idc, "alpha", 0.8F, 0.3F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(infcard, "translationY", 0F, delta).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(drawer?.idc, "alpha", 0.8F, 0.3F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(drawer, "translationY", 0F, delta).setDuration(233).start()
|
||||
}
|
||||
private fun hideInfCardFull() {
|
||||
ObjectAnimator.ofFloat(infcard?.idc, "alpha", 0.8F, 0.0F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(infcard, "translationY", 0F, delta).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(drawer?.idc, "alpha", 0.8F, 0.0F).setDuration(233).start()
|
||||
ObjectAnimator.ofFloat(drawer, "translationY", 0F, delta).setDuration(233).start()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.graphics.BitmapFactory
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.media.AudioManager
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
@@ -20,10 +21,9 @@ import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.liaoinstan.springview.widget.SpringView
|
||||
import kotlinx.android.synthetic.main.activity_viewmanga.*
|
||||
@@ -36,14 +36,14 @@ import kotlinx.android.synthetic.main.widget_titlebar.*
|
||||
import kotlinx.android.synthetic.main.widget_titlebar.view.*
|
||||
import kotlinx.android.synthetic.main.widget_viewmangainfo.*
|
||||
import top.fumiama.copymanga.MainActivity
|
||||
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.ui.Font
|
||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
||||
import top.fumiama.copymanga.tools.thread.TimeThread
|
||||
import top.fumiama.copymanga.tools.ui.Font
|
||||
import top.fumiama.copymanga.views.ScaleImageView
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
@@ -51,6 +51,7 @@ import java.io.InputStream
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.concurrent.FutureTask
|
||||
import java.util.zip.ZipFile
|
||||
import kotlin.math.abs
|
||||
|
||||
class ViewMangaActivity : TitleActivityTemplate() {
|
||||
var count = 0
|
||||
@@ -69,6 +70,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
private var notUseVP = true
|
||||
private var isVertical = false
|
||||
private var q = 100
|
||||
private var tryWebpFirst = true
|
||||
private val size get() = if(realCount / verticalLoadMaxCount > currentItem / verticalLoadMaxCount) verticalLoadMaxCount else realCount % verticalLoadMaxCount
|
||||
var infoDrawerDelta = 0f
|
||||
var pageNum: Int
|
||||
@@ -130,10 +132,11 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
} else prepareImgFromWeb()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
toolsBox.toastError("加载漫画错误")
|
||||
toolsBox.toastError(R.string.load_manga_error)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
||||
super.onWindowFocusChanged(hasFocus)
|
||||
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R)
|
||||
@@ -144,7 +147,6 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
|
||||
systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +185,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
|
||||
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 mid = (if(pn in 1 until realCount) (if(cut) 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)
|
||||
@@ -277,7 +279,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
|
||||
fun countZipEntries(doWhenFinish : (count: Int) -> Unit) = Thread{
|
||||
if (zipFile != null) try {
|
||||
Log.d("Myvm", "zip: $zipFile")
|
||||
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 ->
|
||||
@@ -285,13 +287,13 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
isCut += useCut
|
||||
indexMap += i + 1
|
||||
if (useCut) indexMap += -(i + 1)
|
||||
Log.d("Myvm", "[$i] 分析: ${it.name}, cut: $useCut")
|
||||
Log.d("MyVM", "[$i] 分析: ${it.name}, cut: $useCut")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
runOnUiThread { toolsBox.toastError("统计zip图片数错误!") }
|
||||
runOnUiThread { toolsBox.toastError(R.string.count_zip_entries_error) }
|
||||
}
|
||||
runOnUiThread {
|
||||
Log.d("Myvm", "开始加载控件")
|
||||
Log.d("MyVM", "开始加载控件")
|
||||
doWhenFinish(count)
|
||||
}
|
||||
}.start()
|
||||
@@ -318,7 +320,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
loadOneImg()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
toolsBox.toastError("页数${currentItem}不合法")
|
||||
toolsBox.toastError(getString(R.string.load_page_number_error).format(currentItem))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -364,22 +366,21 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
|
||||
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, isPlaceholder: Boolean = true) {
|
||||
private fun loadImg(imgView: ScaleImageView, bitmap: Bitmap, useCut: Boolean, isLeft: Boolean, isPlaceholder: Boolean = true) {
|
||||
val bitmap2load = if(!isPlaceholder && useCut) cutBitmap(bitmap, isLeft) else bitmap
|
||||
runOnUiThread {
|
||||
imgView.setImageBitmap(bitmap2load)
|
||||
if(!isPlaceholder && isVertical) {
|
||||
imgView.setHeight2FitImgWidth()
|
||||
handler.sendEmptyMessage(VMHandler.DECREASE_IMAGE_COUNT_AND_RESTORE_PAGE_NUMBER_AT_ZERO)
|
||||
//if (!isPlaceholder && isLast == 1) handler.sendEmptyMessageDelayed(VMHandler.RESTORE_PAGE_NUMBER, 233)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadImgUrlInto(imgView: ScaleImageView, url: String, isLast: Int = 0, useCut: Boolean, isLeft: Boolean){
|
||||
private fun loadImgUrlInto(imgView: ScaleImageView, url: String, useCut: Boolean, isLeft: Boolean){
|
||||
Log.d("MyVM", "Load from adt: $url")
|
||||
AutoDownloadThread(CMApi.proxy?.wrap(url)?:url) {
|
||||
it?.let { loadImg(imgView, BitmapFactory.decodeByteArray(it, 0, it.size), isLast, useCut, isLeft, false) }
|
||||
AutoDownloadThread(CMApi.proxy?.wrap(url)?:url, 1000) {
|
||||
it?.let { loadImg(imgView, BitmapFactory.decodeByteArray(it, 0, it.size), useCut, isLeft, false) }
|
||||
}.start()
|
||||
}
|
||||
|
||||
@@ -397,28 +398,28 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
return loading
|
||||
}
|
||||
|
||||
fun loadImgOn(imgView: ScaleImageView, position: Int, isLast: Int = 0){
|
||||
fun loadImgOn(imgView: ScaleImageView, position: Int){
|
||||
Log.d("MyVM", "Load img: $position")
|
||||
val index2load = if(cut) Math.abs(indexMap[position]) -1 else position
|
||||
val index2load = if(cut) 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, false)
|
||||
loadImg(imgView, it, useCut, isLeft, false)
|
||||
}
|
||||
else {
|
||||
loadImg(imgView, getLoadingBitmap(position), isLast, useCut, isLeft, true)
|
||||
loadImg(imgView, getLoadingBitmap(position), useCut, isLeft, true)
|
||||
val re = tasks?.get(index2load)
|
||||
if (re != null) Thread{
|
||||
val data = re.get()
|
||||
if(data != null && data.isNotEmpty()) {
|
||||
BitmapFactory.decodeByteArray(data, 0, data.size)?.let {
|
||||
loadImg(imgView, it, isLast, useCut, isLeft, false)
|
||||
loadImg(imgView, it, useCut, isLeft, false)
|
||||
Log.d("MyVM", "Load position $position from task")
|
||||
}?:Log.d("MyVM", "null bitmap at $position")
|
||||
}
|
||||
else getImgUrl(index2load)?.let { loadImgUrlInto(imgView, it, isLast, useCut, isLeft) }
|
||||
else getImgUrl(index2load)?.let { loadImgUrlInto(imgView, it, useCut, isLeft) }
|
||||
}.start()
|
||||
else getImgUrl(index2load)?.let { loadImgUrlInto(imgView, it, isLast, useCut, isLeft) }
|
||||
else getImgUrl(index2load)?.let { loadImgUrlInto(imgView, it, useCut, isLeft) }
|
||||
}
|
||||
imgView.visibility = View.VISIBLE
|
||||
}
|
||||
@@ -445,27 +446,29 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
if (position >= count || position < 0) null
|
||||
else {
|
||||
val zip = ZipFile(zipFile)
|
||||
try {
|
||||
if (q == 100) BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.webp")))
|
||||
else {
|
||||
val out = ByteArrayOutputStream()
|
||||
BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.webp")))?.compress(Bitmap.CompressFormat.JPEG, q, out)
|
||||
BitmapFactory.decodeStream(ByteArrayInputStream(out.toByteArray()))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
try {
|
||||
if (q == 100) BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.jpg")))
|
||||
var bitmap: Bitmap? = null
|
||||
for (i in 0..1) {
|
||||
val ext = if((i == 0 && tryWebpFirst) || (i == 1 && !tryWebpFirst)) "webp" else "jpg"
|
||||
bitmap = try {
|
||||
if (q == 100) BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.$ext")))
|
||||
else {
|
||||
val out = ByteArrayOutputStream()
|
||||
BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.jpg")))?.compress(Bitmap.CompressFormat.JPEG, q, out)
|
||||
BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.$ext")))?.compress(Bitmap.CompressFormat.JPEG, q, out)
|
||||
BitmapFactory.decodeStream(ByteArrayInputStream(out.toByteArray()))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(this, "加载zip的第${position}项错误", Toast.LENGTH_SHORT).show()
|
||||
if (i == 1) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(this, "加载zip的第${position}项错误", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
null
|
||||
}
|
||||
if (bitmap != null) {
|
||||
tryWebpFirst = ext == "webp"
|
||||
break
|
||||
}
|
||||
}
|
||||
bitmap
|
||||
}
|
||||
|
||||
private fun setIdPosition(position: Int) {
|
||||
@@ -491,9 +494,10 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
it["chapterId"] = hm.chapterId.toString()
|
||||
it["name"] = inftitle.ttitle.text
|
||||
}*/
|
||||
}catch (e: Exception) {
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
toolsBox.toastError("准备控件错误")
|
||||
toolsBox.toastError(R.string.load_chapter_error)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,7 +516,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
idtbcut.isChecked = cut
|
||||
idtbcut.setOnClickListener {
|
||||
pb["useCut"] = idtbcut.isChecked
|
||||
Toast.makeText(this, "下次浏览生效", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.take_effect_on_reload, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,7 +524,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
idtblr.isChecked = r2l
|
||||
idtblr.setOnClickListener {
|
||||
pb["r2l"] = idtblr.isChecked
|
||||
Toast.makeText(this, "下次浏览生效", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.take_effect_on_reload, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,7 +532,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
idtbvp.isChecked = notUseVP
|
||||
idtbvp.setOnClickListener {
|
||||
pb["noVP"] = idtbvp.isChecked
|
||||
Toast.makeText(this, "下次浏览生效", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.take_effect_on_reload, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,7 +555,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
}
|
||||
|
||||
fun updateSeekBar() {
|
||||
if (!isInSeek) hideObjs()
|
||||
if (!isInSeek) hideDrawer()
|
||||
updateSeekText()
|
||||
updateSeekProgress()
|
||||
setProgress()
|
||||
@@ -591,21 +595,22 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
idtbvh.isChecked = isVertical
|
||||
pm = PagesManager(WeakReference(this))
|
||||
if (isVertical) {
|
||||
val vsps = vsp as SpringView
|
||||
vsps.footerView.lht.text = "更多"
|
||||
vsps.headerView.lht.text = "更多"
|
||||
vsps.setListener(object :SpringView.OnFreshListener{
|
||||
override fun onLoadmore() {
|
||||
//scrollForward()
|
||||
pm?.toPage(true)
|
||||
vsps.onFinishFreshAndLoad()
|
||||
}
|
||||
override fun onRefresh() {
|
||||
//scrollBack()
|
||||
pm?.toPage(false)
|
||||
vsps.onFinishFreshAndLoad()
|
||||
}
|
||||
})
|
||||
(vsp as SpringView).apply {
|
||||
footerView.lht.setText(R.string.button_more)
|
||||
headerView.lht.setText(R.string.button_more)
|
||||
setListener(object :SpringView.OnFreshListener{
|
||||
override fun onLoadmore() {
|
||||
//scrollForward()
|
||||
pm?.toPage(true)
|
||||
onFinishFreshAndLoad()
|
||||
}
|
||||
override fun onRefresh() {
|
||||
//scrollBack()
|
||||
pm?.toPage(false)
|
||||
onFinishFreshAndLoad()
|
||||
}
|
||||
})
|
||||
}
|
||||
vp.visibility = View.GONE
|
||||
vsp.visibility = View.VISIBLE
|
||||
initImgList()
|
||||
@@ -623,7 +628,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
}
|
||||
idtbvh.setOnClickListener {
|
||||
pb["vertical"] = idtbvh.isChecked
|
||||
Toast.makeText(this, "下次浏览生效", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.take_effect_on_reload, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,7 +638,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
Log.d("MyVM", "Do scroll back, isVertical: $isVertical, pageNum: $pageNum")
|
||||
handler.obtainMessage(VMHandler.LOAD_ITEM_SCROLL_MODE, currentItem - verticalLoadMaxCount, 0).sendToTarget() //loadImgsIntoLine(currentItem - verticalLoadMaxCount)
|
||||
psivl.postDelayed({ pageNum-- }, 233)
|
||||
}else pageNum--
|
||||
} else pageNum--
|
||||
}
|
||||
|
||||
fun scrollForward() {
|
||||
@@ -674,7 +679,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
|
||||
override fun onBindViewHolder(holder: ViewData, position: Int) {
|
||||
val pos = if (r2l) realCount - position - 1 else position
|
||||
val index2load = if(cut) Math.abs(indexMap[pos]) -1 else pos
|
||||
val index2load = if(cut) abs(indexMap[pos]) -1 else pos
|
||||
val useCut = cut && isCut[index2load]
|
||||
val isLeft = cut && indexMap[pos] > 0
|
||||
if (zipFile?.exists() == true) getImgBitmap(index2load)?.let {
|
||||
@@ -684,15 +689,17 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
else getImgUrl(index2load)?.let{
|
||||
if(useCut){
|
||||
val thisOneI = holder.itemView.onei
|
||||
Glide.with(this@ViewMangaActivity)
|
||||
Glide.with(this@ViewMangaActivity.applicationContext)
|
||||
.asBitmap()
|
||||
.load(GlideUrl(CMApi.proxy?.wrap(it)?:it, CMApi.myGlideHeaders))
|
||||
.placeholder(BitmapDrawable(resources, getLoadingBitmap(pos)))
|
||||
.into(object : SimpleTarget<Bitmap>() {
|
||||
.into(object : CustomTarget<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
thisOneI.setImageBitmap(cutBitmap(resource, isLeft))
|
||||
} })
|
||||
} else Glide.with(this@ViewMangaActivity)
|
||||
}
|
||||
override fun onLoadCleared(placeholder: Drawable?) { }
|
||||
})
|
||||
} else Glide.with(this@ViewMangaActivity.applicationContext)
|
||||
.load(GlideUrl(CMApi.proxy?.wrap(it)?:it, CMApi.myGlideHeaders))
|
||||
.placeholder(BitmapDrawable(resources, getLoadingBitmap(pos)))
|
||||
.into(holder.itemView.onei)
|
||||
@@ -705,7 +712,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
}
|
||||
}
|
||||
|
||||
fun showObjs() {
|
||||
fun showDrawer() {
|
||||
infseek.visibility = View.VISIBLE
|
||||
isearch.visibility = View.VISIBLE
|
||||
ObjectAnimator.ofFloat(
|
||||
@@ -717,7 +724,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
|
||||
clicked = true
|
||||
}
|
||||
|
||||
fun hideObjs() {
|
||||
fun hideDrawer() {
|
||||
ObjectAnimator.ofFloat(
|
||||
oneinfo,
|
||||
"alpha",
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package top.fumiama.copymanga.user
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.widget.Toast
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.MainActivity
|
||||
import top.fumiama.copymanga.json.LoginInfoStructure
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
||||
@@ -47,6 +44,12 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
|
||||
|
||||
|
||||
fun refreshAvatar() : LoginInfoStructure {
|
||||
if (!pref.contains("token")) {
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 400
|
||||
l.message = getString(R.string.noLogin)
|
||||
return l
|
||||
}
|
||||
try {
|
||||
DownloadTools.getHttpContent(getString(R.string.memberInfoApiUrl).format(
|
||||
CMApi.myHostApiUrl))?.decodeToString()?.let {
|
||||
@@ -65,7 +68,7 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
|
||||
}
|
||||
val l = LoginInfoStructure()
|
||||
l.code = 400
|
||||
l.message = getString(R.string.login_get_avatar_failed)
|
||||
l.message = getString(R.string.login_get_avatar_failed)
|
||||
return l
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.util.AttributeSet
|
||||
import androidx.cardview.widget.CardView
|
||||
import java.io.File
|
||||
|
||||
class MangaCardView:CardView {
|
||||
class MangaCardView :CardView {
|
||||
constructor(context: Context): super(context)
|
||||
constructor(context: Context, attrs: AttributeSet?): super (context, attrs)
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)
|
||||
|
||||
@@ -16,6 +16,7 @@ import android.view.MotionEvent
|
||||
import android.widget.ImageView
|
||||
import top.fumiama.copymanga.ui.vm.PagesManager
|
||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
import kotlin.math.sqrt
|
||||
@@ -563,7 +564,7 @@ class ScaleImageView : ImageView {
|
||||
}
|
||||
}catch (e:Exception){
|
||||
e.printStackTrace()
|
||||
ViewMangaActivity.va?.get()?.toolsBox?.toastError("图片加载错误,请尝试下载后使用较低图片质量查看", false)
|
||||
ViewMangaActivity.va?.get()?.toolsBox?.toastError(R.string.show_image_error_try_lower_resolution, false)
|
||||
}
|
||||
}
|
||||
////////////////////////////////有效性判断////////////////////////////////
|
||||
@@ -688,7 +689,7 @@ class ScaleImageView : ImageView {
|
||||
(event.x / width).let {
|
||||
when {
|
||||
it <= 1.0 / 3.0 -> pm?.toPreviousPage()
|
||||
it <= 2.0 / 3.0 -> pm?.manageInfo()
|
||||
it <= 2.0 / 3.0 -> pm?.toggleDrawer()
|
||||
else -> pm?.toNextPage()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,13 @@
|
||||
android:id="@+id/coordiv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="16dp"
|
||||
android:background="?attr/colorPrimarySurface"
|
||||
android:visibility="visible"
|
||||
app:layout_scrollFlags="scroll|enterAlways" />
|
||||
android:background="?attr/colorPrimarySurface" />
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimarySurface"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
@@ -37,6 +37,19 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/laic"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_rawRes="@raw/lottie_loading" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -36,6 +36,19 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/laic"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_rawRes="@raw/lottie_loading" />
|
||||
|
||||
<include
|
||||
android:id="@+id/sgnic"
|
||||
layout="@layout/widget_finalmark"
|
||||
|
||||
@@ -26,6 +26,19 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lai"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_rawRes="@raw/lottie_loading" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/vpi"
|
||||
android:layout_width="0dp"
|
||||
|
||||
1
app/src/main/res/raw/lottie_loading.json
Normal file
1
app/src/main/res/raw/lottie_loading.json
Normal file
File diff suppressed because one or more lines are too long
@@ -4,6 +4,8 @@
|
||||
]>
|
||||
<resources>
|
||||
<string name="app_name">拷贝漫画</string>
|
||||
<string name="file_provider_authority">top.fumiama.copymanga.fileprovider</string>
|
||||
|
||||
<string name="action_settings">设定</string>
|
||||
<string name="action_info">关于</string>
|
||||
<string name="action_download">下载</string>
|
||||
@@ -40,6 +42,17 @@
|
||||
<string name="web_error">网络错误</string>
|
||||
<string name="download_cover_failed">保存封面失败</string>
|
||||
<string name="download_cover_timeout">保存封面超时</string>
|
||||
<string name="take_effect_on_reload">下次浏览生效</string>
|
||||
<string name="end_of_chapter">已经到头了~</string>
|
||||
<string name="press_again_to_load_previous_chapter">再次按下加载上一章</string>
|
||||
<string name="press_again_to_load_next_chapter">再次按下加载下一章</string>
|
||||
<string name="load_local_chapter_info_failed">读取本地章节信息失败</string>
|
||||
<string name="download_chapter_info_failed">下载章节信息失败</string>
|
||||
<string name="load_manga_error">加载漫画错误</string>
|
||||
<string name="count_zip_entries_error">统计zip图片数错误</string>
|
||||
<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="mainPageApiUrl">https://%1$s/api/v3/h5/homeIndex?platform=3</string>
|
||||
<string name="referUrl">https://%1$s</string>
|
||||
@@ -153,4 +166,5 @@
|
||||
|
||||
<string name="old_download_card_name">前往旧版下载</string>
|
||||
<string name="new_download_card_option_hint">选择您的操作</string>
|
||||
<string name="choose_how_download_folder">选择如何打开漫画下载目录</string>
|
||||
</resources>
|
||||
|
||||
12
app/src/main/res/values/weeks.xml
Normal file
12
app/src/main/res/values/weeks.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="weeks">
|
||||
<item>周日</item>
|
||||
<item>周一</item>
|
||||
<item>周二</item>
|
||||
<item>周三</item>
|
||||
<item>周四</item>
|
||||
<item>周五</item>
|
||||
<item>周六</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -23,4 +23,3 @@ android.enableR8.fullMode=true
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonTransitiveRClass=false
|
||||
android.nonFinalResIds=false
|
||||
org.gradle.unsafe.configuration-cache=true
|
||||
Reference in New Issue
Block a user