1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-05 07:20:23 +08:00
修复
1. 最大只能阅读50页
优化
1. 卡顿
This commit is contained in:
源文雨
2025-06-21 00:49:24 +09:00
parent eeb3735103
commit dbb0b9d2b3
25 changed files with 488 additions and 319 deletions

2
.idea/.name generated
View File

@@ -1 +1 @@
拷贝漫画
拷贝漫画Lite

10
.idea/deploymentTargetSelector.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

9
.idea/dictionaries/fumiama.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<component name="ProjectDictionaryState">
<dictionary name="fumiama">
<words>
<w>copymanga</w>
<w>lowpan</w>
<w>volturn</w>
</words>
</dictionary>
</component>

1
.idea/misc.xml generated
View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">

2
.idea/vcs.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -1,6 +1,5 @@
# copymanga 拷贝漫画
# copymanga Lite
拷贝漫画的第三方APP优化阅读/下载体验
近日官方取消了网页端,本项目已不再可用,因此被存档
# 说明
本应用基于官方的`HLML5`手机版本网页端,作者不对其中呈现的任何内容负责
# 功能

View File

@@ -12,8 +12,8 @@ android {
minSdkVersion 23
//noinspection OldTargetApi
targetSdkVersion 34
versionCode 13
versionName '1.5.0'
versionCode 14
versionName '1.5.1'
resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -96,7 +96,7 @@ if (propFile.canRead()){
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.viewpager2:viewpager2:1.1.0'

View File

@@ -1,40 +1,62 @@
javascript:
if (typeof (loaded) == "undefined"){
if (typeof (loaded) == "undefined") {
var loaded = true;
function scanChapters(chapter) {
var chapterList = chapter.getElementsByClassName("tab-pane fade show active")[0].getElementsByTagName("ul")[0].getElementsByTagName("a");
var chapterArr = Array();
for(var i = 0; i < chapterList.length; i++){
for (var i = 0; i < chapterList.length; i++) {
chapterArr.push(JSON.constructor());
chapterArr[i]["name"] = chapterList[i].title;
chapterArr[i]["url"] = chapterList[i].href;
}
return chapterArr;
}
function smoothLoadChapter(speed, interval) {
let prevHeight = document.body.scrollHeight;
let lastTime = 0;
let ticking = false;
function requestTick() {
if (!ticking) {
ticking = true;
requestAnimationFrame(step);
}
}
function step(timestamp) {
if (!lastTime) lastTime = timestamp;
const elapsed = timestamp - lastTime;
if (elapsed >= interval) {
const index = document.getElementsByClassName("comicIndex")[0].innerText;
const count = document.getElementsByClassName("comicCount")[0].innerText;
GM.setLoadingDialogProgress(index, count);
window.scrollBy(0, speed);
lastTime = timestamp;
const currentHeight = document.body.scrollHeight;
if (Math.round(window.innerHeight+window.scrollY+0.5) >= currentHeight) { /*避免小数不符无法触发*/
if (currentHeight === prevHeight) {
var images = document.getElementsByClassName("container-fluid comicContent")[0].getElementsByTagName("li");
var nextChapter = document.getElementsByClassName("comicContent-next")[0].getElementsByTagName("a")[0].href;
var prevChapter = document.getElementsByClassName("comicContent-prev")[1].getElementsByTagName("a")[0].href;
if(nextChapter == location.href) nextChapter = "null";
if(prevChapter == location.href) prevChapter = "null";
var result = document.title.split(" - ")[1] + " " + location.href.substring(location.href.lastIndexOf("/")+1) + "\n" + nextChapter + "\n" + prevChapter;
for(var i = 0; i < images.length; i++) result += "\n" + images[i].getElementsByTagName("img")[0].dataset.src;
GM.setLoadingDialog(false);
GM.loadChapter(result);
return;
}
prevHeight = currentHeight;
}
}
ticking = false;
requestTick();
}
requestTick();
}
function modify() {
var url = location.href;
if(url.indexOf("/chapter/")>0){
window.scroll({ top: document.body.scrollHeight, left: 0, behavior: 'smooth' });
setTimeout(() => {
window.scroll({ top: document.body.scrollHeight, left: 0, behavior: 'smooth' });
setTimeout(() => {
window.scroll({ top: document.body.scrollHeight, left: 0, behavior: 'smooth' });
setTimeout(() => {
window.scroll({ top: document.body.scrollHeight, left: 0, behavior: 'smooth' });
setTimeout(() => {
window.scroll({ top: document.body.scrollHeight, left: 0, behavior: 'smooth' });
var imglist = document.getElementsByClassName("container-fluid comicContent")[0].getElementsByTagName("li");
var nextChapter = document.getElementsByClassName("comicContent-next")[0].getElementsByTagName("a")[0].href;
var prevChapter = document.getElementsByClassName("comicContent-prev")[1].getElementsByTagName("a")[0].href;
if(nextChapter == location.href) nextChapter = "null";
if(prevChapter == location.href) prevChapter = "null";
var liststr = document.title.split(" - ")[1] + " " + location.href.substring(location.href.lastIndexOf("/")+1) + "\n" + nextChapter + "\n" + prevChapter;
for(var i = 0; i < imglist.length; i++) liststr += "\n" + imglist[i].getElementsByTagName("img")[0].dataset.src;
GM.loadChapter(liststr);
}, 500);
}, 500);
}, 500);
}, 500);
if(url.indexOf("/chapter/") > 0){
GM.setLoadingDialog(true);
smoothLoadChapter(320, 16);
} else {
var json = Array();
var chapters = document.getElementsByClassName("upLoop")[0].children;
@@ -55,4 +77,4 @@ if (typeof (loaded) == "undefined"){
}
}
modify();
}else modify();
} else modify();

View File

@@ -2,7 +2,6 @@ package top.fumiama.copymangaweb.activity
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Looper
@@ -20,21 +19,20 @@ import kotlinx.android.synthetic.main.widget_downloadbar.*
import kotlinx.android.synthetic.main.widget_titlebar.*
import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
import top.fumiama.copymangaweb.data.ComicStructure
import top.fumiama.copymangaweb.databinding.ActivityDlBinding
import top.fumiama.copymangaweb.handler.DlHandler
import top.fumiama.copymangaweb.tool.MangaDlTools
import top.fumiama.copymangaweb.tool.MangaDlTools.Companion.wmdlt
import top.fumiama.copymangaweb.tool.ToolsBox
import top.fumiama.copymangaweb.view.ChapterToggleButton
import top.fumiama.copymangaweb.view.LazyScrollView
import top.fumiama.copymangaweb.web.JSHidden
import top.fumiama.copymangaweb.web.WebChromeClient
import java.io.File
import java.lang.Thread.sleep
import java.lang.ref.WeakReference
class DlActivity : Activity() {
class DlActivity : ToolsBoxActivity() {
private var tbtncnt = 0
private var isNewTitle = false
var haveSElectAll = false
@@ -42,13 +40,12 @@ class DlActivity : Activity() {
var dldChapter = 0
var haveDlStarted = false
private var btnNumPerRow = 4
private lateinit var ltbtn: View
private lateinit var toggleButtonLine: View
var tbtnlist: Array<ChapterToggleButton> = arrayOf()
private val handler = DlHandler(this, Looper.myLooper()!!)
private var btnw = 0
private var cdwnWidth = 0
private var canDl = false
private lateinit var toolsBox: ToolsBox
private lateinit var mangaDlTools: MangaDlTools
var multiSelect = false
@@ -59,16 +56,19 @@ class DlActivity : Activity() {
setContentView(binding.root)
mh?.saveUrlsOnly = true
mangaDlTools = MangaDlTools(this)
dwh.settings.userAgentString = getString(R.string.pc_ua)
dwh.webChromeClient = WebChromeClient()
dwh.setWebViewClient("h.js")
dwh.loadJSInterface(JSHidden())
dwh.apply { post {
settings.userAgentString = getString(R.string.pc_ua)
webChromeClient = WebChromeClient()
setWebViewClient("h.js")
loadJSInterface(JSHidden())
} }
handler.sendEmptyMessage(-2) //setLayouts
}
override fun onDestroy() {
mh?.saveUrlsOnly = false
wmdlt?.get()?.exit = true
handler.removeCallbacksAndMessages(null)
super.onDestroy()
}
@@ -112,47 +112,48 @@ class DlActivity : Activity() {
@SuppressLint("SetTextI18n")
fun setLayouts() {
ttitle.text = comicName
toolsBox = ToolsBox(WeakReference(this))
ttitle.apply { post { text = comicName } }
val widthData = toolsBox.calcWidthFromDp(8, 64)
btnNumPerRow = widthData[0]
btnw = widthData[1]
csdwn.viewTreeObserver.addOnGlobalLayoutListener(object :
csdwn.apply { post { viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
cdwnWidth = csdwn.width
csdwn.viewTreeObserver.removeOnGlobalLayoutListener(this)
viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
}) } }
dllazys.onScrollListener = object : LazyScrollView.OnScrollListener {
override fun onBottom() {}
override fun onScroll() { if (csdwn.translationX == 0f) hideDlCard() }
override fun onTop() {}
}
cdwn.setOnClickListener {
if (csdwn.translationX != 0f) showDlCard()
else if (checkedChapter == 0) hideDlCard()
else {
pdwn.progress = 0
if (canDl || checkedChapter == 0) canDl = false
cdwn.let { it.post {
it.setOnClickListener {
if (csdwn.translationX != 0f) showDlCard()
else if (checkedChapter == 0) hideDlCard()
else {
haveDlStarted = true
canDl = true
handler.sendEmptyMessage(9) //set dl card color to red
Toast.makeText(this, "请耐心等待加载...", Toast.LENGTH_SHORT).show()
Thread {
fillChapters()
dlThread { downloadChapterPages(it) }
}.start()
pdwn.progress = 0
if (canDl || checkedChapter == 0) canDl = false
else {
haveDlStarted = true
canDl = true
handler.sendEmptyMessage(9) //set dl card color to red
Toast.makeText(this@DlActivity, "请耐心等待加载...", Toast.LENGTH_SHORT).show()
Thread {
fillChapters()
dlThread { downloadChapterPages(it) }
}.start()
}
}
}
}
cdwn.setOnLongClickListener {
handler.sendEmptyMessage(4)
return@setOnLongClickListener true
}
isearch.setOnClickListener { showMultiSelectInfo() }
analyzeStructure()
it.setOnLongClickListener {
handler.sendEmptyMessage(4)
return@setOnLongClickListener true
}
} }
isearch.apply { post { setOnClickListener { showMultiSelectInfo() } } }
Thread{ analyzeStructure() }.start()
}
private fun showMultiSelectInfo() {
@@ -166,22 +167,24 @@ class DlActivity : Activity() {
for (group in it) {
val tc = layoutInflater.inflate(R.layout.line_caption, ldwn, false)
tc.tcptn.text = group.name
ldwn.addView(
tc,
ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
ldwn.apply { post {
addView(
tc,
ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
)
)
ldwn.addView(
layoutInflater.inflate(R.layout.div_h, ldwn, false),
ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
addView(
layoutInflater.inflate(R.layout.div_h, ldwn, false),
ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
)
)
} }
isNewTitle = true
for (chapter in group.chapters) addTbtn(chapter.name, chapter.url, group.name)
for (chapter in group.chapters) addToggleButton(chapter.name, chapter.url, group.name)
}
}
val mangaHome = File("${getExternalFilesDir("")}/$comicName")
@@ -222,14 +225,17 @@ class DlActivity : Activity() {
}
@SuppressLint("SetTextI18n")
fun addTbtn(title: String, url: String, caption: String) {
fun addToggleButton(title: String, url: String, caption: String) {
if ((tbtncnt % btnNumPerRow == 0) || isNewTitle) {
ltbtn = layoutInflater.inflate(R.layout.line_horizonal, ldwn, false)
ldwn.addView(ltbtn)
toggleButtonLine = layoutInflater.inflate(R.layout.line_horizonal, ldwn, false)
ldwn.apply {
val t = toggleButtonLine
post { addView(t) }
}
tbtncnt = 0
isNewTitle = false
}
val tbv = layoutInflater.inflate(R.layout.button_tbutton, ltbtn.ltbtn, false)
val tbv = layoutInflater.inflate(R.layout.button_tbutton, toggleButtonLine.ltbtn, false)
tbv.tbtn.index = tbtnlist.size
tbtnlist += tbv.tbtn
tbv.tbtn.url = url
@@ -241,28 +247,34 @@ class DlActivity : Activity() {
tbv.tbtn.text = title
tbv.tbtn.hint = caption
tbv.tbtn.layoutParams.width = btnw
val zipf = File("${getExternalFilesDir("")}/$comicName/$caption/$title.zip")
if (zipf.exists()) {
val zipFile = File("${getExternalFilesDir("")}/$comicName/$caption/$title.zip")
if (zipFile.exists()) {
tbv.tbtn.setBackgroundResource(R.drawable.rndbg_checked)
tbv.tbtn.isChecked = false
tbv.tbtn.freezesText = true
}
ltbtn.ltbtn.addView(tbv)
ltbtn.invalidate()
tbv.tbtn.setOnClickListener {
val normalAct = (multiSelect && zipf.exists()) || !zipf.exists()
if (zipf.exists() && !it.tbtn.isChecked) it.tbtn.setBackgroundResource(R.drawable.rndbg_checked)
else if(normalAct) it.tbtn.setBackgroundResource(R.drawable.toggle_button)
if(normalAct){
if (it.tbtn.isChecked) tdwn.text = "$dldChapter/${++checkedChapter}"
else tdwn.text = "$dldChapter/${--checkedChapter}"
}else if(it.tbtn.isChecked){
it.tbtn.isChecked = false
zipPosition?.let { callVM(title, zipf, it) }
toggleButtonLine.apply { post {
ltbtn.addView(tbv)
invalidate()
} }
tbv.tbtn.setOnClickListener { v ->
val normalAct = (multiSelect && zipFile.exists()) || !zipFile.exists()
if (zipFile.exists() && !v.tbtn.isChecked) v.tbtn.apply { post { setBackgroundResource(R.drawable.rndbg_checked) } }
else if(normalAct) v.tbtn.apply { post { setBackgroundResource(R.drawable.toggle_button) } }
if (normalAct) {
if (v.tbtn.isChecked) tdwn.apply { post { text = "$dldChapter/${++checkedChapter}" } }
else tdwn.apply { post { text = "$dldChapter/${--checkedChapter}" } }
} else if(v.tbtn.isChecked) {
v.tbtn.apply { post {
isChecked = false
zipPosition?.let { Thread {
callVM(title, zipFile, it)
}.start() }
} }
}
}
tbv.tbtn.setOnLongClickListener {
if (zipf.exists()) {
if (zipFile.exists()) {
toolsBox.buildInfo("确认删除这些章节?",
"该操作将不可撤销",
"确定",
@@ -270,8 +282,8 @@ class DlActivity : Activity() {
"取消",
{
if (checkedChapter == 0) {
it.tbtn.isChecked = true
tdwn.text = "$dldChapter/${++checkedChapter}"
it.tbtn.apply { post { isChecked = true } }
tdwn.apply { post { text = "$dldChapter/${++checkedChapter}" } }
}
handler.sendEmptyMessage(7)
})
@@ -293,24 +305,26 @@ class DlActivity : Activity() {
handler.sendEmptyMessage(6)
}
private fun callVM(titleText: String, zipFile: File, zipPosition:Int){
private fun callVM(titleText: String, zipFile: File, zipPosition:Int) {
ViewMangaActivity.titleText = titleText
ViewMangaActivity.zipFile = zipFile
//ViewMangaActivity.zipList = zipArrayList
ViewMangaActivity.zipPosition = zipPosition
ViewMangaActivity.cd = zipFile.parentFile
startActivity(Intent(this, ViewMangaActivity::class.java))
startActivity(Intent(this@DlActivity, ViewMangaActivity::class.java))
}
private fun deleteChapter(f: File, v: ToggleButton) {
f.delete()
v.setBackgroundResource(R.drawable.toggle_button)
v.isChecked = false
v.apply { post{
setBackgroundResource(R.drawable.toggle_button)
isChecked = false
} }
}
@SuppressLint("SetTextI18n")
fun updateProgressBar() {
tdwn.text = "${++dldChapter}/$checkedChapter"
tdwn.apply { post { text = "${++dldChapter}/$checkedChapter" } }
setProgress2(dldChapter * 100 / checkedChapter, 233)
}

View File

@@ -16,7 +16,7 @@ import java.io.File
import java.util.regex.Pattern
import java.util.zip.ZipInputStream
class DlListActivity:Activity() {
class DlListActivity: Activity() {
private var nullZipDirStr = emptyArray<String>()
private var handler: DlLHandler? = null
@@ -29,6 +29,12 @@ class DlListActivity:Activity() {
handler?.obtainMessage(3, currentDir)?.sendToTarget() //call scanFile
}
override fun onDestroy() {
super.onDestroy()
handler?.removeCallbacksAndMessages(null)
handler = null
}
fun scanFile(cd: File?){
val isRoot = cd == getExternalFilesDir("")
val jsonFile = File(cd, "info.bin")

View File

@@ -1,7 +1,7 @@
package top.fumiama.copymangaweb.activity
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.net.Uri
import android.os.Bundle
@@ -9,48 +9,59 @@ import android.os.Looper
import android.view.View
import android.webkit.ValueCallback
import android.webkit.WebView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.fab
import kotlinx.android.synthetic.main.activity_main.w
import kotlinx.android.synthetic.main.activity_main.wh
import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
import top.fumiama.copymangaweb.databinding.ActivityMainBinding
import top.fumiama.copymangaweb.handler.MainHandler
import top.fumiama.copymangaweb.tool.SetDraggable
import top.fumiama.copymangaweb.tool.ToolsBox
import top.fumiama.copymangaweb.web.JS
import top.fumiama.copymangaweb.web.JSHidden
import top.fumiama.copymangaweb.web.WebChromeClient
import java.lang.ref.WeakReference
class MainActivity: Activity() {
class MainActivity: ToolsBoxActivity() {
var uploadMessageAboveL: ValueCallback<Array<Uri>>? = null
private var toolsBox: ToolsBox? = null
var dialog: Dialog? = null
@SuppressLint("JavascriptInterface")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
dialog = Dialog(this)
dialog?.setContentView(R.layout.dialog_unzipping)
wm = WeakReference(this)
mh = MainHandler(Looper.myLooper()!!)
toolsBox = ToolsBox(wm as WeakReference<Any>)
toolsBox?.netinfo?.let {
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))
wh.settings.userAgentString = getString(R.string.pc_ua)
wh.webChromeClient = WebChromeClient()
wh.setWebViewClient("h.js")
wh.loadJSInterface(JSHidden())
mh?.sendEmptyMessage(MainHandler.SET_FAB_TO_DOWNLOAD_LIST)
return@let
}
WebView.setWebContentsDebuggingEnabled(true)
w.apply { post {
setWebViewClient("i.js")
webChromeClient = WebChromeClient()
loadJSInterface(JS())
loadUrl(getString(R.string.web_home))
} }
wh.apply { post {
settings.userAgentString = getString(R.string.pc_ua)
webChromeClient = WebChromeClient()
setWebViewClient("h.js")
loadJSInterface(JSHidden())
} }
}
SetDraggable().with(this).onto(fab)
}
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
if(w.canGoBack()) w.goBack()
else super.onBackPressed()
@@ -59,34 +70,27 @@ class MainActivity: Activity() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == FILE_CHOOSER_RESULT_CODE) { //处理返回的图片,并进行上传
if (uploadMessageAboveL == null) return
else {
if(resultCode == RESULT_OK) {
data?.apply {
if(uploadMessageAboveL != null) {
onActivityResultAboveL(requestCode, resultCode, this)
}
}
}
if (uploadMessageAboveL == null || resultCode != RESULT_OK) return
data?.let {
onActivityResultAboveL(requestCode, resultCode, it)
}
}
}
private fun onActivityResultAboveL(requestCode: Int, resultCode: Int, intent: Intent) {
if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null) return
else {
if (resultCode == RESULT_OK) {
intent.clipData?.apply {
var results = arrayOf<Uri>()
for(i in 0..itemCount) {
val item = getItemAt(i)
results += item.uri
}
intent.dataString?.apply {
uploadMessageAboveL?.onReceiveValue(results)
uploadMessageAboveL = null
}
}
if (requestCode != FILE_CHOOSER_RESULT_CODE ||
uploadMessageAboveL == null ||
resultCode != RESULT_OK
) return
intent.clipData?.let { clipData ->
var results = arrayOf<Uri>()
for (i in 0..clipData.itemCount) {
val item = clipData.getItemAt(i)
results += item.uri
}
if (intent.dataString != null) {
uploadMessageAboveL?.onReceiveValue(results)
uploadMessageAboveL = null
}
}
}
@@ -100,14 +104,17 @@ class MainActivity: Activity() {
}
fun openImageChooserActivity() {
//调用自己的图库
val i = Intent(Intent.ACTION_GET_CONTENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "image/*"
startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE)
// 调用自己的图库
startActivityForResult(
Intent.createChooser(
Intent(Intent.ACTION_GET_CONTENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.setType("image/*"), "Image Chooser"
), FILE_CHOOSER_RESULT_CODE
)
}
companion object{
companion object {
const val FILE_CHOOSER_RESULT_CODE = 1
var wm: WeakReference<MainActivity>? = null
var mh: MainHandler? = null

View File

@@ -2,10 +2,14 @@ package top.fumiama.copymangaweb.activity
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.*
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
@@ -16,16 +20,26 @@ import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_viewmanga.*
import kotlinx.android.synthetic.main.page_imgview.*
import kotlinx.android.synthetic.main.page_imgview.view.*
import kotlinx.android.synthetic.main.widget_infodrawer.*
import kotlinx.android.synthetic.main.widget_infodrawer.view.*
import kotlinx.android.synthetic.main.widget_titlebar.*
import kotlinx.android.synthetic.main.widget_viewmangainfo.*
import kotlinx.android.synthetic.main.activity_main.w
import kotlinx.android.synthetic.main.activity_viewmanga.infcard
import kotlinx.android.synthetic.main.activity_viewmanga.oneinfo
import kotlinx.android.synthetic.main.activity_viewmanga.vone
import kotlinx.android.synthetic.main.activity_viewmanga.vp
import kotlinx.android.synthetic.main.page_imgview.onei
import kotlinx.android.synthetic.main.page_imgview.view.onei
import kotlinx.android.synthetic.main.widget_infodrawer.idtblr
import kotlinx.android.synthetic.main.widget_infodrawer.idtbvh
import kotlinx.android.synthetic.main.widget_infodrawer.idtbvolturn
import kotlinx.android.synthetic.main.widget_infodrawer.idtbvp
import kotlinx.android.synthetic.main.widget_infodrawer.idtime
import kotlinx.android.synthetic.main.widget_infodrawer.view.idc
import kotlinx.android.synthetic.main.widget_titlebar.isearch
import kotlinx.android.synthetic.main.widget_titlebar.ttitle
import kotlinx.android.synthetic.main.widget_viewmangainfo.infseek
import kotlinx.android.synthetic.main.widget_viewmangainfo.inftxtprogress
import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
import top.fumiama.copymangaweb.databinding.ActivityViewmangaBinding
import top.fumiama.copymangaweb.handler.TimeThread
import top.fumiama.copymangaweb.tool.PropertiesTools
@@ -33,20 +47,20 @@ import top.fumiama.copymangaweb.tool.ToolsBox
import java.io.File
import java.lang.ref.WeakReference
import java.text.SimpleDateFormat
import java.util.*
import java.util.Date
import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
class ViewMangaActivity : Activity() {
class ViewMangaActivity : ToolsBoxActivity() {
lateinit var handler: Handler
lateinit var tt: TimeThread
lateinit var toolsBox: ToolsBox
var count = 0
var clicked = false
var r2l = true
var infoDrawerDelta = 0f
private var dialog: Dialog? = null
private lateinit var p: PropertiesTools
private var isInSeek = false
private var currentItem = 0
@@ -78,7 +92,6 @@ class ViewMangaActivity : Activity() {
super.onCreate(savedInstanceState)
val binding = ActivityViewmangaBinding.inflate(layoutInflater)
setContentView(binding.root)
toolsBox = ToolsBox(WeakReference(this))
va = WeakReference(this)
p = PropertiesTools(File("$filesDir/settings.properties"))
r2l = p["r2l"] == "true"
@@ -87,30 +100,39 @@ class ViewMangaActivity : Activity() {
tt = TimeThread(handler, 22)
tt.canDo = true
tt.start()
ttitle.text = titleText
dialog = Dialog(this)
dialog?.apply {
setContentView(R.layout.dialog_unzipping)
show()
}
ttitle.apply { post { text = titleText } }
Log.d("MyVM", "dlZip2View: $dlZip2View, mangaZip: $mangaZip")
if(dlZip2View && mangaZip?.exists() != true) toolsBox.toastError("已经到头了~")
else {
else Thread {
try {
count = if (dlZip2View) countZipItems() else imgUrls.size
} catch (e: Exception) {
e.printStackTrace()
toolsBox.toastError("分析图片url错误")
runOnUiThread { toolsBox.toastError("分析图片url错误") }
}
try {
prepareItems()
if(pn > 0) {
pageNum = pn
pn = -1
}else if(pn == -2){
pageNum = count
pn = -1
runOnUiThread {
try {
prepareItems()
if(pn > 0) {
pageNum = pn
pn = -1
}else if(pn == -2){
pageNum = count
pn = -1
}
} catch (e: Exception) {
e.printStackTrace()
toolsBox.toastError("准备控件错误")
} finally {
dialog?.hide()
}
} catch (e: Exception) {
e.printStackTrace()
toolsBox.toastError("准备控件错误")
}
}
}.start()
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
@@ -141,7 +163,7 @@ class ViewMangaActivity : Activity() {
}
private fun setPageNumber(num: Int) {
if (r2l && !notUseVP) vp.currentItem = count - num
if (r2l && !notUseVP) vp.apply { post { currentItem = count - num } }
else if (notUseVP) currentItem = num - 1 else vp.currentItem = num - 1
}
@@ -154,7 +176,7 @@ class ViewMangaActivity : Activity() {
}
private fun loadOneImg() {
if(dlZip2View) onei.setImageBitmap(getImgBitmap(currentItem))
if(dlZip2View) onei.apply { post { setImageBitmap(getImgBitmap(currentItem)) } }
else Glide.with(this@ViewMangaActivity)
.load(imgUrls[currentItem])
.placeholder(R.drawable.ic_dl)
@@ -165,7 +187,7 @@ class ViewMangaActivity : Activity() {
private fun setIdPosition(position: Int) {
infoDrawerDelta = position.toFloat()
infcard.translationY = infoDrawerDelta
infcard.apply { post { translationY = infoDrawerDelta } }
}
@SuppressLint("SetTextI18n")
@@ -180,95 +202,108 @@ class ViewMangaActivity : Activity() {
}
private fun prepareIdBtLR() {
idtblr.isChecked = r2l
idtblr.setOnClickListener {
if (idtblr.isChecked) p["r2l"] = "true"
else p["r2l"] = "false"
Toast.makeText(this, "下次浏览生效", Toast.LENGTH_SHORT).show()
}
idtblr.apply { post {
isChecked = r2l
setOnClickListener {
if (idtblr.isChecked) p["r2l"] = "true"
else p["r2l"] = "false"
Toast.makeText(this@ViewMangaActivity, "下次浏览生效", Toast.LENGTH_SHORT).show()
}
} }
}
private fun prepareIdBtVP() {
idtbvp.isChecked = notUseVP
idtbvp.setOnClickListener {
if (idtbvp.isChecked) p["noAnimation"] = "true"
else p["noAnimation"] = "false"
Toast.makeText(this, "下次浏览生效", Toast.LENGTH_SHORT).show()
}
idtbvp.apply { post {
isChecked = notUseVP
setOnClickListener {
if (idtbvp.isChecked) p["noAnimation"] = "true"
else p["noAnimation"] = "false"
Toast.makeText(this@ViewMangaActivity, "下次浏览生效", Toast.LENGTH_SHORT).show()
}
} }
}
private fun prepareVP() {
if (notUseVP) {
vp.visibility = View.INVISIBLE
vone.visibility = View.VISIBLE
vp.apply { post { visibility = View.INVISIBLE } }
vone.apply { post { visibility = View.VISIBLE } }
} else {
vp.visibility = View.VISIBLE
vone.visibility = View.INVISIBLE
vp.adapter = ViewData(vp).RecyclerViewAdapter()
vp.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
updateSeekBar()
super.onPageSelected(position)
}
})
if (r2l) vp.currentItem = count - 1
vp.apply { post {
visibility = View.VISIBLE
adapter = ViewData(this).RecyclerViewAdapter()
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
updateSeekBar()
super.onPageSelected(position)
}
})
if (r2l) currentItem = count - 1
} }
vone.apply { post { visibility = View.INVISIBLE } }
}
}
private fun updateSeekBar() {
if (!isInSeek) hideObjs()
if (!isInSeek) hideSettings()
updateSeekText()
updateSeekProgress()
}
@SuppressLint("SetTextI18n")
private fun prepareInfoBar(size: Int) {
oneinfo.alpha = 0F
infseek.visibility = View.INVISIBLE
isearch.visibility = View.INVISIBLE
inftxtprogress.text = "$pageNum/$size"
infseek.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, isHuman: Boolean) {
if (isHuman) {
if (p1 >= (pageNum + 1) * 100 / size) scrollForward()
else if (p1 < (pageNum - 1) * 100 / size) scrollBack()
oneinfo.apply { post { alpha = 0F } }
infseek.apply { post {
visibility = View.INVISIBLE
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, isHuman: Boolean) {
if (isHuman) {
if (p1 >= (pageNum + 1) * 100 / size) scrollForward()
else if (p1 < (pageNum - 1) * 100 / size) scrollBack()
}
}
}
override fun onStartTrackingTouch(p0: SeekBar?) {
isInSeek = true
}
override fun onStartTrackingTouch(p0: SeekBar?) {
isInSeek = true
}
override fun onStopTrackingTouch(p0: SeekBar?) {
isInSeek = false
override fun onStopTrackingTouch(p0: SeekBar?) {
isInSeek = false
}
})
} }
isearch.apply { post {
visibility = View.INVISIBLE
setOnClickListener {
handler.sendEmptyMessage(3)
}
})
isearch.setOnClickListener {
handler.sendEmptyMessage(3)
}
} }
inftxtprogress.apply { post { text = "$pageNum/$size" } }
}
private fun prepareIdBtVH() {
idtbvh.isChecked =
p["vertical"] == "true"
if (idtbvh.isChecked) vp.orientation = ViewPager2.ORIENTATION_VERTICAL
idtbvh.setOnClickListener {
if (idtbvh.isChecked) {
vp.orientation = ViewPager2.ORIENTATION_VERTICAL
p["vertical"] = "true"
} else {
vp.orientation = ViewPager2.ORIENTATION_HORIZONTAL
p["vertical"] = "false"
idtbvh.apply { post {
isChecked = p["vertical"] == "true"
setOnClickListener {
if (idtbvh.isChecked) {
vp.apply { post { orientation = ViewPager2.ORIENTATION_VERTICAL } }
p["vertical"] = "true"
} else {
vp.apply { post { orientation = ViewPager2.ORIENTATION_HORIZONTAL } }
p["vertical"] = "false"
}
}
}
} }
if (idtbvh.isChecked) vp.apply { post { orientation = ViewPager2.ORIENTATION_VERTICAL } }
}
private fun prepareIdBtVolTurn() {
idtbvolturn.isChecked = volTurnPage
idtbvolturn.setOnClickListener {
if (idtbvolturn.isChecked) p["volturn"] = "true"
else p["volturn"] = "false"
}
idtbvolturn.apply { post {
isChecked = volTurnPage
setOnClickListener {
if (idtbvolturn.isChecked) p["volturn"] = "true"
else p["volturn"] = "false"
}
} }
}
private fun countZipItems(): Int {
@@ -278,17 +313,12 @@ class ViewMangaActivity : Activity() {
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
ZipFile(mangaZip).use { zip ->
c = zip.size()
}
zip.closeEntry()
zip.close()
}
} catch (e: Exception) {
toolsBox.toastError("读取zip错误!")
runOnUiThread { toolsBox.toastError("读取zip错误!") }
}
return c
}
@@ -303,13 +333,14 @@ class ViewMangaActivity : Activity() {
@SuppressLint("SetTextI18n")
private fun updateSeekText() {
inftxtprogress.text = "$pageNum/$count"
inftxtprogress.apply { post { text = "$pageNum/$count" } }
}
private fun updateSeekProgress() {
infseek.progress = pageNum * 100 / count
infseek.apply { post { progress = pageNum * 100 / count } }
}
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
tt.canDo = false
wm?.get()?.w?.goBack()
@@ -318,6 +349,7 @@ class ViewMangaActivity : Activity() {
override fun onDestroy() {
tt.canDo = false
handler.removeCallbacksAndMessages(null)
super.onDestroy()
}
@@ -347,7 +379,7 @@ class ViewMangaActivity : Activity() {
}
}
fun showObjs() {
fun showSettings() {
infseek.visibility = View.VISIBLE
isearch.visibility = View.VISIBLE
ObjectAnimator.ofFloat(
@@ -359,7 +391,7 @@ class ViewMangaActivity : Activity() {
clicked = true
}
fun hideObjs() {
fun hideSettings() {
ObjectAnimator.ofFloat(
oneinfo,
"alpha",
@@ -375,10 +407,10 @@ class ViewMangaActivity : Activity() {
}
class MyHandler(
private val infcard: View,
private val infoCard: View,
private val toolsBox: ToolsBox
) : Handler(Looper.myLooper()!!) {
private var infcShowed = false
private var infoShown = false
private var delta = -1f
get() {
if (field < 0) field = va?.get()?.infoDrawerDelta ?: 0f
@@ -389,30 +421,30 @@ class ViewMangaActivity : Activity() {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when (msg.what) {
1 -> if (infcShowed) {
hideInfCard(); infcShowed = false
1 -> if (infoShown) {
hideInfCard(); infoShown = false
}
2 -> if (!infcShowed) {
showInfCard(); infcShowed = true
2 -> if (!infoShown) {
showInfCard(); infoShown = true
}
3 -> infcShowed = if (infcShowed) {
3 -> infoShown = if (infoShown) {
hideInfCard(); false
} else {
showInfCard(); true
}
22 -> toolsBox.zis?.idtime?.text =
SimpleDateFormat("HH:mm").format(Date()) + toolsBox.week + toolsBox.netinfo
SimpleDateFormat("HH:mm").format(Date()) + toolsBox.week + toolsBox.netInfo
}
}
private fun showInfCard() {
ObjectAnimator.ofFloat(infcard.idc, "alpha", 0.3F, 0.8F).setDuration(233).start()
ObjectAnimator.ofFloat(infcard, "translationY", delta, 0F).setDuration(233).start()
ObjectAnimator.ofFloat(infoCard.idc, "alpha", 0.3F, 0.8F).setDuration(233).start()
ObjectAnimator.ofFloat(infoCard, "translationY", delta, 0F).setDuration(233).start()
}
private fun hideInfCard() {
ObjectAnimator.ofFloat(infcard.idc, "alpha", 0.8F, 0.3F).setDuration(233).start()
ObjectAnimator.ofFloat(infcard, "translationY", 0F, delta).setDuration(233).start()
ObjectAnimator.ofFloat(infoCard.idc, "alpha", 0.8F, 0.3F).setDuration(233).start()
ObjectAnimator.ofFloat(infoCard, "translationY", 0F, delta).setDuration(233).start()
}
}

View File

@@ -0,0 +1,15 @@
package top.fumiama.copymangaweb.activity.template
import android.app.Activity
import android.os.Bundle
import top.fumiama.copymangaweb.tool.ToolsBox
import java.lang.ref.WeakReference
open class ToolsBoxActivity: Activity() {
lateinit var toolsBox: ToolsBox
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
toolsBox = ToolsBox(WeakReference(this))
}
}

View File

@@ -14,8 +14,7 @@ import java.lang.ref.WeakReference
class DlHandler(activity: DlActivity, looper: Looper) : Handler(looper) {
private val da = WeakReference(activity)
private val d
get() = da.get()
private val d get() = da.get()
private var size = 0
private var refreshSize = true

View File

@@ -7,6 +7,7 @@ import android.os.Looper
import android.os.Message
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.dialog_unzipping.*
import top.fumiama.copymangaweb.activity.DlActivity.Companion.json
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.activity.ViewMangaActivity
@@ -15,19 +16,23 @@ import top.fumiama.copymangaweb.tool.MangaDlTools.Companion.wmdlt
class MainHandler(looper: Looper):Handler(looper) {
var saveUrlsOnly = false
var showDlList = false
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when(msg.what){
1 -> loadUrlInHiddenWebView(msg.obj as String)
2 -> callViewManga(msg.obj as String)
3 -> updateLoadProgress(msg.arg1)
4 -> setFab(msg.obj as String)
5 -> hideFab()
6 -> setFab2DlList()
when(msg.what) {
LOAD_URL_IN_HIDDEN_WEB_VIEW -> loadUrlInHiddenWebView(msg.obj as String)
CALL_VIEW_MANGA -> callViewManga(msg.obj as String)
UPDATE_LOAD_PROGRESS -> updateLoadProgress(msg.arg1)
SET_FAB -> setFab(msg.obj as String)
HIDE_FAB -> hideFab()
SET_FAB_TO_DOWNLOAD_LIST -> setFab2DlList()
SHOW_LOADING_DIALOG -> wm?.get()?.dialog?.show()
HIDE_LOADING_DIALOG -> wm?.get()?.dialog?.hide()
SET_LOADING_DIALOG_TEXT -> wm?.get()?.dialog?.tunz?.text = msg.obj as String
}
}
private fun loadUrlInHiddenWebView(url: String){wm?.get()?.wh?.loadUrl(url)}
private fun callViewManga(content: String){
private fun loadUrlInHiddenWebView(url: String) { wm?.get()?.wh?.apply { post { loadUrl(url) } } }
private fun callViewManga(content: String) = Thread{
val listChapter = content.split('\n')
if(!saveUrlsOnly) {
ViewMangaActivity.titleText = listChapter[0].substringBeforeLast(' ')
@@ -35,26 +40,26 @@ class MainHandler(looper: Looper):Handler(looper) {
ViewMangaActivity.previousChapterUrl = listChapter[2].let { if(it == "null") null else it }
ViewMangaActivity.imgUrls = arrayOf()
for(i in 3 until listChapter.size) ViewMangaActivity.imgUrls += listChapter[i]
wm?.get()?.let { it.startActivity(Intent(it, ViewMangaActivity::class.java)) }
} else{
wm?.get()?.apply { runOnUiThread { startActivity(Intent(this, ViewMangaActivity::class.java)) } }
} else {
var imgs = arrayOf<String>()
for(i in 3 until listChapter.size) imgs += listChapter[i]
wmdlt?.get()?.setChapterImgs(listChapter[0].substringAfterLast(' '), imgs)
}
}
private fun updateLoadProgress(progress: Int){
wm?.get()?.let{
if(it.pw.progress == 100 && progress < 100) {
it.pw.progress = 0
it.pw.visibility = View.VISIBLE
}.start()
private fun updateLoadProgress(p: Int) {
wm?.get()?.pw?.apply { post {
if(progress == 100 && p < 100) {
progress = 0
visibility = View.VISIBLE
}
ObjectAnimator.ofInt(it.pw, "progress", it.pw.progress, progress).setDuration(233).start()
if(progress == 100) it.pw.postDelayed({it.pw.visibility = View.GONE}, 500)
}
ObjectAnimator.ofInt(this, "progress", progress, p).setDuration(233).start()
if(p == 100) postDelayed({ 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 showFab() { wm?.get()?.fab?.apply { post { visibility = View.VISIBLE } } }
private fun hideFab() { wm?.get()?.fab?.apply { post { visibility = View.GONE } } }
private fun setFab(content: String) {
//Log.d("MyMH", "Get chapter json: $content")
showDlList = false
json = content
@@ -64,4 +69,16 @@ class MainHandler(looper: Looper):Handler(looper) {
showDlList = true
showFab()
}
companion object {
const val LOAD_URL_IN_HIDDEN_WEB_VIEW = 1
const val CALL_VIEW_MANGA = 2
const val UPDATE_LOAD_PROGRESS = 3
const val SET_FAB = 4
const val HIDE_FAB = 5
const val SET_FAB_TO_DOWNLOAD_LIST = 6
const val SHOW_LOADING_DIALOG = 7
const val HIDE_LOADING_DIALOG = 8
const val SET_LOADING_DIALOG_TEXT = 9
}
}

View File

@@ -55,10 +55,10 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
).show()
}
}
} else v?.hideObjs()
} else v?.hideSettings()
}
fun manageInfo(){
if (v?.clicked == false) v.showObjs() else v?.hideObjs()
if (v?.clicked == false) v.showSettings() else v?.hideSettings()
}
private fun doubleTapToast(goNext: Boolean){
val hint = if(goNext) "" else ""

View File

@@ -1,5 +1,6 @@
package top.fumiama.copymangaweb.tool
import android.annotation.SuppressLint
import android.content.Context
import android.view.MotionEvent
import android.view.View
@@ -15,12 +16,13 @@ class SetDraggable {
return this
}
@SuppressLint("ClickableViewAccessibility")
fun onto(target: View) {
var lastX = 0
var lastY = 0
var firstX = 0
var firstY = 0
target.setOnTouchListener { v: View, event: MotionEvent ->
target.post { target.setOnTouchListener { v: View, event: MotionEvent ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
lastX = event.rawX.toInt()
@@ -56,7 +58,7 @@ class SetDraggable {
lastY = event.rawY.toInt()
}
}
abs(firstX - lastX) > 3 || abs(firstY - lastY) > 3 //移动微小则判断为点击
}
abs(firstX - lastX) > 3 || abs(firstY - lastY) > 3 // 移动微小则判断为点击
} }
}
}

View File

@@ -8,11 +8,11 @@ import android.net.NetworkCapabilities
import android.widget.Toast
import top.fumiama.copymangaweb.R
import java.lang.ref.WeakReference
import java.util.*
import java.util.Calendar
import kotlin.math.sqrt
class ToolsBox(w: WeakReference<Any>) {
val zis = (w as WeakReference<Activity>).get()
class ToolsBox(w: WeakReference<Activity>) {
val zis = w.get()
val week: String
get() {
val cal = Calendar.getInstance()
@@ -27,7 +27,7 @@ class ToolsBox(w: WeakReference<Any>) {
else -> ""
}
}
val netinfo: String
val netInfo: String
get() {
val cm: ConnectivityManager =
zis?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

View File

@@ -5,24 +5,25 @@ import android.webkit.JavascriptInterface
import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.handler.MainHandler
class JS {
@JavascriptInterface
fun loadComic(url: String){
fun loadComic(url: String) {
val u = when {
url.contains("/details/comic/") -> "${wm?.get()?.getString(R.string.web_comic_detail_pc)}${url.substringAfter("comic")}"
url.contains("/comicContent/") -> "${wm?.get()?.getString(R.string.web_comic_detail_pc)}/${url.substringAfter("comicContent/").substringBefore("/")}/chapter/${url.substringAfterLast("/")}"
else -> ""
}
Log.d("MyJS", "Load comic: $u")
Thread{mh?.obtainMessage(1, u)?.sendToTarget()}.start()
mh?.obtainMessage(MainHandler.LOAD_URL_IN_HIDDEN_WEB_VIEW, u)?.sendToTarget()
}
@JavascriptInterface
fun hideFab(){
Thread{mh?.sendEmptyMessage(5)}.start()
fun hideFab() {
mh?.sendEmptyMessage(MainHandler.HIDE_FAB)
}
@JavascriptInterface
fun enterProfile(){
Thread{mh?.sendEmptyMessage(6)}.start()
mh?.sendEmptyMessage(MainHandler.SET_FAB_TO_DOWNLOAD_LIST)
}
}

View File

@@ -4,11 +4,12 @@ import android.util.Log
import android.webkit.JavascriptInterface
import top.fumiama.copymangaweb.activity.DlActivity
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh
import top.fumiama.copymangaweb.handler.MainHandler
class JSHidden {
@JavascriptInterface
fun loadChapter(listString: String){
Thread{mh?.obtainMessage(2, listString)?.sendToTarget()}.start()
mh?.obtainMessage(MainHandler.CALL_VIEW_MANGA, listString)?.sendToTarget()
}
@JavascriptInterface
fun setTitle(title:String){
@@ -17,6 +18,14 @@ class JSHidden {
}
@JavascriptInterface
fun setFab(content: String){
Thread{mh?.obtainMessage(4, content)?.sendToTarget()}.start()
mh?.obtainMessage(MainHandler.SET_FAB, content)?.sendToTarget()
}
@JavascriptInterface
fun setLoadingDialog(display: Boolean) {
mh?.sendEmptyMessage(if (display) MainHandler.SHOW_LOADING_DIALOG else MainHandler.HIDE_LOADING_DIALOG)
}
@JavascriptInterface
fun setLoadingDialogProgress(index: String, count: String) {
mh?.obtainMessage(MainHandler.SET_LOADING_DIALOG_TEXT, "$index/$count")?.sendToTarget()
}
}

View File

@@ -5,12 +5,13 @@ import android.webkit.*
import android.webkit.WebChromeClient
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.handler.MainHandler
class WebChromeClient:WebChromeClient() {
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
//Log.d("MyWCC", "W progress: $newProgress")
Thread{mh?.obtainMessage(3, newProgress, 0)?.sendToTarget()}.start()
mh?.obtainMessage(MainHandler.UPDATE_LOAD_PROGRESS, newProgress, 0)?.sendToTarget()
}
override fun onJsAlert(

View File

@@ -34,9 +34,9 @@ class WebViewClient(private val context: Context, jsFileName: String):WebViewCli
}.start()
}
override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {
/*override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {
handler?.proceed() // ignore ssl errors
}
}*/
override fun shouldInterceptRequest(
view: WebView?,

View File

@@ -0,0 +1,27 @@
<?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:padding="16dp">
<ProgressBar
android:id="@+id/punz"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/tunz"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tunz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="准备中..."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/punz" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,5 +1,5 @@
<resources>
<string name="app_name">拷贝漫画</string>
<string name="app_name">拷贝Lite</string>
<string name="web_home">https://www.copy20.com</string>
<string name="web_home_www">https://www.copy20.com</string>
<string name="web_comic_detail_pc">https://www.copy20.com/comic</string>

View File

@@ -5,4 +5,4 @@ pluginManagement {
}
include ':app'
rootProject.name = "拷贝漫画"
rootProject.name = "拷贝Lite"