1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-04 23:10: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>reclass</w>
<w>reilia</w>
<w>systembar</w>
</words>
</dictionary>
</component>

View File

@@ -78,7 +78,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.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
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
//noinspection GradleDependency
@@ -91,13 +91,13 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.16.0'
//noinspection KaptUsageInsteadOfKsp
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.liaoinstan.SpringView:library:0a24d3e9dd'
implementation 'com.github.zawadz88:MaterialPopupMenu:4.1.0'
implementation files('libs/com.lapism/search-2.4.1.aar') // https://stackoverflow.com/a/63029110/28801553
//noinspection GradleDependency
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation 'com.airbnb.android:lottie:6.5.2'
implementation 'net.java.dev.jna:jna:5.15.0@aar'
implementation 'com.airbnb.android:lottie:6.6.4'
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.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.coroutines.launch
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R
import kotlin.random.Random
@@ -18,11 +18,10 @@ class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
val pref = MainActivity.mainWeakReference?.get()?.getPreferences(MODE_PRIVATE) ?: return
val isLogout = pref.getString("token", null) != null
val isLogout = !Config.token.value.isNullOrEmpty()
if (isLogout) {
alblogin.setText(R.string.logout)
altusrnm.setText(pref.getString("username", "N/A"))
altusrnm.setText(Config.username.value)
}
alblogin.setOnClickListener {
lifecycleScope.launch {
@@ -61,14 +60,12 @@ class LoginActivity : AppCompatActivity() {
Toast.makeText(this@LoginActivity, l?.message, Toast.LENGTH_LONG).show()
}
}
PreferenceManager.getDefaultSharedPreferences(this)?.apply {
if (getBoolean("settings_cat_general_sw_enable_transparent_systembar", false)) {
WindowCompat.setDecorFitsSystemWindows(window, false)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.statusBarColor = 0
window.navigationBarColor = 0
}
if (Config.general_enable_transparent_system_bar.value) {
WindowCompat.setDecorFitsSystemWindows(window, false)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.statusBarColor = 0
window.navigationBarColor = 0
}
}
}

View File

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

View File

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

View File

@@ -7,7 +7,7 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.ChapterStructure
import top.fumiama.copymanga.json.VolumeStructure
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
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
}
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) {
Log.d("MyV", "下载偏移: $offset")
getApiUrl(offset).let {

View File

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

View File

@@ -13,9 +13,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
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.dmzj.copymanga.R
import java.io.File
import java.security.MessageDigest
@@ -78,7 +77,7 @@ open class AutoDownloadHandler(
var cnt = 0
while (cnt++ <= 3) {
try {
val data = DownloadTools.getHttpContent(CMApi.apiProxy?.wrap(url)?:url)
val data = DownloadTools.getHttpContent(Config.apiProxy?.wrap(url)?:url)
if(exit) return@withContext
val fi = data.inputStream()
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.delay
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.dmzj.copymanga.R
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) {
@@ -17,8 +15,8 @@ class PausableDownloader(private val url: String, private val waitMilliseconds:
while (!exit && c++ < 3) {
try {
val data = (DownloadTools.getHttpContent(
(if(isApi) CMApi.apiProxy?.wrap(url) else null)?:url,
DownloadTools.referer
(if(isApi) Config.apiProxy?.wrap(url) else null)?:url,
Config.referer
))
whenFinish?.let { it(data) }
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.coroutines.Dispatchers
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.dmzj.copymanga.R
import java.io.File
@@ -131,7 +131,7 @@ class CardList(
that?.context?.let { context ->
val waitMillis = cardLoadingWaits.getAndIncrement().toLong()*200
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)) {
if (exitCardList) return@GlideHideLottieViewListener
cardLoadingWaits.decrementAndGet()

View File

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

View File

@@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.app_bar_main.*
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
@ExperimentalStdlibApi
@@ -12,7 +12,7 @@ open class ThemeCardFlow(private val api: Int, nav: Int) : StatusCardFlow(0, nav
private var theme = ""
override fun getApiUrl() =
getString(api).format(
CMApi.myHostApiUrl,
Config.myHostApiUrl.value,
page * 21,
sortWay[sortValue],
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.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import com.google.gson.Gson
import com.sun.jna.Library
import com.sun.jna.Native
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.json.ComandyVersion
import top.fumiama.dmzj.copymanga.R
import java.io.ByteArrayInputStream
@@ -43,16 +41,9 @@ interface Comandy : Library {
return true
}
if (mUseComandy != null) return mUseComandy!!
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
val b = getBoolean("settings_cat_net_sw_use_comandy", false)
Log.d("MyComandy", "use comandy: $b")
mUseComandy = b
return b
}
}
mUseComandy = false
return false
val v = Config.net_use_comandy.value
mUseComandy = v
return v
}
private val libraryFile: File?
get() {
@@ -82,7 +73,7 @@ interface Comandy : Library {
} catch (e: Exception) {
e.printStackTrace()
}
val myVersion = ma.getPreferences(AppCompatActivity.MODE_PRIVATE).getInt("comandy_version", 0)
val myVersion = Config.comandy_version.value?:0
if (myVersion >= remoteVersion) {
Log.d("MyComandy", "lib version $myVersion is latest")
isInInit.set(false)
@@ -99,10 +90,7 @@ interface Comandy : Library {
dataIn.copyTo(dataOut)
}
}
if (remoteVersion > 0) ma.getPreferences(AppCompatActivity.MODE_PRIVATE).edit {
putInt("comandy_version", remoteVersion)
apply()
}
if (remoteVersion > 0) Config.comandy_version.value = remoteVersion
Log.d("MyComandy", "update success")
isInInit.set(false)
} catch (e: Exception) {

View File

@@ -1,10 +1,7 @@
package top.fumiama.copymanga.tools.http
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.api.Config
import java.io.File
import java.io.FileOutputStream
import java.lang.Thread.sleep
@@ -100,7 +97,7 @@ class DownloadPool(folder: String) {
var s = false
while (!s && tryTimes-- > 0) {
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.write(it)
zip.closeEntry()

View File

@@ -1,16 +1,13 @@
package top.fumiama.copymanga.tools.http
import android.content.Context
import android.util.Base64
import android.util.Log
import androidx.preference.PreferenceManager
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.json.ComandyCapsule
import top.fumiama.dmzj.copymanga.R
import java.lang.IllegalArgumentException
import java.net.HttpURLConnection
import java.net.URL
import java.util.concurrent.Callable
@@ -18,13 +15,6 @@ import java.util.concurrent.FutureTask
import java.util.concurrent.atomic.AtomicInteger
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)
fun getApiConnection(url: String, method: String = "GET", refer: String? = null, ua: String? = null, timeout: Int = 20000) =
url.let {
@@ -38,16 +28,10 @@ object DownloadTools {
refer?.let { setRequestProperty("referer", it) }
setRequestProperty("source", "copyApp")
setRequestProperty("webp", "1")
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
setRequestProperty("region", if(!getBoolean("settings_cat_net_sw_use_foreign", false)) "1" else "0")
}
it.getPreferences(Context.MODE_PRIVATE).apply {
setRequestProperty("version", app_ver)
getString("token", "")?.let { tk ->
setRequestProperty("authorization", "Token $tk")
}
}
setRequestProperty("region", if(!Config.net_use_foreign.value) "1" else "0")
setRequestProperty("version", Config.app_ver.value)
Config.token.value?.let { tk ->
setRequestProperty("authorization", "Token $tk")
}
setRequestProperty("platform", "3")
}
@@ -67,14 +51,10 @@ object DownloadTools {
capsule.headers["source"] = "copyApp"
capsule.headers["webp"] = "1"
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).apply {
capsule.headers["region"] = if(!getBoolean("settings_cat_net_sw_use_foreign", false)) "1" else "0"
}
it.getPreferences(Context.MODE_PRIVATE).apply {
capsule.headers["version"] = app_ver
getString("token", "")?.let { tk ->
capsule.headers["authorization"] = "Token $tk"
}
capsule.headers["region"] = if(!Config.net_use_foreign.value) "1" else "0"
capsule.headers["version"] = Config.app_ver.value
Config.token.value?.let { tk ->
capsule.headers["authorization"] = "Token $tk"
}
}
capsule.headers["platform"] = "3"
@@ -105,7 +85,7 @@ object DownloadTools {
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) {
if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) {
getComandyApiConnection(u, "GET", refer, ua).let { capsule ->
@@ -150,7 +130,7 @@ object DownloadTools {
FutureTask(if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) Callable{
try {
Comandy.instance?.request(Gson().toJson(
getComandyNormalConnection(u, "GET", pc_ua))
getComandyNormalConnection(u, "GET", Config.pc_ua))
)?.let { result ->
Gson().fromJson(result, ComandyCapsule::class.java)?.let {
if (it.code != 200) null
@@ -164,7 +144,7 @@ object DownloadTools {
} else Callable {
var ret: ByteArray? = null
try {
val connection = getNormalConnection(u, "GET", pc_ua)
val connection = getNormalConnection(u, "GET", Config.pc_ua)
val ci = connection.inputStream
if(readSize > 0) {
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")
var ret: ByteArray? = null
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
import android.util.Log
import androidx.preference.PreferenceManager
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.Config.proxy_key
import java.net.URLEncoder
import java.nio.charset.Charset
class Proxy(id: Int, private val apiRegex: Regex, keyID: Int? = null) {
private val code = keyID?.let { k ->
MainActivity.mainWeakReference?.get()?.let {
PreferenceManager.getDefaultSharedPreferences(it).getString(it.getString(k), null)
}
}
class Proxy(id: Int, private val apiRegex: Regex) {
private val code get() = proxy_key.value
private val proxyApiUrl = MainActivity.mainWeakReference?.get()?.getString(id)
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")
return u
}
if(!code.isNullOrEmpty()) {
val wu = proxyApiUrl?.format(code, URLEncoder.encode(u, Charset.defaultCharset().name()))?:u
if(code.isNotEmpty() and !proxyApiUrl.isNullOrEmpty()) {
val wu = proxyApiUrl?.format(code, URLEncoder.encode(u, Charset.defaultCharset().name()))
?:u
Log.d("MyP", "[M] wrap: $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 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.view.View
import android.widget.Toast
import androidx.preference.PreferenceManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.api.Config
import top.fumiama.dmzj.copymanga.R
import java.lang.ref.WeakReference
import kotlin.math.sqrt
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
constructor(w: WeakReference<Activity>): this(w.get()?.applicationContext, w)
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
return cm.getNetworkCapabilities(cm.activeNetwork)?.let {
when {
it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> return@let zis.getString(
R.string.TRANSPORT_WIFI)
it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> return@let zis.getString(
R.string.TRANSPORT_CELLULAR)
it.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> return@let zis.getString(
R.string.TRANSPORT_BLUETOOTH)
it.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> return@let zis.getString(
R.string.TRANSPORT_ETHERNET)
it.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) -> return@let zis.getString(
R.string.TRANSPORT_LOWPAN)
it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> return@let zis?.getString(
R.string.TRANSPORT_WIFI)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> return@let zis?.getString(
R.string.TRANSPORT_CELLULAR)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> return@let zis?.getString(
R.string.TRANSPORT_BLUETOOTH)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> return@let zis?.getString(
R.string.TRANSPORT_ETHERNET)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) -> return@let zis?.getString(
R.string.TRANSPORT_LOWPAN)?:""
it.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> return@let "VPN"
else -> return@let transportStringNull
}
@@ -99,11 +100,8 @@ class UITools(that: Context?, w: WeakReference<Activity>? = null) {
val margin = marginLeftDp.toDouble()
val marginPx = dp2px(marginLeftDp)?:16
val screenWidth = zis?.resources?.displayMetrics?.widthPixels?:1080
val numPerRow = ((px2dp(screenWidth)?:400).toDouble() / (widthDp + 2 * margin) + 0.5).toInt().let {
it + (zis?.let {
a -> PreferenceManager.getDefaultSharedPreferences(a).getInt("settings_cat_general_sb_card_per_row", 0)
} ?: 0)
}.let { if(it <= 0) 3 else it }
val numPerRow = (((px2dp(screenWidth)?:400).toDouble() / (widthDp + 2 * margin) + 0.5).toInt()
+ Config.general_card_per_row.value).let { if(it <= 0) 3 else it }
val w = (screenWidth - marginPx*numPerRow*2)/numPerRow
val totalWidth = screenWidth/numPerRow
return listOf(numPerRow, w, totalWidth)

View File

@@ -39,7 +39,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.ThemeStructure
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.GlideHideLottieViewListener
import top.fumiama.copymanga.tools.ui.Navigate
@@ -88,7 +88,7 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
that?.apply {
Glide.with(this).load(
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
)
.timeout(60000)
@@ -222,7 +222,7 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
var line: View? = null
last += v.results.list.size
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}")
that?.isOnPause?.let { isOnPause ->
while (isOnPause && !exit) delay(500)
@@ -277,12 +277,12 @@ class BookHandler(private val th: WeakReference<BookFragment>): Handler(Looper.m
if(exit) return@withContext
last += v.results.list.size
v.results.list.forEach {
urlArray += CMApi.getChapterInfoApiUrl(
urlArray += Config.getChapterInfoApiUrl(
path,
it.uuid,
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
chapterNames += it.name
uuidArray += it.uuid

View File

@@ -5,13 +5,13 @@ import android.widget.Toast
import androidx.navigation.fragment.findNavController
import top.fumiama.copymanga.MainActivity
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
@OptIn(ExperimentalStdlibApi::class)
class HistoryFragment : InfoCardLoader(R.layout.fragment_history, R.id.action_nav_history_to_nav_book, isHistoryBook = true) {
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?) {
if (MainActivity.member?.hasLogin != true) {

View File

@@ -1,11 +1,11 @@
package top.fumiama.copymanga.ui.cardflow.newest
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
@ExperimentalStdlibApi
class NewestFragment : InfoCardLoader(R.layout.fragment_newest, R.id.action_nav_newest_to_nav_book, true) {
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.line_rank.view.*
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.dmzj.copymanga.R
import java.lang.ref.WeakReference
@@ -48,7 +48,7 @@ class RankFragment : InfoCardLoader(R.layout.fragment_rank, R.id.action_nav_rank
override fun getApiUrl() =
getString(R.string.rankApiUrl).format(
CMApi.myHostApiUrl,
Config.myHostApiUrl.value,
page * 21,
sortWay[sortValue],
audienceWay[audience]

View File

@@ -1,11 +1,11 @@
package top.fumiama.copymanga.ui.cardflow.recommend
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
@ExperimentalStdlibApi
class RecFragment : InfoCardLoader(R.layout.fragment_recommend, R.id.action_nav_recommend_to_nav_book, true) {
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.util.Log
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
@ExperimentalStdlibApi
@@ -11,7 +11,7 @@ class SearchFragment : InfoCardLoader(R.layout.fragment_search, R.id.action_nav_
private var query: String? = null
private var type: String? = null
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?) {
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 top.fumiama.copymanga.MainActivity
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
@ExperimentalStdlibApi
@@ -26,7 +26,7 @@ class ShelfFragment : InfoCardLoader(R.layout.fragment_shelf, R.id.action_nav_su
override fun getApiUrl() =
getString(R.string.shelfApiUrl).format(
CMApi.myHostApiUrl,
Config.myHostApiUrl.value,
page * 21,
sortWay[sortValue]
)

View File

@@ -14,7 +14,7 @@ import top.fumiama.copymanga.json.FilterStructure
import top.fumiama.copymanga.json.ThemeStructure
import top.fumiama.copymanga.template.http.PausableDownloader
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
@ExperimentalStdlibApi
@@ -25,7 +25,7 @@ class SortFragment : StatusCardFlow(0, R.id.action_nav_sort_to_nav_book, R.layou
override fun getApiUrl() =
getString(R.string.sortApiUrl).format(
CMApi.myHostApiUrl,
Config.myHostApiUrl.value,
page * 21,
sortWay[sortValue],
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()
lifecycleScope.launch {
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
it.let {
it.inputStream().use { i ->

View File

@@ -11,20 +11,20 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.TopicStructure
import top.fumiama.copymanga.template.http.PausableDownloader
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
@ExperimentalStdlibApi
class TopicFragment : InfoCardLoader(R.layout.fragment_topic, R.id.action_nav_topic_to_nav_book) {
private var type = 1
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?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
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)
withContext(Dispatchers.IO) {
if(ad?.exit == true) return@withContext

View File

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

View File

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

View File

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

View File

@@ -7,13 +7,13 @@ import android.view.View
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
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.template.general.MangaPagesFragmentTemplate
import top.fumiama.copymanga.template.ui.CardList
@@ -32,13 +32,10 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
private var isReverse = false
private var isContentChanged = false
private var exit = false
private var showAll = false
private val showAll get() = manga_dl_show_0m_manga.value
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
wn = WeakReference(this)
showAll = activity?.let {
PreferenceManager.getDefaultSharedPreferences(it)
}?.getBoolean("settings_cat_md_sw_show_0m_manga", false)?:false
}
override fun onPause() {
@@ -74,7 +71,7 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
var size = sortedBookList?.size?:0
if (size > 0) {
if (!showAll) {
sortedBookList = MangaDlTools.getNonEmptyMangaList(sortedBookList) {
sortedBookList = Downloader.getNonEmptyMangaList(sortedBookList) {
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.template.general.NoBackRefreshFragment
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.Navigate
import top.fumiama.dmzj.copymanga.R
@@ -204,7 +204,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
if(it.isEmpty()) return@let
//Log.d("MyHomeFVP", "Load img: $it")
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)))
.timeout(60000).into(holder.itemView.vpi)
@@ -276,7 +276,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
cic.isClickable = false
context?.let {
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)))
.timeout(60000).into(imic)
}
@@ -295,7 +295,7 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
suspend fun refresh(q: CharSequence) = withContext(Dispatchers.IO) {
query = q.toString()
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)
count = results?.results?.total?:0
withContext(Dispatchers.Main) {

View File

@@ -31,7 +31,7 @@ import kotlinx.coroutines.withContext
import top.fumiama.copymanga.json.ComicStructure
import top.fumiama.copymanga.json.IndexStructure
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.Navigate
import top.fumiama.copymanga.tools.ui.UITools
@@ -40,7 +40,7 @@ import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicInteger
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,
that.get()
) {
@@ -369,7 +369,7 @@ class HomeHandler(private val that: WeakReference<HomeFragment>) : AutoDownloadH
if(img.startsWith("http")) {
//Log.d("MyHH", "load card image: $img")
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)) {
cardLoadingWaits.decrementAndGet()
}).timeout(60000)

View File

@@ -29,7 +29,6 @@ import androidx.core.animation.doOnEnd
import androidx.core.content.ContextCompat
import androidx.core.content.edit
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.bumptech.glide.Glide
@@ -54,10 +53,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.api.Config
import top.fumiama.copymanga.template.general.TitleActivityTemplate
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.thread.TimeThread
import top.fumiama.copymanga.tools.ui.Font
@@ -151,14 +149,11 @@ class ViewMangaActivity : TitleActivityTemplate() {
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
val settingsPref = MainActivity.mainWeakReference?.get()?.let { PreferenceManager.getDefaultSharedPreferences(it) }
settingsPref?.getBoolean("settings_cat_vm_sw_always_dark_bg", false)?.let {
if (it) {
Log.d("MyVM", "force dark")
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES
} else {
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
if (Config.view_manga_always_dark_bg.value) {
Log.d("MyVM", "force dark")
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES
} else {
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
postponeEnterTransition()
setContentView(R.layout.activity_viewmanga)
@@ -174,21 +169,21 @@ class ViewMangaActivity : TitleActivityTemplate() {
pn = intent.getIntExtra("pn", 0)
cut = pb["useCut"]
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"]
notUseVP = pb["noVP"] || isVertical
//url = intent.getStringExtra("url")
mHandler = VMHandler(this@ViewMangaActivity, if(urlArray.isNotEmpty()) urlArray[position] else "", resources.getStringArray(R.array.weeks))
lifecycleScope.launch {
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.canDo = true
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
if (!noCellarAlert) noCellarAlert = settingsPref?.getBoolean("settings_cat_net_sw_use_cellar", false) == true
fullyHideInfo = settingsPref?.getBoolean("settings_cat_vm_sw_hide_info", false) == true
if (!noCellarAlert) noCellarAlert = Config.view_manga_use_cellar.value
fullyHideInfo = Config.view_manga_hide_info.value
Log.d("MyVM", "Now ZipFile is $zipFile")
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)
window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
}
@@ -262,7 +257,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
getImgUrlArray()?.let {
tasks = Array(it.size) { i ->
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 }
}
@@ -278,7 +273,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
forEachIndexed { i, it ->
mHandler.obtainMessage(VMHandler.SET_DL_TEXT, "$i/$size").sendToTarget()
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)
}?:run {
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 {
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) }
}.run()
if (!success) button.apply { post {
@@ -918,7 +913,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
val thisOneB = holder.itemView.oneb
Glide.with(this@ViewMangaActivity.applicationContext)
.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)))
.timeout(60000)
.addListener(OneButtonRequestListener(thisOneB))
@@ -929,7 +924,7 @@ class ViewMangaActivity : TitleActivityTemplate() {
override fun onLoadCleared(placeholder: Drawable?) { }
})
} 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)
.placeholder(BitmapDrawable(resources, getLoadingBitmap(pos)))
.addListener(OneButtonRequestListener(holder.itemView.oneb))

View File

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

View File

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