mirror of
https://github.com/fumiama/copymanga.git
synced 2026-06-23 11:00:24 +08:00
v2.4.0
注意 > 由于大版本更新, 闪退问题可能增加. 如无 API 代理需求可以暂缓更新. 新增 1. 更安全的 API 代理, 旧版代理将无法使用 2. 组件下载提示 优化 1. 代码组织架构
This commit is contained in:
2
.idea/dictionaries/fumiama.xml
generated
2
.idea/dictionaries/fumiama.xml
generated
@@ -3,12 +3,14 @@
|
|||||||
<words>
|
<words>
|
||||||
<w>alphae</w>
|
<w>alphae</w>
|
||||||
<w>azurewebsites</w>
|
<w>azurewebsites</w>
|
||||||
|
<w>comancry</w>
|
||||||
<w>comandy</w>
|
<w>comandy</w>
|
||||||
<w>downloaders</w>
|
<w>downloaders</w>
|
||||||
<w>grps</w>
|
<w>grps</w>
|
||||||
<w>hotmanga</w>
|
<w>hotmanga</w>
|
||||||
<w>imgs</w>
|
<w>imgs</w>
|
||||||
<w>kohima</w>
|
<w>kohima</w>
|
||||||
|
<w>libcomancry</w>
|
||||||
<w>libcomandy</w>
|
<w>libcomandy</w>
|
||||||
<w>lowpan</w>
|
<w>lowpan</w>
|
||||||
<w>mangacopy</w>
|
<w>mangacopy</w>
|
||||||
|
|||||||
3
app/.gitignore
vendored
3
app/.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
/build
|
/build
|
||||||
/release
|
/release
|
||||||
/debug
|
/debug
|
||||||
|
signing.properties
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ android {
|
|||||||
applicationId 'top.fumiama.copymanga'
|
applicationId 'top.fumiama.copymanga'
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 66
|
versionCode 67
|
||||||
versionName '2.3.8'
|
versionName '2.4.0'
|
||||||
resourceConfigurations += ['zh', 'zh-rCN']
|
resourceConfigurations += ['zh', 'zh-rCN']
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
@@ -31,6 +31,12 @@ android {
|
|||||||
enableV3Signing true
|
enableV3Signing true
|
||||||
enableV4Signing true
|
enableV4Signing true
|
||||||
}
|
}
|
||||||
|
debug {
|
||||||
|
enableV1Signing true
|
||||||
|
enableV2Signing true
|
||||||
|
enableV3Signing true
|
||||||
|
enableV4Signing true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@@ -45,12 +51,14 @@ android {
|
|||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
|
||||||
debug{
|
|
||||||
minifyEnabled true
|
|
||||||
shrinkResources true
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
|
||||||
}*/
|
}*/
|
||||||
|
debug{
|
||||||
|
//minifyEnabled true
|
||||||
|
//shrinkResources true
|
||||||
|
//vcsInfo.include false
|
||||||
|
//proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_11
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
@@ -70,6 +78,21 @@ android {
|
|||||||
namespace 'top.fumiama.dmzj.copymanga'
|
namespace 'top.fumiama.dmzj.copymanga'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Properties props = new Properties()
|
||||||
|
def propFile = file('signing.properties')
|
||||||
|
if (propFile.canRead()){
|
||||||
|
props.load(new FileInputStream(propFile))
|
||||||
|
|
||||||
|
if (props!=null && props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
|
||||||
|
props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
|
||||||
|
|
||||||
|
android.signingConfigs.debug.storeFile = file(props['STORE_FILE'])
|
||||||
|
android.signingConfigs.debug.storePassword = props['STORE_PASSWORD']
|
||||||
|
android.signingConfigs.debug.keyAlias = props['KEY_ALIAS']
|
||||||
|
android.signingConfigs.debug.keyPassword = props['KEY_PASSWORD']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api fileTree(include: ['*.aar'], dir: 'libs') // https://stackoverflow.com/a/63029110/28801553
|
api fileTree(include: ['*.aar'], dir: 'libs') // https://stackoverflow.com/a/63029110/28801553
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
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.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
@@ -51,16 +50,16 @@ 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.api.Config
|
||||||
import top.fumiama.copymanga.manga.Shelf
|
import top.fumiama.copymanga.api.manga.Shelf
|
||||||
import top.fumiama.copymanga.tools.ui.UITools
|
import top.fumiama.copymanga.view.interaction.UITools
|
||||||
import top.fumiama.copymanga.ui.book.BookFragment.Companion.bookHandler
|
import top.fumiama.copymanga.ui.book.BookFragment.Companion.bookHandler
|
||||||
import top.fumiama.copymanga.ui.book.BookHandler
|
import top.fumiama.copymanga.ui.book.BookHandler
|
||||||
import top.fumiama.copymanga.ui.cardflow.rank.RankFragment
|
import top.fumiama.copymanga.ui.cardflow.rank.RankFragment
|
||||||
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment
|
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment
|
||||||
import top.fumiama.copymanga.ui.download.DownloadFragment
|
import top.fumiama.copymanga.ui.download.DownloadFragment
|
||||||
import top.fumiama.copymanga.ui.download.NewDownloadFragment
|
import top.fumiama.copymanga.ui.download.NewDownloadFragment
|
||||||
import top.fumiama.copymanga.update.Update
|
import top.fumiama.copymanga.api.update.Update
|
||||||
import top.fumiama.copymanga.user.Member
|
import top.fumiama.copymanga.api.user.Member
|
||||||
import top.fumiama.dmzj.copymanga.BuildConfig
|
import top.fumiama.dmzj.copymanga.BuildConfig
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -236,7 +235,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
navtinfo.text = getPreferences(MODE_PRIVATE).getString("navTextInfo", getString(R.string.navTextInfo))
|
navtinfo.text = Config.navTextInfo.value
|
||||||
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
|
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,10 +420,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
MaterialDialog(this).show {
|
MaterialDialog(this).show {
|
||||||
input(prefill = (it as TextView).text) { _, charSequence ->
|
input(prefill = (it as TextView).text) { _, charSequence ->
|
||||||
it.text = charSequence
|
it.text = charSequence
|
||||||
getPreferences(MODE_PRIVATE).edit {
|
Config.navTextInfo.value = charSequence.toString()
|
||||||
putString("navTextInfo", charSequence.toString())
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
positiveButton(android.R.string.ok)
|
positiveButton(android.R.string.ok)
|
||||||
title(R.string.navTextInfoInputHint)
|
title(R.string.navTextInfoInputHint)
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import top.fumiama.copymanga.tools.file.PreferenceInt
|
|||||||
import top.fumiama.copymanga.tools.file.PreferenceString
|
import top.fumiama.copymanga.tools.file.PreferenceString
|
||||||
import top.fumiama.copymanga.tools.file.UserPreferenceInt
|
import top.fumiama.copymanga.tools.file.UserPreferenceInt
|
||||||
import top.fumiama.copymanga.tools.file.UserPreferenceString
|
import top.fumiama.copymanga.tools.file.UserPreferenceString
|
||||||
import top.fumiama.copymanga.tools.http.Proxy
|
import top.fumiama.copymanga.net.Proxy
|
||||||
import top.fumiama.copymanga.tools.http.Resolution
|
import top.fumiama.copymanga.net.Resolution
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -54,12 +54,14 @@ object Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val myHostApiUrl = PreferenceString("settings_cat_net_et_api_url", R.string.hostUrl)
|
val myHostApiUrl = PreferenceString("settings_cat_net_et_api_url", R.string.hostUrl)
|
||||||
|
val navTextInfo = UserPreferenceString("navTextInfo", R.string.navTextInfo)
|
||||||
val proxy_key = PreferenceString(R.string.imgProxyKeyID)
|
val proxy_key = PreferenceString(R.string.imgProxyKeyID)
|
||||||
val app_ver = PreferenceString("settings_cat_general_et_app_version", R.string.app_ver)
|
val app_ver = PreferenceString("settings_cat_general_et_app_version", R.string.app_ver)
|
||||||
val token = UserPreferenceString("token", "", null)
|
val token = UserPreferenceString("token", "", null)
|
||||||
val pc_ua get() = MainActivity.mainWeakReference?.get()?.getString(R.string.pc_ua)?.format(app_ver.value)?:""
|
val pc_ua get() = MainActivity.mainWeakReference?.get()?.getString(R.string.pc_ua)?.format(app_ver.value)?:""
|
||||||
val referer get() = MainActivity.mainWeakReference?.get()?.getString(R.string.referer)?.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 comandy_version = UserPreferenceInt("comandy_version", 0)
|
||||||
|
val comancry_version = UserPreferenceInt("comancry_version", 0)
|
||||||
val user_id = UserPreferenceString("user_id")
|
val user_id = UserPreferenceString("user_id")
|
||||||
val username = UserPreferenceString("username")
|
val username = UserPreferenceString("username")
|
||||||
val nickname = UserPreferenceString("nickname")
|
val nickname = UserPreferenceString("nickname")
|
||||||
@@ -76,6 +78,7 @@ object Config {
|
|||||||
val net_use_foreign = PreferenceBoolean("settings_cat_net_sw_use_foreign", 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)
|
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 net_use_api_proxy = PreferenceBoolean("settings_cat_net_sw_use_api_proxy", false)
|
||||||
|
val net_img_resolution = PreferenceString(R.string.imgResolutionKeyID)
|
||||||
|
|
||||||
val view_manga_always_dark_bg = PreferenceBoolean("settings_cat_vm_sw_always_dark_bg", 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_vertical_max = PreferenceInt("settings_cat_vm_sb_vertical_max", 20)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.manga
|
package top.fumiama.copymanga.api.manga
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
@@ -10,14 +10,12 @@ 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.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
import top.fumiama.copymanga.net.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(Config.myHostApiUrl.value, path).let {
|
private val mBookApiUrl = getString(R.string.bookInfoApiUrl).format(Config.myHostApiUrl.value, path)
|
||||||
Config.apiProxy?.wrap(it)?:it
|
|
||||||
}
|
|
||||||
private val mUserAgent = getString(R.string.pc_ua).format(Config.app_ver.value)
|
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>()
|
||||||
@@ -68,12 +66,16 @@ class Book(val path: String, private val getString: (Int) -> String, private val
|
|||||||
val data: ByteArray = if (loadCache) {
|
val data: ByteArray = if (loadCache) {
|
||||||
name?.let { loadInfo(it) } ?: run {
|
name?.let { loadInfo(it) } ?: run {
|
||||||
isDownload = true
|
isDownload = true
|
||||||
DownloadTools.getHttpContent(mBookApiUrl, null, mUserAgent)
|
Config.apiProxy?.comancry(mBookApiUrl) { url ->
|
||||||
|
DownloadTools.getHttpContent(url, null, mUserAgent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isDownload = true
|
isDownload = true
|
||||||
DownloadTools.getHttpContent(mBookApiUrl, null, mUserAgent)
|
Config.apiProxy?.comancry(mBookApiUrl) { url ->
|
||||||
}
|
DownloadTools.getHttpContent(url, null, mUserAgent)
|
||||||
|
}
|
||||||
|
}?:DownloadTools.getHttpContent(mBookApiUrl, null, mUserAgent)
|
||||||
mBook = data.inputStream().use {
|
mBook = data.inputStream().use {
|
||||||
Gson().fromJson(it.reader(), BookInfoStructure::class.java)
|
Gson().fromJson(it.reader(), BookInfoStructure::class.java)
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package top.fumiama.copymanga.manga
|
package top.fumiama.copymanga.api.manga
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||||
import top.fumiama.copymanga.json.Chapter2Return
|
import top.fumiama.copymanga.json.Chapter2Return
|
||||||
import top.fumiama.copymanga.template.http.PausableDownloader
|
import top.fumiama.copymanga.net.template.PausableDownloader
|
||||||
import top.fumiama.copymanga.tools.http.DownloadPool
|
import top.fumiama.copymanga.net.DownloadPool
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class Downloader {
|
class Downloader {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.manga
|
package top.fumiama.copymanga.api.manga
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.manga
|
package top.fumiama.copymanga.api.manga
|
||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -6,14 +6,14 @@ 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.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
import top.fumiama.copymanga.net.DownloadTools
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
class Shelf(private val getString: (Int) -> String) {
|
class Shelf(private val getString: (Int) -> String) {
|
||||||
private val apiUrl: String get() = getString(R.string.shelfOperateApiUrl).format(Config.myHostApiUrl.value)
|
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 addApiUrl get() = "$apiUrl?platform=3".let { Config.apiProxy?.wrap(it)?:it }
|
private val addApiUrl get() = "$apiUrl?platform=3"
|
||||||
private val delApiUrl get() = "${apiUrl}s?platform=3".let { Config.apiProxy?.wrap(it)?:it }
|
private val delApiUrl get() = "${apiUrl}s?platform=3"
|
||||||
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"
|
||||||
@@ -25,9 +25,11 @@ class Shelf(private val getString: (Int) -> String) {
|
|||||||
append("")
|
append("")
|
||||||
append(Config.token.value)
|
append(Config.token.value)
|
||||||
}
|
}
|
||||||
val re = DownloadTools.requestWithBody(
|
val re = Config.apiProxy?.comancry(addApiUrl) { url ->
|
||||||
addApiUrl, "POST", body.encodeToByteArray()
|
DownloadTools.requestWithBody(
|
||||||
)?.decodeToString() ?: return@withContext "空回应"
|
url, "POST", body.encodeToByteArray()
|
||||||
|
)
|
||||||
|
}?.decodeToString() ?: return@withContext "空回应"
|
||||||
return@withContext try {
|
return@withContext try {
|
||||||
Gson().fromJson(re, ReturnBase::class.java).message
|
Gson().fromJson(re, ReturnBase::class.java).message
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -48,9 +50,11 @@ class Shelf(private val getString: (Int) -> String) {
|
|||||||
append("authorization=Token+")
|
append("authorization=Token+")
|
||||||
append(Config.token.value)
|
append(Config.token.value)
|
||||||
}
|
}
|
||||||
val re = DownloadTools.requestWithBody(
|
val re = Config.apiProxy?.comancry(delApiUrl) { url ->
|
||||||
delApiUrl, "DELETE", body.encodeToByteArray()
|
DownloadTools.requestWithBody(
|
||||||
)?.decodeToString() ?: return@withContext "空回应"
|
url, "DELETE", body.encodeToByteArray()
|
||||||
|
)
|
||||||
|
}?.decodeToString() ?: return@withContext "空回应"
|
||||||
return@withContext try {
|
return@withContext try {
|
||||||
Gson().fromJson(re, ReturnBase::class.java).message
|
Gson().fromJson(re, ReturnBase::class.java).message
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -60,11 +64,11 @@ class Shelf(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(
|
Config.apiProxy?.comancry(queryApiUrlTemplate.format(Config.myHostApiUrl.value, pathWord)) { url ->
|
||||||
queryApiUrlTemplate.format(Config.myHostApiUrl.value, pathWord).let {
|
DownloadTools.getHttpContent(url, Config.referer)
|
||||||
Config.apiProxy?.wrap(it)?:it
|
}?.let {
|
||||||
}, Config.referer
|
Gson().fromJson(it.decodeToString(), BookQueryStructure::class.java)
|
||||||
).decodeToString(), BookQueryStructure::class.java)
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
null
|
null
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.manga
|
package top.fumiama.copymanga.api.manga
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
@@ -6,7 +6,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.withContext
|
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.net.template.PausableDownloader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.update
|
package top.fumiama.copymanga.api.update
|
||||||
//Fumiama 20210601
|
//Fumiama 20210601
|
||||||
//ByteArrayQueue.kt
|
//ByteArrayQueue.kt
|
||||||
//FIFO队列
|
//FIFO队列
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package top.fumiama.copymanga.update
|
package top.fumiama.copymanga.api.update
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import top.fumiama.copymanga.net.Client
|
||||||
|
|
||||||
class SimpleKanban(private val client: Client, private val pwd: String) { //must run in thread
|
class SimpleKanban(private val client: Client, private val pwd: String) { //must run in thread
|
||||||
private val raw: ByteArray?
|
private val raw: ByteArray?
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.update
|
package top.fumiama.copymanga.api.update
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -16,7 +16,8 @@ import kotlinx.android.synthetic.main.dialog_progress.view.*
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import top.fumiama.copymanga.tools.ui.UITools
|
import top.fumiama.copymanga.net.Client
|
||||||
|
import top.fumiama.copymanga.view.interaction.UITools
|
||||||
import top.fumiama.dmzj.copymanga.BuildConfig
|
import top.fumiama.dmzj.copymanga.BuildConfig
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
159
app/src/main/java/top/fumiama/copymanga/api/user/Member.kt
Normal file
159
app/src/main/java/top/fumiama/copymanga/api/user/Member.kt
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
package top.fumiama.copymanga.api.user
|
||||||
|
|
||||||
|
import android.util.Base64
|
||||||
|
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.lib.Comandy
|
||||||
|
import top.fumiama.copymanga.net.DownloadTools
|
||||||
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
import java.net.URLEncoder
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
|
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 (!Config.net_use_api_proxy.value && Comandy.instance.enabled)
|
||||||
|
postComandyLogin(username, pwd, salt)
|
||||||
|
else postLogin(username, pwd, salt))?.let { data ->
|
||||||
|
try {
|
||||||
|
return@withContext saveInfo(data)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
err = e.message.toString()
|
||||||
|
}
|
||||||
|
} ?: run { err = getString(R.string.login_get_conn_failed) }
|
||||||
|
val l = LoginInfoStructure()
|
||||||
|
l.code = 400
|
||||||
|
l.message = err
|
||||||
|
return@withContext l
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得登录信息并更新头像
|
||||||
|
* @return 登录态
|
||||||
|
* - **code**: 449: 未登录, 450: 有 Exception
|
||||||
|
* - **message**: 可以 toast 的信息
|
||||||
|
*/
|
||||||
|
suspend fun info(): LoginInfoStructure = withContext(Dispatchers.IO) {
|
||||||
|
if (!hasLogin) {
|
||||||
|
val l = LoginInfoStructure()
|
||||||
|
l.code = 449
|
||||||
|
l.message = getString(R.string.noLogin)
|
||||||
|
return@withContext l
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val data = Config.apiProxy?.comancry(
|
||||||
|
getString(R.string.memberInfoApiUrl)
|
||||||
|
.format(Config.myHostApiUrl.value)
|
||||||
|
) {
|
||||||
|
DownloadTools.getHttpContent(it)
|
||||||
|
}?.decodeToString()
|
||||||
|
try {
|
||||||
|
val l = Gson().fromJson(data, LoginInfoStructure::class.java)
|
||||||
|
if (l.code == 200) Config.avatar.value = l.results.avatar
|
||||||
|
l
|
||||||
|
} catch (e: Exception) {
|
||||||
|
val l = LoginInfoStructure()
|
||||||
|
l.code = 450
|
||||||
|
l.message = "${getString(R.string.login_get_avatar_failed)}: $data"
|
||||||
|
l
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
val l = LoginInfoStructure()
|
||||||
|
l.code = 450
|
||||||
|
l.message = "${getString(R.string.login_get_avatar_failed)}: $e"
|
||||||
|
l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun logout() = withContext(Dispatchers.IO) {
|
||||||
|
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) {
|
||||||
|
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))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw Exception(data.decodeToString(), e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun postLogin(username: String, pwd: String, salt: Int): ByteArray? =
|
||||||
|
Config.apiProxy?.comancry(getString(R.string.loginApiUrl).format(Config.myHostApiUrl.value)) {
|
||||||
|
DownloadTools.getApiConnection(it, "POST").let { c ->
|
||||||
|
c.doOutput = true
|
||||||
|
c.setRequestProperty(
|
||||||
|
"content-type",
|
||||||
|
"application/x-www-form-urlencoded;charset=utf-8"
|
||||||
|
)
|
||||||
|
c.setRequestProperty("platform", "3")
|
||||||
|
c.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()
|
||||||
|
c.outputStream.write(
|
||||||
|
"username=${
|
||||||
|
URLEncoder.encode(
|
||||||
|
username,
|
||||||
|
Charset.defaultCharset().name()
|
||||||
|
)
|
||||||
|
}&password=$pwdEncoded&salt=$salt&platform=3&authorization=Token+&version=${Config.app_ver.value}&source=copyApp®ion=$r&webp=1".toByteArray()
|
||||||
|
)
|
||||||
|
c.outputStream.close()
|
||||||
|
val b = c.inputStream.readBytes()
|
||||||
|
c.inputStream.close()
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private suspend fun postComandyLogin(username: String, pwd: String, salt: Int) =
|
||||||
|
Config.apiProxy?.comancry(getString(R.string.loginApiUrl).format(Config.myHostApiUrl.value)) {
|
||||||
|
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®ion=$r&webp=1"
|
||||||
|
}.let { capsule ->
|
||||||
|
try {
|
||||||
|
val para = Gson().toJson(capsule)
|
||||||
|
Comandy.instance.getInstance()?.request(para)?.let { result ->
|
||||||
|
Gson().fromJson(result, ComandyCapsule::class.java)!!.let {
|
||||||
|
if (it.code != 200) null
|
||||||
|
else Base64.decode(it.data, Base64.DEFAULT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app/src/main/java/top/fumiama/copymanga/lib/Comancry.kt
Normal file
22
app/src/main/java/top/fumiama/copymanga/lib/Comancry.kt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package top.fumiama.copymanga.lib
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import com.sun.jna.Memory
|
||||||
|
import top.fumiama.copymanga.api.Config
|
||||||
|
import top.fumiama.copymanga.lib.template.LazyLibrary
|
||||||
|
|
||||||
|
class Comancry: LazyLibrary<ComancryMethods>(
|
||||||
|
ComancryMethods::class.java, "libcomancry.so", "API代理",
|
||||||
|
Config.net_use_api_proxy, Config.comancry_version
|
||||||
|
) {
|
||||||
|
suspend fun decrypt(sd: String, data: ByteArray): String? {
|
||||||
|
// 将 ByteArray 转换为 char*
|
||||||
|
val nativeMemory = Memory(data.size.toLong())
|
||||||
|
nativeMemory.write(0, data, 0, data.size) // 将 byteArray 写入内存
|
||||||
|
Log.d("MyComancry", "get data len ${data.size}")
|
||||||
|
return getInstance()?.decrypt(sd, nativeMemory, data.size)
|
||||||
|
}
|
||||||
|
companion object {
|
||||||
|
val instance = Comancry()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package top.fumiama.copymanga.lib
|
||||||
|
|
||||||
|
import com.sun.jna.Library
|
||||||
|
import com.sun.jna.Pointer
|
||||||
|
|
||||||
|
interface ComancryMethods : Library {
|
||||||
|
fun decrypt(sd: String, data: Pointer, len: Int): String?
|
||||||
|
}
|
||||||
13
app/src/main/java/top/fumiama/copymanga/lib/Comandy.kt
Normal file
13
app/src/main/java/top/fumiama/copymanga/lib/Comandy.kt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package top.fumiama.copymanga.lib
|
||||||
|
|
||||||
|
import top.fumiama.copymanga.api.Config
|
||||||
|
import top.fumiama.copymanga.lib.template.LazyLibrary
|
||||||
|
|
||||||
|
class Comandy: LazyLibrary<ComandyMethods>(
|
||||||
|
ComandyMethods::class.java, "libcomandy.so", "网络增强",
|
||||||
|
Config.net_use_comandy, Config.comandy_version
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
val instance = Comandy()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package top.fumiama.copymanga.lib
|
||||||
|
|
||||||
|
import com.sun.jna.Library
|
||||||
|
|
||||||
|
interface ComandyMethods : Library {
|
||||||
|
// fun add_dns(para: String?, is_ipv6: Int): String?
|
||||||
|
|
||||||
|
fun request(para: String): String?
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
package top.fumiama.copymanga.lib.template
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.sun.jna.Library
|
||||||
|
import com.sun.jna.Native
|
||||||
|
import kotlinx.android.synthetic.main.dialog_progress.view.*
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import top.fumiama.copymanga.MainActivity
|
||||||
|
import top.fumiama.copymanga.json.ComandyVersion
|
||||||
|
import top.fumiama.copymanga.tools.file.PreferenceBoolean
|
||||||
|
import top.fumiama.copymanga.tools.file.UserPreferenceInt
|
||||||
|
import top.fumiama.copymanga.net.DownloadTools
|
||||||
|
import top.fumiama.copymanga.net.Client
|
||||||
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
import java.util.zip.GZIPInputStream
|
||||||
|
|
||||||
|
open class LazyLibrary<T: Library>(
|
||||||
|
private val clazz: Class<T>,
|
||||||
|
private val name: String,
|
||||||
|
private val functionName: String,
|
||||||
|
private val isInUse: PreferenceBoolean,
|
||||||
|
private val version: UserPreferenceInt
|
||||||
|
) {
|
||||||
|
private val repoName = name.substring(3).substringBeforeLast(".")
|
||||||
|
private var isInInit = AtomicBoolean(false)
|
||||||
|
private var mInstance: T? = null
|
||||||
|
suspend fun getInstance(): T? {
|
||||||
|
//Log.d("MyLazyLibrary", "get instance @$field")
|
||||||
|
if (mInstance != null) return mInstance
|
||||||
|
mInstance = libraryFile()?.absolutePath?.let { Native.load(it, clazz) }?:return null
|
||||||
|
//Log.d("MyLazyLibrary", "init instance @$field")
|
||||||
|
return mInstance
|
||||||
|
}
|
||||||
|
private var mEnabled: Boolean? = null
|
||||||
|
val enabled: Boolean
|
||||||
|
get() {
|
||||||
|
if (isInInit.get()) {
|
||||||
|
Log.d("MyLazyLibrary", "$name block enabled for isInInit")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (mEnabled != true && DownloadTools.failTimes.get() >= 2) {
|
||||||
|
mEnabled = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (mEnabled != null) return mEnabled!!
|
||||||
|
val v = isInUse.value
|
||||||
|
mEnabled = v
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
private var mLibraryFile: File? = null
|
||||||
|
private suspend fun libraryFile(): File? {
|
||||||
|
if (isInInit.get()) return null
|
||||||
|
mLibraryFile?.let { return it }
|
||||||
|
isInInit.set(true)
|
||||||
|
Log.d("MyLazyLibrary", "start to download/check $name")
|
||||||
|
val prefix = when (Build.SUPPORTED_ABIS[0]) {
|
||||||
|
"arm64-v8a" -> "aarch64"
|
||||||
|
"armeabi-v7a" -> "armv7a"
|
||||||
|
"x86_64" -> "x86_64"
|
||||||
|
"x86" -> "i686"
|
||||||
|
else -> null
|
||||||
|
}?:return null
|
||||||
|
Log.d("MyLazyLibrary", "$name arch: $prefix")
|
||||||
|
MainActivity.mainWeakReference?.get()?.let { ma ->
|
||||||
|
ma.lifecycleScope.launch {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
Log.d("MyLazyLibrary", "$name launched")
|
||||||
|
var f = File(ma.filesDir, "libs")
|
||||||
|
if (!f.exists()) f.mkdirs()
|
||||||
|
f = File(f, name)
|
||||||
|
var remoteVersion = 0
|
||||||
|
if (f.exists()) {
|
||||||
|
DownloadTools.getHttpContent(ma.getString(R.string.comandy_version_url).format(repoName), -1)?.let dataLet@{
|
||||||
|
try {
|
||||||
|
val body = Gson().fromJson(it.decodeToString(), ComandyVersion::class.java)?.body
|
||||||
|
if (body?.startsWith("Version: ") == true) {
|
||||||
|
remoteVersion = body.substring(9).toInt()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
val myVersion = version.value?:0
|
||||||
|
if (myVersion >= remoteVersion) {
|
||||||
|
Log.d("MyLazyLibrary", "$name version $myVersion is latest")
|
||||||
|
isInInit.set(false)
|
||||||
|
mLibraryFile = f
|
||||||
|
return@withContext
|
||||||
|
}
|
||||||
|
Log.d("MyLazyLibrary", "$name version $myVersion <= latest $remoteVersion, update...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
val progressBar = ma.layoutInflater.inflate(R.layout.dialog_progress, null, false)
|
||||||
|
val progressHandler = object : Client.Progress{
|
||||||
|
override fun notify(progressPercentage: Int) {
|
||||||
|
Log.d("MyLazyLibrary", "Set dl $name progress: $progressPercentage")
|
||||||
|
progressBar.dpp.progress = progressPercentage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val info = ma.toolsBox.buildAlertWithView("加载${functionName}组件", progressBar, "隐藏")
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
DownloadTools.getHttpContent(ma.getString(R.string.comandy_download_url).format(repoName, prefix, name), -1, progressHandler)?.let {
|
||||||
|
if(f.exists()) f.delete()
|
||||||
|
try {
|
||||||
|
GZIPInputStream(ByteArrayInputStream(it)).use { dataIn ->
|
||||||
|
f.outputStream().use { dataOut ->
|
||||||
|
dataIn.copyTo(dataOut)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (remoteVersion > 0) version.value = remoteVersion
|
||||||
|
Log.d("MyLazyLibrary", "update success")
|
||||||
|
isInInit.set(false)
|
||||||
|
info.dismiss()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
if(f.exists()) f.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mLibraryFile = if(f.exists()) f else null
|
||||||
|
return@withContext
|
||||||
|
}
|
||||||
|
}.join()
|
||||||
|
}
|
||||||
|
return mLibraryFile
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package top.fumiama.copymanga.update
|
package top.fumiama.copymanga.net
|
||||||
//Fumiama 20210601
|
//Fumiama 20210601
|
||||||
//Client.kt
|
//Client.kt
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import top.fumiama.copymanga.api.update.ByteArrayQueue
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.lang.Thread.sleep
|
import java.lang.Thread.sleep
|
||||||
import java.net.Socket
|
import java.net.Socket
|
||||||
@@ -75,12 +76,17 @@ class Client(private val ip: String, private val port: Int) {
|
|||||||
try {
|
try {
|
||||||
if (isConnect) {
|
if (isConnect) {
|
||||||
Log.d("MyC", "开始接收服务端信息")
|
Log.d("MyC", "开始接收服务端信息")
|
||||||
|
var prevP = 0
|
||||||
while(totalSize > buffer.size) {
|
while(totalSize > buffer.size) {
|
||||||
val count = din?.read(receiveBuffer)?:0
|
val count = din?.read(receiveBuffer)?:0
|
||||||
if(count > 0) {
|
if(count > 0) {
|
||||||
buffer += receiveBuffer.copyOfRange(0, count)
|
buffer += receiveBuffer.copyOfRange(0, count)
|
||||||
Log.d("MyC", "reply length:$count")
|
Log.d("MyC", "reply length:$count")
|
||||||
if(setProgress && totalSize > 0) progress?.notify(100 * buffer.size / totalSize)
|
val p = 100 * buffer.size / totalSize
|
||||||
|
if(setProgress && totalSize > 0 && prevP != p) {
|
||||||
|
progress?.notify(p)
|
||||||
|
prevP = p
|
||||||
|
}
|
||||||
} else sleep(10)
|
} else sleep(10)
|
||||||
}
|
}
|
||||||
} else Log.d("MyC", "no connect to receive message")
|
} else Log.d("MyC", "no connect to receive message")
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
package top.fumiama.copymanga.tools.http
|
package top.fumiama.copymanga.net
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.Log
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.Priority
|
import com.bumptech.glide.Priority
|
||||||
import com.bumptech.glide.Registry
|
import com.bumptech.glide.Registry
|
||||||
@@ -17,8 +16,9 @@ import com.bumptech.glide.load.model.MultiModelLoaderFactory
|
|||||||
import com.bumptech.glide.module.AppGlideModule
|
import com.bumptech.glide.module.AppGlideModule
|
||||||
import com.bumptech.glide.signature.ObjectKey
|
import com.bumptech.glide.signature.ObjectKey
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import top.fumiama.copymanga.MainActivity
|
import kotlinx.coroutines.runBlocking
|
||||||
import top.fumiama.copymanga.json.ComandyCapsule
|
import top.fumiama.copymanga.json.ComandyCapsule
|
||||||
|
import top.fumiama.copymanga.lib.Comandy
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
@GlideModule
|
@GlideModule
|
||||||
@@ -44,7 +44,7 @@ class ComandyGlideModule: AppGlideModule() {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val para = Gson().toJson(capsule)
|
val para = Gson().toJson(capsule)
|
||||||
Comandy.instance!!.request(para).let { result ->
|
runBlocking { Comandy.instance.getInstance() }!!.request(para).let { result ->
|
||||||
Gson().fromJson(result, ComandyCapsule::class.java)!!.let {
|
Gson().fromJson(result, ComandyCapsule::class.java)!!.let {
|
||||||
if (it.code != 200) {
|
if (it.code != 200) {
|
||||||
callback.onLoadFailed(IllegalArgumentException("HTTP${it.code} ${
|
callback.onLoadFailed(IllegalArgumentException("HTTP${it.code} ${
|
||||||
@@ -85,7 +85,7 @@ class ComandyGlideModule: AppGlideModule() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun handles(model: GlideUrl): Boolean {
|
override fun handles(model: GlideUrl): Boolean {
|
||||||
return Comandy.useComandy && Comandy.instance != null && model.toURL().let {
|
return Comandy.instance.enabled && runBlocking { Comandy.instance.getInstance() } != null && model.toURL().let {
|
||||||
it.protocol == "https" && it.host != "copymanga.azurewebsites.net"
|
it.protocol == "https" && it.host != "copymanga.azurewebsites.net"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ class ComandyGlideModule: AppGlideModule() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun handles(model: String): Boolean {
|
override fun handles(model: String): Boolean {
|
||||||
return Comandy.useComandy && Comandy.instance != null && model.startsWith("https://")
|
return Comandy.instance.enabled && runBlocking { Comandy.instance.getInstance() } != null && model.startsWith("https://")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.tools.http
|
package top.fumiama.copymanga.net
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
package top.fumiama.copymanga.tools.http
|
package top.fumiama.copymanga.net
|
||||||
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.Log
|
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.runBlocking
|
||||||
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.api.Config
|
||||||
import top.fumiama.copymanga.json.ComandyCapsule
|
import top.fumiama.copymanga.json.ComandyCapsule
|
||||||
|
import top.fumiama.copymanga.lib.Comandy
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.OutputStream
|
||||||
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
|
||||||
@@ -85,13 +90,39 @@ object DownloadTools {
|
|||||||
capsule
|
capsule
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getHttpContent(u: String, refer: String? = null, ua: String? = Config.pc_ua): ByteArray =
|
private fun InputStream.copyToWithProgress(out: OutputStream, sz: Int, p: Client.Progress, bufferSize: Int = DEFAULT_BUFFER_SIZE): Long {
|
||||||
|
var bytesCopied: Long = 0
|
||||||
|
val buffer = ByteArray(bufferSize)
|
||||||
|
var bytes = read(buffer)
|
||||||
|
var prevP = 0
|
||||||
|
p.notify(0)
|
||||||
|
while (bytes >= 0) {
|
||||||
|
val progress = (100*bytesCopied/sz).toInt()
|
||||||
|
if (prevP != progress) {
|
||||||
|
p.notify(progress)
|
||||||
|
prevP = progress
|
||||||
|
}
|
||||||
|
out.write(buffer, 0, bytes)
|
||||||
|
bytesCopied += bytes
|
||||||
|
bytes = read(buffer)
|
||||||
|
}
|
||||||
|
p.notify(100)
|
||||||
|
return bytesCopied
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun InputStream.readBytesWithProgress(sz: Int, p: Client.Progress): ByteArray {
|
||||||
|
val buffer = ByteArrayOutputStream(maxOf(DEFAULT_BUFFER_SIZE, this.available()))
|
||||||
|
copyToWithProgress(buffer, sz, p)
|
||||||
|
return buffer.toByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getHttpContent(u: String, refer: String? = null, ua: String? = Config.pc_ua, p: Client.Progress? = null): ByteArray =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) {
|
if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.instance.enabled) {
|
||||||
getComandyApiConnection(u, "GET", refer, ua).let { capsule ->
|
getComandyApiConnection(u, "GET", refer, ua).let { capsule ->
|
||||||
val para = Gson().toJson(capsule)
|
val para = Gson().toJson(capsule)
|
||||||
//Log.d("MyDT", "comandy request: $para")
|
//Log.d("MyDT", "comandy request: $para")
|
||||||
Comandy.instance?.request(para)?.let { result ->
|
Comandy.instance.getInstance()?.request(para)?.let { result ->
|
||||||
//Log.d("MyDT", "comandy reply: $result")
|
//Log.d("MyDT", "comandy reply: $result")
|
||||||
Gson().fromJson(result, ComandyCapsule::class.java)!!.let {
|
Gson().fromJson(result, ComandyCapsule::class.java)!!.let {
|
||||||
if (it.code != 200) throw IllegalArgumentException("HTTP${it.code} ${
|
if (it.code != 200) throw IllegalArgumentException("HTTP${it.code} ${
|
||||||
@@ -104,7 +135,12 @@ object DownloadTools {
|
|||||||
}
|
}
|
||||||
failTimes.incrementAndGet()
|
failTimes.incrementAndGet()
|
||||||
getApiConnection(u, "GET", refer, ua).let {
|
getApiConnection(u, "GET", refer, ua).let {
|
||||||
val ret = it.inputStream.readBytes()
|
val sz = it.getHeaderFieldInt("Content-Length", 0)
|
||||||
|
val ret = if (sz > 0 && p != null) {
|
||||||
|
it.inputStream.readBytesWithProgress(sz, p)
|
||||||
|
} else {
|
||||||
|
it.inputStream.readBytes()
|
||||||
|
}
|
||||||
it.disconnect()
|
it.disconnect()
|
||||||
Log.d("MyDT", "getHttpContent: ${ret.size} bytes")
|
Log.d("MyDT", "getHttpContent: ${ret.size} bytes")
|
||||||
failTimes.decrementAndGet()
|
failTimes.decrementAndGet()
|
||||||
@@ -112,24 +148,25 @@ object DownloadTools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getHttpContent(u: String, readSize: Int): ByteArray? {
|
fun getHttpContent(u: String, readSize: Int, p: Client.Progress? = null): ByteArray? {
|
||||||
Log.d("MyDT", "getHttp: $u")
|
Log.d("MyDT", "getHttp: $u")
|
||||||
val task = prepare(u, readSize)
|
val task = prepare(u, readSize, p)
|
||||||
Thread(task).start()
|
Thread(task).start()
|
||||||
return try {
|
return try {
|
||||||
task.get()
|
task.get()
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
if (Comandy.useComandy) failTimes.incrementAndGet()
|
if (Comandy.instance.enabled) failTimes.incrementAndGet()
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun prepare(u: String, readSize: Int = -1) = run {
|
// prepare p only take effect when readSize is -1
|
||||||
|
fun prepare(u: String, readSize: Int = -1, p: Client.Progress? = null) = run {
|
||||||
Log.d("MyDT", "prepareHttp: $u")
|
Log.d("MyDT", "prepareHttp: $u")
|
||||||
FutureTask(if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.useComandy) Callable{
|
FutureTask(if (!u.startsWith("https://copymanga.azurewebsites.net") && Comandy.instance.enabled) Callable{
|
||||||
try {
|
try {
|
||||||
Comandy.instance?.request(Gson().toJson(
|
runBlocking { Comandy.instance.getInstance() }?.request(Gson().toJson(
|
||||||
getComandyNormalConnection(u, "GET", Config.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 {
|
||||||
@@ -146,10 +183,15 @@ object DownloadTools {
|
|||||||
try {
|
try {
|
||||||
val connection = getNormalConnection(u, "GET", Config.pc_ua)
|
val connection = getNormalConnection(u, "GET", Config.pc_ua)
|
||||||
val ci = connection.inputStream
|
val ci = connection.inputStream
|
||||||
|
val sz = connection.getHeaderFieldInt("Content-Length", 0)
|
||||||
if(readSize > 0) {
|
if(readSize > 0) {
|
||||||
ret = ByteArray(readSize)
|
ret = ByteArray(readSize)
|
||||||
ci?.read(ret, 0, readSize)
|
ci?.read(ret, 0, readSize)
|
||||||
} else ret = ci?.readBytes()
|
} else ret = if (sz > 0 && p != null) {
|
||||||
|
ci.readBytesWithProgress(sz, p)
|
||||||
|
} else {
|
||||||
|
ci.readBytes()
|
||||||
|
}
|
||||||
ci?.close()
|
ci?.close()
|
||||||
connection.disconnect()
|
connection.disconnect()
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
@@ -169,12 +211,12 @@ object DownloadTools {
|
|||||||
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? {
|
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.instance.enabled) Callable{
|
||||||
try {
|
try {
|
||||||
val capsule = getComandyApiConnection(url, method, refer, ua)
|
val capsule = getComandyApiConnection(url, method, refer, ua)
|
||||||
contentType?.let { capsule.headers["content-type"] = it }
|
contentType?.let { capsule.headers["content-type"] = it }
|
||||||
capsule.data = body.decodeToString()
|
capsule.data = body.decodeToString()
|
||||||
Comandy.instance?.request(Gson().toJson(capsule))?.let { result ->
|
runBlocking { Comandy.instance.getInstance() }?.request(Gson().toJson(capsule))?.let { result ->
|
||||||
Gson().fromJson(result, ComandyCapsule::class.java)?.let {
|
Gson().fromJson(result, ComandyCapsule::class.java)?.let {
|
||||||
it.data?.let { d -> Base64.decode(d, Base64.DEFAULT) }?:"empty comandy data".encodeToByteArray()
|
it.data?.let { d -> Base64.decode(d, Base64.DEFAULT) }?:"empty comandy data".encodeToByteArray()
|
||||||
}
|
}
|
||||||
53
app/src/main/java/top/fumiama/copymanga/net/Proxy.kt
Normal file
53
app/src/main/java/top/fumiama/copymanga/net/Proxy.kt
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package top.fumiama.copymanga.net
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import top.fumiama.copymanga.MainActivity
|
||||||
|
import top.fumiama.copymanga.api.Config.proxy_key
|
||||||
|
import top.fumiama.copymanga.lib.Comancry
|
||||||
|
import java.net.URLEncoder
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
|
class Proxy(id: Int, private val apiRegex: Regex) {
|
||||||
|
private val code get() = proxy_key.value
|
||||||
|
private val proxyApiUrl = MainActivity.mainWeakReference?.get()?.getString(id)
|
||||||
|
private val sourceDir = MainActivity.mainWeakReference?.get()?.applicationInfo?.sourceDir?.substringBeforeLast("/")?:""
|
||||||
|
private val enabled: Boolean get() = code.isNotEmpty() and sourceDir.isNotEmpty() and !proxyApiUrl.isNullOrEmpty()
|
||||||
|
|
||||||
|
fun wrap(u: String): String {
|
||||||
|
if(!apiRegex.containsMatchIn(u)) {
|
||||||
|
Log.d("MyP", "[N] wrap: $u")
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
if(enabled) {
|
||||||
|
val wu = proxyApiUrl?.format(code, URLEncoder.encode(u, Charset.defaultCharset().name()))
|
||||||
|
?:u
|
||||||
|
Log.d("MyP", "[M] wrap: $wu")
|
||||||
|
return wu
|
||||||
|
}
|
||||||
|
Log.d("MyP", "[C] wrap: $u")
|
||||||
|
//return proxyApiUrl?.format(URLEncoder.encode(u, Charset.defaultCharset().name()))?:u
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun comancry(u: String, use: suspend (String) -> ByteArray?): ByteArray? {
|
||||||
|
if(!apiRegex.containsMatchIn(u)) {
|
||||||
|
Log.d("MyP", "[N] comancry: $u")
|
||||||
|
return use(u)
|
||||||
|
}
|
||||||
|
if(enabled) {
|
||||||
|
val wu = proxyApiUrl?.format(code,
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
URLEncoder.encode(u, Charset.defaultCharset().name())
|
||||||
|
})
|
||||||
|
?:u
|
||||||
|
Log.d("MyP", "[M] comancry: $wu, sd: $sourceDir")
|
||||||
|
return use(wu)?.let { data ->
|
||||||
|
Comancry.instance.decrypt(sourceDir, data)?.encodeToByteArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d("MyP", "[C] comancry: $u")
|
||||||
|
return use(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
11
app/src/main/java/top/fumiama/copymanga/net/Resolution.kt
Normal file
11
app/src/main/java/top/fumiama/copymanga/net/Resolution.kt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package top.fumiama.copymanga.net
|
||||||
|
|
||||||
|
import top.fumiama.copymanga.api.Config
|
||||||
|
|
||||||
|
class Resolution(private val original: Regex) {
|
||||||
|
private val imageResolution: Int
|
||||||
|
get() = Config.net_img_resolution.value.let {
|
||||||
|
if (it.isNotEmpty()) it.toInt() else 1500
|
||||||
|
}
|
||||||
|
fun wrap(u: String) : String = u.replace(original, "c${imageResolution}x.")
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.template.http
|
package top.fumiama.copymanga.net.template
|
||||||
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
@@ -14,7 +14,7 @@ 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.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
import top.fumiama.copymanga.net.DownloadTools
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
|
||||||
@@ -77,7 +77,13 @@ open class AutoDownloadHandler(
|
|||||||
var cnt = 0
|
var cnt = 0
|
||||||
while (cnt++ <= 3) {
|
while (cnt++ <= 3) {
|
||||||
try {
|
try {
|
||||||
val data = DownloadTools.getHttpContent(Config.apiProxy?.wrap(url)?:url)
|
val data = Config.apiProxy?.comancry(url) {
|
||||||
|
DownloadTools.getHttpContent(it)
|
||||||
|
}
|
||||||
|
if (data == null) {
|
||||||
|
delay(2000)
|
||||||
|
continue
|
||||||
|
}
|
||||||
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))
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package top.fumiama.copymanga.template.http
|
package top.fumiama.copymanga.net.template
|
||||||
|
|
||||||
import android.util.Log
|
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.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
import top.fumiama.copymanga.net.DownloadTools
|
||||||
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) {
|
||||||
@@ -14,10 +14,13 @@ class PausableDownloader(private val url: String, private val waitMilliseconds:
|
|||||||
var c = 0
|
var c = 0
|
||||||
while (!exit && c++ < 3) {
|
while (!exit && c++ < 3) {
|
||||||
try {
|
try {
|
||||||
val data = (DownloadTools.getHttpContent(
|
val data = if (isApi) Config.apiProxy?.comancry(url) {
|
||||||
(if(isApi) Config.apiProxy?.wrap(url) else null)?:url,
|
DownloadTools.getHttpContent(it, Config.referer)
|
||||||
Config.referer
|
} else DownloadTools.getHttpContent(url, Config.referer)
|
||||||
))
|
if (data == null) {
|
||||||
|
delay(3000)
|
||||||
|
continue
|
||||||
|
}
|
||||||
whenFinish?.let { it(data) }
|
whenFinish?.let { it(data) }
|
||||||
return@withContext true
|
return@withContext true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
package top.fumiama.copymanga.tools.http
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import android.util.Log
|
|
||||||
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
|
|
||||||
import java.io.File
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
|
||||||
import java.util.zip.GZIPInputStream
|
|
||||||
|
|
||||||
interface Comandy : Library {
|
|
||||||
// fun add_dns(para: String?, is_ipv6: Int): String?
|
|
||||||
|
|
||||||
fun request(para: String): String?
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private var isInInit = AtomicBoolean(false)
|
|
||||||
var instance: Comandy? = null
|
|
||||||
get() {
|
|
||||||
//Log.d("MyComandy", "get instance @$field")
|
|
||||||
if (field != null) return field
|
|
||||||
field = libraryFile?.absolutePath?.let { Native.load(it, Comandy::class.java) }?:return null
|
|
||||||
//Log.d("MyComandy", "init instance @$field")
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
private var mUseComandy: Boolean? = null
|
|
||||||
val useComandy: Boolean
|
|
||||||
get() {
|
|
||||||
if (isInInit.get()) {
|
|
||||||
Log.d("MyComandy", "block useComandy for isInInit")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (mUseComandy != true && DownloadTools.failTimes.get() >= 2) {
|
|
||||||
mUseComandy = true
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (mUseComandy != null) return mUseComandy!!
|
|
||||||
val v = Config.net_use_comandy.value
|
|
||||||
mUseComandy = v
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
private val libraryFile: File?
|
|
||||||
get() {
|
|
||||||
if (isInInit.get()) return null
|
|
||||||
isInInit.set(true)
|
|
||||||
Log.d("MyComandy", "start to download/check lib")
|
|
||||||
val prefix = when (Build.SUPPORTED_ABIS[0]) {
|
|
||||||
"arm64-v8a" -> "aarch64"
|
|
||||||
"armeabi-v7a" -> "armv7a"
|
|
||||||
"x86_64" -> "x86_64"
|
|
||||||
"x86" -> "i686"
|
|
||||||
else -> null
|
|
||||||
}?:return null
|
|
||||||
Log.d("MyComandy", "arch: $prefix")
|
|
||||||
return MainActivity.mainWeakReference?.get()?.let { ma ->
|
|
||||||
var f = File(ma.filesDir, "libs")
|
|
||||||
if (!f.exists()) f.mkdirs()
|
|
||||||
f = File(f, "libcomandy.so")
|
|
||||||
var remoteVersion = 0
|
|
||||||
if (f.exists()) {
|
|
||||||
DownloadTools.getHttpContent(ma.getString(R.string.comandy_version_url), -1)?.let dataLet@{
|
|
||||||
try {
|
|
||||||
val body = Gson().fromJson(it.decodeToString(), ComandyVersion::class.java)?.body
|
|
||||||
if (body?.startsWith("Version: ") == true) {
|
|
||||||
remoteVersion = body.substring(9).toInt()
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
val myVersion = Config.comandy_version.value?:0
|
|
||||||
if (myVersion >= remoteVersion) {
|
|
||||||
Log.d("MyComandy", "lib version $myVersion is latest")
|
|
||||||
isInInit.set(false)
|
|
||||||
return@let f
|
|
||||||
}
|
|
||||||
Log.d("MyComandy", "lib version $myVersion <= latest $remoteVersion, update...")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DownloadTools.getHttpContent(ma.getString(R.string.comandy_download_url).format(prefix), -1)?.let {
|
|
||||||
if(f.exists()) f.delete()
|
|
||||||
try {
|
|
||||||
GZIPInputStream(ByteArrayInputStream(it)).use { dataIn ->
|
|
||||||
f.outputStream().use { dataOut ->
|
|
||||||
dataIn.copyTo(dataOut)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (remoteVersion > 0) Config.comandy_version.value = remoteVersion
|
|
||||||
Log.d("MyComandy", "update success")
|
|
||||||
isInInit.set(false)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
if(f.exists()) f.delete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return@let if(f.exists()) f else null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package top.fumiama.copymanga.tools.http
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
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) {
|
|
||||||
private val code get() = proxy_key.value
|
|
||||||
private val proxyApiUrl = MainActivity.mainWeakReference?.get()?.getString(id)
|
|
||||||
|
|
||||||
fun wrap(u: String): String {
|
|
||||||
if(!apiRegex.containsMatchIn(u)) {
|
|
||||||
Log.d("MyP", "[N] wrap: $u")
|
|
||||||
return 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
|
|
||||||
}
|
|
||||||
Log.d("MyP", "[C] wrap: $u")
|
|
||||||
//return proxyApiUrl?.format(URLEncoder.encode(u, Charset.defaultCharset().name()))?:u
|
|
||||||
return u
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package top.fumiama.copymanga.tools.http
|
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager
|
|
||||||
import top.fumiama.copymanga.MainActivity
|
|
||||||
import top.fumiama.dmzj.copymanga.R
|
|
||||||
|
|
||||||
class Resolution(private val original: Regex) {
|
|
||||||
private val imageResolution: Int
|
|
||||||
get() {
|
|
||||||
MainActivity.mainWeakReference?.get()?.apply {
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(this).apply {
|
|
||||||
val b = getString(getString(R.string.imgResolutionKeyID), null)
|
|
||||||
//Log.d("MyResolution", "use image resolution: $b")
|
|
||||||
return b?.toInt()?:1500
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1500
|
|
||||||
}
|
|
||||||
fun wrap(u: String) : String = u.replace(original, "c${imageResolution}x.")
|
|
||||||
}
|
|
||||||
@@ -17,10 +17,10 @@ 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.Book
|
import top.fumiama.copymanga.api.manga.Book
|
||||||
import top.fumiama.copymanga.manga.Reader
|
import top.fumiama.copymanga.api.manga.Reader
|
||||||
import top.fumiama.copymanga.template.general.NoBackRefreshFragment
|
import top.fumiama.copymanga.view.template.NoBackRefreshFragment
|
||||||
import top.fumiama.copymanga.tools.ui.Navigate
|
import top.fumiama.copymanga.view.interaction.Navigate
|
||||||
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment
|
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.launch
|
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.api.manga.Reader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.ui.GlideBlurTransformation
|
import top.fumiama.copymanga.view.operation.GlideBlurTransformation
|
||||||
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
import top.fumiama.copymanga.view.operation.GlideHideLottieViewListener
|
||||||
import top.fumiama.copymanga.tools.ui.Navigate
|
import top.fumiama.copymanga.view.interaction.Navigate
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package top.fumiama.copymanga.ui.cardflow.author
|
package top.fumiama.copymanga.ui.cardflow.author
|
||||||
|
|
||||||
import top.fumiama.copymanga.template.ui.ThemeCardFlow
|
import top.fumiama.copymanga.view.template.ThemeCardFlow
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package top.fumiama.copymanga.ui.cardflow.caption
|
package top.fumiama.copymanga.ui.cardflow.caption
|
||||||
|
|
||||||
import top.fumiama.copymanga.template.ui.ThemeCardFlow
|
import top.fumiama.copymanga.view.template.ThemeCardFlow
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package top.fumiama.copymanga.ui.cardflow.finish
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import top.fumiama.copymanga.template.ui.StatusCardFlow
|
import top.fumiama.copymanga.view.template.StatusCardFlow
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import kotlinx.android.synthetic.main.line_finish.*
|
import kotlinx.android.synthetic.main.line_finish.*
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import android.os.Bundle
|
|||||||
import android.widget.Toast
|
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.view.template.InfoCardLoader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
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.view.template.InfoCardLoader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import android.os.Bundle
|
|||||||
import com.google.android.material.tabs.TabLayout
|
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.view.template.InfoCardLoader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.ui.UITools
|
import top.fumiama.copymanga.view.interaction.UITools
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
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.view.template.InfoCardLoader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,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.view.template.InfoCardLoader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import androidx.navigation.fragment.findNavController
|
|||||||
import kotlinx.android.synthetic.main.anchor_popular.view.*
|
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.view.template.InfoCardLoader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import top.fumiama.copymanga.json.FilterStructure
|
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.net.template.PausableDownloader
|
||||||
import top.fumiama.copymanga.template.ui.StatusCardFlow
|
import top.fumiama.copymanga.view.template.StatusCardFlow
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
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.net.template.PausableDownloader
|
||||||
import top.fumiama.copymanga.template.ui.InfoCardLoader
|
import top.fumiama.copymanga.view.template.InfoCardLoader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import top.fumiama.copymanga.json.VolumeStructure
|
import top.fumiama.copymanga.json.VolumeStructure
|
||||||
import top.fumiama.copymanga.template.general.NoBackRefreshFragment
|
import top.fumiama.copymanga.view.template.NoBackRefreshFragment
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|||||||
@@ -28,14 +28,14 @@ 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.Downloader
|
import top.fumiama.copymanga.api.manga.Downloader
|
||||||
import top.fumiama.copymanga.manga.Reader
|
import top.fumiama.copymanga.api.manga.Reader
|
||||||
import top.fumiama.copymanga.tools.ui.UITools
|
import top.fumiama.copymanga.view.interaction.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
|
||||||
import top.fumiama.copymanga.ui.vm.ViewMangaActivity
|
import top.fumiama.copymanga.ui.vm.ViewMangaActivity
|
||||||
import top.fumiama.copymanga.views.ChapterToggleButton
|
import top.fumiama.copymanga.view.ChapterToggleButton
|
||||||
import top.fumiama.copymanga.views.LazyScrollView
|
import top.fumiama.copymanga.view.LazyScrollView
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ 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.Downloader
|
import top.fumiama.copymanga.api.manga.Downloader
|
||||||
import top.fumiama.copymanga.manga.Reader
|
import top.fumiama.copymanga.api.manga.Reader
|
||||||
import top.fumiama.copymanga.template.general.NoBackRefreshFragment
|
import top.fumiama.copymanga.view.template.NoBackRefreshFragment
|
||||||
import top.fumiama.copymanga.tools.file.FileUtils
|
import top.fumiama.copymanga.tools.file.FileUtils
|
||||||
import top.fumiama.copymanga.tools.ui.Navigate
|
import top.fumiama.copymanga.view.interaction.Navigate
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ 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.api.Config.manga_dl_show_0m_manga
|
import top.fumiama.copymanga.api.Config.manga_dl_show_0m_manga
|
||||||
import top.fumiama.copymanga.manga.Downloader
|
import top.fumiama.copymanga.api.manga.Downloader
|
||||||
import top.fumiama.copymanga.manga.Reader
|
import top.fumiama.copymanga.api.manga.Reader
|
||||||
import top.fumiama.copymanga.template.general.MangaPagesFragmentTemplate
|
import top.fumiama.copymanga.view.template.MangaPagesFragmentTemplate
|
||||||
import top.fumiama.copymanga.template.ui.CardList
|
import top.fumiama.copymanga.view.template.CardList
|
||||||
import top.fumiama.copymanga.tools.file.FileUtils
|
import top.fumiama.copymanga.tools.file.FileUtils
|
||||||
import top.fumiama.copymanga.tools.ui.Navigate
|
import top.fumiama.copymanga.view.interaction.Navigate
|
||||||
import top.fumiama.copymanga.tools.ui.UITools
|
import top.fumiama.copymanga.view.interaction.UITools
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ import kotlinx.coroutines.withContext
|
|||||||
import top.fumiama.copymanga.MainActivity
|
import top.fumiama.copymanga.MainActivity
|
||||||
import top.fumiama.copymanga.MainActivity.Companion.ime
|
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.view.template.NoBackRefreshFragment
|
||||||
import top.fumiama.copymanga.template.http.PausableDownloader
|
import top.fumiama.copymanga.net.template.PausableDownloader
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
import top.fumiama.copymanga.view.operation.GlideHideLottieViewListener
|
||||||
import top.fumiama.copymanga.tools.ui.Navigate
|
import top.fumiama.copymanga.view.interaction.Navigate
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
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.net.template.AutoDownloadHandler
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
import top.fumiama.copymanga.view.operation.GlideHideLottieViewListener
|
||||||
import top.fumiama.copymanga.tools.ui.Navigate
|
import top.fumiama.copymanga.view.interaction.Navigate
|
||||||
import top.fumiama.copymanga.tools.ui.UITools
|
import top.fumiama.copymanga.view.interaction.UITools
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ 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.tools.ui.UITools
|
import top.fumiama.copymanga.view.interaction.UITools
|
||||||
import top.fumiama.copymanga.views.AutoHideEditTextPreferenceDialogFragmentCompat
|
import top.fumiama.copymanga.view.AutoHideEditTextPreferenceDialogFragmentCompat
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
|
|
||||||
class SettingsFragment: PreferenceFragmentCompat() {
|
class SettingsFragment: PreferenceFragmentCompat() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package top.fumiama.copymanga.ui.vm
|
package top.fumiama.copymanga.ui.vm
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import top.fumiama.copymanga.manga.Reader
|
import top.fumiama.copymanga.api.manga.Reader
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import top.fumiama.copymanga.MainActivity
|
|||||||
import top.fumiama.copymanga.json.Chapter2Return
|
import top.fumiama.copymanga.json.Chapter2Return
|
||||||
import top.fumiama.copymanga.json.ChapterWithContent
|
import top.fumiama.copymanga.json.ChapterWithContent
|
||||||
import top.fumiama.copymanga.json.ComicStructure
|
import top.fumiama.copymanga.json.ComicStructure
|
||||||
import top.fumiama.copymanga.template.http.AutoDownloadHandler
|
import top.fumiama.copymanga.net.template.AutoDownloadHandler
|
||||||
import top.fumiama.copymanga.template.http.PausableDownloader
|
import top.fumiama.copymanga.net.template.PausableDownloader
|
||||||
import top.fumiama.copymanga.views.ScaleImageView
|
import top.fumiama.copymanga.view.ScaleImageView
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|||||||
@@ -54,12 +54,12 @@ 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.api.Config
|
||||||
import top.fumiama.copymanga.template.general.TitleActivityTemplate
|
import top.fumiama.copymanga.view.template.TitleActivityTemplate
|
||||||
import top.fumiama.copymanga.template.http.PausableDownloader
|
import top.fumiama.copymanga.net.template.PausableDownloader
|
||||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
import top.fumiama.copymanga.net.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.view.Font
|
||||||
import top.fumiama.copymanga.views.ScaleImageView
|
import top.fumiama.copymanga.view.ScaleImageView
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|||||||
@@ -1,154 +0,0 @@
|
|||||||
package top.fumiama.copymanga.user
|
|
||||||
|
|
||||||
import android.util.Base64
|
|
||||||
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.http.Comandy
|
|
||||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
|
||||||
import top.fumiama.dmzj.copymanga.R
|
|
||||||
import java.net.URLEncoder
|
|
||||||
import java.nio.charset.Charset
|
|
||||||
|
|
||||||
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 (!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 ->
|
|
||||||
Gson().fromJson(result, ComandyCapsule::class.java)!!.let {
|
|
||||||
if (it.code != 200) {
|
|
||||||
val l = LoginInfoStructure()
|
|
||||||
l.code = it.code
|
|
||||||
l.message = it.data?.let { d -> Base64.decode(d, Base64.DEFAULT).decodeToString() }?:"HTTP ${it.code}"
|
|
||||||
return@withContext l
|
|
||||||
}
|
|
||||||
Base64.decode(it.data, Base64.DEFAULT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
err = e.message.toString()
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}?.let {
|
|
||||||
try {
|
|
||||||
return@withContext saveInfo(it)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
err = e.message.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else getLoginConnection(username, pwd, salt).apply {
|
|
||||||
inputStream.use {
|
|
||||||
it?.readBytes()?.let { data ->
|
|
||||||
try {
|
|
||||||
return@withContext saveInfo(data)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
err = e.message.toString()
|
|
||||||
}
|
|
||||||
}?: run { err = getString(R.string.login_get_conn_failed) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val l = LoginInfoStructure()
|
|
||||||
l.code = 400
|
|
||||||
l.message = err
|
|
||||||
return@withContext l
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得登录信息并更新头像
|
|
||||||
* @return 登录态
|
|
||||||
* - **code**: 449: 未登录, 450: 有 Exception
|
|
||||||
* - **message**: 可以 toast 的信息
|
|
||||||
*/
|
|
||||||
suspend fun info() : LoginInfoStructure = withContext(Dispatchers.IO) {
|
|
||||||
if (!hasLogin) {
|
|
||||||
val l = LoginInfoStructure()
|
|
||||||
l.code = 449
|
|
||||||
l.message = getString(R.string.noLogin)
|
|
||||||
return@withContext l
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
val data = DownloadTools.getHttpContent(
|
|
||||||
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) Config.avatar.value = l.results.avatar
|
|
||||||
l
|
|
||||||
} catch (e : Exception) {
|
|
||||||
val l = LoginInfoStructure()
|
|
||||||
l.code = 450
|
|
||||||
l.message = "${getString(R.string.login_get_avatar_failed)}: $data"
|
|
||||||
l
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
val l = LoginInfoStructure()
|
|
||||||
l.code = 450
|
|
||||||
l.message = "${getString(R.string.login_get_avatar_failed)}: $e"
|
|
||||||
l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun logout() = withContext(Dispatchers.IO) {
|
|
||||||
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) {
|
|
||||||
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))
|
|
||||||
} catch (e: Exception) {
|
|
||||||
throw Exception(data.decodeToString(), e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getLoginConnection(username: String, pwd: String, salt: Int) =
|
|
||||||
getString(R.string.loginApiUrl).format(Config.myHostApiUrl.value).let {
|
|
||||||
Config.apiProxy?.wrap(it)?:it
|
|
||||||
}.let {
|
|
||||||
DownloadTools.getApiConnection(it, "POST").apply {
|
|
||||||
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®ion=$r&webp=1".toByteArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getComandyLoginConnection(username: String, pwd: String, salt: Int) =
|
|
||||||
getString(R.string.loginApiUrl).format(Config.myHostApiUrl.value).let {
|
|
||||||
Config.apiProxy?.wrap(it)?:it
|
|
||||||
}.let {
|
|
||||||
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®ion=$r&webp=1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.views
|
package top.fumiama.copymanga.view
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.views
|
package top.fumiama.copymanga.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.tools.ui
|
package top.fumiama.copymanga.view
|
||||||
|
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.views
|
package top.fumiama.copymanga.view
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package top.fumiama.copymanga.views
|
package top.fumiama.copymanga.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import androidx.cardview.widget.CardView
|
import androidx.cardview.widget.CardView
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class MangaCardView :CardView {
|
class MangaCardView :CardView {
|
||||||
constructor(context: Context): super(context)
|
constructor(context: Context): super(context)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.views
|
package top.fumiama.copymanga.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.views
|
package top.fumiama.copymanga.view
|
||||||
|
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.animation.ValueAnimator.AnimatorUpdateListener
|
import android.animation.ValueAnimator.AnimatorUpdateListener
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.views
|
package top.fumiama.copymanga.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.tools.ui
|
package top.fumiama.copymanga.view.interaction
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.tools.ui
|
package top.fumiama.copymanga.view.interaction
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.tools.ui
|
package top.fumiama.copymanga.view.operation
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.tools.ui
|
package top.fumiama.copymanga.view.operation
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
package top.fumiama.copymanga.template.general
|
package top.fumiama.copymanga.view.template
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import top.fumiama.copymanga.tools.ui.UITools
|
import top.fumiama.copymanga.view.interaction.UITools
|
||||||
|
|
||||||
open class ActivityTemplate: AppCompatActivity() {
|
open class ActivityTemplate: AppCompatActivity() {
|
||||||
lateinit var toolsBox: UITools
|
lateinit var toolsBox: UITools
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.template.ui
|
package top.fumiama.copymanga.view.template
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@@ -14,7 +14,7 @@ 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.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.ui.GlideHideLottieViewListener
|
import top.fumiama.copymanga.view.operation.GlideHideLottieViewListener
|
||||||
import top.fumiama.dmzj.copymanga.R
|
import top.fumiama.dmzj.copymanga.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.template.ui
|
package top.fumiama.copymanga.view.template
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -15,9 +15,8 @@ import top.fumiama.copymanga.json.BookListStructure
|
|||||||
import top.fumiama.copymanga.json.HistoryBookListStructure
|
import top.fumiama.copymanga.json.HistoryBookListStructure
|
||||||
import top.fumiama.copymanga.json.ShelfStructure
|
import top.fumiama.copymanga.json.ShelfStructure
|
||||||
import top.fumiama.copymanga.json.TypeBookListStructure
|
import top.fumiama.copymanga.json.TypeBookListStructure
|
||||||
import top.fumiama.copymanga.template.general.MangaPagesFragmentTemplate
|
import top.fumiama.copymanga.net.template.PausableDownloader
|
||||||
import top.fumiama.copymanga.template.http.PausableDownloader
|
import top.fumiama.copymanga.view.interaction.Navigate
|
||||||
import top.fumiama.copymanga.tools.ui.Navigate
|
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.template.general
|
package top.fumiama.copymanga.view.template
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
@@ -19,8 +19,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.template.ui.CardList
|
import top.fumiama.copymanga.view.interaction.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
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.template.general
|
package top.fumiama.copymanga.view.template
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -11,7 +11,7 @@ import androidx.fragment.app.Fragment
|
|||||||
import kotlinx.android.synthetic.main.content_main.*
|
import kotlinx.android.synthetic.main.content_main.*
|
||||||
import top.fumiama.copymanga.MainActivity
|
import top.fumiama.copymanga.MainActivity
|
||||||
import top.fumiama.copymanga.api.Config
|
import top.fumiama.copymanga.api.Config
|
||||||
import top.fumiama.copymanga.tools.ui.UITools
|
import top.fumiama.copymanga.view.interaction.UITools
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
open class NoBackRefreshFragment(private val layoutToLoad: Int): Fragment() {
|
open class NoBackRefreshFragment(private val layoutToLoad: Int): Fragment() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.template.ui
|
package top.fumiama.copymanga.view.template
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.template.ui
|
package top.fumiama.copymanga.view.template
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fumiama.copymanga.template.general
|
package top.fumiama.copymanga.view.template
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import kotlinx.android.synthetic.main.widget_titlebar.*
|
import kotlinx.android.synthetic.main.widget_titlebar.*
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<top.fumiama.copymanga.views.ChapterToggleButton xmlns:android="http://schemas.android.com/apk/res/android"
|
<top.fumiama.copymanga.view.ChapterToggleButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/tbtn"
|
android:id="@+id/tbtn"
|
||||||
android:layout_width="64dp"
|
android:layout_width="64dp"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<top.fumiama.copymanga.views.MangaCardView
|
<top.fumiama.copymanga.view.MangaCardView
|
||||||
android:id="@+id/cic"
|
android:id="@+id/cic"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
@@ -116,5 +116,5 @@
|
|||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</top.fumiama.copymanga.views.MangaCardView>
|
</top.fumiama.copymanga.view.MangaCardView>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<top.fumiama.copymanga.views.MangaCardView
|
<top.fumiama.copymanga.view.MangaCardView
|
||||||
android:id="@+id/cic"
|
android:id="@+id/cic"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
@@ -62,5 +62,5 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</top.fumiama.copymanga.views.MangaCardView>
|
</top.fumiama.copymanga.view.MangaCardView>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?attr/colorSurface">
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
<top.fumiama.copymanga.views.LazyScrollView
|
<top.fumiama.copymanga.view.LazyScrollView
|
||||||
android:id="@+id/dllazys"
|
android:id="@+id/dllazys"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"/>
|
android:orientation="vertical"/>
|
||||||
</top.fumiama.copymanga.views.LazyScrollView>
|
</top.fumiama.copymanga.view.LazyScrollView>
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/dlsdwn"
|
android:id="@+id/dlsdwn"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
android:layout_marginTop="@dimen/search_layout_padding"
|
android:layout_marginTop="@dimen/search_layout_padding"
|
||||||
android:isScrollContainer="true">
|
android:isScrollContainer="true">
|
||||||
|
|
||||||
<top.fumiama.copymanga.views.ScrollRefreshView
|
<top.fumiama.copymanga.view.ScrollRefreshView
|
||||||
android:id="@+id/fhov"
|
android:id="@+id/fhov"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</top.fumiama.copymanga.views.ScrollRefreshView>
|
</top.fumiama.copymanga.view.ScrollRefreshView>
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
<com.lapism.search.widget.MaterialSearchView
|
<com.lapism.search.widget.MaterialSearchView
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<top.fumiama.copymanga.views.ScaleImageView
|
<top.fumiama.copymanga.view.ScaleImageView
|
||||||
android:id="@+id/onei"
|
android:id="@+id/onei"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -92,8 +92,8 @@
|
|||||||
<string name="apiProxyApiUrl">https://copymanga.azurewebsites.net/api/api?code=%1$s&url=%2$s</string>
|
<string name="apiProxyApiUrl">https://copymanga.azurewebsites.net/api/api?code=%1$s&url=%2$s</string>
|
||||||
<string name="imgResolutionKeyID">settings_cat_net_sb_image_resolution</string>
|
<string name="imgResolutionKeyID">settings_cat_net_sb_image_resolution</string>
|
||||||
|
|
||||||
<string name="comandy_version_url">https://gitea.seku.su/api/v1/repos/fumiama/comandy/releases/tags/default</string>
|
<string name="comandy_version_url">https://gitea.seku.su/api/v1/repos/fumiama/%1$s/releases/tags/default</string>
|
||||||
<string name="comandy_download_url">"https://gitea.seku.su/fumiama/comandy/releases/download/default/%1$s_libcomandy.so.gz"</string>
|
<string name="comandy_download_url">"https://gitea.seku.su/fumiama/%1$s/releases/download/default/%2$s_%3$s.gz"</string>
|
||||||
|
|
||||||
<string name="complete">已完结</string>
|
<string name="complete">已完结</string>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user