mirror of
https://github.com/fumiama/copymanga.git
synced 2026-06-04 23:10:23 +08:00
v2.1.3
新增 1. 详情页标记已下载章节 2. 详情页以tab区分卷标 3. 以深浅标示当前选择的tab 修复 1. 详情页加载结束时卡顿 2. 某些漫画无法变更清晰度 3. 全新上架显示错误 4. 专题系列有时简介不显示 优化 1. 替换弃用API 2. 携程化: 检查更新, 菜单切换, 详情页 3. StatusCardFlow标签排序 4. CardList加载速度 升级 1. 支持库版本
This commit is contained in:
23
.idea/deploymentTargetDropDown.xml
generated
Normal file
23
.idea/deploymentTargetDropDown.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<value>
|
||||
<entry key="app">
|
||||
<State>
|
||||
<targetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="QUICK_BOOT_TARGET" />
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="$USER_HOME$/.android/avd/Pixel_3a_API_33_arm64-v8a.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2024-03-08T06:58:21.703472Z" />
|
||||
</State>
|
||||
</entry>
|
||||
</value>
|
||||
</component>
|
||||
</project>
|
||||
1
.idea/dictionaries/fumiama.xml
generated
1
.idea/dictionaries/fumiama.xml
generated
@@ -4,6 +4,7 @@
|
||||
<w>imgs</w>
|
||||
<w>lowpan</w>
|
||||
<w>nisi</w>
|
||||
<w>reilia</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
4
.idea/gradle.xml
generated
4
.idea/gradle.xml
generated
@@ -4,10 +4,8 @@
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="jbr-17" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
||||
10
.idea/migrations.xml
generated
Normal file
10
.idea/migrations.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
2454
.idea/shelf/Uncommitted_changes_before_Update_at_2024_3_9,_12_23_AM_[Changes]/shelved.patch
generated
Normal file
2454
.idea/shelf/Uncommitted_changes_before_Update_at_2024_3_9,_12_23_AM_[Changes]/shelved.patch
generated
Normal file
File diff suppressed because one or more lines are too long
4
.idea/shelf/Uncommitted_changes_before_Update_at_2024_3_9__12_23_AM__Changes_.xml
generated
Normal file
4
.idea/shelf/Uncommitted_changes_before_Update_at_2024_3_9__12_23_AM__Changes_.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
<changelist name="Uncommitted_changes_before_Update_at_2024_3_9,_12_23_AM_[Changes]" date="1709911381682" recycled="true" deleted="true">
|
||||
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Update_at_2024_3_9,_12_23_AM_[Changes]/shelved.patch" />
|
||||
<option name="DESCRIPTION" value="Uncommitted changes before Update at 2024/3/9, 12:23 AM [Changes]" />
|
||||
</changelist>
|
||||
@@ -8,16 +8,13 @@ android {
|
||||
applicationId 'top.fumiama.copymanga'
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 34
|
||||
versionCode 45
|
||||
versionName '2.1.2'
|
||||
resConfigs 'zh', 'zh-rCN'
|
||||
versionCode 46
|
||||
versionName '2.1.3'
|
||||
resourceConfigurations += ['zh', 'zh-rCN']
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
aaptOptions {
|
||||
cruncherEnabled = false
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -60,20 +57,20 @@ dependencies {
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.6'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.7.6'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.7.7'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
implementation "androidx.preference:preference-ktx:1.2.1"
|
||||
implementation 'com.afollestad.material-dialogs:input:3.3.0'
|
||||
implementation 'com.github.yalantis:ucrop:2.2.6'
|
||||
implementation 'com.to.aboomy:pager2banner:1.0.1'
|
||||
implementation 'com.github.bumptech.glide:glide:4.14.2'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2'
|
||||
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
implementation 'com.github.vovaksenov99:OverscrollableScrollView:1.0'
|
||||
implementation 'com.liaoinstan.springview:library:1.7.0'
|
||||
implementation 'com.github.zawadz88.materialpopupmenu:material-popup-menu:4.0.1'
|
||||
implementation 'com.lapism:search:2.4.1@aar'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
|
||||
implementation 'com.airbnb.android:lottie:6.3.0'
|
||||
implementation 'com.airbnb.android:lottie:6.4.0'
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ class LoginActivity : AppCompatActivity() {
|
||||
val isLogout = pref.getString("token", null) != null
|
||||
if (isLogout) {
|
||||
alblogin.setText(R.string.logout)
|
||||
altusrnm.setText(pref.getString("username", "N/A"))
|
||||
}
|
||||
alblogin.setOnClickListener {
|
||||
lifecycleScope.launch {
|
||||
|
||||
@@ -2,6 +2,7 @@ package top.fumiama.copymanga
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
@@ -18,6 +19,7 @@ import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
@@ -25,6 +27,7 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.net.toUri
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
@@ -40,6 +43,9 @@ import com.yalantis.ucrop.UCrop
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.android.synthetic.main.app_bar_main.*
|
||||
import kotlinx.android.synthetic.main.nav_header_main.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.manga.Shelf
|
||||
import top.fumiama.copymanga.tools.ui.UITools
|
||||
import top.fumiama.copymanga.ui.book.BookFragment.Companion.bookHandler
|
||||
@@ -64,7 +70,6 @@ class MainActivity : AppCompatActivity() {
|
||||
private lateinit var headPic: File
|
||||
lateinit var toolsBox: UITools
|
||||
|
||||
private var latestDestination = 0
|
||||
private var isMenuWaiting = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -114,6 +119,7 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
ime = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
|
||||
var latestDestination: Int
|
||||
navController!!.addOnDestinationChangedListener { _, destination, _ ->
|
||||
latestDestination = destination.id
|
||||
Log.d("MyMA", "latestDestination: $latestDestination")
|
||||
@@ -122,51 +128,16 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
isMenuWaiting = true
|
||||
Log.d("MyMA", "start menu waiting")
|
||||
Thread {
|
||||
sleep(1000)
|
||||
isMenuWaiting = false
|
||||
Log.d("MyMA", "finish menu waiting")
|
||||
runOnUiThread {
|
||||
when (latestDestination) {
|
||||
R.id.nav_home -> {
|
||||
Log.d("MyMA", "enter home")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = true
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = false
|
||||
}
|
||||
R.id.nav_book -> {
|
||||
Log.d("MyMA", "enter book")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = true
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = false
|
||||
}
|
||||
R.id.nav_group -> {
|
||||
Log.d("MyMA", "enter group")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = true
|
||||
}
|
||||
R.id.nav_new_download -> {
|
||||
Log.d("MyMA", "enter new_download")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = true
|
||||
}
|
||||
R.id.nav_rank -> {
|
||||
Log.d("MyMA", "enter rank")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = true
|
||||
}
|
||||
else -> {
|
||||
Log.d("MyMA", "enter others")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = false
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
sleep(1000)
|
||||
withContext(Dispatchers.Main) {
|
||||
isMenuWaiting = false
|
||||
Log.d("MyMA", "finish menu waiting")
|
||||
changeMenuList(latestDestination)
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,24 +189,6 @@ class MainActivity : AppCompatActivity() {
|
||||
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == RESULT_OK) when (requestCode) {
|
||||
UCrop.REQUEST_CROP -> {
|
||||
val fi = headPic.inputStream()
|
||||
navhbg.setImageBitmap(BitmapFactory.decodeStream(fi))
|
||||
fi.close()
|
||||
}
|
||||
MSG_CROP_IMAGE -> {
|
||||
data?.data?.let {
|
||||
saveFile(it)
|
||||
cropImageUri()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String?>,
|
||||
@@ -263,6 +216,47 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeMenuList(latestDestination: Int) {
|
||||
when (latestDestination) {
|
||||
R.id.nav_home -> {
|
||||
Log.d("MyMA", "enter home")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = true
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = false
|
||||
}
|
||||
R.id.nav_book -> {
|
||||
Log.d("MyMA", "enter book")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = true
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = false
|
||||
}
|
||||
R.id.nav_group -> {
|
||||
Log.d("MyMA", "enter group")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = true
|
||||
}
|
||||
R.id.nav_new_download -> {
|
||||
Log.d("MyMA", "enter new_download")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = true
|
||||
}
|
||||
R.id.nav_rank -> {
|
||||
Log.d("MyMA", "enter rank")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = true
|
||||
}
|
||||
else -> {
|
||||
Log.d("MyMA", "enter others")
|
||||
menuMain?.findItem(R.id.action_info)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_download)?.isVisible = false
|
||||
menuMain?.findItem(R.id.action_sort)?.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkReadPermission(): Boolean {
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
@@ -277,11 +271,18 @@ class MainActivity : AppCompatActivity() {
|
||||
} else true
|
||||
}
|
||||
|
||||
private var pickerLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) result.data?.data?.let {
|
||||
saveFile(it)
|
||||
cropImageUri()
|
||||
} else Toast.makeText(this, R.string.err_pick_img, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
@SuppressLint("IntentReset")
|
||||
private fun pickPicture() {
|
||||
val i = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
|
||||
i.type = "image/*"
|
||||
startActivityForResult(i, MSG_CROP_IMAGE)
|
||||
pickerLauncher.launch(i)
|
||||
}
|
||||
|
||||
private fun saveFile(uri: Uri) {
|
||||
@@ -302,11 +303,18 @@ class MainActivity : AppCompatActivity() {
|
||||
if (headPic.exists()) navhbg.setImageURI(headPic.toUri())
|
||||
}
|
||||
|
||||
private var cropLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
val fi = headPic.inputStream()
|
||||
navhbg.setImageBitmap(BitmapFactory.decodeStream(fi))
|
||||
fi.close()
|
||||
} else Toast.makeText(this, R.string.err_crop_img, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
private fun cropImageUri() {
|
||||
val op = UCrop.Options()
|
||||
val r = navhbg.width.toFloat() / navhbg.height.toFloat()
|
||||
Log.d("MyMain", "Img info: (${navhbg.width}, ${navhbg.height})")
|
||||
Log.d("MyMain", "Result code: ${UCrop.REQUEST_CROP}")
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
op.setCompressionFormat(Bitmap.CompressFormat.WEBP_LOSSY)
|
||||
} else {
|
||||
@@ -315,17 +323,17 @@ class MainActivity : AppCompatActivity() {
|
||||
op.setStatusBarColor(resources.getColor(R.color.colorPrimaryDark, theme))
|
||||
op.setToolbarColor(resources.getColor(R.color.colorPrimary, theme))
|
||||
op.setActiveControlsWidgetColor(resources.getColor(R.color.colorAccent, theme))
|
||||
UCrop.of(headPic.toUri(), headPic.toUri())
|
||||
cropLauncher.launch(UCrop.of(headPic.toUri(), headPic.toUri())
|
||||
.withAspectRatio(r, 1F)
|
||||
.withMaxResultSize(navhbg.width, navhbg.height)
|
||||
.withOptions(op)
|
||||
.start(this)
|
||||
.getIntent(this))
|
||||
}
|
||||
|
||||
private fun checkUpdate(ignoreSkip: Boolean) {
|
||||
Thread{
|
||||
Update.checkUpdate(this, toolsBox, ignoreSkip)
|
||||
}.start()
|
||||
lifecycleScope.launch {
|
||||
Update.checkUpdate(this@MainActivity, toolsBox, ignoreSkip)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showAbout() {
|
||||
|
||||
@@ -3,12 +3,13 @@ package top.fumiama.copymanga.json;
|
||||
public class ComicStructure {
|
||||
public String uuid;
|
||||
public String name;
|
||||
public String alias;
|
||||
//public String alias;
|
||||
public int img_type;
|
||||
public ValueDisplayPair region;
|
||||
public ValueDisplayPair status;
|
||||
public ThemeStructure[] theme;
|
||||
public String path_word;
|
||||
public ThemeStructure[] author;
|
||||
public int img_type;
|
||||
public String brief;
|
||||
public String datetime_updated;
|
||||
public String cover;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package top.fumiama.copymanga.manga
|
||||
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.json.BookQueryStructure
|
||||
import top.fumiama.copymanga.json.ReturnBase
|
||||
import top.fumiama.copymanga.tools.http.DownloadTools
|
||||
@@ -12,9 +14,9 @@ class Shelf(private val token: String, getString: (Int) -> String) {
|
||||
private val queryApiUrl = getString(R.string.bookUserQueryApiUrl)
|
||||
private val referer: String = getString(R.string.referer)
|
||||
private val ua: String = getString(R.string.pc_ua)
|
||||
fun add(comicId: String): String {
|
||||
suspend fun add(comicId: String): String = withContext(Dispatchers.IO) {
|
||||
if (comicId.isEmpty()) {
|
||||
return "空漫画ID"
|
||||
return@withContext "空漫画ID"
|
||||
}
|
||||
val body = buildString {
|
||||
append("comic_id=")
|
||||
@@ -25,13 +27,13 @@ class Shelf(private val token: String, getString: (Int) -> String) {
|
||||
}
|
||||
val re = DownloadTools.requestWithBody(
|
||||
"$apiUrl?platform=3", "POST", body.encodeToByteArray(), referer, ua
|
||||
)?.decodeToString() ?: return "空回应"
|
||||
return Gson().fromJson(re, ReturnBase::class.java).message
|
||||
)?.decodeToString() ?: return@withContext "空回应"
|
||||
return@withContext Gson().fromJson(re, ReturnBase::class.java).message
|
||||
}
|
||||
|
||||
fun del(vararg bookIds: Int): String {
|
||||
suspend fun del(vararg bookIds: Int): String = withContext(Dispatchers.IO) {
|
||||
if (bookIds.isEmpty()) {
|
||||
return "空ID列表"
|
||||
return@withContext "空ID列表"
|
||||
}
|
||||
val body = buildString {
|
||||
bookIds.forEach {
|
||||
@@ -44,16 +46,13 @@ class Shelf(private val token: String, getString: (Int) -> String) {
|
||||
}
|
||||
val re = DownloadTools.requestWithBody(
|
||||
"${apiUrl}s?platform=3", "DELETE", body.encodeToByteArray(), referer, ua
|
||||
)?.decodeToString() ?: return "空回应"
|
||||
return Gson().fromJson(re, ReturnBase::class.java).message
|
||||
)?.decodeToString() ?: return@withContext "空回应"
|
||||
return@withContext Gson().fromJson(re, ReturnBase::class.java).message
|
||||
}
|
||||
|
||||
fun query(pathWord: String): BookQueryStructure {
|
||||
DownloadTools.getHttpContent(queryApiUrl.format(hostUrl, pathWord), referer, ua)?.let {
|
||||
return Gson().fromJson(it.decodeToString(), BookQueryStructure::class.java)
|
||||
suspend fun query(pathWord: String): BookQueryStructure? = withContext(Dispatchers.IO) {
|
||||
return@withContext DownloadTools.getHttpContent(queryApiUrl.format(hostUrl, pathWord), referer, ua)?.let {
|
||||
Gson().fromJson(it.decodeToString(), BookQueryStructure::class.java)
|
||||
}
|
||||
val b = BookQueryStructure()
|
||||
b.code = 400
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import kotlinx.android.synthetic.main.card_book.*
|
||||
import kotlinx.android.synthetic.main.card_book.view.*
|
||||
import kotlinx.android.synthetic.main.line_horizonal_empty.view.*
|
||||
import kotlinx.android.synthetic.main.line_lazybooklines.*
|
||||
@@ -36,6 +35,7 @@ class CardList(
|
||||
rows = arrayOfNulls(20)
|
||||
index = 0
|
||||
count = 0
|
||||
cardLoadingWaits.set(0)
|
||||
exitCardList = false
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.line_lazybooklines.*
|
||||
import top.fumiama.copymanga.MainActivity
|
||||
import top.fumiama.copymanga.json.BookListStructure
|
||||
import top.fumiama.copymanga.json.HistoryBookListStructure
|
||||
import top.fumiama.copymanga.json.ShelfStructure
|
||||
@@ -25,8 +24,8 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
|
||||
|
||||
override fun addPage(){
|
||||
super.addPage()
|
||||
ad = AutoDownloadThread(subUrl) {
|
||||
if (it == null) {
|
||||
ad = AutoDownloadThread(subUrl) { data ->
|
||||
if (data == null) {
|
||||
activity?.runOnUiThread {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
@@ -37,7 +36,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
|
||||
isRefresh = false
|
||||
}
|
||||
if(isTypeBook) {
|
||||
val bookList = Gson().fromJson(it?.decodeToString(), TypeBookListStructure::class.java)
|
||||
val bookList = Gson().fromJson(data.decodeToString(), TypeBookListStructure::class.java)
|
||||
bookList?.apply {
|
||||
Log.d("MyICL", "offset:${results.offset}, total:${results.total}")
|
||||
if(results.offset < results.total) {
|
||||
@@ -56,7 +55,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
|
||||
page++
|
||||
}
|
||||
} else if(isHistoryBook) {
|
||||
val bookList = Gson().fromJson(it?.decodeToString(), HistoryBookListStructure::class.java)
|
||||
val bookList = Gson().fromJson(data.decodeToString(), HistoryBookListStructure::class.java)
|
||||
bookList?.apply {
|
||||
Log.d("MyICL", "offset:${results?.offset}, total:${results?.total}")
|
||||
if(results.offset < results.total) {
|
||||
@@ -75,7 +74,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
|
||||
page++
|
||||
}
|
||||
} else if (isShelfBook) {
|
||||
val bookList = Gson().fromJson(it?.decodeToString(), ShelfStructure::class.java)
|
||||
val bookList = Gson().fromJson(data.decodeToString(), ShelfStructure::class.java)
|
||||
bookList?.apply {
|
||||
Log.d("MyICL", "offset:${results?.offset}, total:${results?.total}")
|
||||
if(results.offset < results.total) {
|
||||
@@ -83,7 +82,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
|
||||
results?.list?.forEach{ book ->
|
||||
if(ad?.exit == true) return@AutoDownloadThread
|
||||
cardList?.addCard(
|
||||
book?.comic?.name?:"null", "\n读到${book?.last_browse?.last_browse_name}", book?.comic?.cover,
|
||||
book?.comic?.name?:"null", "\n${book?.last_browse?.last_browse_name?.let { "读到$it" }?:"未读"}", book?.comic?.cover,
|
||||
book?.comic?.path_word, null, null,
|
||||
book?.comic?.status==1,
|
||||
book.comic?.browse?.chapter_uuid != book.comic?.last_chapter_id
|
||||
@@ -95,7 +94,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
|
||||
page++
|
||||
}
|
||||
} else {
|
||||
val bookList = Gson().fromJson(it?.decodeToString(), BookListStructure::class.java)
|
||||
val bookList = Gson().fromJson(data.decodeToString(), BookListStructure::class.java)
|
||||
bookList?.apply {
|
||||
Log.d("MyICL", "offset:${results?.offset}, total:${results?.total}")
|
||||
if(results.offset < results.total) {
|
||||
|
||||
@@ -3,15 +3,18 @@ package top.fumiama.copymanga.template.ui
|
||||
import android.animation.ObjectAnimator
|
||||
import android.view.View
|
||||
import kotlinx.android.synthetic.main.anchor_popular.view.*
|
||||
import kotlinx.android.synthetic.main.line_finish.*
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
open class StatusCardFlow(private val api: Int, nav: Int) : InfoCardLoader(R.layout.fragment_statuscardflow, nav) {
|
||||
val sortWay = listOf("-datetime_updated", "datetime_updated", "popular", "-popular")
|
||||
open class StatusCardFlow(private val api: Int, nav: Int, inflateRes: Int,
|
||||
isTypeBook: Boolean = false,
|
||||
isHistoryBook: Boolean = false,
|
||||
isShelfBook: Boolean = false) : InfoCardLoader(inflateRes, nav, isTypeBook, isHistoryBook, isShelfBook) {
|
||||
val sortWay = listOf("-datetime_updated", "datetime_updated", "-popular", "popular")
|
||||
var sortValue = 0
|
||||
var lineUpdate: View? = null
|
||||
var lineHot: View? = null
|
||||
|
||||
override fun getApiUrl() =
|
||||
getString(api).format(
|
||||
@@ -22,21 +25,17 @@ open class StatusCardFlow(private val api: Int, nav: Int) : InfoCardLoader(R.lay
|
||||
|
||||
override fun setListeners() {
|
||||
super.setListeners()
|
||||
setUpdate(line_finish_time)
|
||||
setHot(line_finish_pop)
|
||||
lineUpdate?.let { setUpdate(it) }
|
||||
lineHot?.let { setHot(it) }
|
||||
lineUpdate?.alpha = 1f
|
||||
lineHot?.alpha = 0.5f
|
||||
}
|
||||
|
||||
open fun setUpdate(that: View) {
|
||||
that.apply {
|
||||
apt.setText(R.string.menu_update_time)
|
||||
setOnClickListener {
|
||||
sortValue = if(apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
1
|
||||
}else{
|
||||
ObjectAnimator.ofFloat(apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
0
|
||||
}
|
||||
sortValue = triggerLine(false)
|
||||
Thread{
|
||||
Thread.sleep(400)
|
||||
activity?.runOnUiThread {
|
||||
@@ -52,13 +51,7 @@ open class StatusCardFlow(private val api: Int, nav: Int) : InfoCardLoader(R.lay
|
||||
that.apply {
|
||||
apt.setText(R.string.menu_hot)
|
||||
setOnClickListener {
|
||||
sortValue = if (apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
3
|
||||
} else {
|
||||
ObjectAnimator.ofFloat(apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
2
|
||||
}
|
||||
sortValue = triggerLine(true)
|
||||
Thread {
|
||||
Thread.sleep(400)
|
||||
activity?.runOnUiThread {
|
||||
@@ -69,4 +62,46 @@ open class StatusCardFlow(private val api: Int, nav: Int) : InfoCardLoader(R.lay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open fun triggerLine(isHot: Boolean): Int {
|
||||
val hot = lineHot?:return 0
|
||||
val update = lineUpdate?:return 0
|
||||
if(sortValue >= 2) {
|
||||
if (isHot) {
|
||||
return if (hot.apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(hot.apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
3
|
||||
} else {
|
||||
ObjectAnimator.ofFloat(hot.apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
2
|
||||
}
|
||||
} else {
|
||||
update.alpha = 1f
|
||||
hot.alpha = 0.5f
|
||||
return if(update.apim.rotation == 0f) {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!isHot) {
|
||||
return if(update.apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(update.apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
1
|
||||
}else{
|
||||
ObjectAnimator.ofFloat(update.apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
0
|
||||
}
|
||||
} else {
|
||||
hot.alpha = 1f
|
||||
update.alpha = 0.5f
|
||||
return if (hot.apim.rotation == 0f) {
|
||||
2
|
||||
} else {
|
||||
3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
package top.fumiama.copymanga.template.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import kotlinx.android.synthetic.main.app_bar_main.*
|
||||
import kotlinx.android.synthetic.main.line_finish.*
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
open class ThemeCardFlow(private val api: Int, nav: Int) : StatusCardFlow(0, nav) {
|
||||
open class ThemeCardFlow(private val api: Int, nav: Int) : StatusCardFlow(0, nav, R.layout.fragment_statuscardflow) {
|
||||
private var theme = ""
|
||||
override fun getApiUrl() =
|
||||
getString(api).format(
|
||||
@@ -26,6 +29,12 @@ open class ThemeCardFlow(private val api: Int, nav: Int) : StatusCardFlow(0, nav
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
lineUpdate = line_finish_time
|
||||
lineHot = line_finish_pop
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
arguments?.getString("name")?.apply {
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.net.URLEncoder
|
||||
|
||||
object CMApi {
|
||||
var proxy = if(Proxy.useImageProxy) Proxy(R.string.imgProxyApiUrl, R.string.imgProxyApiPrefix, R.string.imgProxyKeyID) else null
|
||||
var resolution = Resolution(Regex("\\.c\\d+x\\."))
|
||||
var resolution = Resolution(Regex("c\\d+x\\."))
|
||||
var myGlideHeaders: LazyHeaders? = null
|
||||
get() {
|
||||
MainActivity.mainWeakReference?.get()?.let {
|
||||
|
||||
@@ -16,5 +16,5 @@ class Resolution(private val original: Regex) {
|
||||
}
|
||||
return 1500
|
||||
}
|
||||
fun wrap(u: String) : String = u.replace(original, ".c${imageResolution}x.")
|
||||
fun wrap(u: String) : String = u.replace(original, "c${imageResolution}x.")
|
||||
}
|
||||
|
||||
@@ -13,17 +13,17 @@ class GlideHideLottieViewListener(private val wla: WeakReference<LottieAnimation
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
target: Target<Drawable>,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable?,
|
||||
model: Any?,
|
||||
resource: Drawable,
|
||||
model: Any,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
dataSource: DataSource,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
wla.get()?.apply {
|
||||
|
||||
@@ -6,14 +6,18 @@ import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.app_bar_main.*
|
||||
import kotlinx.android.synthetic.main.card_book.*
|
||||
import kotlinx.android.synthetic.main.fragment_book.*
|
||||
import kotlinx.android.synthetic.main.line_bookinfo_text.*
|
||||
import kotlinx.android.synthetic.main.line_booktandb.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.MainActivity
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.json.VolumeStructure
|
||||
import top.fumiama.copymanga.manga.Reader
|
||||
import top.fumiama.copymanga.template.general.NoBackRefreshFragment
|
||||
@@ -32,14 +36,14 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
ComicDlFragment.exit = false
|
||||
fbl?.setPadding(0, 0, 0, navBarHeight)
|
||||
fbvp?.setPadding(0, 0, 0, navBarHeight)
|
||||
|
||||
if(isFirstInflate) {
|
||||
var path = ""
|
||||
arguments?.apply {
|
||||
if (getBoolean("loadJson")) {
|
||||
getString("name")?.let { name ->
|
||||
mainWeakReference?.get()?.getExternalFilesDir("")?.let {
|
||||
activity?.getExternalFilesDir("")?.let {
|
||||
Gson().fromJson(File(File(it, name), "info.json").readText(), Array<VolumeStructure>::class.java)
|
||||
}?.apply {
|
||||
if (isEmpty() || get(0).results.list.isEmpty()) {
|
||||
@@ -62,10 +66,12 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
mBookHandler = BookHandler(WeakReference(this), path)
|
||||
Log.d("MyBF", "read path: $path")
|
||||
bookHandler = mBookHandler
|
||||
Thread {
|
||||
sleep(600)
|
||||
mBookHandler?.startLoad()
|
||||
}.start()
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
sleep(600)
|
||||
mBookHandler?.startLoad()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bookHandler = mBookHandler
|
||||
}
|
||||
@@ -75,7 +81,7 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
super.onResume()
|
||||
isOnPause = false
|
||||
bookHandler = mBookHandler
|
||||
mainWeakReference?.get()?.apply {
|
||||
activity?.apply {
|
||||
toolbar.title = mBookHandler?.book?.results?.comic?.name
|
||||
}
|
||||
setStartRead()
|
||||
@@ -96,7 +102,7 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
}
|
||||
|
||||
fun setStartRead() {
|
||||
if(mBookHandler?.chapterNames?.isNotEmpty() == true) mainWeakReference?.get()?.apply {
|
||||
if(mBookHandler?.chapterNames?.isNotEmpty() == true) activity?.apply {
|
||||
mBookHandler?.book?.results?.comic?.let { comic ->
|
||||
getPreferences(MODE_PRIVATE).getInt(comic.name, -1).let { p ->
|
||||
this@BookFragment.lbbstart.apply {
|
||||
@@ -118,12 +124,13 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun setAddToShelf() {
|
||||
if(mBookHandler?.chapterNames?.isNotEmpty() == true) {
|
||||
if(mBookHandler?.chapterNames?.isNotEmpty() != true) return
|
||||
lifecycleScope.launch {
|
||||
val b = MainActivity.shelf?.query(mBookHandler?.path!!)
|
||||
mBookHandler?.collect = b?.results?.collect?:-2
|
||||
Log.d("MyBF", "get collect of ${mBookHandler?.path} = ${mBookHandler?.collect}")
|
||||
b?.results?.browse?.chapter_name?.let { name ->
|
||||
btsub.text = "${btsub.text} ${getString(R.string.text_format_cloud_read_to).format(name)}"
|
||||
tic.text = b?.results?.browse?.chapter_name?.let { name ->
|
||||
getString(R.string.text_format_cloud_read_to).format(name)
|
||||
}
|
||||
mBookHandler?.collect?.let { collect ->
|
||||
if (collect > 0) {
|
||||
@@ -132,30 +139,24 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
|
||||
}
|
||||
mBookHandler?.book?.results?.comic?.let { comic ->
|
||||
this@BookFragment.lbbsub.setOnClickListener {
|
||||
if (this@BookFragment.lbbsub.text != getString(R.string.button_sub)) {
|
||||
mBookHandler?.collect?.let { collect ->
|
||||
if (collect < 0) return@setOnClickListener
|
||||
Thread{
|
||||
lifecycleScope.launch clickLaunch@ {
|
||||
if (this@BookFragment.lbbsub.text != getString(R.string.button_sub)) {
|
||||
mBookHandler?.collect?.let { collect ->
|
||||
if (collect < 0) return@clickLaunch
|
||||
val re = MainActivity.shelf?.del(collect)
|
||||
activity?.runOnUiThread {
|
||||
Toast.makeText(context, re, Toast.LENGTH_SHORT).show()
|
||||
if (re == "请求成功") {
|
||||
this@BookFragment.lbbsub.setText(R.string.button_sub)
|
||||
}
|
||||
Toast.makeText(context, re, Toast.LENGTH_SHORT).show()
|
||||
if (re == "请求成功") {
|
||||
this@BookFragment.lbbsub.setText(R.string.button_sub)
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
return@setOnClickListener
|
||||
}
|
||||
Thread{
|
||||
val re = MainActivity.shelf?.add(comic.uuid)
|
||||
activity?.runOnUiThread {
|
||||
Toast.makeText(context, re, Toast.LENGTH_SHORT).show()
|
||||
if (re == "修改成功") {
|
||||
this@BookFragment.lbbsub.setText(R.string.button_sub_subscribed)
|
||||
}
|
||||
return@clickLaunch
|
||||
}
|
||||
}.start()
|
||||
val re = MainActivity.shelf?.add(comic.uuid)
|
||||
Toast.makeText(context, re, Toast.LENGTH_SHORT).show()
|
||||
if (re == "修改成功") {
|
||||
this@BookFragment.lbbsub.setText(R.string.button_sub_subscribed)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,18 @@ import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.app_bar_main.*
|
||||
import kotlinx.android.synthetic.main.card_book.*
|
||||
@@ -22,6 +27,7 @@ import kotlinx.android.synthetic.main.line_bookinfo.*
|
||||
import kotlinx.android.synthetic.main.line_bookinfo_text.*
|
||||
import kotlinx.android.synthetic.main.line_caption.view.*
|
||||
import kotlinx.android.synthetic.main.line_chapter.view.*
|
||||
import kotlinx.android.synthetic.main.page_nested_list.view.*
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.json.BookInfoStructure
|
||||
import top.fumiama.copymanga.json.ChapterStructure
|
||||
@@ -62,7 +68,7 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
var vols: Array<VolumeStructure>? = null
|
||||
var chapterNames = arrayOf<String>()
|
||||
var collect: Int = -1
|
||||
private val divider get() = that?.layoutInflater?.inflate(R.layout.div_h, that?.fbl, false)
|
||||
private val divider get() = that?.layoutInflater?.inflate(R.layout.div_h, that?.lbl, false)
|
||||
|
||||
var urlArray = arrayOf<String>()
|
||||
|
||||
@@ -73,10 +79,7 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
1 -> setCover()
|
||||
2 -> setTexts()
|
||||
3 -> setAuthorsAndTags()
|
||||
//4 -> setOverScale()
|
||||
6 -> if(complete) that?.navigate2dl()
|
||||
7 -> setVolumes()
|
||||
8 -> that?.apply { fbl?.addView(msg.obj as View) }
|
||||
9 -> endSetLayouts()
|
||||
}
|
||||
}
|
||||
@@ -127,11 +130,6 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
Log.d("MyBH", "Set complete: true")
|
||||
}
|
||||
|
||||
/*private fun setOverScale() {
|
||||
if (exit) return
|
||||
that?.fbov?.setScaleView(that!!.fbapp)
|
||||
}*/
|
||||
|
||||
private fun setCover() {
|
||||
if (exit) return
|
||||
that?.apply {
|
||||
@@ -144,63 +142,69 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
?.let { it2 -> RequestOptions.bitmapTransform(it2) }
|
||||
?.let { it3 -> load.apply(it3).into(lbibg) }
|
||||
}
|
||||
imf?.visibility = View.GONE
|
||||
//imf?.visibility = View.GONE
|
||||
//fbl?.addView(divider)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getThemeSeq(authors: Array<ThemeStructure>): CharSequence{
|
||||
/*private fun getThemeSeq(authors: Array<ThemeStructure>): CharSequence{
|
||||
var re = ""
|
||||
for(author in authors) re += author.name + ' '
|
||||
return re
|
||||
}
|
||||
}*/
|
||||
|
||||
private fun setTexts(){
|
||||
private fun setTexts() {
|
||||
if (exit) return
|
||||
//that?.tic?.text = book?.name
|
||||
that?.tic?.visibility = View.GONE
|
||||
//that?.tic?.visibility = View.GONE
|
||||
mainWeakReference?.get()?.toolbar?.title = book?.results?.comic?.name
|
||||
that?.btauth?.text = book?.results?.comic?.author?.let { getThemeSeq(it) }
|
||||
that?.bttag?.text = book?.results?.comic?.theme?.let { getThemeSeq(it) }
|
||||
that?.bthit?.text = that?.getString(R.string.text_format_hit)?.let { String.format(
|
||||
it,
|
||||
that?.btauth?.text = that?.getString(R.string.text_format_region)?.format(
|
||||
book?.results?.comic?.region?.display
|
||||
)
|
||||
that?.bttag?.text = that?.getString(R.string.text_format_img_type)?.format(when(book?.results?.comic?.img_type) {
|
||||
1 -> "条漫"
|
||||
2 -> "普通"
|
||||
else -> "未知类型${book?.results?.comic?.img_type}"
|
||||
})
|
||||
that?.bthit?.text = that?.getString(R.string.text_format_hit)?.format(
|
||||
book?.results?.comic?.popular
|
||||
) }?:""
|
||||
that?.btsub?.text = that?.getString(R.string.text_format_stat)?.let { String.format(
|
||||
it,
|
||||
)
|
||||
that?.btsub?.text = that?.getString(R.string.text_format_stat)?.format(
|
||||
book?.results?.comic?.status?.display
|
||||
) }?:""
|
||||
)
|
||||
that?.bttime?.text = book?.results?.comic?.datetime_updated
|
||||
val v = that?.layoutInflater?.inflate(R.layout.line_text_info, that?.fbl, false)
|
||||
val v = that?.layoutInflater?.inflate(R.layout.line_text_info, that?.lbl, false)
|
||||
(v as TextView).text = book?.results?.comic?.brief
|
||||
that?.fbl?.addView(v)
|
||||
that?.fbl?.addView(divider)
|
||||
that?.lbl?.addView(v)
|
||||
that?.lbl?.addView(divider)
|
||||
}
|
||||
|
||||
private fun setTheme(caption: String, themeStructure: Array<ThemeStructure>, nav: Int) {
|
||||
that?.apply {
|
||||
val t = layoutInflater.inflate(R.layout.line_caption, fbl, false)
|
||||
val t = layoutInflater.inflate(R.layout.line_caption, lbl, false)
|
||||
t.tcptn.text = caption
|
||||
fbl.addView(t)
|
||||
fbl.addView(layoutInflater.inflate(R.layout.div_h, fbl, false))
|
||||
lbl.addView(t)
|
||||
lbl.addView(layoutInflater.inflate(R.layout.div_h, lbl, false))
|
||||
}
|
||||
var line: View? = null
|
||||
val last = themeStructure.size - 1
|
||||
themeStructure.onEachIndexed { i, it ->
|
||||
if(line == null) {
|
||||
if(i == last) {
|
||||
line = that?.layoutInflater?.inflate(R.layout.line_chapter, that!!.fbl, false)
|
||||
line = that?.layoutInflater?.inflate(R.layout.line_chapter, that!!.lbl, false)
|
||||
line?.lcc?.apply {
|
||||
lct.text = it.name
|
||||
lci.setBackgroundResource(R.drawable.ic_list)
|
||||
setOnClickListener { _ ->
|
||||
loadVolume(it.name, it.path_word, nav)
|
||||
}
|
||||
}
|
||||
that?.fbl?.addView(line)
|
||||
that?.lbl?.addView(line)
|
||||
} else {
|
||||
line = that?.layoutInflater?.inflate(R.layout.line_2chapters, that!!.fbl, false)
|
||||
line = that?.layoutInflater?.inflate(R.layout.line_2chapters, that!!.lbl, false)
|
||||
line?.l2cl?.apply {
|
||||
lct.text = it.name
|
||||
lci.setBackgroundResource(R.drawable.ic_list)
|
||||
setOnClickListener { _ ->
|
||||
loadVolume(it.name, it.path_word, nav)
|
||||
}
|
||||
@@ -208,10 +212,11 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
}
|
||||
} else line?.l2cr?.apply {
|
||||
lct.text = it.name
|
||||
lci.setBackgroundResource(R.drawable.ic_list)
|
||||
setOnClickListener { _ ->
|
||||
loadVolume(it.name, it.path_word, nav)
|
||||
}
|
||||
that?.fbl?.addView(line)
|
||||
that?.lbl?.addView(line)
|
||||
line = null
|
||||
}
|
||||
}
|
||||
@@ -228,7 +233,7 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
R.id.action_nav_book_to_nav_author
|
||||
)
|
||||
}
|
||||
fbl.addView(layoutInflater.inflate(R.layout.div_h, fbl, false))
|
||||
lbl.addView(layoutInflater.inflate(R.layout.div_h, lbl, false))
|
||||
theme?.let {
|
||||
setTheme(
|
||||
getString(R.string.caption),
|
||||
@@ -240,11 +245,68 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addVolumesView(v: View) {
|
||||
obtainMessage(8, v).sendToTarget()
|
||||
private fun addVolumesView(l: LinearLayout, v: View) {
|
||||
that?.activity?.runOnUiThread {
|
||||
l.addView(v)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setVolumes() = Thread {
|
||||
private fun setVolume(fbl: LinearLayout, p: Int) = Thread {
|
||||
if (exit) return@Thread
|
||||
that?.apply {
|
||||
book?.results?.apply {
|
||||
var i = 0
|
||||
for (j in 0 until p) {
|
||||
i += vols?.get(j)?.results?.list?.size?:0
|
||||
}
|
||||
var last = i-1
|
||||
vols?.get(p)?.let { v ->
|
||||
if(exit) return@Thread
|
||||
var line: View? = null
|
||||
last += v.results.list.size
|
||||
v.results.list.forEach {
|
||||
val f = CMApi.getZipFile(context?.getExternalFilesDir(""), comic.name, keys[p], it.name)
|
||||
Log.d("MyBH", "i = $i, last=$last, add chapter ${it.name}, line is null: ${line == null}")
|
||||
that?.isOnPause?.let { isOnPause ->
|
||||
while (isOnPause && !exit) sleep(1000)
|
||||
if (exit) return@Thread
|
||||
}?:return@Thread
|
||||
if(line == null) {
|
||||
if(i == last) {
|
||||
line = layoutInflater.inflate(R.layout.line_chapter, fbl, false)
|
||||
line?.lcc?.apply {
|
||||
lct.text = it.name
|
||||
if (f.exists()) lci.setBackgroundResource(R.drawable.ic_success)
|
||||
Log.d("MyBH", "add last single chapter ${it.name}")
|
||||
val index = i
|
||||
setOnClickListener { Reader.viewMangaAt(comic.name, index, urlArray) }
|
||||
}
|
||||
line?.let { l -> addVolumesView(fbl, l) }
|
||||
} else {
|
||||
line = layoutInflater.inflate(R.layout.line_2chapters, fbl, false)
|
||||
line?.l2cl?.apply {
|
||||
lct.text = it.name
|
||||
if (f.exists()) lci.setBackgroundResource(R.drawable.ic_success)
|
||||
val index = i
|
||||
setOnClickListener { Reader.viewMangaAt(comic.name, index, urlArray) }
|
||||
}
|
||||
}
|
||||
} else line?.l2cr?.apply {
|
||||
lct.text = it.name
|
||||
if (f.exists()) lci.setBackgroundResource(R.drawable.ic_success)
|
||||
val index = i
|
||||
setOnClickListener { Reader.viewMangaAt(comic.name, index, urlArray) }
|
||||
line?.let { l -> addVolumesView(fbl, l) }
|
||||
line = null
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
|
||||
private fun setViewManga() = Thread {
|
||||
if (exit) return@Thread
|
||||
that?.apply {
|
||||
book?.results?.apply {
|
||||
@@ -255,58 +317,26 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
var last = -1
|
||||
vols?.forEachIndexed { groupIndex, v ->
|
||||
if(exit) return@Thread
|
||||
addVolumesView(layoutInflater.inflate(R.layout.div_h, fbl, false))
|
||||
val t = layoutInflater.inflate(R.layout.line_caption, fbl, false)
|
||||
t.tcptn.text = keys[groupIndex]
|
||||
addVolumesView(t)
|
||||
addVolumesView(layoutInflater.inflate(R.layout.div_h, fbl, false))
|
||||
var line: View? = null
|
||||
last += v.results.list.size
|
||||
v.results.list.forEach {
|
||||
urlArray += CMApi.getChapterInfoApiUrl(
|
||||
comic.path_word,
|
||||
it.uuid
|
||||
)?:""
|
||||
ViewMangaActivity.fileArray += CMApi.getZipFile(context?.getExternalFilesDir(""), comic.name, keys[groupIndex], it.name)
|
||||
val f = CMApi.getZipFile(context?.getExternalFilesDir(""), comic.name, keys[groupIndex], it.name)
|
||||
ViewMangaActivity.fileArray += f
|
||||
chapterNames += it.name
|
||||
ViewMangaActivity.uuidArray += it.uuid
|
||||
Log.d("MyBH", "i = $i, last=$last, add chapter ${it.name}, line is null: ${line == null}")
|
||||
that?.isOnPause?.let { isOnPause ->
|
||||
while (isOnPause && !exit) sleep(1000)
|
||||
if (exit) return@Thread
|
||||
}?:return@Thread
|
||||
if(line == null) {
|
||||
if(i == last) {
|
||||
line = layoutInflater.inflate(R.layout.line_chapter, that!!.fbl, false)
|
||||
line?.lcc?.apply {
|
||||
lct.text = it.name
|
||||
Log.d("MyBH", "add last single chapter ${it.name}")
|
||||
val index = i
|
||||
setOnClickListener { Reader.viewMangaAt(comic.name, index, urlArray) }
|
||||
}
|
||||
line?.let { l -> addVolumesView(l) }
|
||||
|
||||
} else {
|
||||
line = layoutInflater.inflate(R.layout.line_2chapters, that!!.fbl, false)
|
||||
line?.l2cl?.apply {
|
||||
lct.text = it.name
|
||||
val index = i
|
||||
setOnClickListener { Reader.viewMangaAt(comic.name, index, urlArray) }
|
||||
}
|
||||
}
|
||||
} else line?.l2cr?.apply {
|
||||
lct.text = it.name
|
||||
val index = i
|
||||
setOnClickListener { Reader.viewMangaAt(comic.name, index, urlArray) }
|
||||
line?.let { l -> addVolumesView(l) }
|
||||
line = null
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
sendEmptyMessage(9) // end set layout
|
||||
}
|
||||
}
|
||||
sendEmptyMessage(9) // end set layout
|
||||
}.start()
|
||||
|
||||
private fun loadVolume(name: String, path: String, nav: Int){
|
||||
@@ -375,10 +405,18 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
c++
|
||||
}
|
||||
if (volumes.size == gpws.size) {
|
||||
that?.activity?.runOnUiThread {
|
||||
saveVolumes(volumes)
|
||||
sendEmptyMessage(7)
|
||||
saveVolumes(volumes)
|
||||
that?.fbtab?.let { tab ->
|
||||
that?.fbvp?.let { vp ->
|
||||
that?.activity?.runOnUiThread {
|
||||
vp.adapter = ViewData(vp).RecyclerViewAdapter()
|
||||
TabLayoutMediator(tab, vp) { t, p ->
|
||||
t.text = keys[p]
|
||||
}.attach()
|
||||
}
|
||||
}
|
||||
}
|
||||
setViewManga()
|
||||
}
|
||||
}.start()
|
||||
|
||||
@@ -417,4 +455,18 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
|
||||
}
|
||||
vols = volumes
|
||||
}
|
||||
|
||||
inner class ViewData(itemView: View): RecyclerView.ViewHolder(itemView) {
|
||||
inner class RecyclerViewAdapter: RecyclerView.Adapter<ViewData>() {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewData {
|
||||
return ViewData(that?.layoutInflater?.inflate(R.layout.page_nested_list, parent, false) as NestedScrollView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewData, position: Int) {
|
||||
setVolume(holder.itemView.fbl, position)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = keys.size
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
package top.fumiama.copymanga.ui.cardflow.finish
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import top.fumiama.copymanga.template.ui.StatusCardFlow
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import kotlinx.android.synthetic.main.line_finish.*
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
class FinishFragment : StatusCardFlow(R.string.finishApiUrl, R.id.action_nav_finish_to_nav_book)
|
||||
class FinishFragment : StatusCardFlow(
|
||||
R.string.finishApiUrl, R.id.action_nav_finish_to_nav_book, R.layout.fragment_statuscardflow) {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
lineUpdate = line_finish_time
|
||||
lineHot = line_finish_pop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package top.fumiama.copymanga.ui.cardflow.newest
|
||||
|
||||
import android.view.View
|
||||
import kotlinx.android.synthetic.main.line_lazybooklines.*
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.template.ui.InfoCardLoader
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.os.Bundle
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import kotlinx.android.synthetic.main.fragment_rank.*
|
||||
import kotlinx.android.synthetic.main.line_rank.view.*
|
||||
import top.fumiama.copymanga.MainActivity
|
||||
import top.fumiama.copymanga.template.ui.InfoCardLoader
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.copymanga.tools.ui.UITools
|
||||
@@ -13,7 +12,7 @@ import java.lang.Thread.sleep
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
class RankFragment : InfoCardLoader(R.layout.fragment_rank, R.id.action_nav_rank_to_nav_book, true) {
|
||||
class RankFragment : InfoCardLoader(R.layout.fragment_rank, R.id.action_nav_rank_to_nav_book, isTypeBook = true) {
|
||||
private val sortWay = listOf("day", "week", "month", "total")
|
||||
private var sortValue = 0
|
||||
private val audienceWay = listOf("", "male", "female")
|
||||
|
||||
@@ -2,9 +2,14 @@ package top.fumiama.copymanga.ui.cardflow.shelf
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import kotlinx.android.synthetic.main.anchor_popular.view.*
|
||||
import kotlinx.android.synthetic.main.line_shelf.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.MainActivity
|
||||
import top.fumiama.copymanga.template.ui.InfoCardLoader
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
@@ -37,6 +42,7 @@ class ShelfFragment : InfoCardLoader(R.layout.fragment_shelf, R.id.action_nav_su
|
||||
|
||||
override fun setListeners() {
|
||||
super.setListeners()
|
||||
fade()
|
||||
setUpdate()
|
||||
setModify()
|
||||
setBrowse()
|
||||
@@ -46,20 +52,10 @@ class ShelfFragment : InfoCardLoader(R.layout.fragment_shelf, R.id.action_nav_su
|
||||
if (ad?.exit == true) return
|
||||
line_shelf_updated.apt.setText(R.string.menu_update_time)
|
||||
line_shelf_updated.setOnClickListener {
|
||||
sortValue = if (it.apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
1
|
||||
} else {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
0
|
||||
}
|
||||
Thread {
|
||||
sleep(400)
|
||||
activity?.runOnUiThread {
|
||||
reset()
|
||||
addPage()
|
||||
}
|
||||
}.start()
|
||||
val same = sortValue in 0..1
|
||||
sortValue = rotate(it.apim, same, 0)
|
||||
if (!same) fade()
|
||||
resetDelayed()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,20 +63,10 @@ class ShelfFragment : InfoCardLoader(R.layout.fragment_shelf, R.id.action_nav_su
|
||||
if (ad?.exit == true) return
|
||||
line_shelf_modifier.apt.setText(R.string.menu_add_time)
|
||||
line_shelf_modifier.setOnClickListener {
|
||||
sortValue = if (it.apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
3
|
||||
} else {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
2
|
||||
}
|
||||
Thread {
|
||||
sleep(400)
|
||||
activity?.runOnUiThread {
|
||||
reset()
|
||||
addPage()
|
||||
}
|
||||
}.start()
|
||||
val same = sortValue in 2..3
|
||||
sortValue = rotate(it.apim, same, 2)
|
||||
if (!same) fade()
|
||||
resetDelayed()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,20 +74,60 @@ class ShelfFragment : InfoCardLoader(R.layout.fragment_shelf, R.id.action_nav_su
|
||||
if (ad?.exit == true) return
|
||||
line_shelf_browse.apt.setText(R.string.menu_read_time)
|
||||
line_shelf_browse.setOnClickListener {
|
||||
sortValue = if (it.apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
5
|
||||
val same = sortValue>=4
|
||||
sortValue = rotate(it.apim, same, 4)
|
||||
if (!same) fade()
|
||||
resetDelayed()
|
||||
}
|
||||
}
|
||||
|
||||
private fun rotate(img: View, isSameSlot: Boolean, offset: Int): Int {
|
||||
return if (isSameSlot) {
|
||||
if (img.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(img, "rotation", 0f, 180f).setDuration(233).start()
|
||||
offset+1
|
||||
} else {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
4
|
||||
ObjectAnimator.ofFloat(img, "rotation", 180f, 0f).setDuration(233).start()
|
||||
offset
|
||||
}
|
||||
Thread {
|
||||
} else {
|
||||
if (img.rotation == 0f) {
|
||||
offset
|
||||
} else {
|
||||
offset+1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fade() {
|
||||
when(sortValue) {
|
||||
0, 1 -> {
|
||||
line_shelf_updated.alpha = 1f
|
||||
line_shelf_modifier.alpha = 0.5f
|
||||
line_shelf_browse.alpha = 0.5f
|
||||
}
|
||||
2, 3 -> {
|
||||
line_shelf_updated.alpha = 0.5f
|
||||
line_shelf_modifier.alpha = 1f
|
||||
line_shelf_browse.alpha = 0.5f
|
||||
}
|
||||
4, 5 -> {
|
||||
line_shelf_updated.alpha = 0.5f
|
||||
line_shelf_modifier.alpha = 0.5f
|
||||
line_shelf_browse.alpha = 1f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetDelayed() {
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
sleep(400)
|
||||
activity?.runOnUiThread {
|
||||
withContext(Dispatchers.Main) {
|
||||
reset()
|
||||
addPage()
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,22 @@
|
||||
package top.fumiama.copymanga.ui.cardflow.sort
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.github.zawadz88.materialpopupmenu.popupMenu
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.anchor_popular.view.*
|
||||
import kotlinx.android.synthetic.main.line_sort.*
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.json.FilterStructure
|
||||
import top.fumiama.copymanga.template.http.AutoDownloadThread
|
||||
import top.fumiama.copymanga.template.ui.InfoCardLoader
|
||||
import top.fumiama.copymanga.template.ui.StatusCardFlow
|
||||
import top.fumiama.copymanga.tools.api.CMApi
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.lang.Thread.sleep
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
class SortFragment : InfoCardLoader(R.layout.fragment_sort, R.id.action_nav_sort_to_nav_book) {
|
||||
private val sortWay = listOf("-datetime_updated", "datetime_updated", "-popular", "popular")
|
||||
class SortFragment : StatusCardFlow(0, R.id.action_nav_sort_to_nav_book, R.layout.fragment_sort) {
|
||||
private var theme = -1
|
||||
private var region = -1
|
||||
private var sortValue = 0
|
||||
private var filter: FilterStructure? = null
|
||||
|
||||
override fun getApiUrl() =
|
||||
@@ -30,10 +28,14 @@ class SortFragment : InfoCardLoader(R.layout.fragment_sort, R.id.action_nav_sort
|
||||
if(region >= 0) (filter?.results?.top?.get(region)?.path_word ?: "") else "",
|
||||
)
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
lineUpdate = line_sort_time
|
||||
lineHot = line_sort_hot
|
||||
}
|
||||
|
||||
override fun setListeners() {
|
||||
super.setListeners()
|
||||
setUpdate()
|
||||
setHot()
|
||||
AutoDownloadThread(getString(R.string.filterApiUrl).format(CMApi.myHostApiUrl)) {
|
||||
if(ad?.exit == true) return@AutoDownloadThread
|
||||
it?.let {
|
||||
@@ -46,27 +48,6 @@ class SortFragment : InfoCardLoader(R.layout.fragment_sort, R.id.action_nav_sort
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun setUpdate(){
|
||||
if(ad?.exit == true) return
|
||||
line_sort_time.apt.setText(R.string.menu_update_time)
|
||||
line_sort_time.setOnClickListener {
|
||||
sortValue = if(it.apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
1
|
||||
}else{
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
0
|
||||
}
|
||||
Thread{
|
||||
sleep(400)
|
||||
activity?.runOnUiThread {
|
||||
reset()
|
||||
addPage()
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setClasses(){
|
||||
filter?.results?.top?.let { items ->
|
||||
if(ad?.exit == true) return@let
|
||||
@@ -153,25 +134,4 @@ class SortFragment : InfoCardLoader(R.layout.fragment_sort, R.id.action_nav_sort
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setHot() {
|
||||
if(ad?.exit == true) return
|
||||
line_sort_hot.apt.setText(R.string.menu_hot)
|
||||
line_sort_hot.setOnClickListener {
|
||||
sortValue = if (it.apim.rotation == 0f) {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 0f, 180f).setDuration(233).start()
|
||||
3
|
||||
} else {
|
||||
ObjectAnimator.ofFloat(it.apim, "rotation", 180f, 0f).setDuration(233).start()
|
||||
2
|
||||
}
|
||||
Thread {
|
||||
sleep(400)
|
||||
activity?.runOnUiThread {
|
||||
reset()
|
||||
addPage()
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import android.os.Bundle
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.android.synthetic.main.app_bar_main.*
|
||||
import kotlinx.android.synthetic.main.fragment_topic.*
|
||||
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
|
||||
import top.fumiama.copymanga.json.TopicStructure
|
||||
import top.fumiama.copymanga.template.http.AutoDownloadThread
|
||||
import top.fumiama.copymanga.template.ui.InfoCardLoader
|
||||
@@ -23,12 +22,11 @@ class TopicFragment : InfoCardLoader(R.layout.fragment_topic, R.id.action_nav_to
|
||||
if(ad?.exit == true) return@AutoDownloadThread
|
||||
data?.apply {
|
||||
val r = inputStream().reader()
|
||||
val topic = Gson().fromJson(r, TopicStructure::class.java)
|
||||
topic?.apply {
|
||||
if(ad?.exit != false) return@AutoDownloadThread
|
||||
Gson().fromJson(r, TopicStructure::class.java)?.apply {
|
||||
if(ad?.exit == true) return@AutoDownloadThread
|
||||
activity?.let {
|
||||
it.runOnUiThread {
|
||||
if(ad?.exit != false) return@runOnUiThread
|
||||
if(ad?.exit == true) return@runOnUiThread
|
||||
it.toolbar.title = results.title
|
||||
ftttime.text = results.datetime_created
|
||||
fttintro.text = results.intro
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
package top.fumiama.copymanga.ui.download
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.provider.DocumentsContract
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.net.toUri
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.PreferenceManager
|
||||
import kotlinx.android.synthetic.main.line_lazybooklines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.MainActivity
|
||||
import top.fumiama.copymanga.manga.Reader
|
||||
import top.fumiama.copymanga.template.general.MangaPagesFragmentTemplate
|
||||
import top.fumiama.copymanga.template.ui.CardList
|
||||
import top.fumiama.copymanga.tools.file.FileUtils
|
||||
import top.fumiama.copymanga.tools.ui.Navigate
|
||||
import top.fumiama.copymanga.tools.ui.UITools
|
||||
import top.fumiama.copymanga.tools.file.FileUtils
|
||||
import top.fumiama.copymanga.ui.comicdl.ComicDlFragment
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
import java.io.File
|
||||
@@ -64,49 +63,53 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
|
||||
page = 0
|
||||
isRefresh = false
|
||||
}
|
||||
if(!isEnd) {
|
||||
if(sortedBookList == null || isContentChanged) {
|
||||
Log.d("MyNDF", "Sorting books...")
|
||||
sortedBookList = extDir?.listFiles()?.sortedBy {
|
||||
return@sortedBy Reader.getComicPathWordInFile(it)
|
||||
}
|
||||
if (isReverse) {
|
||||
Log.d("MyNDF", "reversed...")
|
||||
sortedBookList = sortedBookList?.asReversed()
|
||||
}
|
||||
if (!showAll) {
|
||||
sortedBookList = sortedBookList?.filter {
|
||||
return@filter FileUtils.sizeOf(it) / 1048576 > 0
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
if(!isEnd) {
|
||||
if(sortedBookList == null || isContentChanged) {
|
||||
Log.d("MyNDF", "Sorting books...")
|
||||
sortedBookList = extDir?.listFiles()?.sortedBy {
|
||||
return@sortedBy Reader.getComicPathWordInFile(it)
|
||||
}
|
||||
if (isReverse) {
|
||||
Log.d("MyNDF", "reversed...")
|
||||
sortedBookList = sortedBookList?.asReversed()
|
||||
}
|
||||
if (!showAll) {
|
||||
sortedBookList = sortedBookList?.filter {
|
||||
return@filter FileUtils.sizeOf(it) / 1048576 > 0
|
||||
}
|
||||
}
|
||||
isContentChanged = false
|
||||
}
|
||||
}
|
||||
isContentChanged = false
|
||||
}
|
||||
Log.d("MyNDF", "Start drawing cards")
|
||||
cardList?.addCard(oldDlCardName, path = oldDlCardName)
|
||||
var cnt = 1
|
||||
sortedBookList?.let {
|
||||
for(i in it.listIterator(page)) {
|
||||
if(cardList?.exitCardList != false) return
|
||||
page++ // page is actually count
|
||||
val chosenJson = File(i, "info.bin")
|
||||
val newJson = File(i, "info.json")
|
||||
val bookSize = (FileUtils.sizeOf(i)/1048576).toInt()
|
||||
when {
|
||||
chosenJson.exists() -> continue // unsupported old folder
|
||||
newJson.exists() -> {
|
||||
if(cardList?.exitCardList != false) return
|
||||
cardList?.addCard(i.name, "\n${bookSize}MB")
|
||||
cnt++
|
||||
Log.d("MyNDF", "Start drawing cards")
|
||||
cardList?.addCard(oldDlCardName, path = oldDlCardName)
|
||||
var cnt = 1
|
||||
sortedBookList?.let {
|
||||
for(i in it.listIterator(page)) {
|
||||
if(cardList?.exitCardList != false) return@withContext
|
||||
page++ // page is actually count
|
||||
val chosenJson = File(i, "info.bin")
|
||||
val newJson = File(i, "info.json")
|
||||
val bookSize = (FileUtils.sizeOf(i)/1048576).toInt()
|
||||
when {
|
||||
chosenJson.exists() -> continue // unsupported old folder
|
||||
newJson.exists() -> {
|
||||
if(cardList?.exitCardList != false) return@withContext
|
||||
cardList?.addCard(i.name, "\n${bookSize}MB")
|
||||
cnt++
|
||||
}
|
||||
}
|
||||
if (cnt >= 21) break
|
||||
}
|
||||
if(page >= it.size) {
|
||||
isEnd = true
|
||||
}
|
||||
}
|
||||
if (cnt >= 21) break
|
||||
}
|
||||
if(page >= it.size) {
|
||||
isEnd = true
|
||||
}
|
||||
onLoadFinish()
|
||||
}
|
||||
}
|
||||
onLoadFinish()
|
||||
}
|
||||
|
||||
override fun initCardList(weakReference: WeakReference<Fragment>) {
|
||||
@@ -136,12 +139,14 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
|
||||
AlertDialog.Builder(context)
|
||||
.setIcon(R.drawable.ic_launcher_foreground).setMessage("删除下载的漫画${name}吗?")
|
||||
.setTitle("提示").setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
if (chosenFile.exists()) Thread {
|
||||
FileUtils.recursiveRemove(chosenFile)
|
||||
activity?.runOnUiThread {
|
||||
it.visibility = View.INVISIBLE
|
||||
if (chosenFile.exists()) lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
FileUtils.recursiveRemove(chosenFile)
|
||||
withContext(Dispatchers.Main) {
|
||||
it.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||
.show()
|
||||
}
|
||||
|
||||
@@ -7,17 +7,17 @@ class SimpleKanban(private val client: Client, private val pwd: String) { //mu
|
||||
get() {
|
||||
var times = 3
|
||||
var re: ByteArray
|
||||
var firstRecv: ByteArray
|
||||
var firstReceived: ByteArray
|
||||
do {
|
||||
re = byteArrayOf()
|
||||
if(client.initConnect()) {
|
||||
client.sendMessage("${pwd}catquit")
|
||||
client.receiveRawMessage(33) //Welcome to simple kanban server.
|
||||
try {
|
||||
firstRecv = client.receiveRawMessage(4) //le
|
||||
val length = convert2Int(firstRecv)
|
||||
firstReceived = client.receiveRawMessage(4) //le
|
||||
val length = convert2Int(firstReceived)
|
||||
Log.d("MySK", "Msg len: $length")
|
||||
if(firstRecv.size > 4) re += firstRecv.copyOfRange(4, firstRecv.size)
|
||||
if(firstReceived.size > 4) re += firstReceived.copyOfRange(4, firstReceived.size)
|
||||
re += client.receiveRawMessage(length - re.size, setProgress = true)
|
||||
break
|
||||
} catch (e: Exception) {
|
||||
@@ -35,9 +35,9 @@ class SimpleKanban(private val client: Client, private val pwd: String) { //mu
|
||||
(buffer[1].toInt() and 0xff shl 8) or
|
||||
(buffer[0].toInt() and 0xff)
|
||||
|
||||
fun fetchRaw(doOnLoadFailure: ()->Unit = {
|
||||
suspend fun fetchRaw(doOnLoadFailure: suspend ()->Unit = {
|
||||
Log.d("MySD", "Fetch dict failed")
|
||||
}, doOnLoadSuccess: (data: ByteArray)->Unit = {
|
||||
}, doOnLoadSuccess: suspend (data: ByteArray)->Unit = {
|
||||
Log.d("MySD", "Fetch dict success")
|
||||
}) {
|
||||
raw?.apply {
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
package top.fumiama.copymanga.update
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Context.MODE_PRIVATE
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.content.edit
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.android.synthetic.main.dialog_progress.view.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import top.fumiama.copymanga.tools.ui.UITools
|
||||
import top.fumiama.dmzj.copymanga.BuildConfig
|
||||
import top.fumiama.dmzj.copymanga.R
|
||||
@@ -17,8 +23,10 @@ import java.io.File
|
||||
import java.security.MessageDigest
|
||||
|
||||
object Update {
|
||||
fun checkUpdate(activity: Activity, toolsBox: UITools, ignoreSkip: Boolean = false) = activity.apply{
|
||||
suspend fun checkUpdate(activity: AppCompatActivity, toolsBox: UITools, ignoreSkip: Boolean = false) = activity.apply{
|
||||
val client = Client("reilia.fumiama.top", 13212)
|
||||
val kanban = SimpleKanban(client, "fumiama")
|
||||
|
||||
val progressBar = layoutInflater.inflate(R.layout.dialog_progress, null, false)
|
||||
val progressHandler = object : Client.Progress{
|
||||
override fun notify(progressPercentage: Int) {
|
||||
@@ -26,69 +34,85 @@ object Update {
|
||||
progressBar.dpp.progress = progressPercentage
|
||||
}
|
||||
}
|
||||
val kanban = SimpleKanban(client, "fumiama")
|
||||
val msg = kanban[BuildConfig.VERSION_CODE]
|
||||
if(msg != "null") {
|
||||
val verNum = msg.substringBefore('\n').toIntOrNull()
|
||||
val skipNum = getPreferences(MODE_PRIVATE).getInt("skipVersion", 0)
|
||||
|
||||
Log.d("MyUP", "Ver:$verNum, skip: $skipNum")
|
||||
if(verNum != null) {
|
||||
if(msg.contains("md5:")) {
|
||||
if(skipNum < verNum || ignoreSkip) runOnUiThread {
|
||||
toolsBox.buildInfo("看板", msg.substringAfter('\n').substringBeforeLast('\n'), "下载新版", "跳过该版", "取消", {
|
||||
val info = toolsBox.buildAlertWithView("下载进度", progressBar, "隐藏")
|
||||
client.progress = progressHandler
|
||||
Thread {
|
||||
kanban.fetchRaw({
|
||||
runOnUiThread {
|
||||
Toast.makeText(this, "下载失败", Toast.LENGTH_SHORT).show()
|
||||
client.progress = null
|
||||
}
|
||||
}) {
|
||||
val md5 = msg.substringAfterLast("md5:")
|
||||
if (md5 == UITools.toHexStr(
|
||||
MessageDigest.getInstance("MD5").digest(it)
|
||||
)
|
||||
) {
|
||||
runOnUiThread {
|
||||
Toast.makeText(this, "下载成功", Toast.LENGTH_SHORT).show()
|
||||
info.dismiss()
|
||||
}
|
||||
val f = File(externalCacheDir, "new.apk")
|
||||
f.writeBytes(it)
|
||||
install(f, this)
|
||||
} else runOnUiThread {
|
||||
Toast.makeText(this, "文件损坏", Toast.LENGTH_SHORT).show()
|
||||
info.dismiss()
|
||||
}
|
||||
client.progress = null
|
||||
}
|
||||
}.start()
|
||||
}, {
|
||||
getPreferences(MODE_PRIVATE).edit {
|
||||
putInt("skipVersion", verNum)
|
||||
apply()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else runOnUiThread {
|
||||
toolsBox.buildInfo("看板", msg.substringAfter('\n'), "知道了")
|
||||
}
|
||||
val msg = message(kanban)
|
||||
if (msg == "null") {
|
||||
if(ignoreSkip) withContext(Dispatchers.Main) {
|
||||
Toast.makeText(this@apply, "无更新", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
} else if(ignoreSkip) runOnUiThread {
|
||||
Toast.makeText(this, "无更新", Toast.LENGTH_SHORT).show()
|
||||
return@apply
|
||||
}
|
||||
|
||||
val verNum = msg.substringBefore('\n').toIntOrNull()
|
||||
val skipNum = getPreferences(MODE_PRIVATE).getInt("skipVersion", 0)
|
||||
Log.d("MyUP", "Ver:$verNum, skip: $skipNum")
|
||||
if (verNum == null) return@apply
|
||||
|
||||
if(!msg.contains("md5:")) {
|
||||
withContext(Dispatchers.Main) {
|
||||
toolsBox.buildInfo("看板", msg.substringAfter('\n'), "知道了")
|
||||
}
|
||||
return@apply
|
||||
}
|
||||
if(skipNum < verNum || ignoreSkip) {
|
||||
toolsBox.buildInfo("看板", msg.substringAfter('\n').substringBeforeLast('\n'), "下载新版", "跳过该版", "取消", {
|
||||
val info = toolsBox.buildAlertWithView("下载进度", progressBar, "隐藏")
|
||||
client.progress = progressHandler
|
||||
lifecycleScope.launch {
|
||||
fetch(client, kanban, this@apply) {
|
||||
lifecycleScope.launch {
|
||||
val md5 = msg.substringAfterLast("md5:")
|
||||
if (md5 == UITools.toHexStr(
|
||||
MessageDigest.getInstance("MD5").digest(it)
|
||||
)
|
||||
) {
|
||||
Toast.makeText(this@apply, "下载成功", Toast.LENGTH_SHORT).show()
|
||||
info.dismiss()
|
||||
install(it, this@apply)
|
||||
} else runOnUiThread {
|
||||
Toast.makeText(this@apply, "文件损坏", Toast.LENGTH_SHORT).show()
|
||||
info.dismiss()
|
||||
}
|
||||
client.progress = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
getPreferences(MODE_PRIVATE).edit {
|
||||
putInt("skipVersion", verNum)
|
||||
apply()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun install(apkFile: File, activity: Activity) = activity.apply{
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
val contentUri: Uri = FileProvider.getUriForFile(this, "$packageName.fileprovider", apkFile)
|
||||
intent.setDataAndType(contentUri, "application/vnd.android.package-archive")
|
||||
} else intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive")
|
||||
startActivity(intent)
|
||||
private suspend fun message(kanban: SimpleKanban) = withContext(Dispatchers.IO) {
|
||||
return@withContext kanban[BuildConfig.VERSION_CODE]
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetch(client: Client, kanban: SimpleKanban, context: Context, doOnLoadSuccess: (data: ByteArray) -> Unit) = withContext(Dispatchers.IO) {
|
||||
return@withContext kanban.fetchRaw({ downloadFail(client, context) }, doOnLoadSuccess)
|
||||
}
|
||||
|
||||
private suspend fun downloadFail(client: Client, context: Context) = withContext(Dispatchers.Main) {
|
||||
Toast.makeText(context, R.string.download_apk_fail, Toast.LENGTH_SHORT).show()
|
||||
client.progress = null
|
||||
}
|
||||
|
||||
private suspend fun install(data: ByteArray, activity: Activity) = activity.apply{
|
||||
withContext(Dispatchers.IO) {
|
||||
val f = File(externalCacheDir, "new.apk")
|
||||
f.writeBytes(data)
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
val contentUri: Uri = FileProvider.getUriForFile(this@apply, "$packageName.fileprovider", f)
|
||||
intent.setDataAndType(contentUri, "application/vnd.android.package-archive")
|
||||
} else intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive")
|
||||
withContext(Dispatchers.Main) {
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import top.fumiama.dmzj.copymanga.R
|
||||
|
||||
class Member(private val pref: SharedPreferences, private val getString: (Int) -> String) {
|
||||
val hasLogin: Boolean get() = pref.getString("token", "")?.isNotEmpty()?:false
|
||||
suspend fun login(username: String, pwd: String, salt: Int): LoginInfoStructure = withContext(Dispatchers.IO) {
|
||||
suspend fun login(username: String, pwd: String, salt: Int): LoginInfoStructure = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
CMApi.getLoginConnection(username, pwd, salt)?.apply {
|
||||
Gson().fromJson(inputStream.reader(), LoginInfoStructure::class.java)?.let { data ->
|
||||
|
||||
10
app/src/main/res/drawable-anydpi/ic_circle.xml
Normal file
10
app/src/main/res/drawable-anydpi/ic_circle.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="?attr/colorOnSurface"
|
||||
android:pathData="M512 938.667c-235.637 0-426.667-191.03-426.667-426.667S276.363 85.333 512 85.333 938.667 276.363 938.667 512 747.637 938.667 512 938.667m0-64c200.299 0 362.667-162.368 362.667-362.667S712.299 149.333 512 149.333 149.333 311.701 149.333 512 311.701 874.667 512 874.667"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable-anydpi/ic_data.xml
Normal file
10
app/src/main/res/drawable-anydpi/ic_data.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="?attr/colorOnSurface"
|
||||
android:pathData="M512 938.667c-235.637 0-426.667-191.03-426.667-426.667S276.363 85.333 512 85.333 938.667 276.363 938.667 512 747.637 938.667 512 938.667m0-64c200.299 0 362.667-162.368 362.667-362.667S712.299 149.333 512 149.333 149.333 311.701 149.333 512 311.701 874.667 512 874.667m8.213-265.675-81.429-88.704-95.755 99.264a32 32 0 1 1-46.058-44.437L416.33 451.38a32 32 0 0 1 46.613.576l81.792 89.11 136.608-136.992a32 32 0 1 1 45.312 45.184L566.443 609.94a32 32 0 0 1-46.24-.96z"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable-anydpi/ic_hot.xml
Normal file
10
app/src/main/res/drawable-anydpi/ic_hot.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="?attr/colorOnSurface"
|
||||
android:pathData="M790.976 190.72a32 32 0 0 1 45.259-.021 457.25 457.25 0 0 1 134.432 324.416 457.25 457.25 0 0 1-134.294 324.277 32 32 0 1 1-45.258-45.248 393.26 393.26 0 0 0 115.552-279.03 393.26 393.26 0 0 0-115.68-279.146 32 32 0 0 1 0-45.259zm-603.36.128a32 32 0 0 1 45.27 45.248 393.26 393.26 0 0 0-115.553 279.019A393.26 393.26 0 0 0 232.8 794.059a32 32 0 0 1-45.28 45.237A457.25 457.25 0 0 1 53.333 515.115a457.25 457.25 0 0 1 134.294-324.267zm143.179 95.019a32 32 0 0 1 .032 45.248A255.04 255.04 0 0 0 256 512a255.05 255.05 0 0 0 75.147 181.184 32 32 0 1 1-45.216 45.301A319.04 319.04 0 0 1 192 512a319.04 319.04 0 0 1 93.547-226.09 32 32 0 0 1 45.248-.033zm407.36-.267A319.04 319.04 0 0 1 832 512a319.04 319.04 0 0 1-93.653 226.208 32 32 0 0 1-45.28-45.237A255.05 255.05 0 0 0 768 512a255.05 255.05 0 0 0-75.072-181.12 32 32 0 1 1 45.227-45.27zM566.752 384c70.656 0 115.915 57.173 115.915 130.923 0 58.005-47.947 116.789-140.096 181.237a53.33 53.33 0 0 1-61.142 0c-92.149-64.448-140.096-123.232-140.096-181.237 0-73.75 45.259-130.923 115.926-130.923 21.632 0 37.514 5.995 54.741 18.421C529.227 389.995 545.11 384 566.741 384zm0 64c-8.32 0-14.56 3.328-27.52 14.539l-6.336 5.504a32 32 0 0 1-41.77 0l-6.337-5.504c-12.96-11.2-19.2-14.539-27.52-14.539-31.616 0-51.936 25.675-51.936 66.923 0 29.941 34.411 72.938 106.667 124.48 72.256-51.542 106.667-94.539 106.667-124.48 0-41.248-20.32-66.923-51.926-66.923z"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable-anydpi/ic_image.xml
Normal file
10
app/src/main/res/drawable-anydpi/ic_image.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="?attr/colorOnSurface"
|
||||
android:pathData="M938.667 553.92V768c0 64.8-52.534 117.333-117.334 117.333H202.667c-64.8 0-117.334-52.533-117.334-117.333V256c0-64.8 52.534-117.333 117.334-117.333h618.666c64.8 0 117.334 52.533 117.334 117.333zm-64-74.624V256a53.333 53.333 0 0 0-53.334-53.333H202.667A53.333 53.333 0 0 0 149.333 256v344.48A290 290 0 0 1 192 597.333a286.88 286.88 0 0 1 183.296 65.846C427.029 528.384 556.906 437.333 704 437.333c65.707 0 126.997 16.779 170.667 41.963m0 82.24c-5.334-8.32-21.131-21.653-43.648-32.917-34.251-17.131-77.974-27.286-127.019-27.286-121.77 0-229.13 76.267-270.432 188.694-2.73 7.445-7.403 20.32-13.995 38.581-7.68 21.301-34.453 28.107-51.37 13.056-16.438-14.635-28.555-25.067-36.139-31.147A222.9 222.9 0 0 0 192 661.333a225 225 0 0 0-42.667 4.054V768a53.333 53.333 0 0 0 53.334 53.333h618.666A53.333 53.333 0 0 0 874.667 768V561.525zM320 480a96 96 0 1 1 0-192 96 96 0 0 1 0 192m0-64a32 32 0 1 0 0-64 32 32 0 0 0 0 64"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable-anydpi/ic_success.xml
Normal file
10
app/src/main/res/drawable-anydpi/ic_success.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="?attr/colorOnSurface"
|
||||
android:pathData="M878.08 731.275a32 32 0 0 1-54.88-32.939A360.8 360.8 0 0 0 874.667 512c0-200.299-162.368-362.667-362.667-362.667S149.333 311.701 149.333 512 311.701 874.667 512 874.667a360.8 360.8 0 0 0 186.315-51.446 32 32 0 0 1 32.928 54.88A424.8 424.8 0 0 1 512 938.667c-235.637 0-426.667-191.03-426.667-426.667S276.363 85.333 512 85.333 938.667 276.363 938.667 512c0 78.293-21.152 153.568-60.587 219.275M374.581 489.45l84.342 83.989 190.432-190.72a32 32 0 0 1 45.29 45.227L481.632 641.28a32 32 0 0 1-45.227.064L329.42 534.794a32 32 0 1 1 45.162-45.343"/>
|
||||
</vector>
|
||||
@@ -78,7 +78,6 @@
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="获取标题失败"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp"
|
||||
|
||||
@@ -16,29 +16,30 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/nav_header_vertical_spacing"
|
||||
app:layout_constraintBottom_toTopOf="@id/fbov"
|
||||
app:layout_constraintBottom_toTopOf="@id/fbvp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_scrollFlags="scroll|enterAlways" />
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/fbtab"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_scrollFlags="scroll"/>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/fbov"
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/fbvp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:layout_height="match_parent"
|
||||
android:isScrollContainer="true"
|
||||
android:nestedScrollingEnabled="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/fbiinf">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fbl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
app:layout_constraintTop_toBottomOf="@+id/fbiinf"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/fbloading"
|
||||
|
||||
@@ -27,22 +27,32 @@
|
||||
layout="@layout/card_book"
|
||||
android:layout_width="@dimen/book_card_width"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/lbitb"
|
||||
app:layout_constraintEnd_toStartOf="@+id/lbitb"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.499" />
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<include
|
||||
android:id="@+id/lbitb"
|
||||
layout="@layout/line_booktandb"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/nav_header_height"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_weight="2"
|
||||
app:layout_constraintStart_toEndOf="@+id/lbc"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lbl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/lbitb"></LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -20,7 +20,7 @@
|
||||
android:layout_width="@dimen/icon_size_small"
|
||||
android:layout_height="@dimen/icon_size_small"
|
||||
android:layout_marginBottom="@dimen/nav_header_vertical_spacing"
|
||||
android:background="@drawable/ic_list"
|
||||
android:background="@drawable/ic_data"
|
||||
app:layout_constraintBottom_toTopOf="@+id/bitime"
|
||||
app:layout_constraintEnd_toStartOf="@+id/btsub"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -61,7 +61,7 @@
|
||||
android:layout_width="@dimen/icon_size_small"
|
||||
android:layout_height="@dimen/icon_size_small"
|
||||
android:layout_marginBottom="@dimen/nav_header_vertical_spacing"
|
||||
android:background="@drawable/ic_list"
|
||||
android:background="@drawable/ic_image"
|
||||
app:layout_constraintBottom_toTopOf="@+id/bihit"
|
||||
app:layout_constraintEnd_toStartOf="@+id/bttag"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -82,7 +82,7 @@
|
||||
android:layout_width="@dimen/icon_size_small"
|
||||
android:layout_height="@dimen/icon_size_small"
|
||||
android:layout_marginBottom="@dimen/nav_header_vertical_spacing"
|
||||
android:background="@drawable/ic_list"
|
||||
android:background="@drawable/ic_hot"
|
||||
app:layout_constraintBottom_toTopOf="@+id/bisub"
|
||||
app:layout_constraintEnd_toStartOf="@+id/bthit"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -103,7 +103,7 @@
|
||||
android:layout_width="@dimen/icon_size_small"
|
||||
android:layout_height="@dimen/icon_size_small"
|
||||
android:layout_marginBottom="@dimen/nav_header_vertical_spacing"
|
||||
android:background="@drawable/ic_author"
|
||||
android:background="@drawable/ic_locate"
|
||||
app:layout_constraintBottom_toTopOf="@+id/bitag"
|
||||
app:layout_constraintEnd_toStartOf="@+id/btauth"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
android:layout_marginStart="@dimen/nav_header_vertical_spacing"
|
||||
android:layout_marginTop="@dimen/nav_header_vertical_spacing"
|
||||
android:layout_marginBottom="@dimen/nav_header_vertical_spacing"
|
||||
android:background="@drawable/ic_list"
|
||||
android:background="@drawable/ic_circle"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
|
||||
13
app/src/main/res/layout/page_nested_list.xml
Normal file
13
app/src/main/res/layout/page_nested_list.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fbl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
@@ -224,7 +224,7 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_newest"
|
||||
android:name="top.fumiama.copymanga.ui.cardflow.search.SearchFragment"
|
||||
android:name="top.fumiama.copymanga.ui.cardflow.newest.NewestFragment"
|
||||
android:label="@string/new_list"
|
||||
tools:layout="@layout/fragment_newest" >
|
||||
<action
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<string name="menu_home">主页</string>
|
||||
<string name="menu_sort">分类</string>
|
||||
<string name="menu_rank">排行</string>
|
||||
<string name="app_description">©2022–2023源文雨\n本应用为拷贝漫画的第三方客户端,数据均来源于网络,作者不对其中所呈现的任何内容负责。</string>
|
||||
<string name="app_description">©2022–2024源文雨\n本应用为拷贝漫画的第三方客户端,数据均来源于网络,作者不对其中所呈现的任何内容负责。</string>
|
||||
<string name="menu_history">浏览历史</string>
|
||||
<string name="menu_sub">我的订阅</string>
|
||||
<string name="menu_download">我的下载</string>
|
||||
@@ -29,6 +29,9 @@
|
||||
<string name="navTextInfo">illust: Hiten(490219)</string>
|
||||
<string name="navTextInfoInputHint">请设定提示文字内容</string>
|
||||
<string name="clearHeadImgMsg">清除设定的图片?</string>
|
||||
<string name="err_pick_img">选取图片失败</string>
|
||||
<string name="err_crop_img">裁剪图片失败</string>
|
||||
<string name="download_apk_fail">下载更新失败</string>
|
||||
|
||||
<string name="login">登录</string>
|
||||
<string name="logout">注销</string>
|
||||
@@ -112,7 +115,9 @@
|
||||
|
||||
<string name="text_format_hit">热度 %1$d</string>
|
||||
<string name="text_format_stat">状态 %1$s</string>
|
||||
<string name="text_format_cloud_read_to">云端读到 %1$s</string>
|
||||
<string name="text_format_region">区域 %1$s</string>
|
||||
<string name="text_format_img_type">画幅 %1$s</string>
|
||||
<string name="text_format_cloud_read_to">云读至%1$s</string>
|
||||
|
||||
<string name="topics_series">专题系列</string>
|
||||
<string name="manga_rec">漫画推荐</string>
|
||||
|
||||
@@ -10,7 +10,7 @@ buildscript {
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.1'
|
||||
classpath 'com.android.tools.build:gradle:8.2.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
@@ -27,6 +27,6 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
tasks.register('clean', Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip
|
||||
|
||||
Reference in New Issue
Block a user