1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-27 06:10:29 +08:00
1. 增加浏览已下载漫画功能
2. 细节优化提升
This commit is contained in:
fumiama
2020-12-11 23:40:26 +08:00
parent 72f8fb1450
commit c56acd81d1
16 changed files with 268 additions and 71 deletions

View File

@@ -11,8 +11,8 @@ android {
applicationId "top.fumiama.copymanga" applicationId "top.fumiama.copymanga"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 30 targetSdkVersion 30
versionCode 3 versionCode 4
versionName '1.1.1' versionName '1.1.2'
resConfigs "zh", "zh-rCN" resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -36,11 +36,11 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release signingConfig signingConfigs.release
} }
debug{ /*debug{
minifyEnabled true minifyEnabled true
shrinkResources true shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }*/
} }
} }
@@ -49,7 +49,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.core:core-ktx:1.3.2'
//implementation 'androidx.appcompat:appcompat:1.2.0' //implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0' implementation 'androidx.viewpager2:viewpager2:1.0.0'
//implementation 'com.google.android.material:material:1.2.1' //implementation 'com.google.android.material:material:1.2.1'
@@ -59,6 +59,7 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0' implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.code.gson:gson:2.8.6'
//implementation 'com.liaoinstan.springview:library:1.7.0'
} }
andResGuard { andResGuard {
@@ -93,7 +94,7 @@ andResGuard {
"*.gif", "*.gif",
] ]
sevenzip { sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.19' artifact = 'com.tencent.mm:SevenZip:1.2.20'
//path = "/usr/local/bin/7za" //path = "/usr/local/bin/7za"
} }

View File

@@ -18,5 +18,6 @@
</activity> </activity>
<activity android:name=".activity.ViewMangaActivity"/> <activity android:name=".activity.ViewMangaActivity"/>
<activity android:name=".activity.DlActivity"/> <activity android:name=".activity.DlActivity"/>
<activity android:name=".activity.DlListActivity"/>
</application> </application>
</manifest> </manifest>

View File

@@ -38,6 +38,7 @@ if (typeof (loaded) == "undefined") {
if (url.endsWith("/index")) invoke.pinTitle(); if (url.endsWith("/index")) invoke.pinTitle();
else if (url.indexOf("/comicContent/") > 0) setTimeout(function () { invoke.loadChapter() }, 1000); else if (url.indexOf("/comicContent/") > 0) setTimeout(function () { invoke.loadChapter() }, 1000);
else if (url.indexOf("/details/comic/") > 0) GM.loadComic(url); else if (url.indexOf("/details/comic/") > 0) GM.loadComic(url);
else if (url.indexOf("/personal") > 0) GM.enterProfile();
} }
modify(); modify();
invoke.urlChangeListener(modify); invoke.urlChangeListener(modify);

View File

@@ -42,7 +42,7 @@ class DlActivity : Activity() {
var tbtnUrlList = arrayListOf<String>() var tbtnUrlList = arrayListOf<String>()
private val handler = DlHandler(this) private val handler = DlHandler(this)
private var btnw = 0 private var btnw = 0
private var cdwnHeight = 0 private var cdwnWidth = 0
private var canDl = false private var canDl = false
private lateinit var toolsBox: ToolsBox private lateinit var toolsBox: ToolsBox
lateinit var mangaDlTools: MangaDlTools lateinit var mangaDlTools: MangaDlTools
@@ -64,16 +64,14 @@ class DlActivity : Activity() {
super.onDestroy() super.onDestroy()
} }
private fun showDlCard() { private fun showDlCard(){
//ObjectAnimator.ofFloat(csdwn, "alpha", 0.3f, 0.9f).setDuration(233).start() //ObjectAnimator.ofFloat(csdwn, "alpha", 0.3f, 0.9f).setDuration(233).start()
ObjectAnimator.ofFloat(csdwn, "translationY", cdwnHeight.toFloat(), 0f).setDuration(233) ObjectAnimator.ofFloat(csdwn, "translationX", cdwnWidth.toFloat() * 0.9f, 0f).setDuration(233).start()
.start()
} }
private fun hideDlCard() { private fun hideDlCard(){
//ObjectAnimator.ofFloat(csdwn, "alpha", 0.9f, 0.3f).setDuration(233).start() //ObjectAnimator.ofFloat(csdwn, "alpha", 0.9f, 0.3f).setDuration(233).start()
ObjectAnimator.ofFloat(csdwn, "translationY", 0f, cdwnHeight.toFloat()).setDuration(233) ObjectAnimator.ofFloat(csdwn, "translationX", 0f, cdwnWidth.toFloat() * 0.9f).setDuration(233).start()
.start()
} }
private fun fillChapters() { private fun fillChapters() {
@@ -87,7 +85,11 @@ class DlActivity : Activity() {
sleep(2333) sleep(2333)
for (i in tbtnlist.listIterator()) { for (i in tbtnlist.listIterator()) {
if (i.isChecked) dlMethod(i) if (i.isChecked) dlMethod(i)
if (!canDl) break if (!canDl) {
checkedChapter -= dldChapter
dldChapter = 0
break
}
} }
if (canDl) { if (canDl) {
haveDlStarted = false haveDlStarted = false
@@ -107,34 +109,33 @@ class DlActivity : Activity() {
csdwn.viewTreeObserver.addOnGlobalLayoutListener(object : csdwn.viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener { ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() { override fun onGlobalLayout() {
cdwnHeight = csdwn.height cdwnWidth = csdwn.width
Log.d("MyDl", "Get csdwn height: $cdwnHeight")
csdwn.viewTreeObserver.removeOnGlobalLayoutListener(this) csdwn.viewTreeObserver.removeOnGlobalLayoutListener(this)
} }
}) })
dllazys.onScrollListener = object : LazyScrollView.OnScrollListener { dllazys.onScrollListener = object : LazyScrollView.OnScrollListener {
override fun onBottom() { override fun onBottom() {}
if (csdwn.translationY > 0f) showDlCard()
}
override fun onScroll() { override fun onScroll() {
if (csdwn.translationY == 0f) hideDlCard() if (csdwn.translationY == 0f) hideDlCard()
} }
override fun onTop() { override fun onTop() {}
if (csdwn.translationY > 0f) showDlCard()
}
} }
cdwn.setOnClickListener { cdwn.setOnClickListener {
pdwn.progress = 0 if (csdwn.translationX != 0f) showDlCard()
if (canDl || checkedChapter == 0) canDl = false else if (checkedChapter == 0) hideDlCard()
else { else {
haveDlStarted = true pdwn.progress = 0
canDl = true if (canDl || checkedChapter == 0) canDl = false
handler.sendEmptyMessage(9) else {
Toast.makeText(this, "准备下载...", Toast.LENGTH_SHORT).show() haveDlStarted = true
fillChapters() canDl = true
Thread { dlThead { downloadChapterPages(it) } }.start() handler.sendEmptyMessage(9)
Toast.makeText(this, "准备下载...", Toast.LENGTH_SHORT).show()
fillChapters()
Thread { dlThead { downloadChapterPages(it) } }.start()
}
} }
} }
cdwn.setOnLongClickListener { cdwn.setOnLongClickListener {
@@ -177,7 +178,6 @@ class DlActivity : Activity() {
handler.obtainMessage(if (succeed) 1 else -1, tbtnlist.indexOf(i), 0) handler.obtainMessage(if (succeed) 1 else -1, tbtnlist.indexOf(i), 0)
.sendToTarget() .sendToTarget()
} }
override fun handleMessage(succeed: Boolean, pageNow: Int) { override fun handleMessage(succeed: Boolean, pageNow: Int) {
handler.obtainMessage( handler.obtainMessage(
5, 5,
@@ -186,6 +186,13 @@ class DlActivity : Activity() {
succeed succeed
).sendToTarget() ).sendToTarget()
} }
override fun handleMessage(pageNow: Int){
handler.obtainMessage(
10,
tbtnlist.indexOf(i),
pageNow
).sendToTarget()
}
} }
mangaDlTools.dlChapterAndPackIntoZip( mangaDlTools.dlChapterAndPackIntoZip(
File("${getExternalFilesDir("")}/$comicName/${i.hint}/${i.textOn}.zip"), File("${getExternalFilesDir("")}/$comicName/${i.hint}/${i.textOn}.zip"),
@@ -231,13 +238,12 @@ class DlActivity : Activity() {
null, null,
"取消", "取消",
{ {
if (checkedChapter == 0) {
it.tbtn.isChecked = true
tdwn.text = "$dldChapter/${++checkedChapter}"
}
Thread { Thread {
handler.obtainMessage( handler.sendEmptyMessage(7)
7,
tbtnlist.indexOf(it.tbtn),
0,
zipf
).sendToTarget()
}.start() }.start()
}) })
} }
@@ -245,11 +251,10 @@ class DlActivity : Activity() {
} }
} }
fun deleteChapters(zipf: File, index: Int) { fun deleteChapters() {
for (i in tbtnlist) { for (i in tbtnlist) {
if (i.isChecked) { if (i.isChecked) {
val f = val f = File("${getExternalFilesDir("")}/$comicName/${i.hint}/${i.textOn}.zip")
File("${getExternalFilesDir("")}/$comicName/${i.hint}/${i.textOn}.zip")
if (f.exists()) { if (f.exists()) {
deleteChapter(f, i) deleteChapter(f, i)
checkedChapter-- checkedChapter--

View File

@@ -0,0 +1,41 @@
package top.fumiama.copymanga.activity
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_dlist.*
import kotlinx.android.synthetic.main.widget_titlebar.*
import top.fumiama.copymanga.R
import java.io.File
class DlListActivity:Activity() {
private var exDir: File? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dlist)
val titleText = intent.getStringExtra("title")
ttitle.text = titleText?.substringAfterLast("/")
exDir = getExternalFilesDir("")
val innerDir = titleText?.substringAfter("我的下载")
File(exDir, innerDir?:"").list()?.let {
mylv.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, it)
mylv.setOnItemClickListener { _, _, position, _ ->
val chosenFile = File(exDir, "$innerDir/${it[position]}")
val newTitle = "$titleText/${it[position]}"
//Toast.makeText(this, "进入$chosenFile", Toast.LENGTH_SHORT).show()
if (chosenFile.isDirectory) startActivity(
Intent(
this,
DlListActivity::class.java
).putExtra("title", newTitle)
)
else{
ViewMangaActivity.zipFile = chosenFile
ViewMangaActivity.titleText = it[position]
startActivity(Intent(this, ViewMangaActivity::class.java))
}
}
}
}
}

View File

@@ -10,6 +10,7 @@ import android.webkit.WebView
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import top.fumiama.copymanga.R import top.fumiama.copymanga.R
import top.fumiama.copymanga.handler.MainHandler import top.fumiama.copymanga.handler.MainHandler
import top.fumiama.copymanga.tool.ToolsBox
import top.fumiama.copymanga.view.JSWebView import top.fumiama.copymanga.view.JSWebView
import top.fumiama.copymanga.web.JS import top.fumiama.copymanga.web.JS
import top.fumiama.copymanga.web.JSHidden import top.fumiama.copymanga.web.JSHidden
@@ -18,23 +19,30 @@ import java.lang.ref.WeakReference
class MainActivity: Activity() { class MainActivity: Activity() {
var wh: JSWebView? = null var wh: JSWebView? = null
var toolsBox: ToolsBox? = null
@SuppressLint("JavascriptInterface") @SuppressLint("JavascriptInterface")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
wm = WeakReference(this) wm = WeakReference(this)
mh = Looper.myLooper()?.let { MainHandler(it) } mh = MainHandler(Looper.getMainLooper())
toolsBox = ToolsBox(wm as WeakReference<Any>)
toolsBox?.netinfo?.let {
if(it == "无网络" || it == "错误"){
Thread{mh?.sendEmptyMessage(6)}.start()
}else{
WebView.setWebContentsDebuggingEnabled(true)
w.setWebViewClient("i.js")
w.webChromeClient = WebChromeClient()
w.loadJSInterface(JS())
w.loadUrl(getString(R.string.web_home))
WebView.setWebContentsDebuggingEnabled(true) wh = JSWebView(this, getString(R.string.pc_ua))
w.setWebViewClient("i.js") wh?.setWebViewClient("h.js")
w.webChromeClient = WebChromeClient() wh?.loadJSInterface(JSHidden())
w.loadJSInterface(JS()) }
w.loadUrl(getString(R.string.web_home)) }
wh = JSWebView(this, getString(R.string.pc_ua))
wh?.setWebViewClient("h.js")
wh?.loadJSInterface(JSHidden())
} }
override fun onBackPressed() { override fun onBackPressed() {
@@ -43,7 +51,10 @@ class MainActivity: Activity() {
} }
fun onFabClicked(v: View){ fun onFabClicked(v: View){
startActivity(Intent(this, DlActivity::class.java)) startActivity(
Intent(this, (if(mh?.showDlList == true) DlListActivity::class else DlActivity::class).java)
.putExtra("title", "./我的下载")
)
} }
companion object{ companion object{

View File

@@ -3,9 +3,12 @@ package top.fumiama.copymanga.activity
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Message import android.os.Message
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -31,6 +34,8 @@ import java.io.File
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.zip.ZipFile
import java.util.zip.ZipInputStream
class ViewMangaActivity : Activity() { class ViewMangaActivity : Activity() {
@@ -47,6 +52,8 @@ class ViewMangaActivity : Activity() {
var infoDrawerDelta = 0f var infoDrawerDelta = 0f
lateinit var toolsBox: ToolsBox lateinit var toolsBox: ToolsBox
private lateinit var p: PropertiesTools private lateinit var p: PropertiesTools
private var mangaZip = zipFile
private val dlZip2View = mangaZip != null
var pageNum = 1 var pageNum = 1
get() { get() {
field = getPageNumber() field = getPageNumber()
@@ -85,14 +92,15 @@ class ViewMangaActivity : Activity() {
tt.canDo = true tt.canDo = true
tt.start() tt.start()
ttitle.text = titleText ttitle.text = titleText
isearch.visibility = View.VISIBLE
try { try {
count = imgUrls.size count = if (mangaZip != null) countZipItems() else imgUrls.size
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
toolsBox.toastError("分析图片url错误") toolsBox.toastError("分析图片url错误")
} }
try { try {
prepareItems(count) prepareItems()
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
toolsBox.toastError("准备控件错误") toolsBox.toastError("准备控件错误")
@@ -115,10 +123,28 @@ class ViewMangaActivity : Activity() {
else if (notUseVP) currentItem = num - 1 else vp.currentItem = num - 1 else if (notUseVP) currentItem = num - 1 else vp.currentItem = num - 1
} }
private fun getImgBitmap(position: Int): Bitmap? {
if (position >= count || position < 0) return null
else {
val zip = ZipFile(mangaZip)
//if (q == 100)
return BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.webp")))
/*else {
val out = ByteArrayOutputStream()
try {
BitmapFactory.decodeStream(zip.getInputStream(zip.getEntry("${position}.jpg")))
} catch (e: Exception) {
e.printStackTrace()
return null
}?.compress(Bitmap.CompressFormat.JPEG, q, out)
return BitmapFactory.decodeStream(ByteArrayInputStream(out.toByteArray()))
}*/
}
}
private fun loadOneImg() { private fun loadOneImg() {
Glide.with(this@ViewMangaActivity).load( if(dlZip2View) onei.setImageBitmap(getImgBitmap(currentItem))
imgUrls[currentItem] else Glide.with(this@ViewMangaActivity).load(imgUrls[currentItem]).placeholder(R.drawable.bg_comment).into(onei)
).placeholder(R.drawable.bg_comment).into(onei)
updateSeekBar() updateSeekBar()
} }
@@ -128,9 +154,9 @@ class ViewMangaActivity : Activity() {
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun prepareItems(size: Int) { private fun prepareItems() {
prepareVP() prepareVP()
prepareInfoBar(size) prepareInfoBar(count)
if (notUseVP) loadOneImg() else prepareIdBtVH() if (notUseVP) loadOneImg() else prepareIdBtVH()
toolsBox.dp2px(67)?.let { setIdPosition(it) } toolsBox.dp2px(67)?.let { setIdPosition(it) }
prepareIdBtFullScreen() prepareIdBtFullScreen()
@@ -233,6 +259,28 @@ class ViewMangaActivity : Activity() {
} }
} }
private fun countZipItems(): Int {
var c = 0
try {
val exist = mangaZip?.exists() == true
if (!exist) return 0
else {
Log.d("Myvm", "zipf: $mangaZip")
val zip = ZipInputStream(mangaZip?.inputStream()?.buffered())
var entry = zip.nextEntry
while (entry != null) {
if (!entry.isDirectory) c++
entry = zip.nextEntry
}
zip.closeEntry()
zip.close()
}
} catch (e: Exception) {
toolsBox.toastError("读取zip错误!")
}
return c
}
fun scrollBack() { fun scrollBack() {
pageNum-- pageNum--
} }
@@ -278,7 +326,11 @@ class ViewMangaActivity : Activity() {
@SuppressLint("ClickableViewAccessibility", "SetTextI18n") @SuppressLint("ClickableViewAccessibility", "SetTextI18n")
override fun onBindViewHolder(holder: ViewData, position: Int) { override fun onBindViewHolder(holder: ViewData, position: Int) {
val pos = if (r2l) count - position - 1 else position val pos = if (r2l) count - position - 1 else position
Glide.with(this@ViewMangaActivity).load(imgUrls[pos]).placeholder(R.drawable.bg_comment).into(holder.itemView.onei) if(dlZip2View) getImgBitmap(pos)?.let {
//Glide.with(this@ViewMangaActivity).load(it).placeholder(R.drawable.bg_comment).into(holder.itemView.onei)
holder.itemView.onei.setImageBitmap(it)
}
else Glide.with(this@ViewMangaActivity).load(imgUrls[pos]).placeholder(R.drawable.bg_comment).timeout(10000).into(holder.itemView.onei)
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
@@ -359,8 +411,24 @@ class ViewMangaActivity : Activity() {
companion object { companion object {
var va: WeakReference<ViewMangaActivity>? = null var va: WeakReference<ViewMangaActivity>? = null
var imgUrls = arrayOf<String>() var imgUrls = arrayOf<String>()
var zipFile: File? = null
get() {
val re = field
if(field != null) field = null
return re
}
var titleText = "Null" var titleText = "Null"
var nextChapterUrl: String? = null var nextChapterUrl: String? = null
get() {
val re = field
if(field != null) field = null
return re
}
var previousChapterUrl: String? = null var previousChapterUrl: String? = null
get() {
val re = field
if(field != null) field = null
return re
}
} }
} }

View File

@@ -2,6 +2,7 @@ package top.fumiama.copymanga.handler
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Handler import android.os.Handler
import android.os.Looper
import android.os.Message import android.os.Message
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.widget_downloadbar.* import kotlinx.android.synthetic.main.widget_downloadbar.*
@@ -38,11 +39,13 @@ class DlHandler(activity: DlActivity) : Handler() {
-1 -> { -1 -> {
d?.tbtnlist?.get(msg.arg1)?.setBackgroundResource(R.drawable.rndbg_error) d?.tbtnlist?.get(msg.arg1)?.setBackgroundResource(R.drawable.rndbg_error)
d!!.dldChapter-- d!!.dldChapter--
//Looper.prepare()
Toast.makeText( Toast.makeText(
d, d,
"下载${d.tbtnlist[msg.arg1].textOn}失败", "下载${d.tbtnlist[msg.arg1].textOn}失败",
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
//Looper.loop()
d.updateProgressBar() d.updateProgressBar()
} }
4 -> { 4 -> {
@@ -74,17 +77,28 @@ class DlHandler(activity: DlActivity) : Handler() {
?.getImgsCountByHash(d.tbtnUrlList[msg.arg1].substringAfterLast("/")) ?: 0 ?.getImgsCountByHash(d.tbtnUrlList[msg.arg1].substringAfterLast("/")) ?: 0
) )
if (!(msg.obj as Boolean)) { if (!(msg.obj as Boolean)) {
//Looper.prepare()
Toast.makeText( Toast.makeText(
d, d,
"下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败", "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败",
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
//Looper.loop()
} }
} }
6 -> d?.tdwn?.text = "${d?.dldChapter}/${d?.checkedChapter}" 6 -> d?.tdwn?.text = "${d?.dldChapter}/${d?.checkedChapter}"
7 -> d?.deleteChapters(msg.obj as File, msg.arg1) 7 -> d?.deleteChapters()
8 -> d?.cdwn?.setCardBackgroundColor(d.resources.getColor(R.color.colorBlue)) 8 -> d?.cdwn?.setCardBackgroundColor(d.resources.getColor(R.color.colorBlue))
9 -> d?.cdwn?.setCardBackgroundColor(d.resources.getColor(R.color.colorRed)) 9 -> d?.cdwn?.setCardBackgroundColor(d.resources.getColor(R.color.colorRed))
10 -> {
//Looper.prepare()
Toast.makeText(
d,
"下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败,尝试重新下载...",
Toast.LENGTH_SHORT
).show()
//Looper.loop()
}
} }
} }
} }

View File

@@ -19,6 +19,7 @@ import top.fumiama.copymanga.tool.MangaDlTools.Companion.wmdlt
class MainHandler(looper: Looper):Handler(looper) { class MainHandler(looper: Looper):Handler(looper) {
var saveUrlsOnly = false var saveUrlsOnly = false
var showDlList = false
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
super.handleMessage(msg) super.handleMessage(msg)
when(msg.what){ when(msg.what){
@@ -27,6 +28,7 @@ class MainHandler(looper: Looper):Handler(looper) {
3 -> updateLoadProgress(msg.arg1) 3 -> updateLoadProgress(msg.arg1)
4 -> setFab(msg.obj as String) 4 -> setFab(msg.obj as String)
5 -> hideFab() 5 -> hideFab()
6 -> setFab2DlList()
} }
} }
private fun loadUrlInHiddenWebView(url: String){wm?.get()?.wh?.loadUrl(url)} private fun loadUrlInHiddenWebView(url: String){wm?.get()?.wh?.loadUrl(url)}
@@ -55,10 +57,16 @@ class MainHandler(looper: Looper):Handler(looper) {
if(progress == 100) it.pw.postDelayed({it.pw.visibility = View.GONE}, 500) if(progress == 100) it.pw.postDelayed({it.pw.visibility = View.GONE}, 500)
} }
} }
private fun showFab() {wm?.get()?.fab?.visibility = View.VISIBLE}
private fun hideFab() {wm?.get()?.fab?.visibility = View.GONE}
private fun setFab(content: String){ private fun setFab(content: String){
//Log.d("MyMH", "Get chapter json: $content") //Log.d("MyMH", "Get chapter json: $content")
showDlList = false
comicStructure = Gson().fromJson(content.reader(), Array<ComicStructure>::class.java) comicStructure = Gson().fromJson(content.reader(), Array<ComicStructure>::class.java)
wm?.get()?.fab?.visibility = View.VISIBLE showFab()
}
private fun setFab2DlList(){
showDlList = true
showFab()
} }
private fun hideFab() {wm?.get()?.fab?.visibility = View.GONE}
} }

View File

@@ -1,14 +1,13 @@
package top.fumiama.copymanga.tool package top.fumiama.copymanga.tool
import android.util.Log import android.util.Log
import java.io.File
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL
import java.util.concurrent.Callable import java.util.concurrent.Callable
import java.util.concurrent.FutureTask import java.util.concurrent.FutureTask
class DownloadTools { class DownloadTools {
fun getHttpContent(Url: String, refer: String? = null): ByteArray? { fun getHttpContent(Url: String, refer: String? = null, ua: String? = null): ByteArray? {
Log.d("Mydl", "getHttp: $Url") Log.d("Mydl", "getHttp: $Url")
var ret: ByteArray? = null var ret: ByteArray? = null
val task = FutureTask(Callable { val task = FutureTask(Callable {
@@ -18,6 +17,7 @@ class DownloadTools {
connection.connectTimeout = 10000 connection.connectTimeout = 10000
connection.readTimeout = 10000 connection.readTimeout = 10000
refer?.let { connection.setRequestProperty("referer", it) } refer?.let { connection.setRequestProperty("referer", it) }
ua?.let { connection.setRequestProperty("User-agent", it) }
ret = connection.inputStream.readBytes() ret = connection.inputStream.readBytes()
connection.disconnect() connection.disconnect()

View File

@@ -1,11 +1,14 @@
package top.fumiama.copymanga.tool package top.fumiama.copymanga.tool
import android.os.Looper
import android.widget.Toast
import top.fumiama.copymanga.R import top.fumiama.copymanga.R
import top.fumiama.copymanga.activity.DlActivity import top.fumiama.copymanga.activity.DlActivity
import top.fumiama.copymanga.data.ComicStructure import top.fumiama.copymanga.data.ComicStructure
import top.fumiama.copymanga.view.JSWebView import top.fumiama.copymanga.view.JSWebView
import top.fumiama.copymanga.web.JSHidden import top.fumiama.copymanga.web.JSHidden
import java.io.File import java.io.File
import java.lang.Thread.sleep
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.zip.CRC32 import java.util.zip.CRC32
import java.util.zip.CheckedOutputStream import java.util.zip.CheckedOutputStream
@@ -60,8 +63,16 @@ class MangaDlTools(activity: DlActivity) {
var succeed = true var succeed = true
for (i in it.indices) { for (i in it.indices) {
zip.putNextEntry(ZipEntry("$i.webp")) zip.putNextEntry(ZipEntry("$i.webp"))
val s = dl.getHttpContent(it[i])?.let { zip.write(it); true } ?: false var tryTimes = 3
if (!s) succeed = s var s = false
while (!s && tryTimes-- > 0){
s = dl.getHttpContent(it[i], d?.getString(R.string.web_home_www), d?.getString(R.string.pc_ua))?.let { zip.write(it); true } ?: false
if (!s) {
onDownloadedListener?.handleMessage(i + 1)
sleep(2000)
}
}
if(tryTimes == 0) succeed = false
onDownloadedListener?.handleMessage(s, i + 1) onDownloadedListener?.handleMessage(s, i + 1)
zip.flush() zip.flush()
if (exit) break if (exit) break
@@ -76,6 +87,7 @@ class MangaDlTools(activity: DlActivity) {
interface OnDownloadedListener { interface OnDownloadedListener {
fun handleMessage(succeed: Boolean) fun handleMessage(succeed: Boolean)
fun handleMessage(succeed: Boolean, pageNow: Int) fun handleMessage(succeed: Boolean, pageNow: Int)
fun handleMessage(pageNow: Int)
} }
companion object { companion object {

View File

@@ -22,4 +22,8 @@ class JS {
fun hideFab(){ fun hideFab(){
Thread{mh?.sendEmptyMessage(5)}.start() Thread{mh?.sendEmptyMessage(5)}.start()
} }
@JavascriptInterface
fun enterProfile(){
Thread{mh?.sendEmptyMessage(6)}.start()
}
} }

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FCFCFF">
<include
android:id="@+id/myt"
layout="@layout/widget_titlebar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ListView
android:id="@+id/mylv"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/myt" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@@ -23,13 +24,16 @@
android:layout_width="64dp" android:layout_width="64dp"
android:layout_height="64dp" android:layout_height="64dp"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp" android:alpha="0.8"
android:background="@drawable/rndbg_round" android:background="@drawable/rndbg_round"
android:foreground="@drawable/ic_dl" android:foreground="@drawable/ic_dl"
android:foregroundGravity="center" android:foregroundGravity="center"
android:onClick="onFabClicked" android:onClick="onFabClicked"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/w" /> app:layout_constraintEnd_toEndOf="@+id/w"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.275"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -37,6 +37,7 @@
android:layout_height="28dp" android:layout_height="28dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:src="@drawable/ic_edit" android:src="@drawable/ic_edit"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />

View File

@@ -1,14 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = "1.4.10" ext.kotlin_version = '1.4.21'
repositories { repositories {
google() google()
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.0' classpath 'com.android.tools.build:gradle:4.1.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.19' classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.20'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files