1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-08 17:00:28 +08:00

2.0.beta8

1. 增加搜索
2. 升级sdk、api
3. 优化更新
This commit is contained in:
fumiama
2022-01-18 16:23:22 +08:00
parent d94675a1b7
commit babfcac664
27 changed files with 507 additions and 117 deletions

5
.idea/gradle.xml generated
View File

@@ -4,10 +4,10 @@
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="PLATFORM" />
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="1.8" />
<option name="gradleJvm" value="11" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
@@ -15,7 +15,6 @@
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>

28
.idea/misc.xml generated
View File

@@ -1,6 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="app/src/main/res/drawable-anydpi/ic_like.xml" value="0.5572916666666666" />
<entry key="app/src/main/res/drawable-anydpi/ic_setting_search.xml" value="0.5572916666666666" />
<entry key="app/src/main/res/layout/activity_login.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.5095108695652174" />
<entry key="app/src/main/res/layout/app_bar_main.xml" value="0.5095108695652174" />
<entry key="app/src/main/res/layout/card_book.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/card_book_plain.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/content_main.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/fragment_book.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/fragment_chapters.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/fragment_download.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/fragment_home.xml" value="0.5095108695652174" />
<entry key="app/src/main/res/layout/line_1bookline.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/line_bookinfo.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/line_choice_list.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/line_text_info.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/line_word.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/viewpage_banner.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/layout/viewpage_horizonal.xml" value="0.49592391304347827" />
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.5572916666666666" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@@ -21,11 +21,14 @@
# 2. 新版(2.0+)
1. 官方在某段时间关闭`H5`后(现已重新打开),从`2.0`版本开始,本应用进行了全新升级。
2. 新版使用`Material Design`配合官方`APP``API`
3. 本应用默认使用海外线路。
### 功能
1. 浏览主页、分类、排行,查看漫画并阅读
2. 下载漫画。但是由于不可抗力,下载速度较慢且容易出错,这绝对不是优化的原因,绝对不是
3. 阅读下载漫画。
1. 浏览主页、分类、排行、我的下载、标签、作者
2. 查看、搜索漫画并直接阅读
3. 下载漫画。但是由于不可抗力,下载速度较慢且容易出错,这绝对不是优化的原因,绝对不是。
4. 阅读下载的漫画。
5. 检查更新。
### 未实现功能
未在上表列出的官方`APP`的其他功能。

View File

@@ -22,14 +22,14 @@ android {
v2SigningEnabled true
}*/
}
compileSdkVersion 30
compileSdkVersion 31
defaultConfig {
applicationId 'top.fumiama.copymanga'
minSdkVersion 23
targetSdkVersion 30
versionCode 18
versionName '2.0.beta7'
targetSdkVersion 31
versionCode 19
versionName '2.0.beta8'
resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -60,7 +60,7 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '11'
}
bundle{
density{
@@ -75,18 +75,18 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
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'
@@ -96,6 +96,7 @@ dependencies {
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'
}
andResGuard {

View File

@@ -26,7 +26,8 @@
<activity
android:name="top.fumiama.copymanga.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
android:theme="@style/AppTheme.NoActionBar"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -39,7 +40,7 @@
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:screenOrientation="fullSensor"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<activity
android:name="top.fumiama.copymanga.ui.vm.ViewMangaActivity"

View File

@@ -1,6 +1,7 @@
package top.fumiama.copymanga
import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
@@ -13,6 +14,7 @@ import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
@@ -42,7 +44,6 @@ import java.io.File
import java.io.FileInputStream
import java.lang.ref.WeakReference
class MainActivity : AppCompatActivity() {
var isDrawerClosed = true
var menuMain: Menu? = null
@@ -93,6 +94,8 @@ class MainActivity : AppCompatActivity() {
override fun onDrawerStateChanged(newState: Int) {}
})
checkUpdate(false)
ime = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@@ -144,6 +147,7 @@ class MainActivity : AppCompatActivity() {
permissions: Array<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
1 -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) pickPicture()
@@ -272,5 +276,6 @@ class MainActivity : AppCompatActivity() {
companion object{
var mainWeakReference: WeakReference<MainActivity>? = null
var ime: InputMethodManager? = null
}
}

View File

@@ -14,6 +14,7 @@ public class IndexStructure extends ReturnBase {
public FinishComics finishComics;
public static class Banners{
public int type;
public String cover;
public String brief;
public String out_uuid;

View File

@@ -42,7 +42,7 @@ object DownloadTools {
refer?.let { setRequestProperty("referer", it) }
setRequestProperty("source", "copyApp")
setRequestProperty("webp", "1")
setRequestProperty("region", "1")
setRequestProperty("region", "0")
setRequestProperty("platform", "3")
ua?.let { setRequestProperty("User-agent", it) }

View File

@@ -1,18 +1,35 @@
package top.fumiama.copymanga.ui.home
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageButton
import androidx.appcompat.view.ContextThemeWrapper
import androidx.navigation.Navigation
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.google.gson.Gson
import com.lapism.search.internal.SearchLayout
import kotlinx.android.synthetic.main.card_book_plain.view.*
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.line_text_info.view.*
import kotlinx.android.synthetic.main.line_word.view.*
import kotlinx.android.synthetic.main.viewpage_horizonal.view.*
import top.fumiama.dmzj.copymanga.R
import top.fumiama.copymanga.MainActivity.Companion.ime
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.json.BookListStructure
import top.fumiama.copymanga.template.general.NoBackRefreshFragment
import top.fumiama.copymanga.template.http.AutoDownloadThread
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.dmzj.copymanga.R
import java.lang.Thread.sleep
import java.lang.ref.WeakReference
@@ -32,6 +49,78 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
homeHandler.obtainMessage(-1, true).sendToTarget()
while(mainWeakReference?.get()?.isDrawerClosed != true) sleep(233)
//homeHandler.sendEmptyMessage(6) //removeAllViews
fhs.apply {
val recyclerView = findViewById<RecyclerView>(R.id.search_recycler_view)
setAdapterLayoutManager(LinearLayoutManager(context))
val adapter = ListViewHolder(recyclerView).RecyclerViewAdapter()
setAdapter(adapter)
navigationIconSupport = SearchLayout.NavigationIconSupport.SEARCH
setMicIconImageResource(R.drawable.ic_setting_search)
val micView = findViewById<ImageButton>(R.id.search_image_view_mic)
setClearFocusOnBackPressed(true)
setOnNavigationClickListener(object : SearchLayout.OnNavigationClickListener {
override fun onNavigationClick(hasFocus: Boolean) {
if (hasFocus()) {
clearFocus()
}
else requestFocus()
}
})
setTextHint(android.R.string.search_go)
setOnQueryTextListener(object : SearchLayout.OnQueryTextListener {
var lastChangeTime = 0L
override fun onQueryTextChange(newText: CharSequence): Boolean {
postDelayed({
val diff = System.currentTimeMillis() - lastChangeTime
if(diff > 500) {
if (newText.isNotEmpty()) adapter.refresh(newText)
}
}, 1024)
lastChangeTime = System.currentTimeMillis()
return true
}
override fun onQueryTextSubmit(query: CharSequence): Boolean {
/*if(query.isNotEmpty()) {
val key = query.toString()
Toast.makeText(context, key, Toast.LENGTH_SHORT).show()
}*/
return true
}
})
setOnMicClickListener(object : SearchLayout.OnMicClickListener {
val types = arrayOf("", "name", "author", "local")
var i = 0
override fun onMicClick() {
val typenames = resources.getStringArray(R.array.search_types)
AlertDialog.Builder(ContextThemeWrapper(context, R.style.AlertDialogTheme))
.setTitle(R.string.set_search_types)
.setIcon(R.mipmap.ic_launcher)
.setSingleChoiceItems(ArrayAdapter(context, R.layout.line_choice_list, typenames), i){ d, p ->
adapter.type = types[p]
i = p
d.cancel()
}.show()
}
})
setOnFocusChangeListener(object : SearchLayout.OnFocusChangeListener {
override fun onFocusChange(hasFocus: Boolean) {
navigationIconSupport = if (hasFocus) SearchLayout.NavigationIconSupport.ARROW
else {
micView.postDelayed({ micView.visibility = View.VISIBLE }, 233)
SearchLayout.NavigationIconSupport.SEARCH
}
}
})
fhns.setOnTouchListener { _, e ->
if (e.action == MotionEvent.ACTION_UP && mSearchEditText?.text?.isNotEmpty() == true) {
ime?.hideSoftInputFromWindow(mainWeakReference?.get()?.window?.decorView?.windowToken, 0)
}
false
}
}
homeHandler.fhib = null
sleep(600)
homeHandler.startLoad()
@@ -75,4 +164,53 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
override fun getItemCount(): Int = homeHandler.index?.results?.banners?.size?:0
}
}
inner class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
inner class RecyclerViewAdapter :
RecyclerView.Adapter<ListViewHolder>() {
private var results: BookListStructure? = null
var type = ""
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
return ListViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.line_word, parent, false)
)
}
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
Log.d("MyMain", "Bind open at $position")
results?.results?.list?.get(position)?.apply {
holder.itemView.tn.text = name
holder.itemView.ta.text = author.let {
var t = ""
it.forEach { ts ->
t += ts.name + " "
}
return@let t
}
holder.itemView.tb.text = popular.toString()
context?.let {
Glide.with(it).load(GlideUrl(cover, CMApi.myGlideHeaders)).into(holder.itemView.imic)
}
holder.itemView.lwc.setOnClickListener {
val bundle = Bundle()
bundle.putString("path", path_word)
rootView?.let { r -> Navigation.findNavController(r).navigate(R.id.action_nav_home_to_nav_book, bundle) }
}
}
}
override fun getItemCount() = results?.results?.list?.size?:0
fun refresh(query: CharSequence) {
mainWeakReference?.get()?.apply {
AutoDownloadThread(String.format(getString(R.string.searchApiUrl), 0, query, type)) {
results = Gson().fromJson(it?.decodeToString(), BookListStructure::class.java)
runOnUiThread { notifyDataSetChanged() }
}.start()
}
}
}
}
}

View File

@@ -81,6 +81,13 @@ class HomeHandler(that: WeakReference<HomeFragment>) : AutoDownloadHandler(
override fun setGsonItem(gsonObj: Any) {
super.setGsonItem(gsonObj)
index = gsonObj as IndexStructure
var banners = arrayOf<IndexStructure.Results.Banners>()
index?.results?.banners?.forEach {
if(it.type == 1) {
banners += it
}
}
index?.results?.banners = banners
}
override fun onError() {
super.onError()

View File

@@ -0,0 +1,27 @@
package top.fumiama.copymanga.update
//Fumiama 20210601
//ByteArrayQueue.kt
//FIFO队列
class ByteArrayQueue {
private var elements = byteArrayOf()
val size get() = elements.size
fun append(items: ByteArray) {
elements += items
}
fun pop(num: Int = 1): ByteArray? {
return if(num <= elements.size) {
val re = elements.copyOfRange(0, num)
elements = elements.copyOfRange(num, elements.size)
re
} else null
}
fun clear() {
elements = byteArrayOf()
}
fun popAll(): ByteArray {
val re = elements
clear()
return re
}
operator fun plusAssign(items: ByteArray) = append(items)
}

View File

@@ -1,9 +1,9 @@
package top.fumiama.copymanga.update
//Fumiama 20210601
//Client.kt
import android.util.Log
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.io.*
import java.lang.Thread.sleep
import java.net.Socket
class Client(private val ip: String, private val port: Int) {
@@ -26,7 +26,7 @@ class Client(private val ip: String, private val port: Int) {
sc = Socket(ip, port) //通过socket连接服务器
din = sc?.getInputStream() //获取输入流并转换为StreamReader约定编码格式
dout = sc?.getOutputStream() //获取输出流
sc?.soTimeout = 2333 //设置连接超时限制
sc?.soTimeout = 10000 //设置连接超时限制
return if (isConnect) {
Log.d("MyC", "connect server successful")
true
@@ -44,13 +44,15 @@ class Client(private val ip: String, private val port: Int) {
* 发送数据至服务器
* @param message 要发送至服务器的字符串
*/
fun sendMessage(message: CharSequence?): Boolean {
fun sendMessage(message: String?): Boolean = sendMessage(message?.toByteArray())
fun sendMessage(message: ByteArray?): Boolean {
try {
if (isConnect) {
if (message != null) { //判断输出流或者消息是否为空为空的话会产生nullpoint错误
dout?.write(message.toString().toByteArray())
if (message != null) { //判断输出流或者消息是否为空为空的话会产生null pointer错误
dout?.write(message)
dout?.flush()
Log.d("MyC", "Send msg: $message")
Log.d("MyC", "Send msg: ${message.decodeToString()}")
return true
} else Log.d("MyC", "The message to be sent is empty")
Log.d("MyC", "send message succeed")
@@ -62,74 +64,51 @@ class Client(private val ip: String, private val port: Int) {
return false
}
var buffer = byteArrayOf()
fun read(): Char? = din?.read()?.toChar()
fun receiveRawMessage(totalSize: Int = -1, bufferSize: Int = 1048576, setProgress: Boolean = false) : ByteArray {
if(totalSize == buffer.size) {
val re = buffer
buffer = byteArrayOf()
return re
} else {
var re = byteArrayOf()
private var buffer = ByteArrayQueue()
private val receiveBuffer = ByteArray(65536)
fun receiveRawMessage(totalSize: Int, setProgress: Boolean = false) : ByteArray {
if(totalSize == buffer.size) return buffer.popAll()
else {
try {
if (isConnect) {
Log.d("MyC", "开始接收服务端信息")
val inMessage = ByteArray(bufferSize) //设置接受缓冲,避免接受数据过长占用过多内存
var a: Int
do {
a = din?.read(inMessage)?:0 //a存储返回消息的长度
if(a > 0) {
re += inMessage.copyOf(a)
Log.d("MyC", "reply length:$a")
if(totalSize < 0 && a < bufferSize) break
else if(setProgress && totalSize > 0) progress?.notify(100 * re.size / totalSize)
} else break
} while (totalSize > re.size)
while(totalSize > buffer.size) {
val count = din?.read(receiveBuffer)?:0
if(count > 0) {
buffer += receiveBuffer.copyOfRange(0, count)
Log.d("MyC", "reply length:$count")
if(setProgress && totalSize > 0) progress?.notify(100 * buffer.size / totalSize)
} else sleep(10)
}
} else Log.d("MyC", "no connect to receive message")
} catch (e: IOException) {
Log.d("MyC", "receive message failed")
e.printStackTrace()
}
if(totalSize > 0 && re.size > totalSize) {
Log.d("MyC", "Reduce re size from ${re.size} to $totalSize")
buffer += re.copyOfRange(totalSize, re.size)
re = re.copyOf(totalSize)
} else if(totalSize > 0 && buffer.isNotEmpty()) {
Log.d("MyC", "Increase re size.")
buffer += re
if(buffer.size > totalSize) {
re = buffer.copyOf(totalSize)
buffer = buffer.copyOfRange(totalSize, buffer.size)
} else {
re = buffer
buffer = byteArrayOf()
}
} else if(totalSize < 0 && buffer.isNotEmpty()) {
re = buffer
buffer = byteArrayOf()
Log.d("MyC", "clear buffer")
}
return re
return if(totalSize > 0) buffer.pop(totalSize)?:byteArrayOf() else buffer.popAll()
}
}
//fun receiveMessage() = receiveRawMessage().decodeToString()
fun receiveMessage(totalSize: Int) = receiveRawMessage(totalSize).decodeToString()
/**
* 关闭连接
*/
fun closeConnect() = try {
din?.close()
dout?.close()
sc?.close()
sc = null
din = null
dout = null
true
} catch (e: IOException) {
e.printStackTrace()
false
}
din?.close()
dout?.close()
sc?.close()
sc = null
din = null
dout = null
true
} catch (e: IOException) {
e.printStackTrace()
false
}
var progress: Progress? = null

View 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:viewportHeight="1024"
android:viewportWidth="1024">
<path
android:fillColor="@android:color/holo_red_light"
android:pathData="M668 117C833 117 939 250 939 428c0 138-125 291-372 462a97 97 0 0 1-110 0C210 718 85 566 85 428 85 250 191 117 356 117c60 0 100 21 156 68C568 138 608 117 668 117z m0 63c-41 0-70 15-117 55-2 2-14 12-18 15a32 32 0 0 1-42 0c-4-3-16-14-18-15-47-40-76-55-117-55C230 180 149 281 149 427 149 538 263 675 494 835a32 32 0 0 0 37 0C761 675 875 538 875 427c0-145-81-246-207-246z"/>
</vector>

View 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:viewportHeight="1024"
android:viewportWidth="1024">
<path
android:fillColor="@android:color/holo_red_light"
android:pathData="M668 117C833 117 939 250 939 428c0 138-125 291-372 462a97 97 0 0 1-110 0C210 718 85 566 85 428 85 250 191 117 356 117c60 0 100 21 156 68C568 138 608 117 668 117z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="?android:textColorSecondary"
android:pathData="M944 552l-182 331a74 74 0 0 1-65 38h-362a74 74 0 0 1-65-38l-182-331a75 75 0 0 1 0-73l182-331a74 74 0 0 1 65-38h362a74 74 0 0 1 65 38l182 331a75 75 0 0 1 0 73z m-56-31a11 11 0 0 0 0-10l-182-331a11 11 0 0 0-9-5H336a11 11 0 0 0-9 5l-182 331a11 11 0 0 0 0 10l182 331a11 11 0 0 0 9 5h362a11 11 0 0 0 9-5l182-331zM514 683c-94 0-171-76-171-171s76-171 171-171c94 0 171 76 171 171s-76 171-171 171z m0-64c59 0 107-48 107-107s-48-107-107-107-107 48-107 107 48 107 107 107z"/>
</vector>

View File

@@ -79,7 +79,7 @@
android:layout_marginTop="4dp"
android:fontFamily="@font/calibri"
android:gravity="center"
android:text="This is the third-party app for ranobe reading"
android:text="This is the third-party app for manga reading"
android:textColor="#9affffff"
android:textSize="10sp" />

View File

@@ -0,0 +1,53 @@
<?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">
<top.fumiama.copymanga.views.MangaCardView
android:id="@+id/cic"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="@dimen/nav_header_vertical_spacing"
android:layout_marginTop="@dimen/nav_header_vertical_spacing"
android:layout_marginEnd="@dimen/nav_header_vertical_spacing"
android:layout_marginBottom="@dimen/nav_header_vertical_spacing"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="@dimen/global_radius"
app:cardElevation="@dimen/global_card_elevation"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imic"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/sgnic"
layout="@layout/widget_finalmark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</top.fumiama.copymanga.views.MangaCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -6,29 +6,50 @@
android:layout_height="match_parent"
tools:context="top.fumiama.copymanga.ui.home.HomeFragment">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swiperefresh"
<androidx.core.widget.NestedScrollView
android:id="@+id/fhns"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:fillViewport="true">
<top.fumiama.copymanga.views.ScrollRefreshView
android:id="@+id/fhov"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/fhl"
<com.lapism.search.widget.MaterialSearchView
android:id="@+id/fhs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</top.fumiama.copymanga.views.ScrollRefreshView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
app:layout_behavior="com.lapism.search.widget.SearchBehavior">
</com.lapism.search.widget.MaterialSearchView>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<top.fumiama.copymanga.views.ScrollRefreshView
android:id="@+id/fhov"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="@+id/fhl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</top.fumiama.copymanga.views.ScrollRefreshView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />

View File

@@ -0,0 +1,72 @@
<?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:id="@+id/lwc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground">
<include
android:id="@+id/lwi"
layout="@layout/card_book_plain"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/lwl"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/lwl"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="4"
app:layout_constraintStart_toEndOf="@+id/lwi"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginEnd="16dp"
android:textColor="?attr/colorOnSurface"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/ta"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:fontFamily="@font/gotham"
android:textColor="?attr/colorOnSurface"
android:textSize="18sp" />
<TextView
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="10dp" />
</LinearLayout>
<View
android:id="@+id/vl"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginEnd="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -11,4 +11,5 @@
<color name="colorGreen">#BFEA88</color>
<color name="textInputLayout">#ffffff</color>
<color name="colorRed">#F6837A</color>
<color name="searchBarPrimaryColor">#E1E1E1</color>
</resources>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="search_types">
<item>全部</item>
<item>名称</item>
<item>作者</item>
<item>汉化组</item>
</string-array>
</resources>

View File

@@ -7,7 +7,7 @@
<string name="menu_home">主页</string>
<string name="menu_sort">分类</string>
<string name="menu_rank">排行</string>
<string name="app_description">©2021源文雨@CoolApk\n本应用为拷贝漫画的第三方客户端数据均来源于网络作者不对其中所呈现的任何内容负责。</string>
<string name="app_description">©2022源文雨@CoolApk\n本应用为拷贝漫画的第三方客户端数据均来源于网络作者不对其中所呈现的任何内容负责。</string>
<string name="menu_history">浏览历史</string>
<string name="menu_sub">我的订阅</string>
<string name="menu_download">我的下载</string>
@@ -17,6 +17,7 @@
<string name="page_group">漫画下载</string>
<string name="page_topic">专题系列</string>
<string name="check_update">检查更新</string>
<string name="set_search_types">设置搜索类别</string>
<string name="navTextInfo">illust: Hiten(490219)</string>
<string name="navTextInfoInputHint">请设定提示文字内容</string>
@@ -33,6 +34,7 @@
<string name="referUrl">"https://api.copymanga.com"</string>
<string name="recentUpdateApiUrl">https://nnv3api.dmzj1.com/novel/recentUpdate/%1$d.json</string>
<string name="rankApiUrl">https://api.copymanga.com/api/v3/ranks?limit=21&amp;offset=%1$d&amp;date_type=%2$s&amp;platform=3</string>
<string name="searchApiUrl">https://api.copymanga.com/api/v3/search/comic?limit=21&amp;offset=%1$d&amp;q=%2$s&amp;q_type=%3$s&amp;platform=3</string>
<string name="filterApiUrl">https://api.copymanga.com/api/v3/h5/filterIndex/comic/tags?platform=3</string>
<string name="sortApiUrl">https://api.copymanga.com/api/v3/comics?limit=21&amp;offset=%1$d&amp;ordering=%2$s&amp;theme=%3$s&amp;platform=3</string>
<string name="bookInfoApiUrl">https://api.copymanga.com/api/v3/comic2/%1$s?platform=3</string>

View File

@@ -21,4 +21,6 @@
<style name="Widget.MPM.Menu.Dark.CustomBackground">
<item name="android:colorBackground">?attr/colorSurface</item>
</style>
<style name="AlertDialogTheme" parent="Theme.MaterialComponents.Dialog.Alert"/>
</resources>

View File

@@ -1,14 +1,15 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.5.0'
ext.kotlin_version = '1.5.31'
repositories {
google()
jcenter()
mavenCentral()
maven { url 'https://maven.google.com' }
maven { url "https://jitpack.io" }
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.1'
classpath 'com.android.tools.build:gradle:7.0.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.21'

View File

@@ -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-6.8-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip