1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-27 14:20:30 +08:00

v2.0.beta21

新增
1. 退出登录(历史记录不显示就是因为在官方APP或其它第三方APP登录从而使本APP的token无效, 这时退出登录后重登可解)
2. 我的订阅 (fix #28) (fix #31)
修复
1. 专题系列的标题有时无法显示
2. 登录后无法立即显示头像
3. 进入分类页后立即返回则闪退
4. 分类页排序按更新时间和按热度相同
优化
1. 用户头像显示为圆形
This commit is contained in:
源文雨
2023-10-23 00:58:46 +09:00
parent c4ae622880
commit 95e82ab97c
19 changed files with 354 additions and 83 deletions

7
.idea/dictionaries/fumiama.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="fumiama">
<words>
<w>lowpan</w>
</words>
</dictionary>
</component>

View File

@@ -8,8 +8,8 @@ android {
applicationId 'top.fumiama.copymanga' applicationId 'top.fumiama.copymanga'
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 33 targetSdkVersion 33
versionCode 32 versionCode 33
versionName '2.0.beta20' versionName '2.0.beta21'
resConfigs 'zh', 'zh-rCN' resConfigs 'zh', 'zh-rCN'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -2,56 +2,81 @@ package top.fumiama.copymanga
import android.app.Activity import android.app.Activity
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.widget.Toast import android.widget.Toast
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_login.* import kotlinx.android.synthetic.main.activity_login.*
import top.fumiama.copymanga.json.BookListStructure
import top.fumiama.copymanga.json.LoginInfoStructure import top.fumiama.copymanga.json.LoginInfoStructure
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.http.DownloadTools import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import kotlin.random.Random import kotlin.random.Random
import kotlin.random.nextUInt
class LoginActivity:Activity() { class LoginActivity:Activity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login) setContentView(R.layout.activity_login)
val pref = MainActivity.mainWeakReference?.get()?.getPreferences(MODE_PRIVATE) ?: return
val isLogout = pref.getString("token", null) != null
if (isLogout) {
alblogin.setText(R.string.logout)
}
alblogin.setOnClickListener { alblogin.setOnClickListener {
val salt = Random.nextInt(10000) val salt = Random.nextInt(10000)
altusrnm.text?.toString()?.let { username -> val username = altusrnm.text?.toString() ?: run {
altpwd.text?.toString()?.let { pwd -> Toast.makeText(this, R.string.login_null_username, Toast.LENGTH_SHORT).show()
Thread{ return@setOnClickListener
try { }
CMApi.getLoginConnection(username, pwd, salt)?.apply { val pwd = altpwd.text?.toString() ?: run {
Gson().fromJson(inputStream.reader(), LoginInfoStructure::class.java)?.let { Toast.makeText(this, R.string.login_null_pwd, Toast.LENGTH_SHORT).show()
if(it.code == 200) { return@setOnClickListener
MainActivity.mainWeakReference?.get()?.getPreferences(MODE_PRIVATE)?.edit()?.apply { }
putString("token", it.results?.token) Thread{
putString("user_id", it.results?.user_id) if (isLogout) {
putString("username", it.results?.username) pref.edit()?.apply {
putString("nickname", it.results?.nickname) remove("token")
apply() remove("user_id")
DownloadTools.getHttpContent(getString(R.string.memberInfoApiUrl).format(CMApi.myHostApiUrl))?.decodeToString()?.let { remove("username")
val l = Gson().fromJson(it, LoginInfoStructure::class.java) remove("nickname")
if(l.code == 200) { remove("avatar")
putString("avatar", l.results.avatar) apply()
apply() runOnUiThread {
} else runOnUiThread { Toast.makeText(this@LoginActivity, l.message, Toast.LENGTH_SHORT).show() } MainActivity.mainWeakReference?.get()?.refreshUserInfo()
} Toast.makeText(this@LoginActivity, R.string.login_restart_to_apply, Toast.LENGTH_SHORT).show()
runOnUiThread { finish() } finish()
}?:runOnUiThread { Toast.makeText(this@LoginActivity, R.string.login_get_conn_failed, Toast.LENGTH_SHORT).show() }
} else runOnUiThread { Toast.makeText(this@LoginActivity, it.message, Toast.LENGTH_SHORT).show() }
}
disconnect()
}?:runOnUiThread { Toast.makeText(this, R.string.login_get_conn_failed, Toast.LENGTH_SHORT).show() }
}catch (e: Exception) {
runOnUiThread { Toast.makeText(this, e.localizedMessage, Toast.LENGTH_SHORT).show() }
} }
}.start() }
}?:Toast.makeText(this, R.string.login_null_pwd, Toast.LENGTH_SHORT).show() return@Thread
}?:Toast.makeText(this, R.string.login_null_username, Toast.LENGTH_SHORT).show() }
try {
CMApi.getLoginConnection(username, pwd, salt)?.apply {
Gson().fromJson(inputStream.reader(), LoginInfoStructure::class.java)?.let { data ->
if(data.code == 200) {
pref.edit()?.apply {
putString("token", data.results?.token)
putString("user_id", data.results?.user_id)
putString("username", data.results?.username)
putString("nickname", data.results?.nickname)
apply()
DownloadTools.getHttpContent(getString(R.string.memberInfoApiUrl).format(CMApi.myHostApiUrl))?.decodeToString()?.let {
val l = Gson().fromJson(it, LoginInfoStructure::class.java)
if(l.code == 200) {
putString("avatar", l.results.avatar)
apply()
runOnUiThread {
MainActivity.mainWeakReference?.get()?.refreshUserInfo()
}
} else runOnUiThread { Toast.makeText(this@LoginActivity, l.message, Toast.LENGTH_SHORT).show() }
}
runOnUiThread { finish() }
}?:runOnUiThread { Toast.makeText(this@LoginActivity, R.string.login_get_conn_failed, Toast.LENGTH_SHORT).show() }
} else runOnUiThread { Toast.makeText(this@LoginActivity, data.message, Toast.LENGTH_SHORT).show() }
}
disconnect()
}?:runOnUiThread { Toast.makeText(this, R.string.login_get_conn_failed, Toast.LENGTH_SHORT).show() }
} catch (e: Exception) {
runOnUiThread { Toast.makeText(this, e.localizedMessage, Toast.LENGTH_SHORT).show() }
}
}.start()
} }
} }
} }

View File

@@ -1,6 +1,7 @@
package top.fumiama.copymanga package top.fumiama.copymanga
import android.Manifest import android.Manifest
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
@@ -33,6 +34,8 @@ import androidx.navigation.ui.setupWithNavController
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.input.input import com.afollestad.materialdialogs.input.input
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.request.RequestOptions
import com.yalantis.ucrop.UCrop import com.yalantis.ucrop.UCrop
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar_main.* import kotlinx.android.synthetic.main.app_bar_main.*
@@ -92,13 +95,7 @@ class MainActivity : AppCompatActivity() {
Log.d("MyMain", "onDrawerOpened") Log.d("MyMain", "onDrawerOpened")
isDrawerClosed = false isDrawerClosed = false
DownloadFragment.currentDir = getExternalFilesDir("") DownloadFragment.currentDir = getExternalFilesDir("")
getPreferences(MODE_PRIVATE)?.apply { refreshUserInfo()
val name = getString("nickname", getString("username", ""))
val avatar = getString("avatar", "")
if(name != "") navttitle.text = name
else navttitle.setText(R.string.noLogin)
if(avatar != "") Glide.with(this@MainActivity).load(avatar).into(navhicon)
}
} }
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {} override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
@@ -197,7 +194,7 @@ class MainActivity : AppCompatActivity() {
navhbg.setImageBitmap(BitmapFactory.decodeStream(fi)) navhbg.setImageBitmap(BitmapFactory.decodeStream(fi))
fi.close() fi.close()
} }
1 -> { MSG_CROP_IMAGE -> {
data?.data?.let { data?.data?.let {
saveFile(it) saveFile(it)
cropImageUri() cropImageUri()
@@ -213,13 +210,26 @@ class MainActivity : AppCompatActivity() {
) { ) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults) super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) { when (requestCode) {
1 -> { MSG_CROP_IMAGE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) pickPicture() if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) pickPicture()
else Toast.makeText(this, R.string.permissionDenied, Toast.LENGTH_SHORT).show() else Toast.makeText(this, R.string.permissionDenied, Toast.LENGTH_SHORT).show()
} }
} }
} }
fun refreshUserInfo() {
getPreferences(MODE_PRIVATE)?.apply {
val name = getString("nickname", getString("username", ""))
val avatar = getString("avatar", "")
if(name != "") navttitle.text = name
else navttitle.setText(R.string.noLogin)
if(avatar != "")
Glide.with(this@MainActivity).load(avatar)
.apply(RequestOptions.bitmapTransform(CircleCrop()))
.into(navhicon)
}
}
private fun checkReadPermission(): Boolean { private fun checkReadPermission(): Boolean {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && ContextCompat.checkSelfPermission( return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && ContextCompat.checkSelfPermission(
this, this,
@@ -228,16 +238,17 @@ class MainActivity : AppCompatActivity() {
) { ) {
ActivityCompat.requestPermissions( ActivityCompat.requestPermissions(
this, this,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1 arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), MSG_CROP_IMAGE
) )
false false
} else true } else true
} }
@SuppressLint("IntentReset")
private fun pickPicture() { private fun pickPicture() {
val i = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) val i = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
i.type = "image/*" i.type = "image/*"
startActivityForResult(i, 1) startActivityForResult(i, MSG_CROP_IMAGE)
} }
private fun saveFile(uri: Uri) { private fun saveFile(uri: Uri) {
@@ -263,7 +274,11 @@ class MainActivity : AppCompatActivity() {
val r = navhbg.width.toFloat() / navhbg.height.toFloat() val r = navhbg.width.toFloat() / navhbg.height.toFloat()
Log.d("MyMain", "Img info: (${navhbg.width}, ${navhbg.height})") Log.d("MyMain", "Img info: (${navhbg.width}, ${navhbg.height})")
Log.d("MyMain", "Result code: ${UCrop.REQUEST_CROP}") Log.d("MyMain", "Result code: ${UCrop.REQUEST_CROP}")
op.setCompressionFormat(Bitmap.CompressFormat.WEBP) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
op.setCompressionFormat(Bitmap.CompressFormat.WEBP_LOSSY)
} else {
op.setCompressionFormat(Bitmap.CompressFormat.WEBP)
}
op.setStatusBarColor(resources.getColor(R.color.colorPrimaryDark, theme)) op.setStatusBarColor(resources.getColor(R.color.colorPrimaryDark, theme))
op.setToolbarColor(resources.getColor(R.color.colorPrimary, theme)) op.setToolbarColor(resources.getColor(R.color.colorPrimary, theme))
op.setActiveControlsWidgetColor(resources.getColor(R.color.colorAccent, theme)) op.setActiveControlsWidgetColor(resources.getColor(R.color.colorAccent, theme))
@@ -319,6 +334,7 @@ class MainActivity : AppCompatActivity() {
dl.show() dl.show()
} }
@SuppressLint("CheckResult")
fun onNavTInfoClicked(it: View) { fun onNavTInfoClicked(it: View) {
MaterialDialog(this).show { MaterialDialog(this).show {
input(prefill = (it as TextView).text) { _, charSequence -> input(prefill = (it as TextView).text) { _, charSequence ->
@@ -344,5 +360,6 @@ class MainActivity : AppCompatActivity() {
companion object{ companion object{
var mainWeakReference: WeakReference<MainActivity>? = null var mainWeakReference: WeakReference<MainActivity>? = null
var ime: InputMethodManager? = null var ime: InputMethodManager? = null
const val MSG_CROP_IMAGE = 1
} }
} }

View File

@@ -0,0 +1,6 @@
package top.fumiama.copymanga.json;
public class LastBrowseStructure {
public String last_browse_id;
public String last_browse_name;
}

View File

@@ -0,0 +1,14 @@
package top.fumiama.copymanga.json;
public class ShelfStructure extends ReturnBase {
public Results results;
public static class Results extends InfoBase {
public List[] list;
public static class List {
public int uuid;
public boolean b_folder;
public LastBrowseStructure last_browse;
public HistoryComicStructure comic;
}
}
}

View File

@@ -18,7 +18,7 @@ open class MangaPagesFragmentTemplate(inflateRes:Int, val isLazy: Boolean = true
var cardPerRow = 3 var cardPerRow = 3
var cardWidth = 0 var cardWidth = 0
var cardHeight = 0 var cardHeight = 0
lateinit var cardList: CardList var cardList: CardList? = null
var mh: MPATHandler? = null var mh: MPATHandler? = null
var row: View? = null var row: View? = null
var isEnd = false var isEnd = false
@@ -42,7 +42,7 @@ open class MangaPagesFragmentTemplate(inflateRes:Int, val isLazy: Boolean = true
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
cardList.exitCardList = true cardList?.exitCardList = true
mh = null mh = null
row = null row = null
jsonReaderNow = null jsonReaderNow = null

View File

@@ -1,9 +1,9 @@
package top.fumiama.copymanga.template.http package top.fumiama.copymanga.template.http
import top.fumiama.dmzj.copymanga.R import android.util.Log
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.http.DownloadTools import top.fumiama.copymanga.tools.http.DownloadTools
import top.fumiama.dmzj.copymanga.R
class AutoDownloadThread(private val url: String, private val whenFinish: (result: ByteArray?)->Unit): Thread() { class AutoDownloadThread(private val url: String, private val whenFinish: (result: ByteArray?)->Unit): Thread() {
var exit = false var exit = false
@@ -18,5 +18,6 @@ class AutoDownloadThread(private val url: String, private val whenFinish: (resul
) )
} }
if(!exit) whenFinish(re) if(!exit) whenFinish(re)
Log.d("MyADT", "found exit = $exit")
} }
} }

View File

@@ -10,13 +10,14 @@ import kotlinx.android.synthetic.main.line_lazybooklines.*
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
import top.fumiama.copymanga.json.BookListStructure 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.TypeBookListStructure import top.fumiama.copymanga.json.TypeBookListStructure
import top.fumiama.copymanga.template.general.MangaPagesFragmentTemplate import top.fumiama.copymanga.template.general.MangaPagesFragmentTemplate
import top.fumiama.copymanga.template.http.AutoDownloadThread import top.fumiama.copymanga.template.http.AutoDownloadThread
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ExperimentalStdlibApi @ExperimentalStdlibApi
open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isTypeBook: Boolean = false,private val isHistoryBook: Boolean = false): MangaPagesFragmentTemplate(inflateRes) { open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isTypeBook: Boolean = false, private val isHistoryBook: Boolean = false, private val isShelfBook: Boolean = false): MangaPagesFragmentTemplate(inflateRes) {
var offset = 0 var offset = 0
private val subUrl get() = getApiUrl() private val subUrl get() = getApiUrl()
var ad: AutoDownloadThread? = null var ad: AutoDownloadThread? = null
@@ -36,7 +37,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
if(code == 200) { if(code == 200) {
results.list.forEach { book -> results.list.forEach { book ->
if(ad?.exit == true) return@AutoDownloadThread if(ad?.exit == true) return@AutoDownloadThread
cardList.addCard(book.comic.name, null, book.comic.cover, book.comic.path_word, null, null, false) cardList?.addCard(book.comic.name, null, book.comic.cover, book.comic.path_word, null, null, false)
} }
offset += results.list.size offset += results.list.size
} }
@@ -51,7 +52,22 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
if(code == 200) { if(code == 200) {
results.list.forEach{ book -> results.list.forEach{ book ->
if(ad?.exit == true) return@AutoDownloadThread if(ad?.exit == true) return@AutoDownloadThread
cardList.addCard(book.comic.name, null, book.comic.cover, book.comic.path_word, null, null, false) cardList?.addCard(book.comic.name, null, book.comic.cover, book.comic.path_word, null, null, false)
}
offset += results.list.size
}
}
page++
}
} else if (isShelfBook) {
val bookList = Gson().fromJson(it?.decodeToString(), ShelfStructure::class.java)
bookList?.apply {
Log.d("MyICL", "offset:${results.offset}, total:${results.total}")
if(results.offset < results.total) {
if(code == 200) {
results.list.forEach{ book ->
if(ad?.exit == true) return@AutoDownloadThread
cardList?.addCard(book.comic.name, null, book.comic.cover, book.comic.path_word, null, null, false)
} }
offset += results.list.size offset += results.list.size
} }
@@ -66,7 +82,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
if(code == 200) { if(code == 200) {
results.list.forEach{ book -> results.list.forEach{ book ->
if(ad?.exit == true) return@AutoDownloadThread if(ad?.exit == true) return@AutoDownloadThread
cardList.addCard(book.name, null, book.cover, book.path_word, null, null, false) cardList?.addCard(book.name, null, book.cover, book.path_word, null, null, false)
} }
offset += results.list.size offset += results.list.size
} }
@@ -80,7 +96,7 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
} }
override fun initCardList(weakReference: WeakReference<Fragment>) { override fun initCardList(weakReference: WeakReference<Fragment>) {
cardList = CardList(weakReference, cardWidth, cardHeight, cardPerRow) cardList = CardList(weakReference, cardWidth, cardHeight, cardPerRow)
cardList.initClickListeners = object : CardList.InitClickListeners { cardList?.initClickListeners = object : CardList.InitClickListeners {
override fun prepareListeners(v: View, name: String, path: String?, chapterUUID: String?, pn: Int?) { override fun prepareListeners(v: View, name: String, path: String?, chapterUUID: String?, pn: Int?) {
v.setOnClickListener { v.setOnClickListener {
val bundle = Bundle() val bundle = Bundle()
@@ -102,10 +118,20 @@ open class InfoCardLoader(inflateRes:Int, private val navId:Int, private val isT
open fun onLoadFinish(){ open fun onLoadFinish(){
MainActivity.mainWeakReference?.get()?.runOnUiThread { MainActivity.mainWeakReference?.get()?.runOnUiThread {
if(ad?.exit == false) mypl.visibility = View.GONE if(ad?.exit != true) mypl.visibility = View.GONE
} }
} }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ad?.exit = false
}
override fun onResume() {
super.onResume()
ad?.exit = false
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
ad?.exit = true ad?.exit = true

View File

@@ -1,11 +1,8 @@
package top.fumiama.copymanga.ui.cardflow.rank package top.fumiama.copymanga.ui.cardflow.rank
import android.view.View
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_lazybooklines.*
import kotlinx.android.synthetic.main.line_rank.view.* import kotlinx.android.synthetic.main.line_rank.view.*
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
@@ -40,7 +37,7 @@ class RankFragment : InfoCardLoader(R.layout.fragment_rank, R.id.action_nav_rank
sortValue = value sortValue = value
Thread{ Thread{
sleep(400) sleep(400)
if(ad?.exit == false) mh?.sendEmptyMessage(4) if(ad?.exit != true) mh?.sendEmptyMessage(4)
}.start() }.start()
} }
} }

View File

@@ -0,0 +1,90 @@
package top.fumiama.copymanga.ui.cardflow.shelf
import android.animation.ObjectAnimator
import kotlinx.android.synthetic.main.anchor_popular.view.*
import kotlinx.android.synthetic.main.line_shelf.*
import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.dmzj.copymanga.R
import java.lang.Thread.sleep
@ExperimentalStdlibApi
class ShelfFragment : InfoCardLoader(R.layout.fragment_shelf, R.id.action_nav_sub_to_nav_book, isShelfBook = true) {
private val sortWay = listOf(
"-datetime_updated",
"datetime_updated",
"-datetime_modifier",
"datetime_modifier",
"-datetime_browse",
"datetime_browse"
)
private var sortValue = 0
override fun getApiUrl() =
getString(R.string.shelfApiUrl).format(
CMApi.myHostApiUrl,
page * 21,
sortWay[sortValue]
)
override fun setListeners() {
super.setListeners()
setUpdate()
setModify()
setBrowse()
}
private fun setUpdate() {
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)
mh?.sendEmptyMessage(4)
}.start()
}
}
private fun setModify() {
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)
mh?.sendEmptyMessage(4)
}.start()
}
}
private fun setBrowse() {
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
} else {
ObjectAnimator.ofFloat(it.apim, "rotation", 180f, 0f).setDuration(233).start()
4
}
Thread {
sleep(400)
mh?.sendEmptyMessage(4)
}.start()
}
}
}

View File

@@ -1,23 +1,21 @@
package top.fumiama.copymanga.ui.cardflow.sort package top.fumiama.copymanga.ui.cardflow.sort
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.view.View
import com.github.zawadz88.materialpopupmenu.popupMenu import com.github.zawadz88.materialpopupmenu.popupMenu
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.android.synthetic.main.anchor_popular.view.* import kotlinx.android.synthetic.main.anchor_popular.view.*
import kotlinx.android.synthetic.main.line_lazybooklines.*
import kotlinx.android.synthetic.main.line_sort.* import kotlinx.android.synthetic.main.line_sort.*
import top.fumiama.dmzj.copymanga.R
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.json.FilterStructure import top.fumiama.copymanga.json.FilterStructure
import top.fumiama.copymanga.template.http.AutoDownloadThread import top.fumiama.copymanga.template.http.AutoDownloadThread
import top.fumiama.copymanga.template.ui.InfoCardLoader import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.dmzj.copymanga.R
import java.lang.Thread.sleep import java.lang.Thread.sleep
@ExperimentalStdlibApi @ExperimentalStdlibApi
class SortFragment : InfoCardLoader(R.layout.fragment_sort, R.id.action_nav_sort_to_nav_book) { 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") private val sortWay = listOf("-datetime_updated", "datetime_updated", "-popular", "popular")
private var theme = -1 private var theme = -1
private var sortValue = 0 private var sortValue = 0
private var filter: FilterStructure? = null private var filter: FilterStructure? = null
@@ -40,7 +38,7 @@ class SortFragment : InfoCardLoader(R.layout.fragment_sort, R.id.action_nav_sort
filter = Gson().fromJson(it.inputStream().reader(), FilterStructure::class.java) filter = Gson().fromJson(it.inputStream().reader(), FilterStructure::class.java)
if(ad?.exit == true) return@AutoDownloadThread if(ad?.exit == true) return@AutoDownloadThread
mainWeakReference?.get()?.runOnUiThread{ mainWeakReference?.get()?.runOnUiThread{
if(ad?.exit == false) setClasses() if(ad?.exit != true) setClasses()
} }
} }
}.start() }.start()
@@ -109,10 +107,10 @@ class SortFragment : InfoCardLoader(R.layout.fragment_sort, R.id.action_nav_sort
line_sort_hot.setOnClickListener { line_sort_hot.setOnClickListener {
sortValue = if (it.apim.rotation == 0f) { sortValue = if (it.apim.rotation == 0f) {
ObjectAnimator.ofFloat(it.apim, "rotation", 0f, 180f).setDuration(233).start() ObjectAnimator.ofFloat(it.apim, "rotation", 0f, 180f).setDuration(233).start()
1 3
} else { } else {
ObjectAnimator.ofFloat(it.apim, "rotation", 180f, 0f).setDuration(233).start() ObjectAnimator.ofFloat(it.apim, "rotation", 180f, 0f).setDuration(233).start()
0 2
} }
Thread { Thread {
sleep(400) sleep(400)

View File

@@ -1,10 +1,8 @@
package top.fumiama.copymanga.ui.cardflow.topic package top.fumiama.copymanga.ui.cardflow.topic
import android.os.Bundle import android.os.Bundle
import android.view.View
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.android.synthetic.main.app_bar_main.* import kotlinx.android.synthetic.main.app_bar_main.*
import kotlinx.android.synthetic.main.line_lazybooklines.*
import kotlinx.android.synthetic.main.fragment_topic.* import kotlinx.android.synthetic.main.fragment_topic.*
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.json.TopicStructure import top.fumiama.copymanga.json.TopicStructure
@@ -21,15 +19,15 @@ class TopicFragment : InfoCardLoader(R.layout.fragment_topic, R.id.action_nav_to
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AutoDownloadThread(getString(R.string.topicApiUrl).format(CMApi.myHostApiUrl, arguments?.getString("path"))) { AutoDownloadThread(getString(R.string.topicApiUrl).format(CMApi.myHostApiUrl, arguments?.getString("path"))) { data ->
if(ad?.exit == true) return@AutoDownloadThread if(ad?.exit == true) return@AutoDownloadThread
it?.apply { data?.apply {
val r = inputStream().reader() val r = inputStream().reader()
val topic = Gson().fromJson(r, TopicStructure::class.java) val topic = Gson().fromJson(r, TopicStructure::class.java)
topic?.apply { topic?.apply {
if(ad?.exit == true) return@AutoDownloadThread if(ad?.exit == true) return@AutoDownloadThread
mainWeakReference?.get()?.let { mainWeakReference?.get()?.let {
if(ad?.exit == false) it.runOnUiThread { if(ad?.exit != true) it.runOnUiThread {
it.toolbar.title = results.title it.toolbar.title = results.title
ftttime.text = results.datetime_created ftttime.text = results.datetime_created
fttintro.text = results.intro fttintro.text = results.intro

View File

@@ -28,10 +28,10 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
sortedBookList = extDir?.listFiles()?.sorted() sortedBookList = extDir?.listFiles()?.sorted()
} }
Log.d("MyNDF", "Start drawing cards") Log.d("MyNDF", "Start drawing cards")
cardList.addCard(oldDlCardName, path = oldDlCardName) cardList?.addCard(oldDlCardName, path = oldDlCardName)
sortedBookList?.let { sortedBookList?.let {
for(i in it.listIterator(page)) { for(i in it.listIterator(page)) {
if(cardList.exitCardList) return if(cardList?.exitCardList != false) return
page++ // page is actually count page++ // page is actually count
val chosenJson = File(i, "info.bin") val chosenJson = File(i, "info.bin")
val newJson = File(i, "info.json") val newJson = File(i, "info.json")
@@ -39,8 +39,8 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
when{ when{
chosenJson.exists() -> continue // unsupported old folder chosenJson.exists() -> continue // unsupported old folder
newJson.exists() -> { newJson.exists() -> {
if(cardList.exitCardList) return if(cardList?.exitCardList != false) return
cardList.addCard(i.name, " ${bookSize}MB") cardList?.addCard(i.name, " ${bookSize}MB")
} }
} }
} }
@@ -54,7 +54,7 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
override fun initCardList(weakReference: WeakReference<Fragment>) { override fun initCardList(weakReference: WeakReference<Fragment>) {
cardList = CardList(weakReference, cardWidth, cardHeight, cardPerRow) cardList = CardList(weakReference, cardWidth, cardHeight, cardPerRow)
cardList.initClickListeners = object : CardList.InitClickListeners { cardList?.initClickListeners = object : CardList.InitClickListeners {
override fun prepareListeners(v: View, name: String, path: String?, chapterUUID: String?, pn: Int?) { override fun prepareListeners(v: View, name: String, path: String?, chapterUUID: String?, pn: Int?) {
v.setOnClickListener { v.setOnClickListener {
if(name==oldDlCardName && path == oldDlCardName) { if(name==oldDlCardName && path == oldDlCardName) {
@@ -84,7 +84,7 @@ class NewDownloadFragment: MangaPagesFragmentTemplate(R.layout.fragment_newdownl
private fun onLoadFinish() { private fun onLoadFinish() {
MainActivity.mainWeakReference?.get()?.runOnUiThread { MainActivity.mainWeakReference?.get()?.runOnUiThread {
if(!cardList.exitCardList) mypl.visibility = View.GONE if(cardList?.exitCardList == false) mypl.visibility = View.GONE
} }
} }

View File

@@ -137,13 +137,13 @@
android:orientation="horizontal"> android:orientation="horizontal">
<Button <Button
android:id="@+id/alblogin"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/alblogin"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:background="@drawable/buttonshapewhitebg" android:background="@drawable/buttonshapewhitebg"
android:fontFamily="@font/calibri" android:fontFamily="@font/calibri"
android:text="Sign in" android:text="@string/login"
android:textAllCaps="false" android:textAllCaps="false"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="16dp" android:textSize="16dp"

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="top.fumiama.copymanga.ui.cardflow.shelf.ShelfFragment">
<include
android:id="@+id/fslsi"
layout="@layout/line_shelf"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
layout="@layout/line_lazybooklines"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/fslsi" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/div_h"
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginTop="@dimen/nav_header_vertical_spacing"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/line_shelf_updated" />
<include
android:id="@+id/line_shelf_updated"
layout="@layout/anchor_popular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/line_shelf_modifier"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/line_shelf_modifier"
layout="@layout/anchor_popular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/line_shelf_updated"
app:layout_constraintStart_toEndOf="@+id/line_shelf_browse"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/line_shelf_browse"
layout="@layout/anchor_popular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/line_shelf_modifier"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -75,6 +75,20 @@
app:popExitAnim="@anim/slide_in_right_exit"/> app:popExitAnim="@anim/slide_in_right_exit"/>
</fragment> </fragment>
<fragment
android:id="@+id/nav_sub"
android:name="top.fumiama.copymanga.ui.cardflow.shelf.ShelfFragment"
android:label="@string/menu_sub"
tools:layout="@layout/fragment_shelf" >
<action
android:id="@+id/action_nav_sub_to_nav_book"
app:destination="@id/nav_book"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/>
</fragment>
<fragment <fragment
android:id="@+id/nav_history" android:id="@+id/nav_history"
android:name="top.fumiama.copymanga.ui.cardflow.history.HistoryFragment" android:name="top.fumiama.copymanga.ui.cardflow.history.HistoryFragment"

View File

@@ -28,9 +28,12 @@
<string name="navTextInfoInputHint">请设定提示文字内容</string> <string name="navTextInfoInputHint">请设定提示文字内容</string>
<string name="clearHeadImgMsg">清除设定的图片?</string> <string name="clearHeadImgMsg">清除设定的图片?</string>
<string name="login">登录</string>
<string name="logout">注销</string>
<string name="permissionDenied">权限被拒绝</string> <string name="permissionDenied">权限被拒绝</string>
<string name="noLogin">未登录</string> <string name="noLogin">未登录</string>
<string name="load_home_error">"加载主页控件出错"</string> <string name="load_home_error">加载主页控件出错</string>
<string name="text_null">N/A</string> <string name="text_null">N/A</string>
<string name="null_book">获取图书信息失败</string> <string name="null_book">获取图书信息失败</string>
<string name="web_error">网络错误</string> <string name="web_error">网络错误</string>
@@ -56,6 +59,7 @@
<string name="loginApiUrl">https://%1$s/api/v3/login?platform=3</string> <string name="loginApiUrl">https://%1$s/api/v3/login?platform=3</string>
<string name="memberInfoApiUrl">https://%1$s/api/v3/member/info?platform=3</string> <string name="memberInfoApiUrl">https://%1$s/api/v3/member/info?platform=3</string>
<string name="historyApiUrl">https://%1$s/api/v3/member/browse/comics?limit=21&amp;offset=%2$d&amp;platform=3</string> <string name="historyApiUrl">https://%1$s/api/v3/member/browse/comics?limit=21&amp;offset=%2$d&amp;platform=3</string>
<string name="shelfApiUrl">https://%1$s/api/v3/member/collect/comics?limit=21&amp;offset=%2$d&amp;free_type=1&amp;ordering=%3$s&amp;platform=3</string>
<string name="imgProxyApiUrl">https://copymanga.azurewebsites.net/api/img?code=%1$s&amp;url=%2$s</string> <string name="imgProxyApiUrl">https://copymanga.azurewebsites.net/api/img?code=%1$s&amp;url=%2$s</string>
<string name="imgProxyApiPrefix">https://hi77-overseas.mangafuna.xyz/</string> <string name="imgProxyApiPrefix">https://hi77-overseas.mangafuna.xyz/</string>
@@ -80,6 +84,8 @@
<string name="menu_update_time">更新时间</string> <string name="menu_update_time">更新时间</string>
<string name="menu_hot">热度</string> <string name="menu_hot">热度</string>
<string name="menu_add_time">加入时间</string>
<string name="menu_read_time">阅读时间</string>
<string name="button_sub">加入书架</string> <string name="button_sub">加入书架</string>
<string name="button_start">开始阅读</string> <string name="button_start">开始阅读</string>
@@ -125,6 +131,7 @@
<string name="login_null_username">用户名为空</string> <string name="login_null_username">用户名为空</string>
<string name="login_null_pwd">密码为空</string> <string name="login_null_pwd">密码为空</string>
<string name="login_get_conn_failed">连接失败</string> <string name="login_get_conn_failed">连接失败</string>
<string name="login_restart_to_apply">重启应用以彻底退出登录</string>
<string name="old_download_card_name">前往旧版下载</string> <string name="old_download_card_name">前往旧版下载</string>
</resources> </resources>