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