1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-26 05:42:31 +08:00
新增
1. 检测更新
修复
1. 漫画阅读页点击配置黑屏
优化
1. 隐藏搜索页 ranobe
升级
1. SDK 版本到 36
This commit is contained in:
源文雨
2025-07-06 00:17:55 +09:00
parent dbb0b9d2b3
commit 555d78a58f
36 changed files with 893 additions and 531 deletions

2
.idea/.name generated
View File

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

View File

@@ -2,7 +2,11 @@
<dictionary name="fumiama"> <dictionary name="fumiama">
<words> <words>
<w>copymanga</w> <w>copymanga</w>
<w>dere</w>
<w>lowpan</w> <w>lowpan</w>
<w>pdwn</w>
<w>reilia</w>
<w>tbtn</w>
<w>volturn</w> <w>volturn</w>
</words> </words>
</dictionary> </dictionary>

2
.idea/kotlinc.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="KotlinJpsPluginSettings"> <component name="KotlinJpsPluginSettings">
<option name="version" value="1.7.10" /> <option name="version" value="2.1.0" />
</component> </component>
</project> </project>

View File

@@ -1,19 +1,17 @@
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'kotlin-android' id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt' id 'kotlin-kapt'
} }
android { android {
defaultConfig { defaultConfig {
compileSdk 34 compileSdk 36
applicationId "top.fumiama.copymangaweb" applicationId "top.fumiama.copymangaweb"
minSdkVersion 23 minSdkVersion 23
//noinspection OldTargetApi targetSdkVersion 36
targetSdkVersion 34 versionCode 15
versionCode 14 versionName '1.5.2'
versionName '1.5.1'
resConfigs "zh", "zh-rCN" resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -67,6 +65,9 @@ android {
viewBinding { viewBinding {
enabled = true enabled = true
} }
dataBinding {
enable = true
}
bundle{ bundle{
density{ density{
enableSplit = true enableSplit = true
@@ -96,7 +97,9 @@ if (propFile.canRead()){
dependencies { dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.12.0' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
implementation 'androidx.core:core-ktx:1.16.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.9.1'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.viewpager2:viewpager2:1.1.0' implementation 'androidx.viewpager2:viewpager2:1.1.0'
@@ -106,4 +109,5 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.16.0' implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
implementation 'com.google.code.gson:gson:2.13.1' implementation 'com.google.code.gson:gson:2.13.1'
implementation 'top.fumiama:sdict:0.1.1'
} }

View File

@@ -2,6 +2,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@@ -9,6 +10,15 @@
android:roundIcon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" > android:theme="@style/AppTheme" >
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="top.fumiama.copymangaweb.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<activity android:name=".activity.MainActivity" android:exported="true"> <activity android:name=".activity.MainActivity" android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@@ -49,6 +49,9 @@ if (typeof (loaded) == "undefined") {
invoke.hideRanobeTab(); invoke.hideRanobeTab();
invoke.hideRanobeRack(); invoke.hideRanobeRack();
} }
else if (url.indexOf("/searchContent") > 0) {
invoke.hideRanobeRack();
}
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) { else if (url.indexOf("/personal") > 0) {

View File

@@ -8,15 +8,11 @@ import android.os.Looper
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import android.widget.ToggleButton import android.widget.ToggleButton
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_dl.*
import kotlinx.android.synthetic.main.button_tbutton.view.*
import kotlinx.android.synthetic.main.line_caption.view.*
import kotlinx.android.synthetic.main.line_horizonal.view.*
import kotlinx.android.synthetic.main.widget_downloadbar.*
import kotlinx.android.synthetic.main.widget_titlebar.*
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh import top.fumiama.copymangaweb.activity.MainActivity.Companion.mh
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
@@ -33,6 +29,7 @@ import java.io.File
import java.lang.Thread.sleep import java.lang.Thread.sleep
class DlActivity : ToolsBoxActivity() { class DlActivity : ToolsBoxActivity() {
lateinit var mBinding: ActivityDlBinding
private var tbtncnt = 0 private var tbtncnt = 0
private var isNewTitle = false private var isNewTitle = false
var haveSElectAll = false var haveSElectAll = false
@@ -52,11 +49,11 @@ class DlActivity : ToolsBoxActivity() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val binding = ActivityDlBinding.inflate(layoutInflater) mBinding = ActivityDlBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(mBinding.root)
mh?.saveUrlsOnly = true mh?.saveUrlsOnly = true
mangaDlTools = MangaDlTools(this) mangaDlTools = MangaDlTools(this)
dwh.apply { post { mBinding.dwh.apply { post {
settings.userAgentString = getString(R.string.pc_ua) settings.userAgentString = getString(R.string.pc_ua)
webChromeClient = WebChromeClient() webChromeClient = WebChromeClient()
setWebViewClient("h.js") setWebViewClient("h.js")
@@ -72,16 +69,24 @@ class DlActivity : ToolsBoxActivity() {
super.onDestroy() super.onDestroy()
} }
private fun showDlCard(){ private fun showDlCard() {
//ObjectAnimator.ofFloat(csdwn, "alpha", 0.3f, 0.9f).setDuration(233).start() ObjectAnimator.ofFloat(
ObjectAnimator.ofFloat(csdwn, "translationX", cdwnWidth.toFloat() * 0.9f, 0f).setDuration( mBinding.dldlbar.csdwn,
"translationX",
cdwnWidth.toFloat() * 0.9f,
0f
).setDuration(
233 233
).start() ).start()
} }
private fun hideDlCard(){ private fun hideDlCard() {
//ObjectAnimator.ofFloat(csdwn, "alpha", 0.9f, 0.3f).setDuration(233).start() ObjectAnimator.ofFloat(
ObjectAnimator.ofFloat(csdwn, "translationX", 0f, cdwnWidth.toFloat() * 0.9f).setDuration( mBinding.dldlbar.csdwn,
"translationX",
0f,
cdwnWidth.toFloat() * 0.9f
).setDuration(
233 233
).start() ).start()
} }
@@ -112,28 +117,28 @@ class DlActivity : ToolsBoxActivity() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun setLayouts() { fun setLayouts() {
ttitle.apply { post { text = comicName } } mBinding.dtitle.ttitle.apply { post { text = comicName } }
val widthData = toolsBox.calcWidthFromDp(8, 64) val widthData = toolsBox.calcWidthFromDp(8, 64)
btnNumPerRow = widthData[0] btnNumPerRow = widthData[0]
btnw = widthData[1] btnw = widthData[1]
csdwn.apply { post { viewTreeObserver.addOnGlobalLayoutListener(object : mBinding.dldlbar.csdwn.apply { post { viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener { ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() { override fun onGlobalLayout() {
cdwnWidth = csdwn.width cdwnWidth = width
viewTreeObserver.removeOnGlobalLayoutListener(this) viewTreeObserver.removeOnGlobalLayoutListener(this)
} }
}) } } }) } }
dllazys.onScrollListener = object : LazyScrollView.OnScrollListener { mBinding.dllazys.onScrollListener = object : LazyScrollView.OnScrollListener {
override fun onBottom() {} override fun onBottom() {}
override fun onScroll() { if (csdwn.translationX == 0f) hideDlCard() } override fun onScroll() { if (mBinding.dldlbar.csdwn.translationX == 0f) hideDlCard() }
override fun onTop() {} override fun onTop() {}
} }
cdwn.let { it.post { mBinding.dldlbar.cdwn.let { it.post {
it.setOnClickListener { it.setOnClickListener {
if (csdwn.translationX != 0f) showDlCard() if (mBinding.dldlbar.csdwn.translationX != 0f) showDlCard()
else if (checkedChapter == 0) hideDlCard() else if (checkedChapter == 0) hideDlCard()
else { else {
pdwn.progress = 0 mBinding.dldlbar.pdwn.progress = 0
if (canDl || checkedChapter == 0) canDl = false if (canDl || checkedChapter == 0) canDl = false
else { else {
haveDlStarted = true haveDlStarted = true
@@ -152,7 +157,9 @@ class DlActivity : ToolsBoxActivity() {
return@setOnLongClickListener true return@setOnLongClickListener true
} }
} } } }
isearch.apply { post { setOnClickListener { showMultiSelectInfo() } } } mBinding.dtitle.isearch.apply { post {
setOnClickListener { showMultiSelectInfo() }
} }
Thread{ analyzeStructure() }.start() Thread{ analyzeStructure() }.start()
} }
@@ -165,9 +172,9 @@ class DlActivity : ToolsBoxActivity() {
ViewMangaActivity.zipList = arrayOf() ViewMangaActivity.zipList = arrayOf()
Gson().fromJson(json?.reader(), Array<ComicStructure>::class.java)?.let { Gson().fromJson(json?.reader(), Array<ComicStructure>::class.java)?.let {
for (group in it) { for (group in it) {
val tc = layoutInflater.inflate(R.layout.line_caption, ldwn, false) val tc = layoutInflater.inflate(R.layout.line_caption, mBinding.ldwn, false)
tc.tcptn.text = group.name tc.findViewById<TextView>(R.id.tcptn).text = group.name
ldwn.apply { post { mBinding.ldwn.apply { post {
addView( addView(
tc, tc,
ViewGroup.LayoutParams( ViewGroup.LayoutParams(
@@ -176,7 +183,7 @@ class DlActivity : ToolsBoxActivity() {
) )
) )
addView( addView(
layoutInflater.inflate(R.layout.div_h, ldwn, false), layoutInflater.inflate(R.layout.div_h, mBinding.ldwn, false),
ViewGroup.LayoutParams( ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT ViewGroup.LayoutParams.WRAP_CONTENT
@@ -227,45 +234,52 @@ class DlActivity : ToolsBoxActivity() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun addToggleButton(title: String, url: String, caption: String) { fun addToggleButton(title: String, url: String, caption: String) {
if ((tbtncnt % btnNumPerRow == 0) || isNewTitle) { if ((tbtncnt % btnNumPerRow == 0) || isNewTitle) {
toggleButtonLine = layoutInflater.inflate(R.layout.line_horizonal, ldwn, false) toggleButtonLine = layoutInflater.inflate(R.layout.line_horizonal, mBinding.ldwn, false)
ldwn.apply { mBinding.ldwn.apply {
val t = toggleButtonLine val t = toggleButtonLine
post { addView(t) } post { addView(t) }
} }
tbtncnt = 0 tbtncnt = 0
isNewTitle = false isNewTitle = false
} }
val tbv = layoutInflater.inflate(R.layout.button_tbutton, toggleButtonLine.ltbtn, false) val tbv = layoutInflater.inflate(R.layout.button_tbutton, toggleButtonLine.findViewById(R.id.ltbtn), false)
tbv.tbtn.index = tbtnlist.size val tbvTbtn = tbv.findViewById<ChapterToggleButton>(R.id.tbtn)?:return
tbtnlist += tbv.tbtn tbvTbtn.index = tbtnlist.size
tbv.tbtn.url = url tbtnlist += tbvTbtn
tbvTbtn.url = url
tbtncnt++ tbtncnt++
val zipPosition = ViewMangaActivity.zipList?.size val zipPosition = ViewMangaActivity.zipList?.size
ViewMangaActivity.zipList = ViewMangaActivity.zipList?.plus("$title.zip") ViewMangaActivity.zipList = ViewMangaActivity.zipList?.plus("$title.zip")
tbv.tbtn.textOff = title tbvTbtn.textOff = title
tbv.tbtn.textOn = title tbvTbtn.textOn = title
tbv.tbtn.text = title tbvTbtn.text = title
tbv.tbtn.hint = caption tbvTbtn.hint = caption
tbv.tbtn.layoutParams.width = btnw tbvTbtn.layoutParams.width = btnw
val zipFile = File("${getExternalFilesDir("")}/$comicName/$caption/$title.zip") val zipFile = File("${getExternalFilesDir("")}/$comicName/$caption/$title.zip")
if (zipFile.exists()) { if (zipFile.exists()) {
tbv.tbtn.setBackgroundResource(R.drawable.rndbg_checked) tbvTbtn.setBackgroundResource(R.drawable.rndbg_checked)
tbv.tbtn.isChecked = false tbvTbtn.isChecked = false
tbv.tbtn.freezesText = true tbvTbtn.freezesText = true
} }
toggleButtonLine.apply { post { toggleButtonLine.apply { post {
ltbtn.addView(tbv) findViewById<LinearLayout>(R.id.ltbtn)?.addView(tbv)
invalidate() invalidate()
} } } }
tbv.tbtn.setOnClickListener { v -> tbvTbtn.setOnClickListener { v ->
val normalAct = (multiSelect && zipFile.exists()) || !zipFile.exists() val normalAct = (multiSelect && zipFile.exists()) || !zipFile.exists()
if (zipFile.exists() && !v.tbtn.isChecked) v.tbtn.apply { post { setBackgroundResource(R.drawable.rndbg_checked) } } val tbtn = v.findViewById<ChapterToggleButton>(R.id.tbtn)?:return@setOnClickListener
else if(normalAct) v.tbtn.apply { post { setBackgroundResource(R.drawable.toggle_button) } } if (zipFile.exists() && !tbtn.isChecked) tbtn.apply { post { setBackgroundResource(R.drawable.rndbg_checked) } }
else if(normalAct) tbtn.apply { post { setBackgroundResource(R.drawable.toggle_button) } }
if (normalAct) { if (normalAct) {
if (v.tbtn.isChecked) tdwn.apply { post { text = "$dldChapter/${++checkedChapter}" } } mBinding.dldlbar.tdwn.apply {
else tdwn.apply { post { text = "$dldChapter/${--checkedChapter}" } } if (tbtn.isChecked) post {
} else if(v.tbtn.isChecked) { text = "$dldChapter/${++checkedChapter}"
v.tbtn.apply { post { } else post {
text = "$dldChapter/${--checkedChapter}"
}
}
} else if(tbtn.isChecked) {
tbtn.apply { post {
isChecked = false isChecked = false
zipPosition?.let { Thread { zipPosition?.let { Thread {
callVM(title, zipFile, it) callVM(title, zipFile, it)
@@ -273,7 +287,7 @@ class DlActivity : ToolsBoxActivity() {
} } } }
} }
} }
tbv.tbtn.setOnLongClickListener { tbvTbtn.setOnLongClickListener {
if (zipFile.exists()) { if (zipFile.exists()) {
toolsBox.buildInfo("确认删除这些章节?", toolsBox.buildInfo("确认删除这些章节?",
"该操作将不可撤销", "该操作将不可撤销",
@@ -282,8 +296,10 @@ class DlActivity : ToolsBoxActivity() {
"取消", "取消",
{ {
if (checkedChapter == 0) { if (checkedChapter == 0) {
it.tbtn.apply { post { isChecked = true } } tbvTbtn.apply { post { isChecked = true } }
tdwn.apply { post { text = "$dldChapter/${++checkedChapter}" } } mBinding.dldlbar.tdwn.apply { post {
text = "$dldChapter/${++checkedChapter}"
} }
} }
handler.sendEmptyMessage(7) handler.sendEmptyMessage(7)
}) })
@@ -324,7 +340,9 @@ class DlActivity : ToolsBoxActivity() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun updateProgressBar() { fun updateProgressBar() {
tdwn.apply { post { text = "${++dldChapter}/$checkedChapter" } } mBinding.dldlbar.tdwn.apply { post {
text = "${++dldChapter}/$checkedChapter"
} }
setProgress2(dldChapter * 100 / checkedChapter, 233) setProgress2(dldChapter * 100 / checkedChapter, 233)
} }
@@ -336,6 +354,7 @@ class DlActivity : ToolsBoxActivity() {
} }
fun setProgress2(end: Int, duration: Long) { fun setProgress2(end: Int, duration: Long) {
val pdwn = mBinding.dldlbar.pdwn
ObjectAnimator.ofInt( ObjectAnimator.ofInt(
pdwn, pdwn,
"progress", "progress",

View File

@@ -7,8 +7,6 @@ import android.os.Bundle
import android.os.Looper import android.os.Looper
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_dlist.*
import kotlinx.android.synthetic.main.widget_titlebar.*
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.databinding.ActivityDlistBinding import top.fumiama.copymangaweb.databinding.ActivityDlistBinding
import top.fumiama.copymangaweb.handler.DlLHandler import top.fumiama.copymangaweb.handler.DlLHandler
@@ -17,14 +15,15 @@ import java.util.regex.Pattern
import java.util.zip.ZipInputStream import java.util.zip.ZipInputStream
class DlListActivity: Activity() { class DlListActivity: Activity() {
private lateinit var mBinding: ActivityDlistBinding
private var nullZipDirStr = emptyArray<String>() private var nullZipDirStr = emptyArray<String>()
private var handler: DlLHandler? = null private var handler: DlLHandler? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val binding = ActivityDlistBinding.inflate(layoutInflater) mBinding = ActivityDlistBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(mBinding.root)
ttitle.text = intent.getStringExtra("title") mBinding.myt.ttitle.text = intent.getStringExtra("title")
handler = DlLHandler(Looper.myLooper()!!, this) handler = DlLHandler(Looper.myLooper()!!, this)
handler?.obtainMessage(3, currentDir)?.sendToTarget() //call scanFile handler?.obtainMessage(3, currentDir)?.sendToTarget() //call scanFile
} }
@@ -42,8 +41,8 @@ class DlListActivity: Activity() {
if(o1.endsWith(".zip") && o2.endsWith(".zip")) (10000*getFloat(o1) - 10000*getFloat(o2) + 0.5).toInt() if(o1.endsWith(".zip") && o2.endsWith(".zip")) (10000*getFloat(o1) - 10000*getFloat(o2) + 0.5).toInt()
else o1[0] - o2[0] else o1[0] - o2[0]
}?.let { }?.let {
mylv.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, it) mBinding.mylv.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, it)
mylv.setOnItemClickListener { _, _, position, _ -> mBinding.mylv.setOnItemClickListener { _, _, position, _ ->
val chosenFile = File(cd, it[position]) val chosenFile = File(cd, it[position])
val chosenJson = File(chosenFile, "info.bin") val chosenJson = File(chosenFile, "info.bin")
//Toast.makeText(this, "进入$chosenFile", Toast.LENGTH_SHORT).show() //Toast.makeText(this, "进入$chosenFile", Toast.LENGTH_SHORT).show()
@@ -69,7 +68,7 @@ class DlListActivity: Activity() {
} }
} }
} }
mylv.setOnItemLongClickListener { _, _, position, _ -> mBinding.mylv.setOnItemLongClickListener { _, _, position, _ ->
val chosenFile = File(cd, it[position]) val chosenFile = File(cd, it[position])
AlertDialog.Builder(this) AlertDialog.Builder(this)
.setIcon(R.drawable.ic_launcher_foreground).setMessage("在此执行删除/查错?") .setIcon(R.drawable.ic_launcher_foreground).setMessage("在此执行删除/查错?")

View File

@@ -1,7 +1,6 @@
package top.fumiama.copymangaweb.activity package top.fumiama.copymangaweb.activity
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
@@ -9,14 +8,17 @@ import android.os.Looper
import android.view.View import android.view.View
import android.webkit.ValueCallback import android.webkit.ValueCallback
import android.webkit.WebView import android.webkit.WebView
import kotlinx.android.synthetic.main.activity_main.fab import androidx.lifecycle.lifecycleScope
import kotlinx.android.synthetic.main.activity_main.w import kotlinx.coroutines.Dispatchers
import kotlinx.android.synthetic.main.activity_main.wh import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymangaweb.BuildConfig
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
import top.fumiama.copymangaweb.databinding.ActivityMainBinding import top.fumiama.copymangaweb.databinding.ActivityMainBinding
import top.fumiama.copymangaweb.handler.MainHandler import top.fumiama.copymangaweb.handler.MainHandler
import top.fumiama.copymangaweb.tool.SetDraggable import top.fumiama.copymangaweb.tool.SetDraggable
import top.fumiama.copymangaweb.tool.Updater
import top.fumiama.copymangaweb.web.JS import top.fumiama.copymangaweb.web.JS
import top.fumiama.copymangaweb.web.JSHidden import top.fumiama.copymangaweb.web.JSHidden
import top.fumiama.copymangaweb.web.WebChromeClient import top.fumiama.copymangaweb.web.WebChromeClient
@@ -24,16 +26,13 @@ import java.lang.ref.WeakReference
class MainActivity: ToolsBoxActivity() { class MainActivity: ToolsBoxActivity() {
var uploadMessageAboveL: ValueCallback<Array<Uri>>? = null var uploadMessageAboveL: ValueCallback<Array<Uri>>? = null
var dialog: Dialog? = null lateinit var mBinding: ActivityMainBinding
@SuppressLint("JavascriptInterface") @SuppressLint("JavascriptInterface")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater) mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(mBinding.root)
dialog = Dialog(this)
dialog?.setContentView(R.layout.dialog_unzipping)
wm = WeakReference(this) wm = WeakReference(this)
mh = MainHandler(Looper.myLooper()!!) mh = MainHandler(Looper.myLooper()!!)
@@ -43,27 +42,33 @@ class MainActivity: ToolsBoxActivity() {
return@let return@let
} }
lifecycleScope.launch {
withContext(Dispatchers.IO) {
goCheckUpdate(false)
}
}
WebView.setWebContentsDebuggingEnabled(true) WebView.setWebContentsDebuggingEnabled(true)
w.apply { post { mBinding.w.apply { post {
setWebViewClient("i.js") setWebViewClient("i.js")
webChromeClient = WebChromeClient() webChromeClient = WebChromeClient()
loadJSInterface(JS()) loadJSInterface(JS())
loadUrl(getString(R.string.web_home)) loadUrl(getString(R.string.web_home))
} } } }
wh.apply { post { mBinding.wh.apply { post {
settings.userAgentString = getString(R.string.pc_ua) settings.userAgentString = getString(R.string.pc_ua)
webChromeClient = WebChromeClient() webChromeClient = WebChromeClient()
setWebViewClient("h.js") setWebViewClient("h.js")
loadJSInterface(JSHidden()) loadJSInterface(JSHidden())
} } } }
} }
SetDraggable().with(this).onto(fab) SetDraggable().with(this).onto(mBinding.fab)
} }
@Deprecated("Deprecated in Java") @Deprecated("Deprecated in Java")
override fun onBackPressed() { override fun onBackPressed() {
if(w.canGoBack()) w.goBack() if(mBinding.w.canGoBack()) mBinding.w.goBack()
else super.onBackPressed() else super.onBackPressed()
} }
@@ -95,6 +100,15 @@ class MainActivity: ToolsBoxActivity() {
} }
} }
private suspend fun goCheckUpdate(ignoreSkip: Boolean) {
Updater(
WeakReference(this),
toolsBox,
ignoreSkip,
getPreferences(MODE_PRIVATE).getInt("skipVersion", 0)
).check(BuildConfig.VERSION_CODE)
}
fun onFabClicked(v: View){ fun onFabClicked(v: View){
DlListActivity.currentDir = getExternalFilesDir("") DlListActivity.currentDir = getExternalFilesDir("")
startActivity( startActivity(

View File

@@ -20,23 +20,6 @@ import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
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.R
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
@@ -44,6 +27,7 @@ import top.fumiama.copymangaweb.databinding.ActivityViewmangaBinding
import top.fumiama.copymangaweb.handler.TimeThread import top.fumiama.copymangaweb.handler.TimeThread
import top.fumiama.copymangaweb.tool.PropertiesTools import top.fumiama.copymangaweb.tool.PropertiesTools
import top.fumiama.copymangaweb.tool.ToolsBox import top.fumiama.copymangaweb.tool.ToolsBox
import top.fumiama.copymangaweb.view.ScaleImageView
import java.io.File import java.io.File
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@@ -54,6 +38,7 @@ import java.util.zip.ZipInputStream
class ViewMangaActivity : ToolsBoxActivity() { class ViewMangaActivity : ToolsBoxActivity() {
lateinit var handler: Handler lateinit var handler: Handler
lateinit var tt: TimeThread lateinit var tt: TimeThread
lateinit var mBinding: ActivityViewmangaBinding
var count = 0 var count = 0
var clicked = false var clicked = false
@@ -90,13 +75,13 @@ class ViewMangaActivity : ToolsBoxActivity() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val binding = ActivityViewmangaBinding.inflate(layoutInflater) mBinding = ActivityViewmangaBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(mBinding.root)
va = WeakReference(this) va = WeakReference(this)
p = PropertiesTools(File("$filesDir/settings.properties")) p = PropertiesTools(File("$filesDir/settings.properties"))
r2l = p["r2l"] == "true" r2l = p["r2l"] == "true"
notUseVP = p["noAnimation"] == "true" notUseVP = p["noAnimation"] == "true"
handler = MyHandler(infcard, toolsBox) handler = MyHandler(toolsBox)
tt = TimeThread(handler, 22) tt = TimeThread(handler, 22)
tt.canDo = true tt.canDo = true
tt.start() tt.start()
@@ -105,7 +90,7 @@ class ViewMangaActivity : ToolsBoxActivity() {
setContentView(R.layout.dialog_unzipping) setContentView(R.layout.dialog_unzipping)
show() show()
} }
ttitle.apply { post { text = titleText } } mBinding.oneinfo.inftitle.ttitle.apply { post { text = titleText } }
Log.d("MyVM", "dlZip2View: $dlZip2View, mangaZip: $mangaZip") Log.d("MyVM", "dlZip2View: $dlZip2View, mangaZip: $mangaZip")
if(dlZip2View && mangaZip?.exists() != true) toolsBox.toastError("已经到头了~") if(dlZip2View && mangaZip?.exists() != true) toolsBox.toastError("已经到头了~")
else Thread { else Thread {
@@ -121,7 +106,7 @@ class ViewMangaActivity : ToolsBoxActivity() {
if(pn > 0) { if(pn > 0) {
pageNum = pn pageNum = pn
pn = -1 pn = -1
}else if(pn == -2){ } else if(pn == -2){
pageNum = count pageNum = count
pn = -1 pn = -1
} }
@@ -129,7 +114,8 @@ class ViewMangaActivity : ToolsBoxActivity() {
e.printStackTrace() e.printStackTrace()
toolsBox.toastError("准备控件错误") toolsBox.toastError("准备控件错误")
} finally { } finally {
dialog?.hide() dialog?.dismiss()
dialog = null
} }
} }
}.start() }.start()
@@ -158,13 +144,13 @@ class ViewMangaActivity : ToolsBoxActivity() {
} }
private fun getPageNumber(): Int { private fun getPageNumber(): Int {
return if (r2l && !notUseVP) count - vp.currentItem return if (r2l && !notUseVP) count - mBinding.vp.currentItem
else (if (notUseVP) currentItem else vp.currentItem) + 1 else (if (notUseVP) currentItem else mBinding.vp.currentItem) + 1
} }
private fun setPageNumber(num: Int) { private fun setPageNumber(num: Int) {
if (r2l && !notUseVP) vp.apply { post { currentItem = count - num } } if (r2l && !notUseVP) mBinding.vp.apply { post { currentItem = count - num } }
else if (notUseVP) currentItem = num - 1 else vp.currentItem = num - 1 else if (notUseVP) currentItem = num - 1 else mBinding.vp.currentItem = num - 1
} }
private fun getImgBitmap(position: Int): Bitmap? { private fun getImgBitmap(position: Int): Bitmap? {
@@ -176,18 +162,18 @@ class ViewMangaActivity : ToolsBoxActivity() {
} }
private fun loadOneImg() { private fun loadOneImg() {
if(dlZip2View) onei.apply { post { setImageBitmap(getImgBitmap(currentItem)) } } if(dlZip2View) mBinding.vone.onei.apply { post { setImageBitmap(getImgBitmap(currentItem)) } }
else Glide.with(this@ViewMangaActivity) else Glide.with(this@ViewMangaActivity)
.load(imgUrls[currentItem]) .load(toolsBox.resolution.wrap(imgUrls[currentItem]))
.placeholder(R.drawable.ic_dl) .placeholder(R.drawable.ic_dl)
.dontAnimate() .dontAnimate()
.into(onei) .into(mBinding.vone.onei)
updateSeekBar() updateSeekBar()
} }
private fun setIdPosition(position: Int) { private fun setIdPosition(position: Int) {
infoDrawerDelta = position.toFloat() infoDrawerDelta = position.toFloat()
infcard.apply { post { translationY = infoDrawerDelta } } mBinding.infcard.root.apply { post { translationY = infoDrawerDelta } }
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@@ -202,10 +188,10 @@ class ViewMangaActivity : ToolsBoxActivity() {
} }
private fun prepareIdBtLR() { private fun prepareIdBtLR() {
idtblr.apply { post { mBinding.infcard.idtblr.apply { post {
isChecked = r2l isChecked = r2l
setOnClickListener { setOnClickListener {
if (idtblr.isChecked) p["r2l"] = "true" if (mBinding.infcard.idtblr.isChecked) p["r2l"] = "true"
else p["r2l"] = "false" else p["r2l"] = "false"
Toast.makeText(this@ViewMangaActivity, "下次浏览生效", Toast.LENGTH_SHORT).show() Toast.makeText(this@ViewMangaActivity, "下次浏览生效", Toast.LENGTH_SHORT).show()
} }
@@ -213,10 +199,10 @@ class ViewMangaActivity : ToolsBoxActivity() {
} }
private fun prepareIdBtVP() { private fun prepareIdBtVP() {
idtbvp.apply { post { mBinding.infcard.idtbvp.apply { post {
isChecked = notUseVP isChecked = notUseVP
setOnClickListener { setOnClickListener {
if (idtbvp.isChecked) p["noAnimation"] = "true" if (mBinding.infcard.idtbvp.isChecked) p["noAnimation"] = "true"
else p["noAnimation"] = "false" else p["noAnimation"] = "false"
Toast.makeText(this@ViewMangaActivity, "下次浏览生效", Toast.LENGTH_SHORT).show() Toast.makeText(this@ViewMangaActivity, "下次浏览生效", Toast.LENGTH_SHORT).show()
} }
@@ -225,10 +211,10 @@ class ViewMangaActivity : ToolsBoxActivity() {
private fun prepareVP() { private fun prepareVP() {
if (notUseVP) { if (notUseVP) {
vp.apply { post { visibility = View.INVISIBLE } } mBinding.vp.apply { post { visibility = View.INVISIBLE } }
vone.apply { post { visibility = View.VISIBLE } } mBinding.vone.root.apply { post { visibility = View.VISIBLE } }
} else { } else {
vp.apply { post { mBinding.vp.apply { post {
visibility = View.VISIBLE visibility = View.VISIBLE
adapter = ViewData(this).RecyclerViewAdapter() adapter = ViewData(this).RecyclerViewAdapter()
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
@@ -239,7 +225,7 @@ class ViewMangaActivity : ToolsBoxActivity() {
}) })
if (r2l) currentItem = count - 1 if (r2l) currentItem = count - 1
} } } }
vone.apply { post { visibility = View.INVISIBLE } } mBinding.vone.root.apply { post { visibility = View.INVISIBLE } }
} }
} }
@@ -251,8 +237,8 @@ class ViewMangaActivity : ToolsBoxActivity() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun prepareInfoBar(size: Int) { private fun prepareInfoBar(size: Int) {
oneinfo.apply { post { alpha = 0F } } mBinding.oneinfo.root.apply { post { alpha = 0F } }
infseek.apply { post { mBinding.oneinfo.infseek.apply { post {
visibility = View.INVISIBLE visibility = View.INVISIBLE
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, isHuman: Boolean) { override fun onProgressChanged(p0: SeekBar?, p1: Int, isHuman: Boolean) {
@@ -271,36 +257,38 @@ class ViewMangaActivity : ToolsBoxActivity() {
} }
}) })
} } } }
isearch.apply { post { mBinding.oneinfo.inftitle.isearch.apply { post {
visibility = View.INVISIBLE visibility = View.INVISIBLE
setOnClickListener { setOnClickListener {
handler.sendEmptyMessage(3) this@ViewMangaActivity.handler.sendEmptyMessage(3)
} }
} } } }
inftxtprogress.apply { post { text = "$pageNum/$size" } } mBinding.oneinfo.inftxtprogress.apply { post { text = "$pageNum/$size" } }
} }
private fun prepareIdBtVH() { private fun prepareIdBtVH() {
idtbvh.apply { post { mBinding.infcard.idtbvh.apply { post {
isChecked = p["vertical"] == "true" isChecked = p["vertical"] == "true"
setOnClickListener { setOnClickListener {
if (idtbvh.isChecked) { if (mBinding.infcard.idtbvh.isChecked) {
vp.apply { post { orientation = ViewPager2.ORIENTATION_VERTICAL } } mBinding.vp.apply { post { orientation = ViewPager2.ORIENTATION_VERTICAL } }
p["vertical"] = "true" p["vertical"] = "true"
} else { } else {
vp.apply { post { orientation = ViewPager2.ORIENTATION_HORIZONTAL } } mBinding.vp.apply { post { orientation = ViewPager2.ORIENTATION_HORIZONTAL } }
p["vertical"] = "false" p["vertical"] = "false"
} }
} }
if (isChecked) mBinding.vp.apply { post {
orientation = ViewPager2.ORIENTATION_VERTICAL
} }
} } } }
if (idtbvh.isChecked) vp.apply { post { orientation = ViewPager2.ORIENTATION_VERTICAL } }
} }
private fun prepareIdBtVolTurn() { private fun prepareIdBtVolTurn() {
idtbvolturn.apply { post { mBinding.infcard.idtbvolturn.apply { post {
isChecked = volTurnPage isChecked = volTurnPage
setOnClickListener { setOnClickListener {
if (idtbvolturn.isChecked) p["volturn"] = "true" if (mBinding.infcard.idtbvolturn.isChecked) p["volturn"] = "true"
else p["volturn"] = "false" else p["volturn"] = "false"
} }
} } } }
@@ -333,17 +321,17 @@ class ViewMangaActivity : ToolsBoxActivity() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun updateSeekText() { private fun updateSeekText() {
inftxtprogress.apply { post { text = "$pageNum/$count" } } mBinding.oneinfo.inftxtprogress.apply { post { text = "$pageNum/$count" } }
} }
private fun updateSeekProgress() { private fun updateSeekProgress() {
infseek.apply { post { progress = pageNum * 100 / count } } mBinding.oneinfo.infseek.apply { post { progress = pageNum * 100 / count } }
} }
@Deprecated("Deprecated in Java") @Deprecated("Deprecated in Java")
override fun onBackPressed() { override fun onBackPressed() {
tt.canDo = false tt.canDo = false
wm?.get()?.w?.goBack() wm?.get()?.mBinding?.w?.goBack()
super.onBackPressed() super.onBackPressed()
} }
@@ -366,11 +354,16 @@ class ViewMangaActivity : ToolsBoxActivity() {
@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
if(dlZip2View) getImgBitmap(pos)?.let { holder.itemView.findViewById<ScaleImageView>(R.id.onei)?.let { oneImage ->
//Glide.with(this@ViewMangaActivity).load(it).placeholder(R.drawable.bg_comment).into(holder.itemView.onei) if(dlZip2View) getImgBitmap(pos)?.let {
holder.itemView.onei.setImageBitmap(it) //Glide.with(this@ViewMangaActivity).load(it).placeholder(R.drawable.bg_comment).into(holder.itemView.onei)
oneImage.setImageBitmap(it)
}
else Glide.with(this@ViewMangaActivity)
.load(toolsBox.resolution.wrap(imgUrls[pos])).placeholder(R.drawable.ic_dl)
.dontAnimate().timeout(10000)
.into(oneImage)
} }
else Glide.with(this@ViewMangaActivity).load(imgUrls[pos]).placeholder(R.drawable.ic_dl).dontAnimate().timeout(10000).into(holder.itemView.onei)
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
@@ -380,34 +373,35 @@ class ViewMangaActivity : ToolsBoxActivity() {
} }
fun showSettings() { fun showSettings() {
infseek.visibility = View.VISIBLE mBinding.oneinfo.infseek.visibility = View.VISIBLE
isearch.visibility = View.VISIBLE mBinding.oneinfo.inftitle.isearch.visibility = View.VISIBLE
val v = mBinding.oneinfo.root
ObjectAnimator.ofFloat( ObjectAnimator.ofFloat(
oneinfo, v,
"alpha", "alpha",
oneinfo.alpha, v.alpha,
1F 1F
).setDuration(233).start() ).setDuration(233).start()
clicked = true clicked = true
} }
fun hideSettings() { fun hideSettings() {
val v = mBinding.oneinfo.root
ObjectAnimator.ofFloat( ObjectAnimator.ofFloat(
oneinfo, v,
"alpha", "alpha",
oneinfo.alpha, v.alpha,
0F 0F
).setDuration(233).start() ).setDuration(233).start()
clicked = false clicked = false
infseek.postDelayed({ mBinding.oneinfo.infseek.postDelayed({
infseek.visibility = View.INVISIBLE mBinding.oneinfo.infseek.visibility = View.INVISIBLE
isearch.visibility = View.INVISIBLE mBinding.oneinfo.inftitle.isearch.visibility = View.INVISIBLE
}, 300) }, 300)
handler.sendEmptyMessage(1) handler.sendEmptyMessage(1)
} }
class MyHandler( class MyHandler(
private val infoCard: View,
private val toolsBox: ToolsBox private val toolsBox: ToolsBox
) : Handler(Looper.myLooper()!!) { ) : Handler(Looper.myLooper()!!) {
private var infoShown = false private var infoShown = false
@@ -432,19 +426,27 @@ class ViewMangaActivity : ToolsBoxActivity() {
} else { } else {
showInfCard(); true showInfCard(); true
} }
22 -> toolsBox.zis?.idtime?.text = 22 -> (toolsBox.zis as? ViewMangaActivity)?.mBinding?.infcard?.idtime?.apply { post {
SimpleDateFormat("HH:mm").format(Date()) + toolsBox.week + toolsBox.netInfo text = SimpleDateFormat("HH:mm")
.format(Date()) + toolsBox.week + toolsBox.netInfo
} }
} }
} }
private fun showInfCard() { private fun showInfCard() {
ObjectAnimator.ofFloat(infoCard.idc, "alpha", 0.3F, 0.8F).setDuration(233).start() Log.d("MyVM", "showInfCard delta $delta")
ObjectAnimator.ofFloat(infoCard, "translationY", delta, 0F).setDuration(233).start() va?.get()?.mBinding?.infcard?.apply {
ObjectAnimator.ofFloat(idc, "alpha", 0.3F, 0.8F).setDuration(233).start()
ObjectAnimator.ofFloat(root, "translationY", delta, 0F).setDuration(233).start()
}
} }
private fun hideInfCard() { private fun hideInfCard() {
ObjectAnimator.ofFloat(infoCard.idc, "alpha", 0.8F, 0.3F).setDuration(233).start() Log.d("MyVM", "hideInfCard delta $delta")
ObjectAnimator.ofFloat(infoCard, "translationY", 0F, delta).setDuration(233).start() va?.get()?.mBinding?.infcard?.apply {
ObjectAnimator.ofFloat(idc, "alpha", 0.8F, 0.3F).setDuration(233).start()
ObjectAnimator.ofFloat(root, "translationY", 0F, delta).setDuration(233).start()
}
} }
} }

View File

@@ -2,14 +2,50 @@ package top.fumiama.copymangaweb.activity.template
import android.app.Activity import android.app.Activity
import android.os.Bundle import android.os.Bundle
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import top.fumiama.copymangaweb.tool.ToolsBox import top.fumiama.copymangaweb.tool.ToolsBox
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
open class ToolsBoxActivity: Activity() { open class ToolsBoxActivity: Activity(), LifecycleOwner {
lateinit var toolsBox: ToolsBox lateinit var toolsBox: ToolsBox
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.currentState = Lifecycle.State.CREATED
lifecycleRegistry.currentState = Lifecycle.State.STARTED
toolsBox = ToolsBox(WeakReference(this)) toolsBox = ToolsBox(WeakReference(this))
} }
override fun onStart() {
super.onStart()
lifecycleRegistry.currentState = Lifecycle.State.STARTED
}
override fun onResume() {
super.onResume()
lifecycleRegistry.currentState = Lifecycle.State.RESUMED
}
override fun onPause() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
super.onPause()
}
override fun onStop() {
lifecycleRegistry.currentState = Lifecycle.State.CREATED
super.onStop()
}
override fun onDestroy() {
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
super.onDestroy()
}
override val lifecycle: Lifecycle
get() = lifecycleRegistry
} }

View File

@@ -6,7 +6,6 @@ import android.os.Looper
import android.os.Message import android.os.Message
import android.widget.Toast import android.widget.Toast
import android.widget.ToggleButton import android.widget.ToggleButton
import kotlinx.android.synthetic.main.widget_downloadbar.*
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.DlActivity import top.fumiama.copymangaweb.activity.DlActivity
import top.fumiama.copymangaweb.tool.MangaDlTools.Companion.wmdlt import top.fumiama.copymangaweb.tool.MangaDlTools.Companion.wmdlt
@@ -24,41 +23,52 @@ class DlHandler(activity: DlActivity, looper: Looper) : Handler(looper) {
when (msg.what) { when (msg.what) {
-2 -> d?.setLayouts() -2 -> d?.setLayouts()
1 -> { 1 -> {
d?.tbtnlist?.get(msg.arg1)?.setBackgroundResource(R.drawable.rndbg_checked) d?.tbtnlist?.get(msg.arg1)?.apply { post {
d?.tbtnlist?.get(msg.arg1)?.isChecked = false setBackgroundResource(R.drawable.rndbg_checked)
d?.updateProgressBar() isChecked = false
if (d?.haveDlStarted == false) { d?.updateProgressBar()
d?.dldChapter = 0 if (d?.haveDlStarted == false) {
d?.checkedChapter = 0 d?.dldChapter = 0
this.postDelayed({ d?.checkedChapter = 0
d?.setProgress2(0, 233) postDelayed({
d?.tdwn?.text = "0/0" d?.setProgress2(0, 233)
}, 400) d?.mBinding?.dldlbar?.tdwn?.apply { post {
} text = d?.getString(R.string.zero_per_zero)
} }
}, 400)
}
} }
} }
-1 -> { -1 -> {
d?.tbtnlist?.get(msg.arg1)?.setBackgroundResource(R.drawable.rndbg_error) d?.tbtnlist?.get(msg.arg1)?.apply { post {
d!!.dldChapter-- setBackgroundResource(R.drawable.rndbg_error)
Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}失败", Toast.LENGTH_SHORT).show() d!!.dldChapter--
d?.updateProgressBar() Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}失败", Toast.LENGTH_SHORT).show()
d?.updateProgressBar()
} }
} }
4 -> { 4 -> {
d?.pdwn?.progress = 0 d?.mBinding?.dldlbar?.pdwn?.apply { post { progress = 0 } }
val selectDownloaded = d?.multiSelect?:false val selectDownloaded = d?.multiSelect?:false
if (d?.haveSElectAll == true) { if (d?.haveSElectAll == true) {
d?.tbtnlist?.forEach { i -> d?.tbtnlist?.forEach { i ->
if(i.freezesText) i.setBackgroundResource(R.drawable.rndbg_checked) else i.setBackgroundResource(R.drawable.toggle_button) i.apply { post {
i.isChecked = false if(freezesText) setBackgroundResource(R.drawable.rndbg_checked)
else setBackgroundResource(R.drawable.toggle_button)
isChecked = false
} }
} }
d?.haveSElectAll = false d?.haveSElectAll = false
d?.checkedChapter = 0 d?.checkedChapter = 0
d?.dldChapter = 0 d?.dldChapter = 0
} else { } else {
d?.let { d?.let {
val checkBtn = { i: ToggleButton, it: DlActivity -> val checkBtn = { i: ToggleButton, a: DlActivity ->
i.setBackgroundResource(R.drawable.toggle_button) i.apply { post {
i.isChecked = true setBackgroundResource(R.drawable.toggle_button)
it.checkedChapter++ isChecked = true
a.checkedChapter++
} }
} }
for (i in it.tbtnlist) { for (i in it.tbtnlist) {
if(selectDownloaded) checkBtn(i, it) if(selectDownloaded) checkBtn(i, it)
@@ -67,7 +77,9 @@ class DlHandler(activity: DlActivity, looper: Looper) : Handler(looper) {
} }
d?.haveSElectAll = true d?.haveSElectAll = true
} }
d?.tdwn?.text = "${d?.dldChapter}/${d?.checkedChapter}" d?.mBinding?.dldlbar?.tdwn?.apply { post {
text = "${d?.dldChapter}/${d?.checkedChapter}"
} }
} }
5 -> { 5 -> {
setSize(msg.arg2, msg.arg1) setSize(msg.arg2, msg.arg1)
@@ -75,14 +87,20 @@ class DlHandler(activity: DlActivity, looper: Looper) : Handler(looper) {
if (!(msg.obj as Boolean)) { if (!(msg.obj as Boolean)) {
Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败", Toast.LENGTH_SHORT).show() Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败", Toast.LENGTH_SHORT).show()
}else{ }else{
val progressTxt = d?.tdwn?.text.toString() val progressTxt = d?.mBinding?.dldlbar?.tdwn?.text.toString()
d?.tdwn?.text = "${progressTxt.substringBefore(' ')}${msg.arg2}/${size}" d?.mBinding?.dldlbar?.tdwn?.apply { post {
text = "${progressTxt.substringBefore(' ')}${msg.arg2}/${size}"
} }
} }
} }
6 -> d?.tdwn?.text = "${d?.dldChapter}/${d?.checkedChapter}" 6 -> d?.mBinding?.dldlbar?.tdwn?.apply { post { text = "${d?.dldChapter}/${d?.checkedChapter}" } }
7 -> d?.deleteChapters() 7 -> d?.deleteChapters()
8 -> d?.resources?.getColor(R.color.colorBlue)?.let { d?.cdwn?.setCardBackgroundColor(it) } 8 -> d?.resources?.getColor(R.color.colorBlue)?.let { d?.mBinding?.dldlbar?.cdwn?.apply { post {
9 -> d?.resources?.getColor(R.color.colorRed)?.let { d?.cdwn?.setCardBackgroundColor(it) } setCardBackgroundColor(it)
} } }
9 -> d?.resources?.getColor(R.color.colorRed)?.let { d?.mBinding?.dldlbar?.cdwn?.apply { post {
setCardBackgroundColor(it)
} } }
10 -> Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败,尝试重新下载...", Toast.LENGTH_SHORT).show() 10 -> Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败,尝试重新下载...", Toast.LENGTH_SHORT).show()
} }
} }

View File

@@ -1,13 +1,14 @@
package top.fumiama.copymangaweb.handler package top.fumiama.copymangaweb.handler
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.app.Dialog
import android.content.Intent import android.content.Intent
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.os.Message import android.os.Message
import android.view.View import android.view.View
import kotlinx.android.synthetic.main.activity_main.* import android.widget.TextView
import kotlinx.android.synthetic.main.dialog_unzipping.* import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.DlActivity.Companion.json import top.fumiama.copymangaweb.activity.DlActivity.Companion.json
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.activity.ViewMangaActivity import top.fumiama.copymangaweb.activity.ViewMangaActivity
@@ -16,6 +17,7 @@ import top.fumiama.copymangaweb.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 var showDlList = false
private var dialog: Dialog? = null
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
super.handleMessage(msg) super.handleMessage(msg)
@@ -26,12 +28,27 @@ class MainHandler(looper: Looper):Handler(looper) {
SET_FAB -> setFab(msg.obj as String) SET_FAB -> setFab(msg.obj as String)
HIDE_FAB -> hideFab() HIDE_FAB -> hideFab()
SET_FAB_TO_DOWNLOAD_LIST -> setFab2DlList() SET_FAB_TO_DOWNLOAD_LIST -> setFab2DlList()
SHOW_LOADING_DIALOG -> wm?.get()?.dialog?.show() SHOW_LOADING_DIALOG -> {
HIDE_LOADING_DIALOG -> wm?.get()?.dialog?.hide() wm?.get()?.apply {
SET_LOADING_DIALOG_TEXT -> wm?.get()?.dialog?.tunz?.text = msg.obj as String (dialog?:Dialog(this).also {
it.setContentView(R.layout.dialog_unzipping)
dialog = it
}).show()
}
}
HIDE_LOADING_DIALOG -> {
dialog?.dismiss()
dialog = null
}
SET_LOADING_DIALOG_TEXT -> {
val t = msg.obj as? String?:return
dialog?.findViewById<TextView>(R.id.tunz)?.apply { post {
text = t
} }
}
} }
} }
private fun loadUrlInHiddenWebView(url: String) { wm?.get()?.wh?.apply { post { loadUrl(url) } } } private fun loadUrlInHiddenWebView(url: String) { wm?.get()?.mBinding?.wh?.apply { post { loadUrl(url) } } }
private fun callViewManga(content: String) = Thread{ private fun callViewManga(content: String) = Thread{
val listChapter = content.split('\n') val listChapter = content.split('\n')
if(!saveUrlsOnly) { if(!saveUrlsOnly) {
@@ -48,7 +65,7 @@ class MainHandler(looper: Looper):Handler(looper) {
} }
}.start() }.start()
private fun updateLoadProgress(p: Int) { private fun updateLoadProgress(p: Int) {
wm?.get()?.pw?.apply { post { wm?.get()?.mBinding?.pw?.apply { post {
if(progress == 100 && p < 100) { if(progress == 100 && p < 100) {
progress = 0 progress = 0
visibility = View.VISIBLE visibility = View.VISIBLE
@@ -57,8 +74,8 @@ class MainHandler(looper: Looper):Handler(looper) {
if(p == 100) postDelayed({ visibility = View.GONE }, 500) if(p == 100) postDelayed({ visibility = View.GONE }, 500)
} } } }
} }
private fun showFab() { wm?.get()?.fab?.apply { post { visibility = View.VISIBLE } } } private fun showFab() { wm?.get()?.mBinding?.fab?.apply { post { visibility = View.VISIBLE } } }
private fun hideFab() { wm?.get()?.fab?.apply { post { visibility = View.GONE } } } private fun hideFab() { wm?.get()?.mBinding?.fab?.apply { post { 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 showDlList = false

View File

@@ -7,12 +7,12 @@ 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, ua: String? = null): ByteArray? { fun getHttpContent(u: String, refer: String? = null, ua: String? = null): ByteArray? {
Log.d("Mydl", "getHttp: $Url") Log.d("Mydl", "getHttp: $u")
var ret: ByteArray? = null var ret: ByteArray? = null
val task = FutureTask(Callable { val task = FutureTask(Callable {
try { try {
val connection = URL(Url).openConnection() as HttpURLConnection val connection = URL(u).openConnection() as HttpURLConnection
connection.requestMethod = "GET" connection.requestMethod = "GET"
connection.connectTimeout = 10000 connection.connectTimeout = 10000
connection.readTimeout = 10000 connection.readTimeout = 10000

View File

@@ -2,7 +2,6 @@ package top.fumiama.copymangaweb.tool
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.DlActivity import top.fumiama.copymangaweb.activity.DlActivity
import kotlinx.android.synthetic.main.activity_dl.*
import java.io.File import java.io.File
import java.lang.Thread.sleep import java.lang.Thread.sleep
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@@ -16,7 +15,7 @@ class MangaDlTools(activity: DlActivity) {
var exit = false var exit = false
private val sem = Semaphore(1) private val sem = Semaphore(1)
private val da = WeakReference(activity) private val da = WeakReference(activity)
private val d = da.get() private val d get() = da.get()
private val p = PropertiesTools(File("${d?.filesDir}/chapters.hash")) private val p = PropertiesTools(File("${d?.filesDir}/chapters.hash"))
private var imgUrlsList: Array<Array<String>?>? = null private var imgUrlsList: Array<Array<String>?>? = null
private var chaptersCount = 0 private var chaptersCount = 0
@@ -38,7 +37,7 @@ class MangaDlTools(activity: DlActivity) {
sem.acquire() sem.acquire()
da.get()?.apply { da.get()?.apply {
p[url.substringAfterLast("/")] = (chaptersCount++).toString() p[url.substringAfterLast("/")] = (chaptersCount++).toString()
runOnUiThread { dwh.loadUrl(url) } runOnUiThread { mBinding.dwh.apply { post { loadUrl(url) } } }
} }
} }
@@ -48,7 +47,7 @@ class MangaDlTools(activity: DlActivity) {
} }
fun dlChapterAndPackIntoZip(zipf: File, hash: String){ fun dlChapterAndPackIntoZip(zipf: File, hash: String){
imgUrlsList?.get(p[hash].toInt())?.let { imgUrlsList?.get(p[hash].toInt())?.let { images ->
val dl = DownloadTools() val dl = DownloadTools()
zipf.parentFile?.let { if (!it.exists()) it.mkdirs() } zipf.parentFile?.let { if (!it.exists()) it.mkdirs() }
if (zipf.exists()) zipf.delete() if (zipf.exists()) zipf.delete()
@@ -56,12 +55,16 @@ class MangaDlTools(activity: DlActivity) {
val zip = ZipOutputStream(CheckedOutputStream(zipf.outputStream(), CRC32())) val zip = ZipOutputStream(CheckedOutputStream(zipf.outputStream(), CRC32()))
zip.setLevel(9) zip.setLevel(9)
var succeed = true var succeed = true
for (i in it.indices) { for (i in images.indices) {
zip.putNextEntry(ZipEntry("$i.webp")) zip.putNextEntry(ZipEntry("$i.webp"))
var tryTimes = 3 var tryTimes = 3
var s = false var s = false
while (!s && tryTimes-- > 0){ 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 s = d?.toolsBox?.resolution?.wrap(images[i])?.let { u ->
dl.getHttpContent(u, d?.getString(R.string.web_home_www),
d?.getString(R.string.pc_ua)
)?.let { zip.write(it); true } ?: false
} ?: false
if (!s) { if (!s) {
onDownloadedListener?.handleMessage(i + 1) onDownloadedListener?.handleMessage(i + 1)
sleep(2000) sleep(2000)

View File

@@ -2,7 +2,6 @@ package top.fumiama.copymangaweb.tool
import android.content.Intent import android.content.Intent
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm import top.fumiama.copymangaweb.activity.MainActivity.Companion.wm
import top.fumiama.copymangaweb.activity.ViewMangaActivity import top.fumiama.copymangaweb.activity.ViewMangaActivity
import java.io.File import java.io.File
@@ -14,8 +13,8 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
private var isEndR = false private var isEndR = false
fun toPreviousPage(){ toPage(v?.r2l==true) } fun toPreviousPage(){ toPage(v?.r2l==true) }
fun toNextPage(){ toPage(v?.r2l!=true) } fun toNextPage(){ toPage(v?.r2l!=true) }
private fun judgePrevious() = v?.pageNum?:0 > 1 private fun judgePrevious() = (v?.pageNum ?: 0) > 1
private fun judgeNext() = v?.pageNum?:0 < v?.count?:0 private fun judgeNext() = (v?.pageNum ?: 0) < (v?.count ?: 0)
private fun toPage(goNext:Boolean){ private fun toPage(goNext:Boolean){
if (v?.clicked == false) { if (v?.clicked == false) {
if (if(goNext)judgeNext() else judgePrevious()) { if (if(goNext)judgeNext() else judgePrevious()) {
@@ -31,13 +30,16 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
if (chapterUrl != null) { if (chapterUrl != null) {
if (if(goNext)isEndR else isEndL) { if (if(goNext)isEndR else isEndL) {
if(!goNext) ViewMangaActivity.pn = -2 if(!goNext) ViewMangaActivity.pn = -2
wm?.get()?.w?.loadUrl("javascript:invoke.clickClass(\"comicControlBottomTopClick\",${if(goNext)1 else 0});") wm?.get()?.mBinding?.w?.apply { post {
loadUrl("javascript:invoke.clickClass(\"comicControlBottomTopClick\",${if(goNext)1 else 0});")
} }
v.tt.canDo = false v.tt.canDo = false
v.finish() v.finish()
} else doubleTapToast(goNext) } else doubleTapToast(goNext)
} else { } else {
val newZipPosition = ViewMangaActivity.zipPosition + (if(goNext) 1 else -1) val newZipPosition = ViewMangaActivity.zipPosition + (if(goNext) 1 else -1)
if(v.dlZip2View && newZipPosition >= 0 && newZipPosition < ViewMangaActivity.zipList?.size?:0){ if(v.dlZip2View && newZipPosition >= 0 && newZipPosition <
(ViewMangaActivity.zipList?.size ?: 0)){
if (if(goNext)isEndR else isEndL){ if (if(goNext)isEndR else isEndL){
if(!goNext) ViewMangaActivity.pn = -2 if(!goNext) ViewMangaActivity.pn = -2
ViewMangaActivity.zipPosition = newZipPosition ViewMangaActivity.zipPosition = newZipPosition

View File

@@ -0,0 +1,5 @@
package top.fumiama.copymangaweb.tool
class Resolution(private val original: Regex) {
fun wrap(u: String) : String = u.replace(original, "c1500x.")
}

View File

@@ -5,14 +5,15 @@ import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.view.View
import android.widget.Toast import android.widget.Toast
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.Calendar import java.util.Calendar
import kotlin.math.sqrt import kotlin.math.sqrt
class ToolsBox(w: WeakReference<Activity>) { class ToolsBox(private val w: WeakReference<Activity>) {
val zis = w.get() val zis get () = w.get()
val week: String val week: String
get() { get() {
val cal = Calendar.getInstance() val cal = Calendar.getInstance()
@@ -43,6 +44,8 @@ class ToolsBox(w: WeakReference<Activity>) {
} }
} ?: "错误" } ?: "错误"
} }
val resolution = Resolution(Regex("c\\d+x\\."))
fun toastError(s: String, willFinish: Boolean = true) { fun toastError(s: String, willFinish: Boolean = true) {
Toast.makeText(zis?.applicationContext, s, Toast.LENGTH_SHORT).show() Toast.makeText(zis?.applicationContext, s, Toast.LENGTH_SHORT).show()
if (willFinish) zis?.finish() if (willFinish) zis?.finish()
@@ -66,6 +69,26 @@ class ToolsBox(w: WeakReference<Activity>) {
txtN?.let { info.setNeutralButton(it) { _, _ -> neutral?.let { it() } } } txtN?.let { info.setNeutralButton(it) { _, _ -> neutral?.let { it() } } }
info.show() info.show()
} }
fun buildAlertWithView(
title: String,
view: View,
txtOk: String? = null,
txtN: String? = null,
txtCancel: String? = null,
ok: (() -> Unit)? = null,
neutral: (() -> Unit)? = null,
cancel: (() -> Unit)? = null
): AlertDialog {
val info = AlertDialog.Builder(zis)
info.setIcon(R.drawable.ic_launcher_foreground)
info.setTitle(title)
info.setView(view)
txtOk?.let { info.setPositiveButton(it) { _, _ -> ok?.let { it() } } }
txtCancel?.let { info.setNegativeButton(it) { _, _ -> cancel?.let { it() } } }
txtN?.let { info.setNeutralButton(it) { _, _ -> neutral?.let { it() } } }
return info.show()
}
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()}
} }

View File

@@ -0,0 +1,124 @@
package top.fumiama.copymangaweb.tool
import android.app.Activity
import android.app.AlertDialog
import android.content.Context.MODE_PRIVATE
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.util.Log
import android.widget.ProgressBar
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.core.content.edit
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymangaweb.R
import top.fumiama.copymangaweb.activity.template.ToolsBoxActivity
import top.fumiama.sdict.ApkUpdater
import top.fumiama.sdict.io.Client
import java.io.File
import java.lang.ref.WeakReference
class Updater(
private val a: WeakReference<ToolsBoxActivity>, private val toolsBox: ToolsBox,
private val ignoreSkip: Boolean, private val skipNum: Int,
): ApkUpdater("reilia.fumiama.top", 13213, "fumiama") {
private var mInfo: AlertDialog? = null
set(value) {
field?.dismiss()
field = value
}
override suspend fun onCheckLatestVersion(version: Int) {
super.onCheckLatestVersion(version)
a.get()?.apply {
if (ignoreSkip) withContext(Dispatchers.Main) {
Toast.makeText(this@apply, "无更新", Toast.LENGTH_SHORT).show()
}
}
}
override suspend fun onCheckNewVersion(version: Int, message: String, md5: String?) {
super.onCheckNewVersion(version, message, md5)
if (md5 == null) {
withContext(Dispatchers.Main) {
toolsBox.buildInfo("看板", message, "知道了")
}
return
}
if(skipNum < version || ignoreSkip) {
val progressBar =
a.get()?.layoutInflater?.inflate(R.layout.dialog_progress, null, false) ?: return
val progressHandler = object : Client.Progress {
override fun notify(progressPercentage: Int) {
Log.d("MyUP", "Set progress: $progressPercentage")
progressBar.findViewById<ProgressBar>(R.id.dpp)?.progress = progressPercentage
}
}
withContext(Dispatchers.Main) {
toolsBox.buildInfo("看板", message, "下载新版", "跳过该版", "取消", {
mInfo = toolsBox.buildAlertWithView("下载进度", progressBar, "隐藏")
a.get()?.lifecycleScope?.launch { withContext(Dispatchers.IO) {
download(md5, progressHandler)
} }
}, {
a.get()?.apply {
getPreferences(MODE_PRIVATE).edit {
putInt("skipVersion", version)
apply()
}
}
})
}
}
}
override suspend fun onDownloadNewVersionFailed(cause: Int) {
super.onDownloadNewVersionFailed(cause)
withContext(Dispatchers.Main) {
mInfo?.dismiss()
mInfo = null
when (cause) {
UPDATE_FAIL_NETWORK -> a.get()?.apply {
Toast.makeText(this@apply, "网络错误", Toast.LENGTH_SHORT).show()
}
UPDATE_FAIL_FILE_CORRUPT -> a.get()?.apply {
Toast.makeText(this@apply, "文件损坏", Toast.LENGTH_SHORT).show()
}
else -> {}
}
}
}
override suspend fun onDownloadNewVersionSuccess(data: ByteArray) {
super.onDownloadNewVersionSuccess(data)
withContext(Dispatchers.Main) {
mInfo?.dismiss()
mInfo = null
a.get()?.apply {
Toast.makeText(this@apply, "下载成功", Toast.LENGTH_SHORT).show()
install(data, this)
}
}
}
private suspend fun install(data: ByteArray, activity: Activity) = activity.apply {
withContext(Dispatchers.IO) {
val f = File(externalCacheDir, "new.apk")
f.writeBytes(data)
val intent = Intent(Intent.ACTION_VIEW)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val contentUri: Uri = FileProvider.getUriForFile(this@apply, "$packageName.fileprovider", f)
intent.setDataAndType(contentUri, "application/vnd.android.package-archive")
} else intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive")
withContext(Dispatchers.Main) {
startActivity(intent)
}
}
}
}

View File

@@ -7,7 +7,7 @@ import android.util.Log
import android.webkit.WebView import android.webkit.WebView
import top.fumiama.copymangaweb.web.WebViewClient import top.fumiama.copymangaweb.web.WebViewClient
@SuppressLint("JavascriptInterface") @SuppressLint("JavascriptInterface", "SetJavaScriptEnabled")
class JSWebView : WebView { class JSWebView : WebView {
constructor(context: Context): super(context) constructor(context: Context): super(context)
constructor(context: Context, attributeSet: AttributeSet): super(context, attributeSet) constructor(context: Context, attributeSet: AttributeSet): super(context, attributeSet)

View File

@@ -21,13 +21,11 @@ class LazyScrollView : ScrollView {
when (event.action) { when (event.action) {
MotionEvent.ACTION_UP -> this.postDelayed({ MotionEvent.ACTION_UP -> this.postDelayed({
if (view != null && onScrollListener != null) { if (view != null && onScrollListener != null) {
if (onScrollListener != null) { //Log.d("MyS", "view?.measuredHeight: ${view?.measuredHeight}, scrollY: $scrollY, height: $height")
//Log.d("MyS", "view?.measuredHeight: ${view?.measuredHeight}, scrollY: $scrollY, height: $height") when {
when { (view?.measuredHeight ?: 0) <= scrollY + height -> onScrollListener?.onBottom()
view?.measuredHeight?:0 <= scrollY + height -> onScrollListener?.onBottom() scrollY == 0 -> onScrollListener?.onTop()
scrollY == 0 -> onScrollListener?.onTop() else -> onScrollListener?.onScroll()
else -> onScrollListener?.onScroll()
}
} }
} }
}, 233) }, 233)

View File

@@ -2,9 +2,10 @@ package top.fumiama.copymangaweb.web
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.net.http.SslError
import android.util.Log import android.util.Log
import android.webkit.* import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import android.widget.Toast import android.widget.Toast
import top.fumiama.copymangaweb.R import top.fumiama.copymangaweb.R

File diff suppressed because one or more lines are too long

View File

@@ -50,6 +50,7 @@
</top.fumiama.copymangaweb.view.LazyScrollView> </top.fumiama.copymangaweb.view.LazyScrollView>
<include <include
android:id="@+id/dldlbar"
layout="@layout/widget_downloadbar" layout="@layout/widget_downloadbar"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -1,59 +1,60 @@
<?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" <layout 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:id="@+id/vcp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/vone"
layout="@layout/page_imgview"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/onec" android:id="@+id/vcp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:alpha="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<include <include
android:id="@+id/infcard" android:id="@+id/vone"
layout="@layout/widget_infodrawer" layout="@layout/page_imgview"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent" android:visibility="invisible"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include <androidx.viewpager2.widget.ViewPager2
android:id="@+id/oneinfo" android:id="@+id/vp"
layout="@layout/widget_viewmangainfo" android:layout_width="0dp"
android:layout_width="0dp" android:layout_height="0dp"
android:layout_height="0dp" android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/onec"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<include
android:id="@+id/infcard"
layout="@layout/widget_infodrawer"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
android:id="@+id/oneinfo"
layout="@layout/widget_viewmangainfo"
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_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -0,0 +1,42 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:background="@drawable/rndbg_white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_dere"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<ProgressBar
android:id="@+id/dpp"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:progress="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,14 +1,16 @@
<?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" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
tools:viewBindingIgnore="true" <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/onecons" tools:viewBindingIgnore="true"
android:layout_width="match_parent" android:id="@+id/onecons"
android:layout_height="match_parent">
<top.fumiama.copymangaweb.view.ScaleImageView
android:id="@+id/onei"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout> <top.fumiama.copymangaweb.view.ScaleImageView
android:id="@+id/onei"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,69 +1,71 @@
<?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" <layout 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" xmlns:tools="http://schemas.android.com/tools">
tools:viewBindingIgnore="true" <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/csdwn" tools:viewBindingIgnore="true"
android:layout_width="match_parent" android:id="@+id/csdwn"
android:layout_height="match_parent" android:layout_width="match_parent"
android:alpha="0.9"> android:layout_height="match_parent"
android:alpha="0.9">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/cdwn" android:id="@+id/cdwn"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:foreground="?android:attr/selectableItemBackground" android:foreground="?android:attr/selectableItemBackground"
app:cardBackgroundColor="@color/colorBlue" app:cardBackgroundColor="@color/colorBlue"
app:cardCornerRadius="16dp" app:cardCornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ProgressBar <ProgressBar
android:id="@+id/pdwn" android:id="@+id/pdwn"
style="?android:attr/progressBarStyleHorizontal" style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:progress="0" android:progress="0"
app:layout_constraintBottom_toTopOf="@+id/tdwn" app:layout_constraintBottom_toTopOf="@+id/tdwn"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" /> app:layout_constraintTop_toBottomOf="@+id/textView" />
<TextView <TextView
android:id="@+id/tdwn" android:id="@+id/tdwn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:text="0/0" android:text="@string/zero_per_zero"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pdwn" /> app:layout_constraintTop_toBottomOf="@+id/pdwn" />
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="单击此处下载/暂停 长按此处全选/清空 长按某话删除" android:text="@string/hint_download_card"
app:layout_constraintBottom_toTopOf="@+id/pdwn" app:layout_constraintBottom_toTopOf="@+id/pdwn"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,97 +1,99 @@
<?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" <layout 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" xmlns:tools="http://schemas.android.com/tools">
tools:viewBindingIgnore="true" <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" tools:viewBindingIgnore="true"
android:layout_height="match_parent"> android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/idc" android:id="@+id/idc"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:alpha="0.3" android:alpha="0.3"
android:background="#FCFCFF" android:background="#FCFCFF"
app:cardCornerRadius="16dp" app:cardCornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"> app:layout_constraintVertical_bias="0.0">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <TextView
android:id="@+id/idtime" android:id="@+id/idtime"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:text="加载中..." android:text="@string/loading"
android:textColor="#000000" android:textColor="#000000"
app:layout_constraintBottom_toTopOf="@+id/idtbvh" app:layout_constraintBottom_toTopOf="@+id/idtbvh"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" /> app:layout_constraintVertical_bias="0.0" />
<ToggleButton <ToggleButton
android:id="@+id/idtbvolturn" android:id="@+id/idtbvolturn"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:background="@drawable/toggle_button" android:background="@drawable/toggle_button"
android:textOff="音量翻页关" android:textOff="@string/vol_turn_off"
android:textOn="音量翻页开" android:textOn="@string/vol_turn_on"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/idtbvh" app:layout_constraintEnd_toStartOf="@+id/idtbvh"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/idtime" app:layout_constraintTop_toBottomOf="@+id/idtime"
app:layout_constraintVertical_bias="0.0" /> app:layout_constraintVertical_bias="0.0" />
<ToggleButton <ToggleButton
android:id="@+id/idtbvh" android:id="@+id/idtbvh"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:background="@drawable/toggle_button" android:background="@drawable/toggle_button"
android:textOff="横向" android:textOff="@string/horizontal"
android:textOn="竖向" android:textOn="@string/vertical"
app:layout_constraintEnd_toStartOf="@id/idtbvp" app:layout_constraintEnd_toStartOf="@id/idtbvp"
app:layout_constraintStart_toEndOf="@+id/idtbvolturn" app:layout_constraintStart_toEndOf="@+id/idtbvolturn"
app:layout_constraintTop_toTopOf="@+id/idtbvolturn" /> app:layout_constraintTop_toTopOf="@+id/idtbvolturn" />
<ToggleButton <ToggleButton
android:id="@+id/idtbvp" android:id="@+id/idtbvp"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:background="@drawable/toggle_button" android:background="@drawable/toggle_button"
android:textOff="动画开" android:textOff="@string/animation_on"
android:textOn="动画关" android:textOn="@string/animation_off"
app:layout_constraintEnd_toStartOf="@+id/idtblr" app:layout_constraintEnd_toStartOf="@+id/idtblr"
app:layout_constraintStart_toEndOf="@id/idtbvh" app:layout_constraintStart_toEndOf="@id/idtbvh"
app:layout_constraintTop_toTopOf="@+id/idtbvolturn" /> app:layout_constraintTop_toTopOf="@+id/idtbvolturn" />
<ToggleButton <ToggleButton
android:id="@+id/idtblr" android:id="@+id/idtblr"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:background="@drawable/toggle_button" android:background="@drawable/toggle_button"
android:textOff="←前 后→" android:textOff="@string/arrow_front_back"
android:textOn="←后 前→" android:textOn="@string/arrow_back_front"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/idtbvp" app:layout_constraintStart_toEndOf="@+id/idtbvp"
app:layout_constraintTop_toTopOf="@+id/idtbvolturn" /> app:layout_constraintTop_toTopOf="@+id/idtbvolturn" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,60 +1,62 @@
<?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" <layout 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" xmlns:tools="http://schemas.android.com/tools">
tools:viewBindingIgnore="true" <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" tools:viewBindingIgnore="true"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="match_parent">
android:foreground="?android:attr/selectableItemBackground"
app:cardBackgroundColor="#FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="48dp"
android:foreground="@drawable/line_colorful" android:foreground="?android:attr/selectableItemBackground"
android:foregroundGravity="fill_horizontal|bottom|center"> app:cardBackgroundColor="#FFFFFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ttitle" android:layout_width="match_parent"
android:layout_width="0dp" android:layout_height="match_parent"
android:layout_height="wrap_content" android:foreground="@drawable/line_colorful"
android:layout_marginEnd="8dp" android:foregroundGravity="fill_horizontal|bottom|center">
android:gravity="start"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/isearch"
app:layout_constraintStart_toEndOf="@+id/ilogo"
app:layout_constraintTop_toTopOf="parent" />
<ImageView <TextView
android:id="@+id/isearch" android:id="@+id/ttitle"
android:layout_width="28dp" android:layout_width="0dp"
android:layout_height="28dp" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:src="@drawable/ic_edit" android:gravity="start"
app:layout_constraintBottom_toBottomOf="parent" android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintEnd_toStartOf="@+id/isearch"
app:layout_constraintStart_toEndOf="@+id/ilogo"
app:layout_constraintTop_toTopOf="parent" />
<ImageView <ImageView
android:id="@+id/ilogo" android:id="@+id/isearch"
android:layout_width="48dp" android:layout_width="28dp"
android:layout_height="64dp" android:layout_height="28dp"
android:scaleType="centerCrop" android:layout_marginEnd="8dp"
android:src="@drawable/ic_launcher_foreground" android:src="@drawable/ic_edit"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> <ImageView
android:id="@+id/ilogo"
android:layout_width="48dp"
android:layout_height="64dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_launcher_foreground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.cardview.widget.CardView> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,52 +1,54 @@
<?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" <layout 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" xmlns:tools="http://schemas.android.com/tools">
tools:viewBindingIgnore="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/inftitle"
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" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp" tools:viewBindingIgnore="true"
android:layout_height="24dp" android:layout_width="match_parent"
android:layout_marginStart="8dp" android:layout_height="match_parent">
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:alpha="0.8"
android:background="@drawable/rndbg_white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/inftitle">
<SeekBar <include
android:id="@+id/infseek" android:id="@+id/inftitle"
layout="@layout/widget_titlebar"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@+id/inftxtprogress"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/inftxtprogress" android:layout_width="0dp"
android:layout_width="wrap_content" android:layout_height="24dp"
android:layout_height="wrap_content" android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:text="0/0" android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent" android:alpha="0.8"
android:background="@drawable/rndbg_white"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/infseek" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@+id/inftitle">
<SeekBar
android:id="@+id/infseek"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/inftxtprogress"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/inftxtprogress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/zero_per_zero"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/infseek"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </layout>

View File

@@ -7,4 +7,15 @@
<string name="pc_ua">Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38</string> <string name="pc_ua">Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38</string>
<string name="blocked_ad">已屏蔽其他网站页面</string> <string name="blocked_ad">已屏蔽其他网站页面</string>
<string name="loading">加载中…</string>
<string name="vol_turn_off">音量翻页关</string>
<string name="vol_turn_on">音量翻页开</string>
<string name="horizontal">横向</string>
<string name="vertical">竖向</string>
<string name="animation_on">动画开</string>
<string name="animation_off">动画关</string>
<string name="arrow_front_back">←前 后→</string>
<string name="arrow_back_front">←后 前→</string>
<string name="zero_per_zero">0/0</string>
<string name="hint_download_card">单击此处下载/暂停 长按此处全选/清空 长按某话删除</string>
</resources> </resources>

View File

@@ -0,0 +1,5 @@
<paths>
<external-files-path name="ef" path="."/>
<files-path name="if" path="."/>
<external-cache-path name="ec" path="."/>
</paths>

View File

@@ -9,7 +9,7 @@ buildscript {
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.3.2' classpath 'com.android.tools.build:gradle:8.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View File

@@ -23,4 +23,4 @@ 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
cm_kotlin_version=1.7.10 cm_kotlin_version=2.1.0

View File

@@ -1,6 +1,6 @@
#Fri Sep 04 18:15:43 CST 2020 #Sun Jun 22 01:57:19 JST 2025
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip