1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-05 07:20:23 +08:00
优化
1. 集中管理设置项
升级
1. androidx.constraintlayout -> 2.2.1
2. gson -> 2.12.1
3. lottie -> 6.6.4
4. jna -> 5.17.0
This commit is contained in:
源文雨
2025-03-24 18:44:00 +09:00
parent 01da01c4fb
commit af8aca46a4
44 changed files with 489 additions and 406 deletions

View File

@@ -17,6 +17,7 @@
<w>pausable</w> <w>pausable</w>
<w>reclass</w> <w>reclass</w>
<w>reilia</w> <w>reilia</w>
<w>systembar</w>
</words> </words>
</dictionary> </dictionary>
</component> </component>

View File

@@ -78,7 +78,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.12.0' implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
//noinspection GradleDependency //noinspection GradleDependency
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7' implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
//noinspection GradleDependency //noinspection GradleDependency
@@ -91,13 +91,13 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.16.0' implementation 'com.github.bumptech.glide:glide:4.16.0'
//noinspection KaptUsageInsteadOfKsp //noinspection KaptUsageInsteadOfKsp
kapt 'com.github.bumptech.glide:compiler:4.16.0' kapt 'com.github.bumptech.glide:compiler:4.16.0'
implementation 'com.google.code.gson:gson:2.11.0' implementation 'com.google.code.gson:gson:2.12.1'
implementation 'com.github.vovaksenov99:OverscrollableScrollView:1.0' implementation 'com.github.vovaksenov99:OverscrollableScrollView:1.0'
implementation 'com.github.liaoinstan.SpringView:library:0a24d3e9dd' implementation 'com.github.liaoinstan.SpringView:library:0a24d3e9dd'
implementation 'com.github.zawadz88:MaterialPopupMenu:4.1.0' implementation 'com.github.zawadz88:MaterialPopupMenu:4.1.0'
implementation files('libs/com.lapism/search-2.4.1.aar') // https://stackoverflow.com/a/63029110/28801553 implementation files('libs/com.lapism/search-2.4.1.aar') // https://stackoverflow.com/a/63029110/28801553
//noinspection GradleDependency //noinspection GradleDependency
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation 'com.airbnb.android:lottie:6.5.2' implementation 'com.airbnb.android:lottie:6.6.4'
implementation 'net.java.dev.jna:jna:5.15.0@aar' implementation 'net.java.dev.jna:jna:5.17.0@aar'
} }

View File

@@ -7,9 +7,9 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import kotlinx.android.synthetic.main.activity_login.* import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import kotlin.random.Random import kotlin.random.Random
@@ -18,11 +18,10 @@ class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login) setContentView(R.layout.activity_login)
val pref = MainActivity.mainWeakReference?.get()?.getPreferences(MODE_PRIVATE) ?: return val isLogout = !Config.token.value.isNullOrEmpty()
val isLogout = pref.getString("token", null) != null
if (isLogout) { if (isLogout) {
alblogin.setText(R.string.logout) alblogin.setText(R.string.logout)
altusrnm.setText(pref.getString("username", "N/A")) altusrnm.setText(Config.username.value)
} }
alblogin.setOnClickListener { alblogin.setOnClickListener {
lifecycleScope.launch { lifecycleScope.launch {
@@ -61,14 +60,12 @@ class LoginActivity : AppCompatActivity() {
Toast.makeText(this@LoginActivity, l?.message, Toast.LENGTH_LONG).show() Toast.makeText(this@LoginActivity, l?.message, Toast.LENGTH_LONG).show()
} }
} }
PreferenceManager.getDefaultSharedPreferences(this)?.apply { if (Config.general_enable_transparent_system_bar.value) {
if (getBoolean("settings_cat_general_sw_enable_transparent_systembar", false)) { WindowCompat.setDecorFitsSystemWindows(window, false)
WindowCompat.setDecorFitsSystemWindows(window, false) window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) window.statusBarColor = 0
window.statusBarColor = 0 window.navigationBarColor = 0
window.navigationBarColor = 0
}
} }
} }
} }

View File

@@ -23,7 +23,6 @@ import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.collection.size
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.edit import androidx.core.content.edit
@@ -32,7 +31,6 @@ import androidx.core.view.WindowCompat
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.contains
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp import androidx.navigation.ui.navigateUp
@@ -52,6 +50,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.manga.Shelf import top.fumiama.copymanga.manga.Shelf
import top.fumiama.copymanga.tools.ui.UITools import top.fumiama.copymanga.tools.ui.UITools
import top.fumiama.copymanga.ui.book.BookFragment.Companion.bookHandler import top.fumiama.copymanga.ui.book.BookFragment.Companion.bookHandler
@@ -172,7 +171,7 @@ class MainActivity : AppCompatActivity() {
)[it]) )[it])
} }
} }
if (getBoolean("settings_cat_general_sw_enable_transparent_systembar", false)) { if (Config.general_enable_transparent_system_bar.value) {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
@@ -255,23 +254,22 @@ class MainActivity : AppCompatActivity() {
} }
} }
suspend fun refreshUserInfo() = withContext(Dispatchers.IO) { suspend fun refreshUserInfo(): Unit = withContext(Dispatchers.IO) {
getPreferences(MODE_PRIVATE)?.apply { var name = Config.nickname.value
val name = getString("nickname", getString("username", "")) if (name.isNullOrEmpty()) name = Config.username.value
val avatar = getString("avatar", "") val avatar = Config.avatar.value
navttitle.apply { post { navttitle.apply { post {
if(name != "") text = name if(!name.isNullOrEmpty()) text = name
else setText(R.string.noLogin) else setText(R.string.noLogin)
} } } }
navhicon.apply ic@ { post { navhicon.apply ic@ { post {
if(avatar != "") if(!avatar.isNullOrEmpty())
Glide.with(this@MainActivity).load(avatar) Glide.with(this@MainActivity).load(avatar)
.apply(RequestOptions.bitmapTransform(CircleCrop())) .apply(RequestOptions.bitmapTransform(CircleCrop()))
.timeout(60000) .timeout(60000)
.into(this@ic) .into(this@ic)
else setImageResource(R.mipmap.ic_launcher) else setImageResource(R.mipmap.ic_launcher)
} } } }
}
} }
private fun changeMenuList(latestDestination: Int) { private fun changeMenuList(latestDestination: Int) {
@@ -450,9 +448,7 @@ class MainActivity : AppCompatActivity() {
get() { get() {
if (field != null) return field if (field != null) return field
return mainWeakReference?.get()?.let { return mainWeakReference?.get()?.let {
field = Shelf( field = Shelf { id ->
it.getPreferences(Context.MODE_PRIVATE)
.getString("token", "")?:return@let null) { id ->
return@Shelf it.getString(id) return@Shelf it.getString(id)
} }
field field
@@ -462,10 +458,8 @@ class MainActivity : AppCompatActivity() {
get() { get() {
if (field != null) return field if (field != null) return field
return mainWeakReference?.get()?.let { return mainWeakReference?.get()?.let {
it.getPreferences(MODE_PRIVATE)?.let { pref -> field = Member { id ->
field = Member(pref) { id -> return@Member it.getString(id)
return@Member it.getString(id)
}
} }
field field
} }

View File

@@ -0,0 +1,93 @@
package top.fumiama.copymanga.api
import com.bumptech.glide.load.model.LazyHeaders
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.tools.file.PreferenceBoolean
import top.fumiama.copymanga.tools.file.PreferenceInt
import top.fumiama.copymanga.tools.file.PreferenceString
import top.fumiama.copymanga.tools.file.UserPreferenceInt
import top.fumiama.copymanga.tools.file.UserPreferenceString
import top.fumiama.copymanga.tools.http.Proxy
import top.fumiama.copymanga.tools.http.Resolution
import top.fumiama.dmzj.copymanga.R
import java.io.File
object Config {
var imageProxy: Proxy? = null
get() {
if (!net_use_img_proxy.value) return null
if (field != null) return field
field = Proxy(
R.string.imgProxyApiUrl,
Regex("^https://[0-9a-z-]+\\.mangafun[a-z]\\.(xyz|fun)/"),
)
return field
}
var apiProxy: Proxy? = null
get() {
if (!net_use_api_proxy.value) return null
if (field != null) return field
field = Proxy(
R.string.apiProxyApiUrl,
Regex("^https://(api|www)\\.(copymanga|mangacopy|copy-manga)\\.\\w+/api/"),
)
return field
}
val resolution = Resolution(Regex("c\\d+x\\."))
var myGlideHeaders: LazyHeaders? = null
get() {
if (field === null)
field = LazyHeaders.Builder()
.addHeader("referer", referer)
.addHeader("User-Agent", pc_ua)
.addHeader("source", "copyApp")
.addHeader("webp", "1")
.addHeader("version", app_ver.value)
.addHeader(
"region",
if (net_use_foreign.value) "1" else "0"
)
.addHeader("platform", "3")
.build()
return field
}
val myHostApiUrl = PreferenceString("settings_cat_net_et_api_url", R.string.hostUrl)
val proxy_key = PreferenceString(R.string.imgProxyKeyID)
val app_ver = PreferenceString("settings_cat_general_et_app_version", R.string.app_ver)
val token = UserPreferenceString("token", "", null)
val pc_ua get() = MainActivity.mainWeakReference?.get()?.getString(R.string.pc_ua)?.format(app_ver.value)?:""
val referer get() = MainActivity.mainWeakReference?.get()?.getString(R.string.referer)?.format(app_ver.value)?:""
val comandy_version = UserPreferenceInt("comandy_version", 0)
val user_id = UserPreferenceString("user_id")
val username = UserPreferenceString("username")
val nickname = UserPreferenceString("nickname")
val avatar = UserPreferenceString("avatar")
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)
val general_card_per_row = PreferenceInt("settings_cat_general_sb_card_per_row", 0)
val manga_dl_max_batch = PreferenceInt("settings_cat_md_sb_max_batch", 16)
val manga_dl_show_0m_manga = PreferenceBoolean("settings_cat_md_sw_show_0m_manga", false)
val net_use_comandy = PreferenceBoolean("settings_cat_net_sw_use_comandy", false)
val net_use_foreign = PreferenceBoolean("settings_cat_net_sw_use_foreign", false)
private val net_use_img_proxy = PreferenceBoolean("settings_cat_net_sw_use_img_proxy", false)
val net_use_api_proxy = PreferenceBoolean("settings_cat_net_sw_use_api_proxy", false)
val view_manga_always_dark_bg = PreferenceBoolean("settings_cat_vm_sw_always_dark_bg", false)
val view_manga_vertical_max = PreferenceInt("settings_cat_vm_sb_vertical_max", 20)
val view_manga_quality = PreferenceInt("settings_cat_vm_sb_quality", 100)
val view_manga_vol_turn = PreferenceBoolean("settings_cat_vm_sw_vol_turn", false)
val view_manga_use_cellar = PreferenceBoolean("settings_cat_net_sw_use_cellar", false)
val view_manga_hide_info = PreferenceBoolean("settings_cat_vm_sw_hide_info", false)
fun getZipFile(exDir: File?, manga: String, caption: CharSequence, name: CharSequence) =
File(File(File(exDir, manga), caption.toString()), "$name.zip")
fun getChapterInfoApiUrl(path: String?, uuid: String?, version: Int) =
MainActivity.mainWeakReference?.get()?.getString(R.string.chapterInfoApiUrl)
?.format(myHostApiUrl.value, path, if (version >= 2) "$version" else "" , uuid)
}

View File

@@ -9,16 +9,16 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.BookInfoStructure import top.fumiama.copymanga.json.BookInfoStructure
import top.fumiama.copymanga.json.ThemeStructure import top.fumiama.copymanga.json.ThemeStructure
import top.fumiama.copymanga.json.VolumeStructure import top.fumiama.copymanga.json.VolumeStructure
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.http.DownloadTools import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import java.io.File import java.io.File
class Book(val path: String, private val getString: (Int) -> String, private val exDir: File, private val loadCache: Boolean = false, private val mPassName: String? = null) { class Book(val path: String, private val getString: (Int) -> String, private val exDir: File, private val loadCache: Boolean = false, private val mPassName: String? = null) {
private val mBookApiUrl = getString(R.string.bookInfoApiUrl).format(CMApi.myHostApiUrl, path).let { private val mBookApiUrl = getString(R.string.bookInfoApiUrl).format(Config.myHostApiUrl.value, path).let {
CMApi.apiProxy?.wrap(it)?:it Config.apiProxy?.wrap(it)?:it
} }
private val mUserAgent = getString(R.string.pc_ua).format(DownloadTools.app_ver) private val mUserAgent = getString(R.string.pc_ua).format(Config.app_ver.value)
private var mBook: BookInfoStructure? = null private var mBook: BookInfoStructure? = null
private var mGroupPathWords = arrayOf<String>() private var mGroupPathWords = arrayOf<String>()
private var mKeys = arrayOf<String>() private var mKeys = arrayOf<String>()
@@ -139,7 +139,7 @@ class Book(val path: String, private val getString: (Int) -> String, private val
val mangaFolder = File(exDir, name) val mangaFolder = File(exDir, name)
if(!mangaFolder.exists()) mangaFolder.mkdirs() if(!mangaFolder.exists()) mangaFolder.mkdirs()
val f = File(mangaFolder, "head.jpg") val f = File(mangaFolder, "head.jpg")
if(force || !f.exists()) (cover?.let { CMApi.imageProxy?.wrap(it) } ?:cover)?.let { if(force || !f.exists()) (cover?.let { Config.imageProxy?.wrap(it) } ?:cover)?.let {
Thread { Thread {
DownloadTools.getHttpContent(it, -1)?.let { data -> DownloadTools.getHttpContent(it, -1)?.let { data ->
f.writeBytes(data) f.writeBytes(data)

View File

@@ -8,7 +8,7 @@ import top.fumiama.copymanga.template.http.PausableDownloader
import top.fumiama.copymanga.tools.http.DownloadPool import top.fumiama.copymanga.tools.http.DownloadPool
import java.io.File import java.io.File
class MangaDlTools { class Downloader {
private var pool: DownloadPool? = null private var pool: DownloadPool? = null
private var grp: CharSequence = "" private var grp: CharSequence = ""
private var indexMap = hashMapOf<String, Int>() private var indexMap = hashMapOf<String, Int>()

View File

@@ -5,16 +5,15 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.BookQueryStructure import top.fumiama.copymanga.json.BookQueryStructure
import top.fumiama.copymanga.json.ReturnBase import top.fumiama.copymanga.json.ReturnBase
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.http.DownloadTools import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
class Shelf(private val token: String, private val getString: (Int) -> String) { class Shelf(private val getString: (Int) -> String) {
private val apiUrl: String get() = getString(R.string.shelfOperateApiUrl).format(CMApi.myHostApiUrl) private val apiUrl: String get() = getString(R.string.shelfOperateApiUrl).format(Config.myHostApiUrl.value)
private val queryApiUrlTemplate = getString(R.string.bookUserQueryApiUrl) private val queryApiUrlTemplate = getString(R.string.bookUserQueryApiUrl)
private val referer: String = getString(R.string.referer).format(DownloadTools.app_ver) private val addApiUrl get() = "$apiUrl?platform=3".let { Config.apiProxy?.wrap(it)?:it }
private val addApiUrl get() = "$apiUrl?platform=3".let { CMApi.apiProxy?.wrap(it)?:it } private val delApiUrl get() = "${apiUrl}s?platform=3".let { Config.apiProxy?.wrap(it)?:it }
private val delApiUrl get() = "${apiUrl}s?platform=3".let { CMApi.apiProxy?.wrap(it)?:it }
suspend fun add(comicId: String): String = withContext(Dispatchers.IO) { suspend fun add(comicId: String): String = withContext(Dispatchers.IO) {
if (comicId.isEmpty()) { if (comicId.isEmpty()) {
return@withContext "空漫画ID" return@withContext "空漫画ID"
@@ -24,7 +23,7 @@ class Shelf(private val token: String, private val getString: (Int) -> String) {
append(comicId) append(comicId)
append("&is_collect=1&authorization=Token+") append("&is_collect=1&authorization=Token+")
append("") append("")
append(token) append(Config.token.value)
} }
val re = DownloadTools.requestWithBody( val re = DownloadTools.requestWithBody(
addApiUrl, "POST", body.encodeToByteArray() addApiUrl, "POST", body.encodeToByteArray()
@@ -47,7 +46,7 @@ class Shelf(private val token: String, private val getString: (Int) -> String) {
append("&") append("&")
} }
append("authorization=Token+") append("authorization=Token+")
append(token) append(Config.token.value)
} }
val re = DownloadTools.requestWithBody( val re = DownloadTools.requestWithBody(
delApiUrl, "DELETE", body.encodeToByteArray() delApiUrl, "DELETE", body.encodeToByteArray()
@@ -62,9 +61,9 @@ class Shelf(private val token: String, private val getString: (Int) -> String) {
suspend fun query(pathWord: String): BookQueryStructure? = withContext(Dispatchers.IO) { suspend fun query(pathWord: String): BookQueryStructure? = withContext(Dispatchers.IO) {
try { try {
Gson().fromJson(DownloadTools.getHttpContent( Gson().fromJson(DownloadTools.getHttpContent(
queryApiUrlTemplate.format(CMApi.myHostApiUrl, pathWord).let { queryApiUrlTemplate.format(Config.myHostApiUrl.value, pathWord).let {
CMApi.apiProxy?.wrap(it)?:it Config.apiProxy?.wrap(it)?:it
}, referer }, Config.referer
).decodeToString(), BookQueryStructure::class.java) ).decodeToString(), BookQueryStructure::class.java)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View File

@@ -7,7 +7,7 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.ChapterStructure import top.fumiama.copymanga.json.ChapterStructure
import top.fumiama.copymanga.json.VolumeStructure import top.fumiama.copymanga.json.VolumeStructure
import top.fumiama.copymanga.template.http.PausableDownloader import top.fumiama.copymanga.template.http.PausableDownloader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
class Volume(private val path: String, private val groupPathWord: String, getString: (Int) -> String, private val isExit: ()->Boolean, private val setProgress: ((Int) -> Unit)? = null) { class Volume(private val path: String, private val groupPathWord: String, getString: (Int) -> String, private val isExit: ()->Boolean, private val setProgress: ((Int) -> Unit)? = null) {
@@ -39,7 +39,7 @@ class Volume(private val path: String, private val groupPathWord: String, getStr
return@withContext mVolume return@withContext mVolume
} }
private fun getApiUrl(offset: Int) = mGroupInfoApiUrlTemplate.format(CMApi.myHostApiUrl, path, groupPathWord, offset) private fun getApiUrl(offset: Int) = mGroupInfoApiUrlTemplate.format(Config.myHostApiUrl.value, path, groupPathWord, offset)
private suspend fun download(re: Array<VolumeStructure?>, offset: Int, c: Int) = withContext(Dispatchers.IO) { private suspend fun download(re: Array<VolumeStructure?>, offset: Int, c: Int) = withContext(Dispatchers.IO) {
Log.d("MyV", "下载偏移: $offset") Log.d("MyV", "下载偏移: $offset")
getApiUrl(offset).let { getApiUrl(offset).let {

View File

@@ -8,10 +8,9 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.animation.doOnEnd import androidx.core.animation.doOnEnd
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
import kotlinx.android.synthetic.main.content_main.* import kotlinx.android.synthetic.main.content_main.*
import kotlinx.coroutines.runBlocking
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.ui.UITools import top.fumiama.copymanga.tools.ui.UITools
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
@@ -20,9 +19,7 @@ open class NoBackRefreshFragment(private val layoutToLoad: Int): Fragment() {
val rootView: View get() = _rootView!! val rootView: View get() = _rootView!!
var isFirstInflate = true var isFirstInflate = true
var navBarHeight = 0 var navBarHeight = 0
private val disableAnimation = MainActivity.mainWeakReference?.get()?.let { private val disableAnimation get() = Config.general_disable_kanban_animation.value
PreferenceManager.getDefaultSharedPreferences(it)
}?.getBoolean("settings_cat_general_sw_disable_kanban_animation", false)?:false
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,

View File

@@ -13,9 +13,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.json.ReturnBase import top.fumiama.copymanga.json.ReturnBase
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.http.DownloadTools import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.dmzj.copymanga.R
import java.io.File import java.io.File
import java.security.MessageDigest import java.security.MessageDigest
@@ -78,7 +77,7 @@ open class AutoDownloadHandler(
var cnt = 0 var cnt = 0
while (cnt++ <= 3) { while (cnt++ <= 3) {
try { try {
val data = DownloadTools.getHttpContent(CMApi.apiProxy?.wrap(url)?:url) val data = DownloadTools.getHttpContent(Config.apiProxy?.wrap(url)?:url)
if(exit) return@withContext if(exit) return@withContext
val fi = data.inputStream() val fi = data.inputStream()
val pass = setGsonItem(Gson().fromJson(fi.reader(), jsonClass)) val pass = setGsonItem(Gson().fromJson(fi.reader(), jsonClass))

View File

@@ -4,10 +4,8 @@ import android.util.Log
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.http.DownloadTools import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.dmzj.copymanga.R
import kotlin.random.Random import kotlin.random.Random
class PausableDownloader(private val url: String, private val waitMilliseconds: Long = 0, private val isApi: Boolean = true, private val whenFinish: (suspend (result: ByteArray)->Unit)? = null) { class PausableDownloader(private val url: String, private val waitMilliseconds: Long = 0, private val isApi: Boolean = true, private val whenFinish: (suspend (result: ByteArray)->Unit)? = null) {
@@ -17,8 +15,8 @@ class PausableDownloader(private val url: String, private val waitMilliseconds:
while (!exit && c++ < 3) { while (!exit && c++ < 3) {
try { try {
val data = (DownloadTools.getHttpContent( val data = (DownloadTools.getHttpContent(
(if(isApi) CMApi.apiProxy?.wrap(url) else null)?:url, (if(isApi) Config.apiProxy?.wrap(url) else null)?:url,
DownloadTools.referer Config.referer
)) ))
whenFinish?.let { it(data) } whenFinish?.let { it(data) }
return@withContext true return@withContext true

View File

@@ -13,7 +13,7 @@ import kotlinx.android.synthetic.main.line_horizonal_empty.view.*
import kotlinx.android.synthetic.main.line_lazybooklines.* import kotlinx.android.synthetic.main.line_lazybooklines.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import java.io.File import java.io.File
@@ -131,7 +131,7 @@ class CardList(
that?.context?.let { context -> that?.context?.let { context ->
val waitMillis = cardLoadingWaits.getAndIncrement().toLong()*200 val waitMillis = cardLoadingWaits.getAndIncrement().toLong()*200
val g = Glide.with(context).load( val g = Glide.with(context).load(
GlideUrl(CMApi.imageProxy?.wrap(head)?:head, CMApi.myGlideHeaders) GlideUrl(Config.imageProxy?.wrap(head)?:head, Config.myGlideHeaders)
).addListener(GlideHideLottieViewListener(WeakReference(it.laic)) { ).addListener(GlideHideLottieViewListener(WeakReference(it.laic)) {
if (exitCardList) return@GlideHideLottieViewListener if (exitCardList) return@GlideHideLottieViewListener
cardLoadingWaits.decrementAndGet() cardLoadingWaits.decrementAndGet()

View File

@@ -3,9 +3,7 @@ package top.fumiama.copymanga.template.ui
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.view.View import android.view.View
import kotlinx.android.synthetic.main.anchor_popular.view.* import kotlinx.android.synthetic.main.anchor_popular.view.*
import kotlinx.coroutines.Dispatchers import top.fumiama.copymanga.api.Config
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi @ExperimentalStdlibApi
@@ -20,7 +18,7 @@ open class StatusCardFlow(private val api: Int, nav: Int, inflateRes: Int,
override fun getApiUrl() = override fun getApiUrl() =
getString(api).format( getString(api).format(
CMApi.myHostApiUrl, Config.myHostApiUrl.value,
page * 21, page * 21,
sortWay[sortValue] sortWay[sortValue]
) )

View File

@@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.View import android.view.View
import kotlinx.android.synthetic.main.app_bar_main.* import kotlinx.android.synthetic.main.app_bar_main.*
import kotlinx.android.synthetic.main.line_finish.* import kotlinx.android.synthetic.main.line_finish.*
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi @ExperimentalStdlibApi
@@ -12,7 +12,7 @@ open class ThemeCardFlow(private val api: Int, nav: Int) : StatusCardFlow(0, nav
private var theme = "" private var theme = ""
override fun getApiUrl() = override fun getApiUrl() =
getString(api).format( getString(api).format(
CMApi.myHostApiUrl, Config.myHostApiUrl.value,
page * 21, page * 21,
sortWay[sortValue], sortWay[sortValue],
theme theme

View File

@@ -1,78 +0,0 @@
package top.fumiama.copymanga.tools.api
import androidx.preference.PreferenceManager
import com.bumptech.glide.load.model.LazyHeaders
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.copymanga.tools.http.Proxy
import top.fumiama.copymanga.tools.http.Resolution
import top.fumiama.dmzj.copymanga.R
import java.io.File
object CMApi {
var imageProxy: Proxy? = null
get() {
if (field != null) return field
if (Proxy.useImageProxy) field = Proxy(
R.string.imgProxyApiUrl,
Regex("^https://[0-9a-z-]+\\.mangafun[a-z]\\.(xyz|fun)/"),
R.string.imgProxyKeyID
)
return field
}
var apiProxy: Proxy? = null
get() {
if (field != null) return field
if (Proxy.useApiProxy) field = Proxy(
R.string.apiProxyApiUrl,
Regex("^https://api\\.(copymanga|mangacopy)\\.\\w+/api/"),
R.string.imgProxyKeyID
)
return field
}
var resolution = Resolution(Regex("c\\d+x\\."))
var myGlideHeaders: LazyHeaders? = null
get() {
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
if (field === null)
field = LazyHeaders.Builder()
.addHeader("referer", DownloadTools.referer)
.addHeader("User-Agent", DownloadTools.pc_ua)
.addHeader("source", "copyApp")
.addHeader("webp", "1")
.addHeader("version", DownloadTools.app_ver)
.addHeader(
"region",
if (!getBoolean("settings_cat_net", false)) "1" else "0"
)
.addHeader("platform", "3")
.build()
}
}
return field
}
var myHostApiUrl: String = ""
get() {
if (field != "") return field
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
getString("settings_cat_net_et_api_url", "")?.let { host ->
if (host != "") {
field = host
return host
}
}
}
field = it.getString(R.string.hostUrl)
}
return field
}
fun getZipFile(exDir: File?, manga: String, caption: CharSequence, name: CharSequence) =
File(exDir, "$manga/$caption/$name.zip")
fun getChapterInfoApiUrl(path: String?, uuid: String?, version: Int) =
MainActivity.mainWeakReference?.get()?.getString(R.string.chapterInfoApiUrl)
?.format(myHostApiUrl, path, if (version >= 2) "$version" else "" , uuid)
}

View File

@@ -0,0 +1,20 @@
package top.fumiama.copymanga.tools.file
import android.util.Log
import androidx.preference.PreferenceManager
import top.fumiama.copymanga.MainActivity
data class PreferenceBoolean(private val key: String, private var default: Boolean) {
val value: Boolean
get() {
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
getBoolean(key, default).let { v ->
Log.d("MyPB", "get key $key value $v")
return v
}
}
}
return default
}
}

View File

@@ -0,0 +1,20 @@
package top.fumiama.copymanga.tools.file
import android.util.Log
import androidx.preference.PreferenceManager
import top.fumiama.copymanga.MainActivity
data class PreferenceInt(private val key: String, private var default: Int) {
val value: Int
get() {
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
getInt(key, default).let { v ->
Log.d("MyPI", "get key $key value $v")
return v
}
}
}
return default
}
}

View File

@@ -0,0 +1,36 @@
package top.fumiama.copymanga.tools.file
import android.util.Log
import androidx.preference.PreferenceManager
import top.fumiama.copymanga.MainActivity
data class PreferenceString(private val key: String, private var default: String?, private val defaultID: Int) {
constructor(key: Int, default: String?, defaultID: Int): this(
MainActivity.mainWeakReference?.get()?.getString(key) ?:"", default, defaultID)
constructor(key: String, default: Int): this(key, null, default)
constructor(key: Int): this(key, "", 0)
private val defaultField: String
get() {
if (default != null) return default!!
MainActivity.mainWeakReference?.get()?.let {
default = it.getString(defaultID)
}
return default?:""
}
val value: String
get() {
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
getString(key, null)?.let { v ->
if (v.isNotEmpty()) {
Log.d("MyPS", "get key $key value $v")
return v
}
}
}
}
Log.d("MyPS", "get default key $key value $defaultField")
return defaultField
}
}

View File

@@ -0,0 +1,46 @@
package top.fumiama.copymanga.tools.file
import android.util.Log
import androidx.appcompat.app.AppCompatActivity.MODE_PRIVATE
import androidx.core.content.edit
import top.fumiama.copymanga.MainActivity
data class UserPreferenceInt(private val key: String, private var default: Int) {
var value: Int? = null
get() {
field?.let {
Log.d("MyUPI", "get cached key $key value $it")
return it
}
MainActivity.mainWeakReference?.get()?.let {
it.getPreferences(MODE_PRIVATE).apply {
getInt(key, default).let { v ->
field = v
Log.d("MyUPI", "get new key $key value $v")
return v
}
}
}
Log.d("MyUPI", "get default key $key value $default")
return default
}
set(value) {
if (value == null) {
Log.d("MyUPI", "remove key $key")
MainActivity.mainWeakReference?.get()?.let {
it.getPreferences(MODE_PRIVATE).apply {
edit(commit = true) { remove(key) }
}
}
field = default
return
}
field = value
Log.d("MyUPI", "set key $key value $value")
MainActivity.mainWeakReference?.get()?.let {
it.getPreferences(MODE_PRIVATE).apply {
edit(commit = true) { putInt(key, value) }
}
}
}
}

View File

@@ -0,0 +1,62 @@
package top.fumiama.copymanga.tools.file
import android.util.Log
import androidx.appcompat.app.AppCompatActivity.MODE_PRIVATE
import androidx.core.content.edit
import top.fumiama.copymanga.MainActivity
data class UserPreferenceString(private val key: String, private var default: String?, private val defaultID: Int?) {
constructor(key: String): this(key, "", 0)
constructor(key: String, default: Int): this(key, null, default)
constructor(key: String, default: String): this(key, default, 0)
private val defaultField: String?
get() {
default?.let { return it }
defaultID?.let { id ->
MainActivity.mainWeakReference?.get()?.let {
default = it.getString(id)
}
}
return default
}
var value: String? = null
get() {
field?.let {
Log.d("MyUPS", "get cached key $key value $it")
return it
}
MainActivity.mainWeakReference?.get()?.let {
it.getPreferences(MODE_PRIVATE).apply {
getString(key, null)?.let { v ->
if (v.isNotEmpty()) {
field = v
Log.d("MyUPS", "get new key $key value $v")
return v
}
}
}
}
field = defaultField
Log.d("MyUPS", "get default key $key value $field")
return field
}
set(value) {
if (value == null) {
Log.d("MyUPS", "get remove key $key")
MainActivity.mainWeakReference?.get()?.let {
it.getPreferences(MODE_PRIVATE).apply {
edit(commit = true) { remove(key) }
}
}
field = defaultField
return
}
field = value
Log.d("MyUPS", "set key $key value $value")
MainActivity.mainWeakReference?.get()?.let {
it.getPreferences(MODE_PRIVATE).apply {
edit(commit = true) { putString(key, value) }
}
}
}
}

View File

@@ -2,13 +2,11 @@ package top.fumiama.copymanga.tools.http
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import com.google.gson.Gson import com.google.gson.Gson
import com.sun.jna.Library import com.sun.jna.Library
import com.sun.jna.Native import com.sun.jna.Native
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.json.ComandyVersion import top.fumiama.copymanga.json.ComandyVersion
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
@@ -43,16 +41,9 @@ interface Comandy : Library {
return true return true
} }
if (mUseComandy != null) return mUseComandy!! if (mUseComandy != null) return mUseComandy!!
MainActivity.mainWeakReference?.get()?.let { val v = Config.net_use_comandy.value
PreferenceManager.getDefaultSharedPreferences(it).apply { mUseComandy = v
val b = getBoolean("settings_cat_net_sw_use_comandy", false) return v
Log.d("MyComandy", "use comandy: $b")
mUseComandy = b
return b
}
}
mUseComandy = false
return false
} }
private val libraryFile: File? private val libraryFile: File?
get() { get() {
@@ -82,7 +73,7 @@ interface Comandy : Library {
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
val myVersion = ma.getPreferences(AppCompatActivity.MODE_PRIVATE).getInt("comandy_version", 0) val myVersion = Config.comandy_version.value?:0
if (myVersion >= remoteVersion) { if (myVersion >= remoteVersion) {
Log.d("MyComandy", "lib version $myVersion is latest") Log.d("MyComandy", "lib version $myVersion is latest")
isInInit.set(false) isInInit.set(false)
@@ -99,10 +90,7 @@ interface Comandy : Library {
dataIn.copyTo(dataOut) dataIn.copyTo(dataOut)
} }
} }
if (remoteVersion > 0) ma.getPreferences(AppCompatActivity.MODE_PRIVATE).edit { if (remoteVersion > 0) Config.comandy_version.value = remoteVersion
putInt("comandy_version", remoteVersion)
apply()
}
Log.d("MyComandy", "update success") Log.d("MyComandy", "update success")
isInInit.set(false) isInInit.set(false)
} catch (e: Exception) { } catch (e: Exception) {

View File

@@ -1,10 +1,7 @@
package top.fumiama.copymanga.tools.http package top.fumiama.copymanga.tools.http
import android.util.Log import android.util.Log
import kotlinx.coroutines.Dispatchers import top.fumiama.copymanga.api.Config
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.tools.api.CMApi
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.lang.Thread.sleep import java.lang.Thread.sleep
@@ -100,7 +97,7 @@ class DownloadPool(folder: String) {
var s = false var s = false
while (!s && tryTimes-- > 0) { while (!s && tryTimes-- > 0) {
val u = imgUrls[index] val u = imgUrls[index]
s = (DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(u)?:u), -1))?.let { s = (DownloadTools.getHttpContent(Config.resolution.wrap(Config.imageProxy?.wrap(u)?:u), -1))?.let {
zip.putNextEntry(ZipEntry("$index.${if(imgUrls[index].contains(".webp")) "webp" else "jpg"}")) zip.putNextEntry(ZipEntry("$index.${if(imgUrls[index].contains(".webp")) "webp" else "jpg"}"))
zip.write(it) zip.write(it)
zip.closeEntry() zip.closeEntry()

View File

@@ -1,16 +1,13 @@
package top.fumiama.copymanga.tools.http package top.fumiama.copymanga.tools.http
import android.content.Context
import android.util.Base64 import android.util.Base64
import android.util.Log import android.util.Log
import androidx.preference.PreferenceManager
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.json.ComandyCapsule import top.fumiama.copymanga.json.ComandyCapsule
import top.fumiama.dmzj.copymanga.R
import java.lang.IllegalArgumentException
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL
import java.util.concurrent.Callable import java.util.concurrent.Callable
@@ -18,13 +15,6 @@ import java.util.concurrent.FutureTask
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
object DownloadTools { object DownloadTools {
val app_ver = MainActivity.mainWeakReference?.get()?.let { main ->
PreferenceManager.getDefaultSharedPreferences(main)
?.getString("settings_cat_general_et_app_version", main.getString(R.string.app_ver))
?:main.getString(R.string.app_ver)
}!!
val pc_ua = MainActivity.mainWeakReference?.get()!!.getString(R.string.pc_ua).format(app_ver)
val referer = MainActivity.mainWeakReference?.get()!!.getString(R.string.referer).format(app_ver)
val failTimes = AtomicInteger(0) val failTimes = AtomicInteger(0)
fun getApiConnection(url: String, method: String = "GET", refer: String? = null, ua: String? = null, timeout: Int = 20000) = fun getApiConnection(url: String, method: String = "GET", refer: String? = null, ua: String? = null, timeout: Int = 20000) =
url.let { url.let {
@@ -38,16 +28,10 @@ object DownloadTools {
refer?.let { setRequestProperty("referer", it) } refer?.let { setRequestProperty("referer", it) }
setRequestProperty("source", "copyApp") setRequestProperty("source", "copyApp")
setRequestProperty("webp", "1") setRequestProperty("webp", "1")
MainActivity.mainWeakReference?.get()?.let { setRequestProperty("region", if(!Config.net_use_foreign.value) "1" else "0")
PreferenceManager.getDefaultSharedPreferences(it).apply { setRequestProperty("version", Config.app_ver.value)
setRequestProperty("region", if(!getBoolean("settings_cat_net_sw_use_foreign", false)) "1" else "0") Config.token.value?.let { tk ->
} setRequestProperty("authorization", "Token $tk")
it.getPreferences(Context.MODE_PRIVATE).apply {
setRequestProperty("version", app_ver)
getString("token", "")?.let { tk ->
setRequestProperty("authorization", "Token $tk")
}
}
} }
setRequestProperty("platform", "3") setRequestProperty("platform", "3")
} }
@@ -67,14 +51,10 @@ object DownloadTools {
capsule.headers["source"] = "copyApp" capsule.headers["source"] = "copyApp"
capsule.headers["webp"] = "1" capsule.headers["webp"] = "1"
MainActivity.mainWeakReference?.get()?.let { MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply { capsule.headers["region"] = if(!Config.net_use_foreign.value) "1" else "0"
capsule.headers["region"] = if(!getBoolean("settings_cat_net_sw_use_foreign", false)) "1" else "0" capsule.headers["version"] = Config.app_ver.value
} Config.token.value?.let { tk ->
it.getPreferences(Context.MODE_PRIVATE).apply { capsule.headers["authorization"] = "Token $tk"
capsule.headers["version"] = app_ver
getString("token", "")?.let { tk ->
capsule.headers["authorization"] = "Token $tk"
}
} }
} }
capsule.headers["platform"] = "3" capsule.headers["platform"] = "3"
@@ -105,7 +85,7 @@ object DownloadTools {
capsule capsule
} }
suspend fun getHttpContent(u: String, refer: String? = null, ua: String? = pc_ua): ByteArray = suspend fun getHttpContent(u: String, refer: String? = null, ua: String? = Config.pc_ua): ByteArray =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) { if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) {
getComandyApiConnection(u, "GET", refer, ua).let { capsule -> getComandyApiConnection(u, "GET", refer, ua).let { capsule ->
@@ -150,7 +130,7 @@ object DownloadTools {
FutureTask(if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) Callable{ FutureTask(if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) Callable{
try { try {
Comandy.instance?.request(Gson().toJson( Comandy.instance?.request(Gson().toJson(
getComandyNormalConnection(u, "GET", pc_ua)) getComandyNormalConnection(u, "GET", Config.pc_ua))
)?.let { result -> )?.let { result ->
Gson().fromJson(result, ComandyCapsule::class.java)?.let { Gson().fromJson(result, ComandyCapsule::class.java)?.let {
if (it.code != 200) null if (it.code != 200) null
@@ -164,7 +144,7 @@ object DownloadTools {
} else Callable { } else Callable {
var ret: ByteArray? = null var ret: ByteArray? = null
try { try {
val connection = getNormalConnection(u, "GET", pc_ua) val connection = getNormalConnection(u, "GET", Config.pc_ua)
val ci = connection.inputStream val ci = connection.inputStream
if(readSize > 0) { if(readSize > 0) {
ret = ByteArray(readSize) ret = ByteArray(readSize)
@@ -186,7 +166,7 @@ object DownloadTools {
} }
}*/ }*/
fun requestWithBody(url: String, method: String, body: ByteArray, refer: String? = referer, ua: String? = pc_ua, contentType: String? = "application/x-www-form-urlencoded;charset=utf-8"): ByteArray? { fun requestWithBody(url: String, method: String, body: ByteArray, refer: String? = Config.referer, ua: String? = Config.pc_ua, contentType: String? = "application/x-www-form-urlencoded;charset=utf-8"): ByteArray? {
Log.d("MyDT", "$method Http: $url") Log.d("MyDT", "$method Http: $url")
var ret: ByteArray? = null var ret: ByteArray? = null
val task = FutureTask(if(!url.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) Callable{ val task = FutureTask(if(!url.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) Callable{

View File

@@ -1,17 +1,13 @@
package top.fumiama.copymanga.tools.http package top.fumiama.copymanga.tools.http
import android.util.Log import android.util.Log
import androidx.preference.PreferenceManager
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.Config.proxy_key
import java.net.URLEncoder import java.net.URLEncoder
import java.nio.charset.Charset import java.nio.charset.Charset
class Proxy(id: Int, private val apiRegex: Regex, keyID: Int? = null) { class Proxy(id: Int, private val apiRegex: Regex) {
private val code = keyID?.let { k -> private val code get() = proxy_key.value
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).getString(it.getString(k), null)
}
}
private val proxyApiUrl = MainActivity.mainWeakReference?.get()?.getString(id) private val proxyApiUrl = MainActivity.mainWeakReference?.get()?.getString(id)
fun wrap(u: String): String { fun wrap(u: String): String {
@@ -19,8 +15,9 @@ class Proxy(id: Int, private val apiRegex: Regex, keyID: Int? = null) {
Log.d("MyP", "[N] wrap: $u") Log.d("MyP", "[N] wrap: $u")
return u return u
} }
if(!code.isNullOrEmpty()) { if(code.isNotEmpty() and !proxyApiUrl.isNullOrEmpty()) {
val wu = proxyApiUrl?.format(code, URLEncoder.encode(u, Charset.defaultCharset().name()))?:u val wu = proxyApiUrl?.format(code, URLEncoder.encode(u, Charset.defaultCharset().name()))
?:u
Log.d("MyP", "[M] wrap: $wu") Log.d("MyP", "[M] wrap: $wu")
return wu return wu
} }
@@ -28,37 +25,4 @@ class Proxy(id: Int, private val apiRegex: Regex, keyID: Int? = null) {
//return proxyApiUrl?.format(URLEncoder.encode(u, Charset.defaultCharset().name()))?:u //return proxyApiUrl?.format(URLEncoder.encode(u, Charset.defaultCharset().name()))?:u
return u return u
} }
companion object {
private var mUseImageProxy: Boolean? = null
val useImageProxy: Boolean
get() {
if (mUseImageProxy != null) return mUseImageProxy!!
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
val b = getBoolean("settings_cat_net_sw_use_img_proxy", false)
Log.d("MyProxy", "use image proxy: $b")
mUseImageProxy = b
return b
}
}
mUseImageProxy = false
return false
}
private var mUseApiProxy: Boolean? = null
val useApiProxy: Boolean
get() {
if (mUseApiProxy != null) return mUseApiProxy!!
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
val b = getBoolean("settings_cat_net_sw_use_api_proxy", false)
Log.d("MyProxy", "use api proxy: $b")
mUseApiProxy = b
return b
}
}
mUseApiProxy = false
return false
}
}
} }

View File

@@ -8,15 +8,16 @@ import android.net.ConnectivityManager
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.preference.PreferenceManager
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import kotlin.math.sqrt import kotlin.math.sqrt
class UITools(that: Context?, w: WeakReference<Activity>? = null) { class UITools(that: Context?, w: WeakReference<Activity>? = null) {
private val zis = that private val weakZis = WeakReference(that)
private val zis get() = weakZis.get()
private val weak = w private val weak = w
constructor(w: WeakReference<Activity>): this(w.get()?.applicationContext, w) constructor(w: WeakReference<Activity>): this(w.get()?.applicationContext, w)
val transportStringNull = zis?.getString(R.string.TRANSPORT_NULL) ?: "TRANSPORT_NULL" val transportStringNull = zis?.getString(R.string.TRANSPORT_NULL) ?: "TRANSPORT_NULL"
@@ -27,16 +28,16 @@ class UITools(that: Context?, w: WeakReference<Activity>? = null) {
zis?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager zis?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return cm.getNetworkCapabilities(cm.activeNetwork)?.let { return cm.getNetworkCapabilities(cm.activeNetwork)?.let {
when { when {
it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> return@let zis.getString( it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> return@let zis?.getString(
R.string.TRANSPORT_WIFI) R.string.TRANSPORT_WIFI)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> return@let zis.getString( it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> return@let zis?.getString(
R.string.TRANSPORT_CELLULAR) R.string.TRANSPORT_CELLULAR)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> return@let zis.getString( it.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> return@let zis?.getString(
R.string.TRANSPORT_BLUETOOTH) R.string.TRANSPORT_BLUETOOTH)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> return@let zis.getString( it.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> return@let zis?.getString(
R.string.TRANSPORT_ETHERNET) R.string.TRANSPORT_ETHERNET)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) -> return@let zis.getString( it.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) -> return@let zis?.getString(
R.string.TRANSPORT_LOWPAN) R.string.TRANSPORT_LOWPAN)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> return@let "VPN" it.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> return@let "VPN"
else -> return@let transportStringNull else -> return@let transportStringNull
} }
@@ -99,11 +100,8 @@ class UITools(that: Context?, w: WeakReference<Activity>? = null) {
val margin = marginLeftDp.toDouble() val margin = marginLeftDp.toDouble()
val marginPx = dp2px(marginLeftDp)?:16 val marginPx = dp2px(marginLeftDp)?:16
val screenWidth = zis?.resources?.displayMetrics?.widthPixels?:1080 val screenWidth = zis?.resources?.displayMetrics?.widthPixels?:1080
val numPerRow = ((px2dp(screenWidth)?:400).toDouble() / (widthDp + 2 * margin) + 0.5).toInt().let { val numPerRow = (((px2dp(screenWidth)?:400).toDouble() / (widthDp + 2 * margin) + 0.5).toInt()
it + (zis?.let { + Config.general_card_per_row.value).let { if(it <= 0) 3 else it }
a -> PreferenceManager.getDefaultSharedPreferences(a).getInt("settings_cat_general_sb_card_per_row", 0)
} ?: 0)
}.let { if(it <= 0) 3 else it }
val w = (screenWidth - marginPx*numPerRow*2)/numPerRow val w = (screenWidth - marginPx*numPerRow*2)/numPerRow
val totalWidth = screenWidth/numPerRow val totalWidth = screenWidth/numPerRow
return listOf(numPerRow, w, totalWidth) return listOf(numPerRow, w, totalWidth)

View File

@@ -39,7 +39,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.ThemeStructure import top.fumiama.copymanga.json.ThemeStructure
import top.fumiama.copymanga.manga.Reader import top.fumiama.copymanga.manga.Reader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.ui.GlideBlurTransformation import top.fumiama.copymanga.tools.ui.GlideBlurTransformation
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
import top.fumiama.copymanga.tools.ui.Navigate import top.fumiama.copymanga.tools.ui.Navigate
@@ -88,7 +88,7 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
that?.apply { that?.apply {
Glide.with(this).load( Glide.with(this).load(
if (book?.cover != null) if (book?.cover != null)
GlideUrl(CMApi.imageProxy?.wrap(book?.cover!!)?:book?.cover!!, CMApi.myGlideHeaders) GlideUrl(Config.imageProxy?.wrap(book?.cover!!)?:book?.cover!!, Config.myGlideHeaders)
else book?.cachedCover else book?.cachedCover
) )
.timeout(60000) .timeout(60000)
@@ -222,7 +222,7 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
var line: View? = null var line: View? = null
last += v.results.list.size last += v.results.list.size
v.results.list.forEach { v.results.list.forEach {
val f = CMApi.getZipFile(context?.getExternalFilesDir(""), comicName, keys[p], it.name) val f = Config.getZipFile(context?.getExternalFilesDir(""), comicName, keys[p], it.name)
//Log.d("MyBH", "i = $i, last=$last, add chapter ${it.name}, line is null: ${line == null}") //Log.d("MyBH", "i = $i, last=$last, add chapter ${it.name}, line is null: ${line == null}")
that?.isOnPause?.let { isOnPause -> that?.isOnPause?.let { isOnPause ->
while (isOnPause && !exit) delay(500) while (isOnPause && !exit) delay(500)
@@ -277,12 +277,12 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
if(exit) return@withContext if(exit) return@withContext
last += v.results.list.size last += v.results.list.size
v.results.list.forEach { v.results.list.forEach {
urlArray += CMApi.getChapterInfoApiUrl( urlArray += Config.getChapterInfoApiUrl(
path, path,
it.uuid, it.uuid,
version version
)?:"" )?:""
val f = CMApi.getZipFile(context?.getExternalFilesDir(""), comicName, keys[groupIndex], it.name) val f = Config.getZipFile(context?.getExternalFilesDir(""), comicName, keys[groupIndex], it.name)
Reader.fileArray += f Reader.fileArray += f
chapterNames += it.name chapterNames += it.name
uuidArray += it.uuid uuidArray += it.uuid

View File

@@ -5,13 +5,13 @@ import android.widget.Toast
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
class HistoryFragment : InfoCardLoader(R.layout.fragment_history, R.id.action_nav_history_to_nav_book, isHistoryBook = true) { class HistoryFragment : InfoCardLoader(R.layout.fragment_history, R.id.action_nav_history_to_nav_book, isHistoryBook = true) {
override fun getApiUrl() = override fun getApiUrl() =
getString(R.string.historyApiUrl).format(CMApi.myHostApiUrl, page * 21) getString(R.string.historyApiUrl).format(Config.myHostApiUrl.value, page * 21)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
if (MainActivity.member?.hasLogin != true) { if (MainActivity.member?.hasLogin != true) {

View File

@@ -1,11 +1,11 @@
package top.fumiama.copymanga.ui.cardflow.newest package top.fumiama.copymanga.ui.cardflow.newest
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi @ExperimentalStdlibApi
class NewestFragment : InfoCardLoader(R.layout.fragment_newest, R.id.action_nav_newest_to_nav_book, true) { class NewestFragment : InfoCardLoader(R.layout.fragment_newest, R.id.action_nav_newest_to_nav_book, true) {
override fun getApiUrl() = override fun getApiUrl() =
getString(R.string.newestApiUrl).format(CMApi.myHostApiUrl, page * 21) getString(R.string.newestApiUrl).format(Config.myHostApiUrl.value, page * 21)
} }

View File

@@ -5,7 +5,7 @@ import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.fragment_rank.* import kotlinx.android.synthetic.main.fragment_rank.*
import kotlinx.android.synthetic.main.line_rank.view.* import kotlinx.android.synthetic.main.line_rank.view.*
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.ui.UITools import top.fumiama.copymanga.tools.ui.UITools
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@@ -48,7 +48,7 @@ class RankFragment : InfoCardLoader(R.layout.fragment_rank, R.id.action_nav_rank
override fun getApiUrl() = override fun getApiUrl() =
getString(R.string.rankApiUrl).format( getString(R.string.rankApiUrl).format(
CMApi.myHostApiUrl, Config.myHostApiUrl.value,
page * 21, page * 21,
sortWay[sortValue], sortWay[sortValue],
audienceWay[audience] audienceWay[audience]

View File

@@ -1,11 +1,11 @@
package top.fumiama.copymanga.ui.cardflow.recommend package top.fumiama.copymanga.ui.cardflow.recommend
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi @ExperimentalStdlibApi
class RecFragment : InfoCardLoader(R.layout.fragment_recommend, R.id.action_nav_recommend_to_nav_book, true) { class RecFragment : InfoCardLoader(R.layout.fragment_recommend, R.id.action_nav_recommend_to_nav_book, true) {
override fun getApiUrl() = override fun getApiUrl() =
getString(R.string.recommendApiUrl).format(CMApi.myHostApiUrl, page * 21) getString(R.string.recommendApiUrl).format(Config.myHostApiUrl.value, page * 21)
} }

View File

@@ -3,7 +3,7 @@ package top.fumiama.copymanga.ui.cardflow.search
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi @ExperimentalStdlibApi
@@ -11,7 +11,7 @@ class SearchFragment : InfoCardLoader(R.layout.fragment_search, R.id.action_nav_
private var query: String? = null private var query: String? = null
private var type: String? = null private var type: String? = null
override fun getApiUrl() = override fun getApiUrl() =
getString(R.string.searchApiUrl).format(CMApi.myHostApiUrl, page * 21, query, type) getString(R.string.searchApiUrl).format(Config.myHostApiUrl.value, page * 21, query, type)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -9,7 +9,7 @@ import kotlinx.android.synthetic.main.anchor_popular.view.*
import kotlinx.android.synthetic.main.line_shelf.* import kotlinx.android.synthetic.main.line_shelf.*
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi @ExperimentalStdlibApi
@@ -26,7 +26,7 @@ class ShelfFragment : InfoCardLoader(R.layout.fragment_shelf, R.id.action_nav_su
override fun getApiUrl() = override fun getApiUrl() =
getString(R.string.shelfApiUrl).format( getString(R.string.shelfApiUrl).format(
CMApi.myHostApiUrl, Config.myHostApiUrl.value,
page * 21, page * 21,
sortWay[sortValue] sortWay[sortValue]
) )

View File

@@ -14,7 +14,7 @@ import top.fumiama.copymanga.json.FilterStructure
import top.fumiama.copymanga.json.ThemeStructure import top.fumiama.copymanga.json.ThemeStructure
import top.fumiama.copymanga.template.http.PausableDownloader import top.fumiama.copymanga.template.http.PausableDownloader
import top.fumiama.copymanga.template.ui.StatusCardFlow import top.fumiama.copymanga.template.ui.StatusCardFlow
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi @ExperimentalStdlibApi
@@ -25,7 +25,7 @@ class SortFragment : StatusCardFlow(0, R.id.action_nav_sort_to_nav_book, R.layou
override fun getApiUrl() = override fun getApiUrl() =
getString(R.string.sortApiUrl).format( getString(R.string.sortApiUrl).format(
CMApi.myHostApiUrl, Config.myHostApiUrl.value,
page * 21, page * 21,
sortWay[sortValue], sortWay[sortValue],
if(theme >= 0 && theme < (filter?.results?.theme?.size ?: 0)) (filter?.results?.theme?.get(theme)?.path_word ?: "") else "", if(theme >= 0 && theme < (filter?.results?.theme?.size ?: 0)) (filter?.results?.theme?.get(theme)?.path_word ?: "") else "",
@@ -42,7 +42,7 @@ class SortFragment : StatusCardFlow(0, R.id.action_nav_sort_to_nav_book, R.layou
super.setListeners() super.setListeners()
lifecycleScope.launch { lifecycleScope.launch {
setProgress(5) setProgress(5)
PausableDownloader(getString(R.string.filterApiUrl).format(CMApi.myHostApiUrl)) { PausableDownloader(getString(R.string.filterApiUrl).format(Config.myHostApiUrl.value)) {
if(ad?.exit == true) return@PausableDownloader if(ad?.exit == true) return@PausableDownloader
it.let { it.let {
it.inputStream().use { i -> it.inputStream().use { i ->

View File

@@ -11,20 +11,20 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.TopicStructure import top.fumiama.copymanga.json.TopicStructure
import top.fumiama.copymanga.template.http.PausableDownloader import top.fumiama.copymanga.template.http.PausableDownloader
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi @ExperimentalStdlibApi
class TopicFragment : InfoCardLoader(R.layout.fragment_topic, R.id.action_nav_topic_to_nav_book) { class TopicFragment : InfoCardLoader(R.layout.fragment_topic, R.id.action_nav_topic_to_nav_book) {
private var type = 1 private var type = 1
override fun getApiUrl() = override fun getApiUrl() =
getString(R.string.topicContentApiUrl).format(CMApi.myHostApiUrl, arguments?.getString("path"), type, offset) getString(R.string.topicContentApiUrl).format(Config.myHostApiUrl.value, arguments?.getString("path"), type, offset)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
lifecycleScope.launch { lifecycleScope.launch {
setProgress(5) setProgress(5)
PausableDownloader(getString(R.string.topicApiUrl).format(CMApi.myHostApiUrl, arguments?.getString("path"))) { data -> PausableDownloader(getString(R.string.topicApiUrl).format(Config.myHostApiUrl.value, arguments?.getString("path"))) { data ->
setProgress(10) setProgress(10)
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
if(ad?.exit == true) return@withContext if(ad?.exit == true) return@withContext

View File

@@ -50,7 +50,7 @@ class ComicDlFragment: NoBackRefreshFragment(R.layout.fragment_dlcomic) {
super.onDestroy() super.onDestroy()
//mainWeakReference?.get()?.menuMain?.let { setMenuInvisible(it) } //mainWeakReference?.get()?.menuMain?.let { setMenuInvisible(it) }
handler?.downloading = false handler?.downloading = false
handler?.mangaDlTools?.exit = true handler?.downloader?.exit = true
handler?.dl?.dismiss() handler?.dl?.dismiss()
exit = true exit = true
handler = null handler = null

View File

@@ -11,7 +11,6 @@ import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.android.synthetic.main.button_tbutton.* import kotlinx.android.synthetic.main.button_tbutton.*
import kotlinx.android.synthetic.main.button_tbutton.view.* import kotlinx.android.synthetic.main.button_tbutton.view.*
@@ -25,12 +24,12 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.json.ChapterStructure import top.fumiama.copymanga.json.ChapterStructure
import top.fumiama.copymanga.json.ComicStructureOld import top.fumiama.copymanga.json.ComicStructureOld
import top.fumiama.copymanga.json.VolumeStructure import top.fumiama.copymanga.json.VolumeStructure
import top.fumiama.copymanga.manga.MangaDlTools import top.fumiama.copymanga.manga.Downloader
import top.fumiama.copymanga.manga.Reader import top.fumiama.copymanga.manga.Reader
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.ui.UITools import top.fumiama.copymanga.tools.ui.UITools
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment.Companion.exit import top.fumiama.copymanga.ui.comicdl.ComicDlFragment.Companion.exit
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment.Companion.json import top.fumiama.copymanga.ui.comicdl.ComicDlFragment.Companion.json
@@ -65,13 +64,13 @@ class ComicDlHandler(
private var tbtnlist: Array<ChapterToggleButton> = arrayOf() private var tbtnlist: Array<ChapterToggleButton> = arrayOf()
private var tbtncnt = 0 private var tbtncnt = 0
private var isNewTitle = false private var isNewTitle = false
val mangaDlTools = MangaDlTools() val downloader = Downloader()
private var multiSelect = false private var multiSelect = false
private var finishMap = arrayOf<Boolean?>() private var finishMap = arrayOf<Boolean?>()
var downloading = false var downloading = false
private var urlArray = arrayOf<String>() private var urlArray = arrayOf<String>()
private var uuidArray = arrayOf<String>() private var uuidArray = arrayOf<String>()
private val maxBatch = that?.activity?.let { PreferenceManager.getDefaultSharedPreferences(it) }?.getInt("settings_cat_md_sb_max_batch", 16)?:16 private val maxBatch = Config.manga_dl_max_batch.value
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
@@ -170,7 +169,7 @@ class ComicDlHandler(
if (multiSelect) { if (multiSelect) {
for (i in tbtnlist) { for (i in tbtnlist) {
if (i.isChecked) { if (i.isChecked) {
val f = CMApi.getZipFile(that?.context?.getExternalFilesDir(""), comicName, i.caption?:"null", i.chapterName) val f = Config.getZipFile(that?.context?.getExternalFilesDir(""), comicName, i.caption?:"null", i.chapterName)
if (f.exists()) { if (f.exists()) {
deleteChapter(f, i) deleteChapter(f, i)
checkedChapter-- checkedChapter--
@@ -225,7 +224,7 @@ class ComicDlHandler(
else{ else{
that!!.pdwn.progress = 0 that!!.pdwn.progress = 0
if (downloading || checkedChapter == 0) { if (downloading || checkedChapter == 0) {
mangaDlTools.wait = !mangaDlTools.wait!! downloader.wait = !downloader.wait!!
} else that?.lifecycleScope?.launch { } else that?.lifecycleScope?.launch {
downloading = true downloading = true
sendEmptyMessage(9) sendEmptyMessage(9)
@@ -238,7 +237,7 @@ class ComicDlHandler(
sendEmptyMessage(4) sendEmptyMessage(4)
return@setOnLongClickListener true return@setOnLongClickListener true
} }
mangaDlTools.onDownloadedListener = object :MangaDlTools.OnDownloadedListener { downloader.onDownloadedListener = object :Downloader.OnDownloadedListener {
override fun handleMessage(index: Int, isSuccess: Boolean, message: String) { override fun handleMessage(index: Int, isSuccess: Boolean, message: String) {
that?.lifecycleScope?.launch { that?.lifecycleScope?.launch {
if(isSuccess) onZipDownloadFinish(index) if(isSuccess) onZipDownloadFinish(index)
@@ -287,7 +286,7 @@ class ComicDlHandler(
while (totalInDownload.get() >= maxBatch) delay(1000) while (totalInDownload.get() >= maxBatch) delay(1000)
totalInDownload.incrementAndGet() totalInDownload.incrementAndGet()
launch { launch {
mangaDlTools.downloadChapterInVol( downloader.downloadChapterInVol(
it, it,
i.chapterName, i.chapterName,
i.caption?:"null", i.caption?:"null",
@@ -308,7 +307,7 @@ class ComicDlHandler(
updateProgressBar() updateProgressBar()
that?.apply { that?.apply {
cdwn.postDelayed({ cdwn.postDelayed({
if (mangaDlTools.exit) return@postDelayed if (downloader.exit) return@postDelayed
if (dldChapter == checkedChapter) { if (dldChapter == checkedChapter) {
checkedChapter = 0 checkedChapter = 0
setProgress2(0, 233) setProgress2(0, 233)
@@ -341,7 +340,7 @@ class ComicDlHandler(
} }
private suspend fun addButtons(chapters: Array<ChapterStructure>, caption: String, version: Int) = withContext(Dispatchers.IO) { private suspend fun addButtons(chapters: Array<ChapterStructure>, caption: String, version: Int) = withContext(Dispatchers.IO) {
chapters.forEach { chapter -> chapters.forEach { chapter ->
val u = CMApi.getChapterInfoApiUrl(chapter.comic_path_word, chapter.uuid, version)?:"" val u = Config.getChapterInfoApiUrl(chapter.comic_path_word, chapter.uuid, version)?:""
addButton(chapter.name, chapter.uuid, caption, u) addButton(chapter.name, chapter.uuid, caption, u)
urlArray += u urlArray += u
} }
@@ -372,7 +371,7 @@ class ComicDlHandler(
that?.ltbtn?.invalidate() that?.ltbtn?.invalidate()
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val zipf = CMApi.getZipFile(that!!.context?.getExternalFilesDir(""), comicName, caption, title) val zipf = Config.getZipFile(that!!.context?.getExternalFilesDir(""), comicName, caption, title)
Log.d("MyCD", "Get zipf: $zipf") Log.d("MyCD", "Get zipf: $zipf")
Reader.fileArray += zipf Reader.fileArray += zipf
if (zipf.exists()) withContext(Dispatchers.Main) { if (zipf.exists()) withContext(Dispatchers.Main) {
@@ -440,7 +439,7 @@ class ComicDlHandler(
} }
isNewTitle = true isNewTitle = true
for (chapter in group.chapters) { for (chapter in group.chapters) {
val newUrl = CMApi.getChapterInfoApiUrl( val newUrl = Config.getChapterInfoApiUrl(
chapter.url.substringAfter("/comic/").substringBefore('/'), chapter.url.substringAfter("/comic/").substringBefore('/'),
chapter.url.substringAfterLast('/'), version, chapter.url.substringAfterLast('/'), version,
)?:"" )?:""

View File

@@ -14,7 +14,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.manga.MangaDlTools import top.fumiama.copymanga.manga.Downloader
import top.fumiama.copymanga.manga.Reader import top.fumiama.copymanga.manga.Reader
import top.fumiama.copymanga.template.general.NoBackRefreshFragment import top.fumiama.copymanga.template.general.NoBackRefreshFragment
import top.fumiama.copymanga.tools.file.FileUtils import top.fumiama.copymanga.tools.file.FileUtils
@@ -149,7 +149,7 @@ class DownloadFragment: NoBackRefreshFragment(R.layout.fragment_download) {
fun removeAllEmpty() { fun removeAllEmpty() {
MainActivity.mainWeakReference?.get()?.getExternalFilesDir("")?.listFiles()?.toList().let { MainActivity.mainWeakReference?.get()?.getExternalFilesDir("")?.listFiles()?.toList().let {
var removed = false var removed = false
MangaDlTools.getEmptyMangaList(it)?.forEach { f -> Downloader.getEmptyMangaList(it)?.forEach { f ->
if (f.exists()) { if (f.exists()) {
FileUtils.recursiveRemove(f) FileUtils.recursiveRemove(f)
removed = true removed = true

View File

@@ -7,13 +7,13 @@ import android.view.View
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.manga.MangaDlTools import top.fumiama.copymanga.api.Config.manga_dl_show_0m_manga
import top.fumiama.copymanga.manga.Downloader
import top.fumiama.copymanga.manga.Reader import top.fumiama.copymanga.manga.Reader
import top.fumiama.copymanga.template.general.MangaPagesFragmentTemplate import top.fumiama.copymanga.template.general.MangaPagesFragmentTemplate
import top.fumiama.copymanga.template.ui.CardList import top.fumiama.copymanga.template.ui.CardList
@@ -32,13 +32,10 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
private var isReverse = false private var isReverse = false
private var isContentChanged = false private var isContentChanged = false
private var exit = false private var exit = false
private var showAll = false private val showAll get() = manga_dl_show_0m_manga.value
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
wn = WeakReference(this) wn = WeakReference(this)
showAll = activity?.let {
PreferenceManager.getDefaultSharedPreferences(it)
}?.getBoolean("settings_cat_md_sw_show_0m_manga", false)?:false
} }
override fun onPause() { override fun onPause() {
@@ -74,7 +71,7 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
var size = sortedBookList?.size?:0 var size = sortedBookList?.size?:0
if (size > 0) { if (size > 0) {
if (!showAll) { if (!showAll) {
sortedBookList = MangaDlTools.getNonEmptyMangaList(sortedBookList) { sortedBookList = Downloader.getNonEmptyMangaList(sortedBookList) {
setProgress(40+20*it/100) setProgress(40+20*it/100)
} }
} }

View File

@@ -32,7 +32,7 @@ import top.fumiama.copymanga.MainActivity.Companion.ime
import top.fumiama.copymanga.json.BookListStructure import top.fumiama.copymanga.json.BookListStructure
import top.fumiama.copymanga.template.general.NoBackRefreshFragment import top.fumiama.copymanga.template.general.NoBackRefreshFragment
import top.fumiama.copymanga.template.http.PausableDownloader import top.fumiama.copymanga.template.http.PausableDownloader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
import top.fumiama.copymanga.tools.ui.Navigate import top.fumiama.copymanga.tools.ui.Navigate
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@@ -204,7 +204,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
if(it.isEmpty()) return@let if(it.isEmpty()) return@let
//Log.d("MyHomeFVP", "Load img: $it") //Log.d("MyHomeFVP", "Load img: $it")
Glide.with(this@HomeFragment).load( Glide.with(this@HomeFragment).load(
GlideUrl(CMApi.imageProxy?.wrap(it)?:it, CMApi.myGlideHeaders) GlideUrl(Config.imageProxy?.wrap(it)?:it, Config.myGlideHeaders)
) )
.addListener(GlideHideLottieViewListener(WeakReference(holder.itemView.lai))) .addListener(GlideHideLottieViewListener(WeakReference(holder.itemView.lai)))
.timeout(60000).into(holder.itemView.vpi) .timeout(60000).into(holder.itemView.vpi)
@@ -276,7 +276,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
cic.isClickable = false cic.isClickable = false
context?.let { context?.let {
Glide.with(it) Glide.with(it)
.load(GlideUrl(CMApi.imageProxy?.wrap(cover)?:cover, CMApi.myGlideHeaders)) .load(GlideUrl(Config.imageProxy?.wrap(cover)?:cover, Config.myGlideHeaders))
.addListener(GlideHideLottieViewListener(WeakReference(laic))) .addListener(GlideHideLottieViewListener(WeakReference(laic)))
.timeout(60000).into(imic) .timeout(60000).into(imic)
} }
@@ -295,7 +295,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
suspend fun refresh(q: CharSequence) = withContext(Dispatchers.IO) { suspend fun refresh(q: CharSequence) = withContext(Dispatchers.IO) {
query = q.toString() query = q.toString()
activity?.apply { activity?.apply {
PausableDownloader(getString(R.string.searchApiUrl).format(CMApi.myHostApiUrl, 0, query, type)) { PausableDownloader(getString(R.string.searchApiUrl).format(Config.myHostApiUrl.value, 0, query, type)) {
results = Gson().fromJson(it.decodeToString(), BookListStructure::class.java) results = Gson().fromJson(it.decodeToString(), BookListStructure::class.java)
count = results?.results?.total?:0 count = results?.results?.total?:0
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {

View File

@@ -31,7 +31,7 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.ComicStructure import top.fumiama.copymanga.json.ComicStructure
import top.fumiama.copymanga.json.IndexStructure import top.fumiama.copymanga.json.IndexStructure
import top.fumiama.copymanga.template.http.AutoDownloadHandler import top.fumiama.copymanga.template.http.AutoDownloadHandler
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
import top.fumiama.copymanga.tools.ui.Navigate import top.fumiama.copymanga.tools.ui.Navigate
import top.fumiama.copymanga.tools.ui.UITools import top.fumiama.copymanga.tools.ui.UITools
@@ -40,7 +40,7 @@ import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadHandler( class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadHandler(
that.get()?.getString(R.string.mainPageApiUrl)!!.format(CMApi.myHostApiUrl), that.get()?.getString(R.string.mainPageApiUrl)!!.format(Config.myHostApiUrl.value),
IndexStructure::class.java, IndexStructure::class.java,
that.get() that.get()
) { ) {
@@ -369,7 +369,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
if(img.startsWith("http")) { if(img.startsWith("http")) {
//Log.d("MyHH", "load card image: $img") //Log.d("MyHH", "load card image: $img")
val waitMillis = cardLoadingWaits.getAndIncrement().toLong()*200 val waitMillis = cardLoadingWaits.getAndIncrement().toLong()*200
val g = Glide.with(it).load(GlideUrl(CMApi.imageProxy?.wrap(img)?:img, CMApi.myGlideHeaders)) val g = Glide.with(it).load(GlideUrl(Config.imageProxy?.wrap(img)?:img, Config.myGlideHeaders))
.addListener(GlideHideLottieViewListener(WeakReference(cv.laic)) { .addListener(GlideHideLottieViewListener(WeakReference(cv.laic)) {
cardLoadingWaits.decrementAndGet() cardLoadingWaits.decrementAndGet()
}).timeout(60000) }).timeout(60000)

View File

@@ -29,7 +29,6 @@ import androidx.core.animation.doOnEnd
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.edit import androidx.core.content.edit
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@@ -54,10 +53,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.template.general.TitleActivityTemplate import top.fumiama.copymanga.template.general.TitleActivityTemplate
import top.fumiama.copymanga.template.http.PausableDownloader import top.fumiama.copymanga.template.http.PausableDownloader
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.http.DownloadTools import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.copymanga.tools.thread.TimeThread import top.fumiama.copymanga.tools.thread.TimeThread
import top.fumiama.copymanga.tools.ui.Font import top.fumiama.copymanga.tools.ui.Font
@@ -151,14 +149,11 @@ class ViewMangaActivity : TitleActivityTemplate() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
val settingsPref = MainActivity.mainWeakReference?.get()?.let { PreferenceManager.getDefaultSharedPreferences(it) } if (Config.view_manga_always_dark_bg.value) {
settingsPref?.getBoolean("settings_cat_vm_sw_always_dark_bg", false)?.let { Log.d("MyVM", "force dark")
if (it) { delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES
Log.d("MyVM", "force dark") } else {
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
} else {
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
} }
postponeEnterTransition() postponeEnterTransition()
setContentView(R.layout.activity_viewmanga) setContentView(R.layout.activity_viewmanga)
@@ -174,21 +169,21 @@ class ViewMangaActivity : TitleActivityTemplate() {
pn = intent.getIntExtra("pn", 0) pn = intent.getIntExtra("pn", 0)
cut = pb["useCut"] cut = pb["useCut"]
r2l = pb["r2l"] r2l = pb["r2l"]
verticalLoadMaxCount = settingsPref?.getInt("settings_cat_vm_sb_vertical_max", 20)?.let { if(it > 0) it else 20 }?:20 verticalLoadMaxCount = Config.view_manga_vertical_max.value.let { if(it > 0) it else 20 }
isVertical = pb["vertical"] isVertical = pb["vertical"]
notUseVP = pb["noVP"] || isVertical notUseVP = pb["noVP"] || isVertical
//url = intent.getStringExtra("url") //url = intent.getStringExtra("url")
mHandler = VMHandler(this@ViewMangaActivity, if(urlArray.isNotEmpty()) urlArray[position] else "", resources.getStringArray(R.array.weeks)) mHandler = VMHandler(this@ViewMangaActivity, if(urlArray.isNotEmpty()) urlArray[position] else "", resources.getStringArray(R.array.weeks))
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
settingsPref?.getInt("settings_cat_vm_sb_quality", 100)?.let { q = if (it > 0) it else 100 } Config.view_manga_quality.value.let { q = if (it > 0) it else 100 }
tt = TimeThread(mHandler, VMHandler.SET_NET_INFO, 10000) tt = TimeThread(mHandler, VMHandler.SET_NET_INFO, 10000)
tt.canDo = true tt.canDo = true
tt.start() tt.start()
volTurnPage = settingsPref?.getBoolean("settings_cat_vm_sw_vol_turn", false)?:false volTurnPage = Config.view_manga_vol_turn.value
am = getSystemService(Service.AUDIO_SERVICE) as AudioManager am = getSystemService(Service.AUDIO_SERVICE) as AudioManager
if (!noCellarAlert) noCellarAlert = settingsPref?.getBoolean("settings_cat_net_sw_use_cellar", false) == true if (!noCellarAlert) noCellarAlert = Config.view_manga_use_cellar.value
fullyHideInfo = settingsPref?.getBoolean("settings_cat_vm_sw_hide_info", false) == true fullyHideInfo = Config.view_manga_hide_info.value
Log.d("MyVM", "Now ZipFile is $zipFile") Log.d("MyVM", "Now ZipFile is $zipFile")
try { try {
@@ -205,7 +200,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
} }
} }
} }
if (settingsPref?.getBoolean("settings_cat_general_sw_enable_transparent_systembar", false) == true) { if (Config.general_enable_transparent_system_bar.value) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R)
window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
} }
@@ -262,7 +257,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
getImgUrlArray()?.let { getImgUrlArray()?.let {
tasks = Array(it.size) { i -> tasks = Array(it.size) { i ->
val u = it[i]?:return@Array null val u = it[i]?:return@Array null
return@Array DownloadTools.prepare(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(u)?:u)) return@Array DownloadTools.prepare(Config.resolution.wrap(Config.imageProxy?.wrap(u)?:u))
} }
tasksRunStatus = Array(it.size) { return@Array false } tasksRunStatus = Array(it.size) { return@Array false }
} }
@@ -278,7 +273,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
forEachIndexed { i, it -> forEachIndexed { i, it ->
mHandler.obtainMessage(VMHandler.SET_DL_TEXT, "$i/$size").sendToTarget() mHandler.obtainMessage(VMHandler.SET_DL_TEXT, "$i/$size").sendToTarget()
if(it != null) try { if(it != null) try {
DownloadTools.getHttpContent(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(it)?:it), 1024)?.inputStream()?.let { DownloadTools.getHttpContent(Config.resolution.wrap(Config.imageProxy?.wrap(it)?:it), 1024)?.inputStream()?.let {
isCut[i] = canCut(it) isCut[i] = canCut(it)
}?:run { }?:run {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
@@ -428,7 +423,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
private suspend fun loadImgUrlInto(imgView: ScaleImageView, button: Button, url: String, useCut: Boolean, isLeft: Boolean, check: (() -> Boolean)? = null): Boolean { private suspend fun loadImgUrlInto(imgView: ScaleImageView, button: Button, url: String, useCut: Boolean, isLeft: Boolean, check: (() -> Boolean)? = null): Boolean {
Log.d("MyVM", "Load from adt: $url") Log.d("MyVM", "Load from adt: $url")
val success = PausableDownloader(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(url)?:url), 1000, false) { data -> val success = PausableDownloader(Config.resolution.wrap(Config.imageProxy?.wrap(url)?:url), 1000, false) { data ->
check?.let { it() }?.let { if(it) loadImg(imgView, BitmapFactory.decodeByteArray(data, 0, data.size), useCut, isLeft, false) } check?.let { it() }?.let { if(it) loadImg(imgView, BitmapFactory.decodeByteArray(data, 0, data.size), useCut, isLeft, false) }
}.run() }.run()
if (!success) button.apply { post { if (!success) button.apply { post {
@@ -918,7 +913,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
val thisOneB = holder.itemView.oneb val thisOneB = holder.itemView.oneb
Glide.with(this@ViewMangaActivity.applicationContext) Glide.with(this@ViewMangaActivity.applicationContext)
.asBitmap() .asBitmap()
.load(GlideUrl(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(it)?:it), CMApi.myGlideHeaders)) .load(GlideUrl(Config.resolution.wrap(Config.imageProxy?.wrap(it)?:it), Config.myGlideHeaders))
.placeholder(BitmapDrawable(resources, getLoadingBitmap(pos))) .placeholder(BitmapDrawable(resources, getLoadingBitmap(pos)))
.timeout(60000) .timeout(60000)
.addListener(OneButtonRequestListener(thisOneB)) .addListener(OneButtonRequestListener(thisOneB))
@@ -929,7 +924,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
override fun onLoadCleared(placeholder: Drawable?) { } override fun onLoadCleared(placeholder: Drawable?) { }
}) })
} else Glide.with(this@ViewMangaActivity.applicationContext) } else Glide.with(this@ViewMangaActivity.applicationContext)
.load(GlideUrl(CMApi.resolution.wrap(CMApi.imageProxy?.wrap(it)?:it), CMApi.myGlideHeaders)) .load(GlideUrl(Config.resolution.wrap(Config.imageProxy?.wrap(it)?:it), Config.myGlideHeaders))
.timeout(60000) .timeout(60000)
.placeholder(BitmapDrawable(resources, getLoadingBitmap(pos))) .placeholder(BitmapDrawable(resources, getLoadingBitmap(pos)))
.addListener(OneButtonRequestListener(holder.itemView.oneb)) .addListener(OneButtonRequestListener(holder.itemView.oneb))

View File

@@ -1,28 +1,24 @@
package top.fumiama.copymanga.user package top.fumiama.copymanga.user
import android.content.SharedPreferences
import android.util.Base64 import android.util.Base64
import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.json.ComandyCapsule import top.fumiama.copymanga.json.ComandyCapsule
import top.fumiama.copymanga.json.LoginInfoStructure import top.fumiama.copymanga.json.LoginInfoStructure
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.http.Comandy import top.fumiama.copymanga.tools.http.Comandy
import top.fumiama.copymanga.tools.http.DownloadTools import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.copymanga.tools.http.DownloadTools.app_ver
import top.fumiama.copymanga.tools.http.DownloadTools.pc_ua
import top.fumiama.copymanga.tools.http.Proxy
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import java.net.URLEncoder import java.net.URLEncoder
import java.nio.charset.Charset import java.nio.charset.Charset
class Member(private val pref: SharedPreferences, private val getString: (Int) -> String) { class Member(private val getString: (Int) -> String) {
val hasLogin: Boolean get() = pref.getString("token", "")?.isNotEmpty()?:false val hasLogin: Boolean get() = Config.token.value?.isNotEmpty()?:false
suspend fun login(username: String, pwd: String, salt: Int): LoginInfoStructure = withContext(Dispatchers.IO) { suspend fun login(username: String, pwd: String, salt: Int): LoginInfoStructure = withContext(Dispatchers.IO) {
var err = "" var err = ""
if (!Proxy.useApiProxy && Comandy.useComandy) getComandyLoginConnection(username, pwd, salt).let { capsule -> if (!Config.net_use_api_proxy.value && Comandy.useComandy)
getComandyLoginConnection(username, pwd, salt).let { capsule ->
try { try {
val para = Gson().toJson(capsule) val para = Gson().toJson(capsule)
Comandy.instance?.request(para)?.let { result -> Comandy.instance?.request(para)?.let { result ->
@@ -72,7 +68,7 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
* - **message**: 可以 toast 的信息 * - **message**: 可以 toast 的信息
*/ */
suspend fun info() : LoginInfoStructure = withContext(Dispatchers.IO) { suspend fun info() : LoginInfoStructure = withContext(Dispatchers.IO) {
if (!pref.contains("token")) { if (!hasLogin) {
val l = LoginInfoStructure() val l = LoginInfoStructure()
l.code = 449 l.code = 449
l.message = getString(R.string.noLogin) l.message = getString(R.string.noLogin)
@@ -80,16 +76,13 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
} }
try { try {
val data = DownloadTools.getHttpContent( val data = DownloadTools.getHttpContent(
getString(R.string.memberInfoApiUrl).format(CMApi.myHostApiUrl).let { getString(R.string.memberInfoApiUrl).format(Config.myHostApiUrl.value).let {
CMApi.apiProxy?.wrap(it)?:it Config.apiProxy?.wrap(it)?:it
} }
).decodeToString() ).decodeToString()
try { try {
val l = Gson().fromJson(data, LoginInfoStructure::class.java) val l = Gson().fromJson(data, LoginInfoStructure::class.java)
if(l.code == 200) pref.edit()?.apply { if(l.code == 200) Config.avatar.value = l.results.avatar
putString("avatar", l.results.avatar)
apply()
}
l l
} catch (e : Exception) { } catch (e : Exception) {
val l = LoginInfoStructure() val l = LoginInfoStructure()
@@ -106,28 +99,22 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
} }
suspend fun logout() = withContext(Dispatchers.IO) { suspend fun logout() = withContext(Dispatchers.IO) {
pref.edit()?.apply { Config.token.value = ""
remove("token") Config.user_id.value = null
remove("user_id") Config.username.value = null
remove("username") Config.nickname.value = null
remove("nickname") Config.avatar.value = null
remove("avatar")
apply()
}
} }
private suspend fun saveInfo(data: ByteArray) = data.inputStream().use { dataIn -> private suspend fun saveInfo(data: ByteArray) = data.inputStream().use { dataIn ->
try { try {
Gson().fromJson(dataIn.reader(), LoginInfoStructure::class.java)?.let { l -> Gson().fromJson(dataIn.reader(), LoginInfoStructure::class.java)?.let { l ->
if(l.code == 200) { if(l.code == 200) {
pref.edit()?.apply { Config.token.value = l.results?.token
putString("token", l.results?.token) Config.user_id.value = l.results?.user_id
putString("user_id", l.results?.user_id) Config.username.value = l.results?.username
putString("username", l.results?.username) Config.nickname.value = l.results.nickname
putString("nickname", l.results?.nickname) return@use info()
apply()
return@use info()
}
} }
return@use l return@use l
}?: throw Exception(getString(R.string.login_parse_json_error)) }?: throw Exception(getString(R.string.login_parse_json_error))
@@ -137,35 +124,31 @@ class Member(private val pref: SharedPreferences, private val getString: (Int) -
} }
private fun getLoginConnection(username: String, pwd: String, salt: Int) = private fun getLoginConnection(username: String, pwd: String, salt: Int) =
getString(R.string.loginApiUrl).format(CMApi.myHostApiUrl).let { getString(R.string.loginApiUrl).format(Config.myHostApiUrl.value).let {
CMApi.apiProxy?.wrap(it)?:it Config.apiProxy?.wrap(it)?:it
}.let { }.let {
DownloadTools.getApiConnection(it, "POST").apply { DownloadTools.getApiConnection(it, "POST").apply {
pref.apply { doOutput = true
doOutput = true setRequestProperty("content-type", "application/x-www-form-urlencoded;charset=utf-8")
setRequestProperty("content-type", "application/x-www-form-urlencoded;charset=utf-8") setRequestProperty("platform", "3")
setRequestProperty("platform", "3") setRequestProperty("accept", "application/json")
setRequestProperty("accept", "application/json") val r = if(!Config.net_use_foreign.value) "1" else "0"
val r = if(!getBoolean("settings_cat_net_sw_use_foreign", false)) "1" else "0" val pwdEncoded = Base64.encode("$pwd-$salt".toByteArray(), Base64.DEFAULT).decodeToString()
val pwdEncoded = Base64.encode("$pwd-$salt".toByteArray(), Base64.DEFAULT).decodeToString() outputStream.write("username=${URLEncoder.encode(username, Charset.defaultCharset().name())}&password=$pwdEncoded&salt=$salt&platform=3&authorization=Token+&version=${Config.app_ver.value}&source=copyApp&region=$r&webp=1".toByteArray())
outputStream.write("username=${URLEncoder.encode(username, Charset.defaultCharset().name())}&password=$pwdEncoded&salt=$salt&platform=3&authorization=Token+&version=$app_ver&source=copyApp&region=$r&webp=1".toByteArray())
}
} }
} }
private fun getComandyLoginConnection(username: String, pwd: String, salt: Int) = private fun getComandyLoginConnection(username: String, pwd: String, salt: Int) =
getString(R.string.loginApiUrl).format(CMApi.myHostApiUrl).let { getString(R.string.loginApiUrl).format(Config.myHostApiUrl.value).let {
CMApi.apiProxy?.wrap(it)?:it Config.apiProxy?.wrap(it)?:it
}.let { }.let {
DownloadTools.getComandyApiConnection(it, "POST", null, pc_ua).apply { DownloadTools.getComandyApiConnection(it, "POST", null, Config.pc_ua).apply {
pref.apply { headers["content-type"] = "application/x-www-form-urlencoded;charset=utf-8"
headers["content-type"] = "application/x-www-form-urlencoded;charset=utf-8" headers["platform"] = "3"
headers["platform"] = "3" headers["accept"] = "application/json"
headers["accept"] = "application/json" val r = if(!Config.net_use_foreign.value) "1" else "0"
val r = if(!getBoolean("settings_cat_net_sw_use_foreign", false)) "1" else "0" val pwdEncoded = Base64.encode("$pwd-$salt".toByteArray(), Base64.DEFAULT).decodeToString()
val pwdEncoded = Base64.encode("$pwd-$salt".toByteArray(), Base64.DEFAULT).decodeToString() data = "username=${URLEncoder.encode(username, Charset.defaultCharset().name())}&password=$pwdEncoded&salt=$salt&platform=3&authorization=Token+&version=${Config.app_ver.value}&source=copyApp&region=$r&webp=1"
data = "username=${URLEncoder.encode(username, Charset.defaultCharset().name())}&password=$pwdEncoded&salt=$salt&platform=3&authorization=Token+&version=$app_ver&source=copyApp&region=$r&webp=1"
}
} }
} }
} }

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [ <!DOCTYPE resources [
<!ENTITY hosturl "api.mangacopy.com"> <!ENTITY hosturl "api.mangacopy.com">
<!ENTITY appver "2.2.0"> <!ENTITY appver "2.2.6">
]> ]>
<resources> <resources>
<string name="app_name">拷贝漫画</string> <string name="app_name">拷贝漫画</string>