1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-04 23:10:23 +08:00
优化
1. 文件组织
升级
1. com.google.android.material -> 1.13.0
This commit is contained in:
源文雨
2025-12-04 22:04:58 +08:00
parent 036fdac4a9
commit 0fdd3f4489
37 changed files with 297 additions and 398 deletions

View File

@@ -12,8 +12,8 @@ android {
minSdkVersion 23
//noinspection OldTargetApi
targetSdkVersion 34
versionCode 81
versionName '2.5.8'
versionCode 82
versionName '2.5.9'
resourceConfigurations += ['zh', 'zh-rCN']
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -101,7 +101,7 @@ dependencies {
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.12.0'
implementation 'com.google.android.material:material:1.13.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
//noinspection GradleDependency
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
@@ -124,5 +124,5 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation 'com.airbnb.android:lottie:6.6.6'
implementation 'net.java.dev.jna:jna:5.17.0@aar'
implementation 'top.fumiama:sdict:0.1.0'
implementation 'top.fumiama:sdict:0.1.1'
}

View File

@@ -59,7 +59,7 @@ import top.fumiama.copymanga.ui.cardflow.rank.RankFragment
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment
import top.fumiama.copymanga.ui.download.DownloadFragment
import top.fumiama.copymanga.ui.download.NewDownloadFragment
import top.fumiama.copymanga.api.update.Update
import top.fumiama.copymanga.api.update.Updater
import top.fumiama.copymanga.api.user.Member
import top.fumiama.copymanga.lib.Comancry
import top.fumiama.copymanga.lib.Comandy
@@ -140,7 +140,7 @@ class MainActivity : AppCompatActivity() {
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
override fun onDrawerStateChanged(newState: Int) {}
})
goCheckUpdate(false)
lifecycleScope.launch { goCheckUpdate(false) }
ime = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
@@ -459,9 +459,14 @@ class MainActivity : AppCompatActivity() {
.getIntent(this))
}
private fun goCheckUpdate(ignoreSkip: Boolean) {
lifecycleScope.launch {
Update.checkUpdate(this@MainActivity, toolsBox, ignoreSkip)
private suspend fun goCheckUpdate(ignoreSkip: Boolean) {
withContext(Dispatchers.IO) {
Updater(
WeakReference(this@MainActivity),
toolsBox,
ignoreSkip,
getPreferences(MODE_PRIVATE).getInt("skipVersion", 0)
).check(BuildConfig.VERSION_CODE)
}
}
@@ -477,7 +482,7 @@ class MainActivity : AppCompatActivity() {
dl.setIcon(R.mipmap.ic_launcher)
dl.setPositiveButton(android.R.string.ok) { _, _ -> }
dl.setNeutralButton(R.string.check_update) {_, _ ->
goCheckUpdate(true)
lifecycleScope.launch { goCheckUpdate(true) }
}
dl.show()
}

View File

@@ -42,24 +42,15 @@ object Config {
get() {
if (field === null)
field = LazyHeaders.Builder()
.addHeader("referer", referer)
.addHeader("User-Agent", pc_ua)
.addHeader("source", net_source.value)
.addHeader("webp", "1")
.addHeader("version", app_ver.value)
.addHeader(
"region",
if (net_use_foreign.value) "1" else "0"
)
.addHeader("platform", platform.value)
.build()
return field
}
val proxyUrl = MainActivity.mainWeakReference?.get()?.getString(R.string.proxyUrl)!!
val pc_ua get() = MainActivity.mainWeakReference?.get()?.getString(R.string.pc_ua)?.format(app_ver.value)?:""
val pc_ua get() = MainActivity.mainWeakReference?.get()?.getString(R.string.pc_ua)?:""
val default_ua get() = MainActivity.mainWeakReference?.get()?.getString(R.string.default_ua)?:""
val referer get() = MainActivity.mainWeakReference?.get()?.getString(R.string.referer)?.format(app_ver.value)?:""
val requested get() = MainActivity.mainWeakReference?.get()?.getString(R.string.requested)?:""
val navTextInfo = UserPreferenceString("navTextInfo", R.string.navTextInfo)
val token = UserPreferenceString("token", "", null)
@@ -70,7 +61,7 @@ object Config {
val nickname = UserPreferenceString("nickname")
val avatar = UserPreferenceString("avatar")
val app_ver = PreferenceString("settings_cat_general_et_app_version", R.string.app_ver)
val version = PreferenceString("settings_cat_general_et_app_version", R.string.version)
val platform = PreferenceString("settings_cat_general_et_platform", R.string.platform)
val general_enable_transparent_system_bar = PreferenceBoolean("settings_cat_general_sw_enable_transparent_systembar", false)
val general_disable_kanban_animation = PreferenceBoolean("settings_cat_general_sw_disable_kanban_animation", false)
@@ -82,11 +73,11 @@ object Config {
val reverseProxyUrl = PreferenceString(R.string.reverseProxyKeyID)
val networkApiUrl = PreferenceString("settings_cat_net_et_api_url", R.string.hostUrl)
val proxy_key = PreferenceString(R.string.imgProxyCodeKeyID)
val net_use_gzip = PreferenceBoolean("settings_cat_net_sw_use_gzip", false)
val net_use_json = PreferenceBoolean("settings_cat_net_sw_use_json", false)
val net_platform = PreferenceBoolean("settings_cat_net_sw_platform", false)
val net_use_gzip = PreferenceBoolean("settings_cat_net_sw_use_gzip", true)
val net_use_json = PreferenceBoolean("settings_cat_net_sw_use_json", true)
val net_platform = PreferenceBoolean("settings_cat_net_sw_platform", true)
val net_referer = PreferenceBoolean("settings_cat_net_sw_referer", false)
val net_version = PreferenceBoolean("settings_cat_net_sw_version", false)
val net_version = PreferenceBoolean("settings_cat_net_sw_version", true)
val net_region = PreferenceBoolean("settings_cat_net_sw_region", false)
val net_no_webp = PreferenceBoolean("settings_cat_net_no_webp", false)
val net_use_comandy = PreferenceBoolean("settings_cat_net_sw_use_comandy", false)
@@ -95,7 +86,7 @@ object Config {
val net_use_api_proxy = PreferenceBoolean("settings_cat_net_sw_use_api_proxy", false)
val net_img_resolution = PreferenceString(R.string.imgResolutionKeyID)
val net_umstring = PreferenceString("settings_cat_net_et_umstring")
val net_source = PreferenceString("settings_cat_net_et_source", R.string.source)
val net_source = PreferenceString("settings_cat_net_et_source", R.string.requested)
val net_ua = PreferenceString("settings_cat_net_et_ua", R.string.default_ua)
val view_manga_inverse_chapters = PreferenceBoolean("settings_cat_vm_sw_inverse_chapters", false)

View File

@@ -1,71 +0,0 @@
package top.fumiama.copymanga.api.update
import android.util.Log
import top.fumiama.sdict.io.Client
class SimpleKanban(private val client: Client, private val pwd: String) { //must run in thread
private val raw: ByteArray?
get() {
var times = 3
var re: ByteArray
var firstReceived: ByteArray
do {
re = byteArrayOf()
if(client.initConnect()) {
client.sendMessage("${pwd}catquit")
client.receiveRawMessage(33) //Welcome to simple kanban server.
try {
firstReceived = client.receiveRawMessage(4) //le
val length = convert2Int(firstReceived)
Log.d("MySK", "Msg len: $length")
if(firstReceived.size > 4) re += firstReceived.copyOfRange(4, firstReceived.size)
re += client.receiveRawMessage(length - re.size, setProgress = true)
break
} catch (e: Exception) {
e.printStackTrace()
}
client.closeConnect()
}
} while (times-- > 0)
return if(re.isEmpty()) null else re
}
private fun convert2Int(buffer: ByteArray) =
(buffer[3].toInt() and 0xff shl 24) or
(buffer[2].toInt() and 0xff shl 16) or
(buffer[1].toInt() and 0xff shl 8) or
(buffer[0].toInt() and 0xff)
suspend fun fetchRaw(doOnLoadFailure: suspend ()->Unit = {
Log.d("MySD", "Fetch dict failed")
}, doOnLoadSuccess: suspend (data: ByteArray)->Unit = {
Log.d("MySD", "Fetch dict success")
}) {
raw?.apply {
doOnLoadSuccess(this)
}?:doOnLoadFailure()
}
operator fun get(version: Int): String =
if(client.initConnect()) {
client.sendMessage("${pwd}get${version}quit")
client.receiveRawMessage(36) //Welcome to simple kanban server. get
val r = try {
val firstReceive = client.receiveRawMessage(4)
if(firstReceive.decodeToString() == "null") "null"
else {
val length = convert2Int(firstReceive)
Log.d("MySK", "Msg len: $length")
var re = byteArrayOf()
if(firstReceive.size > 4) re += firstReceive.copyOfRange(4, firstReceive.size)
re += client.receiveRawMessage(length - re.size)
if(re.isNotEmpty()) re.decodeToString() else "null"
}
} catch (e: Exception){
e.printStackTrace()
"null"
}
client.closeConnect()
r
} else "null"
}

View File

@@ -1,120 +0,0 @@
package top.fumiama.copymanga.api.update
import android.app.Activity
import android.content.Context
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.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.core.content.edit
import androidx.lifecycle.lifecycleScope
import kotlinx.android.synthetic.main.dialog_progress.view.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.sdict.io.Client
import top.fumiama.copymanga.view.interaction.UITools
import top.fumiama.dmzj.copymanga.BuildConfig
import top.fumiama.dmzj.copymanga.R
import top.fumiama.sdict.utils.Utils.toHexStr
import java.io.File
import java.security.MessageDigest
object Update {
suspend fun checkUpdate(activity: AppCompatActivity, toolsBox: UITools, ignoreSkip: Boolean = false) = activity.apply{
val client = Client("reilia.fumiama.top", 13212)
val kanban = SimpleKanban(client, "fumiama")
val progressBar = layoutInflater.inflate(R.layout.dialog_progress, null, false)
val progressHandler = object : Client.Progress{
override fun notify(progressPercentage: Int) {
Log.d("MyUP", "Set progress: $progressPercentage")
progressBar.dpp.progress = progressPercentage
}
}
val msg = message(kanban)
if (msg == "null") {
if(ignoreSkip) withContext(Dispatchers.Main) {
Toast.makeText(this@apply, "无更新", Toast.LENGTH_SHORT).show()
}
return@apply
}
val verNum = msg.substringBefore('\n').toIntOrNull()
val skipNum = getPreferences(MODE_PRIVATE).getInt("skipVersion", 0)
Log.d("MyUP", "Ver:$verNum, skip: $skipNum")
if (verNum == null) return@apply
if(!msg.contains("md5:")) {
withContext(Dispatchers.Main) {
toolsBox.buildInfo("看板", msg.substringAfter('\n'), "知道了")
}
return@apply
}
if(skipNum < verNum || ignoreSkip) {
toolsBox.buildInfo("看板", msg.substringAfter('\n').substringBeforeLast('\n'), "下载新版", "跳过该版", "取消", {
val info = toolsBox.buildAlertWithView("下载进度", progressBar, "隐藏")
client.progress = progressHandler
lifecycleScope.launch {
fetch(client, kanban, this@apply) {
lifecycleScope.launch {
val md5 = msg.substringAfterLast("md5:")
if (md5 == toHexStr(
MessageDigest.getInstance("MD5").digest(it)
)
) {
Toast.makeText(this@apply, "下载成功", Toast.LENGTH_SHORT).show()
info.dismiss()
install(it, this@apply)
} else {
Toast.makeText(this@apply, "文件损坏", Toast.LENGTH_SHORT).show()
info.dismiss()
}
client.progress = null
}
}
}
}, {
getPreferences(MODE_PRIVATE).edit {
putInt("skipVersion", verNum)
apply()
}
})
}
}
private suspend fun message(kanban: SimpleKanban) = withContext(Dispatchers.IO) {
return@withContext kanban[BuildConfig.VERSION_CODE]
}
private suspend fun fetch(client: Client, kanban: SimpleKanban, context: Context, doOnLoadSuccess: (data: ByteArray) -> Unit) = withContext(Dispatchers.IO) {
return@withContext kanban.fetchRaw({ downloadFail(client, context) }, doOnLoadSuccess)
}
private suspend fun downloadFail(client: Client, context: Context) = withContext(Dispatchers.Main) {
Toast.makeText(context, R.string.download_apk_fail, Toast.LENGTH_SHORT).show()
client.progress = null
}
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

@@ -0,0 +1,121 @@
package top.fumiama.copymanga.api.update
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.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.core.content.edit
import androidx.lifecycle.lifecycleScope
import kotlinx.android.synthetic.main.dialog_progress.view.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.view.interaction.UITools
import top.fumiama.dmzj.copymanga.R
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<AppCompatActivity>, private val toolsBox: UITools,
private val ignoreSkip: Boolean, private val skipNum: Int,
): ApkUpdater("reilia.fumiama.top", 13212, "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.dpp.progress = progressPercentage
}
}
toolsBox.buildInfo("看板", message, "下载新版", "跳过该版", "取消", {
mInfo = toolsBox.buildAlertWithView("下载进度", progressBar, "隐藏")
a.get()?.lifecycleScope?.launch { 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

@@ -69,7 +69,7 @@ class Member(private val getString: (Int) -> String) {
username,
Charset.defaultCharset().name()
)
}&password=$pwdEncoded&salt=$salt&platform=${Config.platform.value}&authorization=Token+&version=${Config.app_ver.value}&source=copyApp&region=$r&webp=1".encodeToByteArray(),
}&password=$pwdEncoded&salt=$salt&platform=${Config.platform.value}&version=${Config.version.value}&source=Official".encodeToByteArray(),
"POST", "application/x-www-form-urlencoded;charset=utf-8")
}.encodeToByteArray()
}

View File

@@ -37,23 +37,23 @@ object DownloadTools {
if (it.isEmpty()) return@let
setRequestProperty("user-agent", if (it == Config.default_ua) Config.pc_ua else it)
}
Config.net_source.value.let { if(it.isNotEmpty()) setRequestProperty("source", it) }
Config.net_source.value.let { if(it.isNotEmpty()) setRequestProperty("x-requested-with", it) }
// deviceinfo
if (!Config.net_no_webp.value) setRequestProperty("webp", "1")
setRequestProperty("dt", SimpleDateFormat("yyyy.MM.dd", Locale.getDefault()).format(Calendar.getInstance().time))
//setRequestProperty("dt", SimpleDateFormat("yyyy.MM.dd", Locale.getDefault()).format(Calendar.getInstance().time))
if (Config.net_use_gzip.value) setRequestProperty("accept-encoding", "gzip")
setRequestProperty("authorization", "Token${Config.token.value?.let { tk ->
if (tk.isNotEmpty()) " $tk" else ""
}?:""}")
if (Config.net_platform.value) setRequestProperty("platform", Config.platform.value)
if (Config.net_referer.value) setRequestProperty("referer", Config.referer)
//if (Config.net_referer.value) setRequestProperty("referer", Config.referer)
if (Config.net_use_json.value) setRequestProperty("accept", "application/json")
if (Config.net_version.value) setRequestProperty("version", Config.app_ver.value)
if (Config.net_region.value) setRequestProperty("region", if(!Config.net_use_foreign.value) "1" else "0")
if (Config.net_version.value) setRequestProperty("version", Config.version.value)
//if (Config.net_region.value) setRequestProperty("region", if(!Config.net_use_foreign.value) "1" else "0")
// device
// host
Config.net_umstring.value.let { if (it.isNotEmpty()) setRequestProperty("umstring", it) }
setRequestProperty("connection", "close")
//Config.net_umstring.value.let { if (it.isNotEmpty()) setRequestProperty("umstring", it) }
//setRequestProperty("connection", "close")
}
Log.d("MyDT", "getConnection: $url\n${connection.requestProperties.map { "${it.key}: ${it.value}" }.joinToString("\n")}")
return connection
@@ -69,22 +69,22 @@ object DownloadTools {
if (it.isEmpty()) return@let
capsule.headers["user-agent"] = if (it == Config.default_ua) Config.pc_ua else it
}
Config.net_source.value.let { if(it.isNotEmpty()) capsule.headers["source"] = it }
Config.net_source.value.let { if(it.isNotEmpty()) capsule.headers["x-requested-with"] = it }
// deviceinfo
if (!Config.net_no_webp.value) capsule.headers["webp"] = "1"
capsule.headers["dt"] = SimpleDateFormat("yyyy.MM.dd", Locale.getDefault()).format(Calendar.getInstance().time)
//capsule.headers["dt"] = SimpleDateFormat("yyyy.MM.dd", Locale.getDefault()).format(Calendar.getInstance().time)
if (Config.net_use_gzip.value) capsule.headers["accept-encoding"] = "gzip"
capsule.headers["authorization"] = "Token${Config.token.value?.let { tk ->
if (tk.isNotEmpty()) " $tk" else ""
}?:""}"
if (Config.net_platform.value) capsule.headers["platform"] = Config.platform.value
if (Config.net_referer.value) capsule.headers["referer"] = Config.referer
//if (Config.net_referer.value) capsule.headers["referer"] = Config.referer
if (Config.net_use_json.value) capsule.headers["accept"] = "application/json"
if (Config.net_version.value) capsule.headers["version"] = Config.app_ver.value
if (Config.net_region.value) capsule.headers["region"] = if(!Config.net_use_foreign.value) "1" else "0"
if (Config.net_version.value) capsule.headers["version"] = Config.version.value
//if (Config.net_region.value) capsule.headers["region"] = if(!Config.net_use_foreign.value) "1" else "0"
// device
// host
Config.net_umstring.value.let { if (it.isNotEmpty()) capsule.headers["umstring"] = it }
//Config.net_umstring.value.let { if (it.isNotEmpty()) capsule.headers["umstring"] = it }
capsule.headers["connection"] = "close"
Log.d("MyDT", "getComandyConnection: $url\n${capsule.headers.map { "${it.key}: ${it.value}" }.joinToString("\n")}")

View File

@@ -45,7 +45,7 @@ class ConfigLoader {
var viewMangaHideInfo: Boolean,
) {
fun export() {
Config.app_ver.value = appVer
Config.version.value = appVer
Config.platform.value = platform
Config.general_enable_transparent_system_bar.value = generalEnableTransparentSystemBar
Config.general_disable_kanban_animation.value = generalDisableKanbanAnimation
@@ -88,7 +88,7 @@ class ConfigLoader {
val settings: Settings
constructor(): this(Settings(
appVer = Config.app_ver.value,
appVer = Config.version.value,
platform = Config.platform.value,
generalEnableTransparentSystemBar = Config.general_enable_transparent_system_bar.value,
generalDisableKanbanAnimation = Config.general_disable_kanban_animation.value,

View File

@@ -25,7 +25,7 @@ import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.api.manga.Book
import top.fumiama.copymanga.api.manga.Reader
import top.fumiama.copymanga.strings.Chinese
import top.fumiama.copymanga.view.template.NoBackRefreshFragment
import top.fumiama.copymanga.view.template.fragment.NoBackRefreshFragment
import top.fumiama.copymanga.view.interaction.Navigate
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment
import top.fumiama.dmzj.copymanga.R

View File

@@ -1,6 +1,6 @@
package top.fumiama.copymanga.ui.cardflow.author
import top.fumiama.copymanga.view.template.ThemeCardFlow
import top.fumiama.copymanga.view.template.cardflow.ThemeCardFlow
import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi

View File

@@ -1,6 +1,6 @@
package top.fumiama.copymanga.ui.cardflow.caption
import top.fumiama.copymanga.view.template.ThemeCardFlow
import top.fumiama.copymanga.view.template.cardflow.ThemeCardFlow
import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi

View File

@@ -2,7 +2,7 @@ package top.fumiama.copymanga.ui.cardflow.finish
import android.os.Bundle
import android.view.View
import top.fumiama.copymanga.view.template.StatusCardFlow
import top.fumiama.copymanga.view.template.cardflow.StatusCardFlow
import top.fumiama.dmzj.copymanga.R
import kotlinx.android.synthetic.main.line_finish.*

View File

@@ -4,7 +4,7 @@ import android.os.Bundle
import android.widget.Toast
import androidx.navigation.fragment.findNavController
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.view.template.InfoCardLoader
import top.fumiama.copymanga.view.template.cardflow.InfoCardLoader
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R

View File

@@ -1,6 +1,6 @@
package top.fumiama.copymanga.ui.cardflow.newest
import top.fumiama.copymanga.view.template.InfoCardLoader
import top.fumiama.copymanga.view.template.cardflow.InfoCardLoader
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R

View File

@@ -4,7 +4,7 @@ import android.os.Bundle
import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.fragment_rank.*
import kotlinx.android.synthetic.main.line_rank.view.*
import top.fumiama.copymanga.view.template.InfoCardLoader
import top.fumiama.copymanga.view.template.cardflow.InfoCardLoader
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.view.interaction.UITools
import top.fumiama.dmzj.copymanga.R

View File

@@ -1,6 +1,6 @@
package top.fumiama.copymanga.ui.cardflow.recommend
import top.fumiama.copymanga.view.template.InfoCardLoader
import top.fumiama.copymanga.view.template.cardflow.InfoCardLoader
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R

View File

@@ -2,7 +2,7 @@ package top.fumiama.copymanga.ui.cardflow.search
import android.os.Bundle
import android.util.Log
import top.fumiama.copymanga.view.template.InfoCardLoader
import top.fumiama.copymanga.view.template.cardflow.InfoCardLoader
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R
import java.net.URLEncoder

View File

@@ -8,7 +8,7 @@ import androidx.navigation.fragment.findNavController
import kotlinx.android.synthetic.main.anchor_popular.view.*
import kotlinx.android.synthetic.main.line_shelf.*
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.view.template.InfoCardLoader
import top.fumiama.copymanga.view.template.cardflow.InfoCardLoader
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R

View File

@@ -13,7 +13,7 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.FilterStructure
import top.fumiama.copymanga.json.ThemeStructure
import top.fumiama.copymanga.net.template.PausableDownloader
import top.fumiama.copymanga.view.template.StatusCardFlow
import top.fumiama.copymanga.view.template.cardflow.StatusCardFlow
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R

View File

@@ -10,7 +10,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.TopicStructure
import top.fumiama.copymanga.net.template.PausableDownloader
import top.fumiama.copymanga.view.template.InfoCardLoader
import top.fumiama.copymanga.view.template.cardflow.InfoCardLoader
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R

View File

@@ -14,7 +14,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.VolumeStructure
import top.fumiama.copymanga.view.template.NoBackRefreshFragment
import top.fumiama.copymanga.view.template.fragment.NoBackRefreshFragment
import top.fumiama.dmzj.copymanga.R
import java.io.File
import java.lang.ref.WeakReference

View File

@@ -16,7 +16,7 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.manga.Downloader
import top.fumiama.copymanga.api.manga.Reader
import top.fumiama.copymanga.view.template.NoBackRefreshFragment
import top.fumiama.copymanga.view.template.fragment.NoBackRefreshFragment
import top.fumiama.copymanga.storage.FileUtils
import top.fumiama.copymanga.view.interaction.Navigate
import top.fumiama.dmzj.copymanga.R

View File

@@ -26,8 +26,8 @@ import top.fumiama.copymanga.storage.FileUtils
import top.fumiama.copymanga.storage.FileUtils.compressToUserFile
import top.fumiama.copymanga.view.interaction.Navigate
import top.fumiama.copymanga.view.interaction.UITools
import top.fumiama.copymanga.view.template.CardList
import top.fumiama.copymanga.view.template.MangaPagesFragmentTemplate
import top.fumiama.copymanga.view.template.component.CardList
import top.fumiama.copymanga.view.template.fragment.MangaPagesFragmentTemplate
import top.fumiama.dmzj.copymanga.R
import java.io.File
import java.lang.ref.WeakReference

View File

@@ -34,13 +34,13 @@ import top.fumiama.copymanga.json.BookListStructure
import top.fumiama.copymanga.net.template.PausableDownloader
import top.fumiama.copymanga.view.interaction.Navigate
import top.fumiama.copymanga.view.operation.GlideHideLottieViewListener
import top.fumiama.copymanga.view.template.NoBackRefreshFragment
import top.fumiama.copymanga.view.template.fragment.NoBackRefreshFragment
import top.fumiama.dmzj.copymanga.R
import java.lang.ref.WeakReference
import java.net.URLEncoder
import java.nio.charset.Charset
class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home, true) {
class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
lateinit var homeHandler: HomeHandler
val vm: HomeViewModel by viewModels()
@@ -48,6 +48,8 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home, true) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (!isFirstInflate) return
val theme = resources.newTheme()
swiperefresh?.setColorSchemeColors(
resources.getColor(R.color.colorAccent, theme),
@@ -233,7 +235,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home, true) {
}
override fun onBindViewHolder(holder: ViewData, position: Int) {
val thisBanner = homeHandler.index?.results?.banners?.get(position)
val thisBanner = homeHandler.homeIndex?.results?.banners?.get(position)
thisBanner?.cover?.let {
if(it.isEmpty()) return@let
//Log.d("MyHomeFVP", "Load img: $it")
@@ -246,12 +248,12 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home, true) {
holder.itemView.vpt.text = thisBanner?.brief
holder.itemView.vpc.setOnClickListener {
val bundle = Bundle()
homeHandler.index?.results?.banners?.get(position)?.comic?.path_word?.let { it1 -> bundle.putString("path", it1) }
homeHandler.homeIndex?.results?.banners?.get(position)?.comic?.path_word?.let { it1 -> bundle.putString("path", it1) }
Navigate.safeNavigateTo(findNavController(), R.id.action_nav_home_to_nav_book, bundle)
}
}
override fun getItemCount(): Int = homeHandler.index?.results?.banners?.size?:0
override fun getItemCount(): Int = homeHandler.homeIndex?.results?.banners?.size?:0
}
}

View File

@@ -44,14 +44,14 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
IndexStructure::class.java,
that.get()
) {
private val homeF get() = that.get()
var index: IndexStructure? = null
private val homeFragment get() = that.get()
var homeIndex: IndexStructure? = null
private var fhib: Banner? = null
get() {
Log.d("MyHH", "Get fhib.")
if (field == null) {
field = homeF?.layoutInflater?.inflate(R.layout.viewpage_banner, homeF?.fhl, false) as Banner
homeF?.homeHandler?.sendEmptyMessage(3)
field = homeFragment?.layoutInflater?.inflate(R.layout.viewpage_banner, homeFragment?.fhl, false) as Banner
homeFragment?.homeHandler?.sendEmptyMessage(3)
}
return field
}
@@ -60,31 +60,31 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
super.handleMessage(msg)
when (msg.what) {
-1 -> {
homeF?.apply {
homeFragment?.apply {
swiperefresh?.isRefreshing = msg.obj as Boolean
if(msg.obj as Boolean) showKanban() else hideKanban()
}
}
//0 -> setLayouts()
1 -> inflateCardLines()
2 -> homeF?.swiperefresh?.let { setSwipe(it) }
2 -> homeFragment?.swiperefresh?.let { setSwipe(it) }
3 -> setBanner(fhib!!)
5 -> setBannerInfo(msg.obj as Banner)
7 -> inflateBanner()
}
}
override fun getGsonItem() = index
override fun getGsonItem() = homeIndex
override fun setGsonItem(gsonObj: Any) :Boolean {
val pass = super.setGsonItem(gsonObj)
index = gsonObj as IndexStructure
homeIndex = gsonObj as IndexStructure
var banners = arrayOf<IndexStructure.Results.Banners>()
index?.results?.banners?.forEach {
homeIndex?.results?.banners?.forEach {
if(it.type == 1) {
banners += it
}
}
index?.results?.banners = banners
homeIndex?.results?.banners = banners
return pass
}
override suspend fun onError() {
@@ -93,28 +93,28 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
sendEmptyMessage(2) //setSwipe
obtainMessage(-1, false).sendToTarget() //closeLoad
withContext(Dispatchers.Main) {
Toast.makeText(homeF?.context, R.string.web_error, Toast.LENGTH_SHORT).show()
Toast.makeText(homeFragment?.context, R.string.web_error, Toast.LENGTH_SHORT).show()
}
}
override suspend fun doWhenFinishDownload(): Unit = withContext(Dispatchers.IO) {
super.doWhenFinishDownload()
raw?.let {
Log.d("MyHFH", "save raw: $it")
homeF?.apply { activity?.runOnUiThread {
homeFragment?.apply { activity?.runOnUiThread {
vm.saveIndexStructure(it)
} }
}
}
private fun inflateBanner() {
homeF?.fhl?.let { it.post {
homeFragment?.fhl?.let { it.post {
fhib = null
it.addView(fhib)
} }
}
private suspend fun inflateTopics() {
index?.results?.topics?.list?.let {
homeIndex?.results?.topics?.list?.let {
var comics = arrayOf<ComicStructure>()
for((i, topic) in it.withIndex()){
if(i > 2) break
@@ -124,19 +124,19 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
newComic.path_word = topic.path_word
comics += newComic
}
if(comics.size == 3) allocateLine(homeF?.getString(R.string.topics_series)?:"", R.drawable.img_hot_serial, comics, isTopic = true)
if(comics.size == 3) allocateLine(homeFragment?.getString(R.string.topics_series)?:"", R.drawable.img_hot_serial, comics, isTopic = true)
}
}
private suspend fun inflateRec() {
index?.results?.recComics?.list?.let {
homeIndex?.results?.recComics?.list?.let {
var comics = arrayOf<ComicStructure>()
for((i, rec) in it.withIndex()){
if(i > 2) break
comics += rec.comic
}
if(comics.size == 3) allocateLine(homeF?.getString(R.string.manga_rec)?:"", R.drawable.img_master_work, comics) {
homeF?.findNavController()?.let { nav ->
if(comics.size == 3) allocateLine(homeFragment?.getString(R.string.manga_rec)?:"", R.drawable.img_master_work, comics) {
homeFragment?.findNavController()?.let { nav ->
Navigate.safeNavigateTo(nav, R.id.action_nav_home_to_nav_recommend)
}
}
@@ -145,74 +145,74 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
private suspend fun inflateRank(){
var comics = arrayOf<ComicStructure>()
if (index?.results?.rankDayComics == null) {
if (homeIndex?.results?.rankDayComics == null) {
// is in hotmanga
index?.results?.rankWeeklyFreeComics?.list?.let {
homeIndex?.results?.rankWeeklyFreeComics?.list?.let {
for((i, book) in it.withIndex()){
if(i > 2) break
comics += book.comic
}
}
if(comics.size == 3) allocateLine(homeF?.getString(R.string.hot_rank_list)?:"", R.drawable.img_novel_bill, comics) {
homeF?.findNavController()?.navigate(R.id.nav_rank)
if(comics.size == 3) allocateLine(homeFragment?.getString(R.string.hot_rank_list)?:"", R.drawable.img_novel_bill, comics) {
homeFragment?.findNavController()?.navigate(R.id.nav_rank)
}
return
}
index?.results?.rankDayComics?.list?.let {
homeIndex?.results?.rankDayComics?.list?.let {
for((i, book) in it.withIndex()){
if(i > 2) break
comics += book.comic
}
}
index?.results?.rankWeekComics?.list?.let {
homeIndex?.results?.rankWeekComics?.list?.let {
for((i, book) in it.withIndex()){
if(i > 2) break
comics += book.comic
}
}
index?.results?.rankMonthComics?.list?.let {
homeIndex?.results?.rankMonthComics?.list?.let {
for((i, book) in it.withIndex()){
if(i > 2) break
comics += book.comic
}
}
if(comics.size == 9) allocateLine(homeF?.getString(R.string.rank_list)?:"", R.drawable.img_novel_bill, comics) {
homeF?.findNavController()?.navigate(R.id.nav_rank)
if(comics.size == 9) allocateLine(homeFragment?.getString(R.string.rank_list)?:"", R.drawable.img_novel_bill, comics) {
homeFragment?.findNavController()?.navigate(R.id.nav_rank)
}
}
private suspend fun inflateHot(){
if (index?.results?.hotComics == null) {
if (homeIndex?.results?.hotComics == null) {
// is in hotmanga
index?.results?.updateWeeklyFreeComics?.let {
homeIndex?.results?.updateWeeklyFreeComics?.let {
var comics = arrayOf<ComicStructure>()
for((i, rec) in it.list.withIndex()){
if(i > 5) break
comics += rec.comic
}
if(comics.size == 6) allocateLine(homeF?.getString(R.string.hot_list)?:"", R.drawable.img_hot, comics)
if(comics.size == 6) allocateLine(homeFragment?.getString(R.string.hot_list)?:"", R.drawable.img_hot, comics)
}
return
}
index?.results?.hotComics?.let {
homeIndex?.results?.hotComics?.let {
var comics = arrayOf<ComicStructure>()
for((i, rec) in it.withIndex()){
if(i > 8) break
comics += rec.comic
}
if(comics.size == 9) allocateLine(homeF?.getString(R.string.hot_list)?:"", R.drawable.img_hot, comics)
if(comics.size == 9) allocateLine(homeFragment?.getString(R.string.hot_list)?:"", R.drawable.img_hot, comics)
}
}
private suspend fun inflateNew(){
index?.results?.newComics?.let {
homeIndex?.results?.newComics?.let {
var comics = arrayOf<ComicStructure>()
for((i, rec) in it.withIndex()){
if(i > 8) break
comics += rec.comic
}
if(comics.size == 9) allocateLine(homeF?.getString(R.string.new_list)?:"", R.drawable.img_latest_pub, comics) {
homeF?.findNavController()?.let { nav ->
if(comics.size == 9) allocateLine(homeFragment?.getString(R.string.new_list)?:"", R.drawable.img_latest_pub, comics) {
homeFragment?.findNavController()?.let { nav ->
Navigate.safeNavigateTo(nav, R.id.action_nav_home_to_nav_newest)
}
}
@@ -220,14 +220,14 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
}
private suspend fun inflateFinish(){
index?.results?.finishComics?.list?.let {
homeIndex?.results?.finishComics?.list?.let {
var comics = arrayOf<ComicStructure>()
for((i, rec) in it.withIndex()){
if(i > 5) break
comics += rec
}
if(comics.size == 6) allocateLine(homeF?.getString(R.string.complete)?:"", R.drawable.img_novel_eye, comics, true) {
homeF?.findNavController()?.let { nav ->
if(comics.size == 6) allocateLine(homeFragment?.getString(R.string.complete)?:"", R.drawable.img_novel_eye, comics, true) {
homeFragment?.findNavController()?.let { nav ->
Navigate.safeNavigateTo(nav, R.id.action_nav_home_to_nav_finish)
}
}
@@ -235,7 +235,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
}
private fun inflateCardLines() {
homeF?.lifecycleScope?.launch {
homeFragment?.lifecycleScope?.launch {
withContext(Dispatchers.IO) {
inflateRec()
inflateTopics()
@@ -263,42 +263,42 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
}
private fun setBannerInfo(v: Banner){
homeF?.context?.let { UITools(it) }?.let {
homeFragment?.context?.let { UITools(it) }?.let {
v
.addPageTransformer(ScaleInTransformer())
.setPageMargin(it.dp2px(20) ?: 0, it.dp2px(10) ?: 0)
.setIndicator(
IndicatorView(homeF!!.context)
IndicatorView(homeFragment!!.context)
.setIndicatorColor(Color.DKGRAY)
.setIndicatorSelectorColor(Color.WHITE)
.setIndicatorStyle(IndicatorView.IndicatorStyle.INDICATOR_BEZIER)
).adapter = homeF?.ViewData(v)?.RecyclerViewAdapter()
).adapter = homeFragment?.ViewData(v)?.RecyclerViewAdapter()
}
v.invalidate()
}
@SuppressLint("NotifyDataSetChanged")
private fun setSwipe(sw: SwipeRefreshLayout) {
homeF?.fhov?.swipeRefreshLayout = sw
homeFragment?.fhov?.swipeRefreshLayout = sw
sw.setOnRefreshListener {
Log.d("MyHFH", "Refresh items.")
homeF?.lifecycleScope?.launch {
homeFragment?.lifecycleScope?.launch {
withContext(Dispatchers.IO) {
homeF?.showKanban()
homeFragment?.showKanban()
fhib?.let {
it.isAutoPlay = false
index = null
homeIndex = null
it.adapter?.notifyDataSetChanged()
}
fhib = null
delay(300)
withContext(Dispatchers.Main) {
homeF?.fhl?.let {
homeFragment?.fhl?.let {
val oa = ObjectAnimator.ofFloat(it, "alpha", 1f, 0f).setDuration(233)
oa.doOnEnd { _ ->
it.removeAllViews()
it.alpha = 1f
homeF?.vm?.saveIndexStructure(null) // reload
homeFragment?.vm?.saveIndexStructure(null) // reload
}
oa.start()
}
@@ -313,7 +313,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
finish: Boolean = false, isTopic: Boolean = false, onClick: (() -> Unit)? = null
): Unit = withContext(Dispatchers.IO) {
val c = comics.size / 3
homeF?.layoutInflater?.inflate(
homeFragment?.layoutInflater?.inflate(
when(c){
1 -> R.layout.line_1bookline
2 -> R.layout.line_2bookline
@@ -329,7 +329,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
if(onClick != null) setOnClickListener { onClick() }
}
}
homeF?.fhl?.let { it.post { it.addView(this) } }
homeFragment?.fhl?.let { it.post { it.addView(this) } }
}
return@withContext
}
@@ -354,7 +354,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
private fun setCards(cv: CardView, pw: String, name: String, img: String, isFinal: Boolean, isTopic: Boolean) {
cv.tic.apply { post { text = name } }
homeF?.let {
homeFragment?.let {
if(img.startsWith("http")) {
//Log.d("MyHH", "load card image: $img")
val waitMillis = cardLoadingWaits.getAndIncrement().toLong()*200
@@ -372,7 +372,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
cv.setOnClickListener {
val bundle = Bundle()
bundle.putString("path", pw)
homeF?.findNavController()?.let { nav ->
homeFragment?.findNavController()?.let { nav ->
Navigate.safeNavigateTo(nav, if(isTopic) R.id.action_nav_home_to_nav_topic else R.id.action_nav_home_to_nav_book, bundle)
}
}
@@ -383,7 +383,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
v.viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
homeF?.context?.let { UITools(it) }?.let {
homeFragment?.context?.let { UITools(it) }?.let {
val spaceTitle = it.dp2px(49)!!
val cardSpace = it.dp2px(16)!!
v.layoutParams.height =

View File

@@ -54,7 +54,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.view.template.TitleActivityTemplate
import top.fumiama.copymanga.view.template.activity.TitleActivityTemplate
import top.fumiama.copymanga.net.template.PausableDownloader
import top.fumiama.copymanga.net.DownloadTools
import top.fumiama.copymanga.view.interaction.TimeThread
@@ -339,14 +339,15 @@ class ViewMangaActivity : TitleActivityTemplate() {
suspend fun countZipEntries(doWhenFinish : suspend (count: Int) -> Unit) = withContext(Dispatchers.IO) {
if (zipFile != null) try {
Log.d("MyVM", "zip: $zipFile")
val zip = ZipFile(zipFile)
count = zip.size()
if(cut) zip.entries().toList().sortedBy{ it.name.substringBefore('.').toInt()}.forEachIndexed { i, it ->
val useCut = canCut(zip.getInputStream(it))
isCut += useCut
indexMap += i + 1
if (useCut) indexMap += -(i + 1)
Log.d("MyVM", "[$i] 分析: ${it.name}, cut: $useCut")
ZipFile(zipFile).use { zip ->
count = zip.size()
if(cut) zip.entries().toList().sortedBy{ it.name.substringBefore('.').toInt()}.forEachIndexed { i, it ->
val useCut = canCut(zip.getInputStream(it))
isCut += useCut
indexMap += i + 1
if (useCut) indexMap += -(i + 1)
Log.d("MyVM", "[$i] 分析: ${it.name}, cut: $useCut")
}
}
} catch (e: Exception) {
toolsBox.toastErrorAndFinish(R.string.count_zip_entries_error)

View File

@@ -1,4 +1,4 @@
package top.fumiama.copymanga.view.template
package top.fumiama.copymanga.view.template.activity
import android.os.Bundle
import android.view.View

View File

@@ -1,4 +1,4 @@
package top.fumiama.copymanga.view.template
package top.fumiama.copymanga.view.template.activity
import android.os.Bundle
import kotlinx.android.synthetic.main.widget_titlebar.*

View File

@@ -1,4 +1,4 @@
package top.fumiama.copymanga.view.template
package top.fumiama.copymanga.view.template.cardflow
import android.annotation.SuppressLint
import android.os.Bundle
@@ -22,6 +22,8 @@ import top.fumiama.copymanga.json.TypeBookListStructure
import top.fumiama.copymanga.net.template.PausableDownloader
import top.fumiama.copymanga.strings.Chinese
import top.fumiama.copymanga.view.interaction.Navigate
import top.fumiama.copymanga.view.template.fragment.MangaPagesFragmentTemplate
import top.fumiama.copymanga.view.template.component.CardList
import top.fumiama.dmzj.copymanga.R
import java.lang.ref.WeakReference

View File

@@ -1,4 +1,4 @@
package top.fumiama.copymanga.view.template
package top.fumiama.copymanga.view.template.cardflow
import android.animation.ObjectAnimator
import android.view.View

View File

@@ -1,4 +1,4 @@
package top.fumiama.copymanga.view.template
package top.fumiama.copymanga.view.template.cardflow
import android.os.Bundle
import android.view.View

View File

@@ -1,4 +1,4 @@
package top.fumiama.copymanga.view.template
package top.fumiama.copymanga.view.template.component
import android.annotation.SuppressLint
import android.net.Uri

View File

@@ -1,10 +1,7 @@
package top.fumiama.copymanga.view.template
package top.fumiama.copymanga.view.template.fragment
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Bundle
import android.util.Log
import android.view.View
@@ -19,52 +16,32 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.view.interaction.UITools
import top.fumiama.dmzj.copymanga.R
import top.fumiama.copymanga.view.template.component.CardList
import java.lang.ref.WeakReference
open class MangaPagesFragmentTemplate(inflateRes:Int, private val isLazy: Boolean = true, val forceLoad: Boolean = false) : NoBackRefreshFragment(inflateRes) {
open class MangaPagesFragmentTemplate(
inflateRes:Int, private val isLazy: Boolean = true,
val forceLoad: Boolean = false
) : NoBackRefreshFragment(inflateRes) {
var cardPerRow = 3
var cardWidth = 0
var cardHeight = 0
var cardList: CardList? = null
//var row: View? = null
var isEnd = false
//var jsonReaderNow: JsonReader? = null
var page = 0
var isRefresh = false
private val transportStringNull = context?.getString(R.string.TRANSPORT_NULL) ?: "TRANSPORT_NULL"
private val transportStringError = context?.getString(R.string.TRANSPORT_ERROR) ?: "TRANSPORT_ERROR"
private val netInfo: String
get() {
val cm: ConnectivityManager =
context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return cm.getNetworkCapabilities(cm.activeNetwork)?.let {
when {
it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> return@let context?.getString(
R.string.TRANSPORT_WIFI)
it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> return@let context?.getString(
R.string.TRANSPORT_CELLULAR)
it.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> return@let context?.getString(
R.string.TRANSPORT_BLUETOOTH)
it.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> return@let context?.getString(
R.string.TRANSPORT_ETHERNET)
it.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) -> return@let context?.getString(
R.string.TRANSPORT_LOWPAN)
it.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> return@let "VPN"
else -> return@let transportStringNull
}
} ?: transportStringError
}
@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if(isFirstInflate) {
if (!forceLoad && (netInfo == transportStringNull || netInfo == transportStringError)) {
val tb = (activity as MainActivity).toolsBox
val netInfo = tb.netInfo
if (!forceLoad && (netInfo == tb.transportStringNull || netInfo == tb.transportStringError)) {
findNavController().popBackStack()
return
}
@@ -81,8 +58,6 @@ open class MangaPagesFragmentTemplate(inflateRes:Int, private val isLazy: Boolea
override fun onDestroy() {
super.onDestroy()
cardList?.exitCardList = true
//row = null
//jsonReaderNow = null
}
private suspend fun setLayouts() = withContext(Dispatchers.IO) {
@@ -100,39 +75,33 @@ open class MangaPagesFragmentTemplate(inflateRes:Int, private val isLazy: Boolea
Log.d("MyMPAT", "Card per row: $cardPerRow")
Log.d("MyMPAT", "Card width: $cardWidth")
initCardList(WeakReference(this@MangaPagesFragmentTemplate))
managePage()
addPage()
if (isLazy) { mysp.apply { post {
setListener(object : SpringView.OnFreshListener {
override fun onLoadmore() {
lifecycleScope.launch {
addPage()
}
}
override fun onRefresh() {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
showKanban()
reset()
delay(600)
addPage()
hideKanban()
}
}
}
})
} } }
setListeners()
hideKanban()
}
private suspend fun managePage() {
addPage()
if (isLazy) {
mysp.apply {
post {
setListener(object : SpringView.OnFreshListener {
override fun onLoadmore() {
lifecycleScope.launch {
addPage()
}
}
override fun onRefresh() {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
showKanban()
reset()
delay(600)
addPage()
hideKanban()
}
}
}
})
}
}
}
}
open suspend fun addPage() {}
open suspend fun onLoadFinish() = withContext(Dispatchers.Main) {

View File

@@ -1,4 +1,4 @@
package top.fumiama.copymanga.view.template
package top.fumiama.copymanga.view.template.fragment
import android.animation.ObjectAnimator
import android.os.Bundle

View File

@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
<!ENTITY hosturl "api.copy-manga.com">
<!ENTITY appver "2.3.0">
<!ENTITY hosturl "api.2024manga.com">
<!ENTITY appver "2024.4.28">
<!ENTITY proxyurl "copymanga.azurewebsites.net">
<!ENTITY platform "3">
<!ENTITY source "copyApp">
<!ENTITY source "com.manga2020.app">
]>
<resources>
<string name="app_name">拷贝漫画</string>
<string name="source">&source;</string>
<string name="action_settings">设定</string>
<string name="action_info">关于</string>
@@ -67,12 +66,12 @@
<string name="analyze_img_size_error">读取图片大小失败</string>
<string name="networkApiUrl">/api/v3/system/network2?platform=%1$s</string>
<string name="mainPageApiUrl">/api/v3/h5/homeIndex2?platform=%1$s</string>
<string name="mainPageApiUrl">/api/v3/h5/homeIndex?platform=%1$s</string>
<string name="hostUrl">&hosturl;</string>
<string name="proxyUrl">&proxyurl;</string>
<string name="rankApiUrl">/api/v3/ranks?limit=21&amp;offset=%1$d&amp;date_type=%2$s&amp;audience_type=%3$s&amp;platform=%4$s</string>
<string name="searchApiUrl">/api/v3/search/comic?limit=21&amp;offset=%1$d&amp;q=%2$s&amp;q_type=%3$s&amp;platform=%4$s</string>
<string name="filterApiUrl">/api/v3/h5/filter/comic/tags?platform=%1$s</string>
<string name="filterApiUrl">/api/v3/h5/filterIndex/comic/tags?type=1&amp;platform=%1$s</string>
<string name="sortApiUrl">/api/v3/comics?limit=21&amp;offset=%1$d&amp;ordering=%2$s&amp;theme=%3$s&amp;top=%4$s&amp;platform=%5$s</string>
<string name="bookInfoApiUrl">/api/v3/comic2/%1$s?platform=%2$s</string>
<string name="bookUserQueryApiUrl">/api/v3/comic2/%1$s/query?platform=%2$s</string>
@@ -114,10 +113,10 @@
<string name="TRANSPORT_NULL">无网络</string>
<string name="TRANSPORT_ERROR">网络错误</string>
<string name="pc_ua">COPY/%1$s</string>
<string name="pc_ua">Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Mobile Safari/537.36 Edg/141.0.0.0</string>
<string name="default_ua">__default_ua__</string>
<string name="app_ver">&appver;</string>
<string name="referer">com.copymanga.app-%1$s</string>
<string name="version">&appver;</string>
<string name="requested">&source;</string>
<string name="platform">&platform;</string>
<string name="menu_update_time">更新时间</string>

View File

@@ -39,7 +39,7 @@
<EditTextPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:defaultValue="@string/app_ver"
android:defaultValue="@string/version"
android:selectAllOnFocus="false"
android:singleLine="true"
android:title="@string/settings_cat_general_et_title_app_version"