├── .gitignore
├── .idea
├── .name
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── compiler.xml
├── deploymentTargetDropDown.xml
├── deploymentTargetSelector.xml
├── dictionaries
│ ├── fumiama.xml
│ └── rumia.xml
├── gradle.xml
├── jarRepositories.xml
├── kotlinc.xml
├── migrations.xml
├── misc.xml
└── vcs.xml
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── com.lapism
│ │ └── search-2.4.1.aar
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── top
│ │ └── fumiama
│ │ └── copymanga
│ │ ├── LoginActivity.kt
│ │ ├── MainActivity.kt
│ │ ├── api
│ │ ├── Config.kt
│ │ ├── manga
│ │ │ ├── Book.kt
│ │ │ ├── Downloader.kt
│ │ │ ├── Reader.kt
│ │ │ ├── Shelf.kt
│ │ │ └── Volume.kt
│ │ ├── update
│ │ │ ├── ByteArrayQueue.kt
│ │ │ ├── SimpleKanban.kt
│ │ │ └── Update.kt
│ │ └── user
│ │ │ └── Member.kt
│ │ ├── json
│ │ ├── BookInfoStructure.java
│ │ ├── BookListStructure.java
│ │ ├── BookQueryStructure.java
│ │ ├── Chapter2Return.java
│ │ ├── ChapterStructure.java
│ │ ├── ChapterWithContent.java
│ │ ├── ComandyCapsule.java
│ │ ├── ComandyVersion.java
│ │ ├── ComicStructure.java
│ │ ├── ComicStructureOld.java
│ │ ├── FilterStructure.java
│ │ ├── HistoryBookListStructure.java
│ │ ├── HistoryComicStructure.java
│ │ ├── IndexStructure.java
│ │ ├── InfoBase.java
│ │ ├── InfoStructure.java
│ │ ├── LastBrowseStructure.java
│ │ ├── LoginInfoStructure.java
│ │ ├── NetworkStructure.java
│ │ ├── ResultsBase.java
│ │ ├── ReturnBase.java
│ │ ├── SeriesStructure.java
│ │ ├── ShelfStructure.java
│ │ ├── ThemeStructure.java
│ │ ├── TopicStructure.java
│ │ ├── TypeBookListStructure.java
│ │ ├── TypeBookStructure.java
│ │ ├── UUIDUrlPair.java
│ │ ├── ValueDisplayPair.java
│ │ └── VolumeStructure.java
│ │ ├── lib
│ │ ├── Comancry.kt
│ │ ├── ComancryMethods.kt
│ │ ├── Comandy.kt
│ │ ├── ComandyMethods.kt
│ │ └── template
│ │ │ └── LazyLibrary.kt
│ │ ├── net
│ │ ├── Client.kt
│ │ ├── ComandyGlideModule.kt
│ │ ├── DownloadPool.kt
│ │ ├── DownloadTools.kt
│ │ ├── Proxy.kt
│ │ ├── Resolution.kt
│ │ └── template
│ │ │ ├── AutoDownloadHandler.kt
│ │ │ └── PausableDownloader.kt
│ │ ├── storage
│ │ ├── FileUtils.kt
│ │ ├── PreferenceBoolean.kt
│ │ ├── PreferenceInt.kt
│ │ ├── PreferenceString.kt
│ │ ├── PropertiesTools.kt
│ │ ├── UserPreferenceInt.kt
│ │ └── UserPreferenceString.kt
│ │ ├── strings
│ │ └── Chinese.kt
│ │ ├── ui
│ │ ├── book
│ │ │ ├── BookFragment.kt
│ │ │ └── BookHandler.kt
│ │ ├── cardflow
│ │ │ ├── author
│ │ │ │ └── AuthorFragment.kt
│ │ │ ├── caption
│ │ │ │ └── CaptionFragment.kt
│ │ │ ├── finish
│ │ │ │ └── FinishFragment.kt
│ │ │ ├── history
│ │ │ │ └── HistoryFragment.kt
│ │ │ ├── newest
│ │ │ │ └── NewestFragment.kt
│ │ │ ├── rank
│ │ │ │ └── RankFragment.kt
│ │ │ ├── recommend
│ │ │ │ └── RecFragment.kt
│ │ │ ├── search
│ │ │ │ └── SearchFragment.kt
│ │ │ ├── shelf
│ │ │ │ └── ShelfFragment.kt
│ │ │ ├── sort
│ │ │ │ └── SortFragment.kt
│ │ │ └── topic
│ │ │ │ └── TopicFragment.kt
│ │ ├── comicdl
│ │ │ ├── ComicDlFragment.kt
│ │ │ └── ComicDlHandler.kt
│ │ ├── download
│ │ │ ├── DownloadFragment.kt
│ │ │ └── NewDownloadFragment.kt
│ │ ├── home
│ │ │ ├── HomeFragment.kt
│ │ │ └── HomeHandler.kt
│ │ ├── settings
│ │ │ └── SettingsFragment.kt
│ │ └── vm
│ │ │ ├── PagesManager.kt
│ │ │ ├── VMHandler.kt
│ │ │ └── ViewMangaActivity.kt
│ │ └── view
│ │ ├── AutoHideEditTextPreferenceDialogFragmentCompat.kt
│ │ ├── ChapterToggleButton.kt
│ │ ├── Font.kt
│ │ ├── LazyScrollView.kt
│ │ ├── MangaCardView.kt
│ │ ├── OverScrollView.kt
│ │ ├── ScaleImageView.kt
│ │ ├── ScrollRefreshView.kt
│ │ ├── interaction
│ │ ├── Navigate.kt
│ │ ├── TimeThread.kt
│ │ └── UITools.kt
│ │ ├── operation
│ │ ├── GlideBlurTransformation.kt
│ │ └── GlideHideLottieViewListener.kt
│ │ └── template
│ │ ├── ActivityTemplate.kt
│ │ ├── CardList.kt
│ │ ├── InfoCardLoader.kt
│ │ ├── MangaPagesFragmentTemplate.kt
│ │ ├── NoBackRefreshFragment.kt
│ │ ├── StatusCardFlow.kt
│ │ ├── ThemeCardFlow.kt
│ │ └── TitleActivityTemplate.kt
│ └── res
│ ├── anim
│ ├── slide_in_right.xml
│ ├── slide_in_right_exit.xml
│ ├── slide_out_left.xml
│ └── slide_out_left_exit.xml
│ ├── drawable-anydpi
│ ├── bg_rnd_green.xml
│ ├── buttonshapewhitebg.xml
│ ├── ic_anchor_down.xml
│ ├── ic_author.xml
│ ├── ic_circle.xml
│ ├── ic_data.xml
│ ├── ic_dere.xml
│ ├── ic_email_white_24dp.xml
│ ├── ic_hot.xml
│ ├── ic_image.xml
│ ├── ic_launcher_background.xml
│ ├── ic_launcher_foreground.xml
│ ├── ic_line_more.xml
│ ├── ic_list.xml
│ ├── ic_locate.xml
│ ├── ic_lock_white_24dp.xml
│ ├── ic_menu_del.xml
│ ├── ic_menu_download.xml
│ ├── ic_menu_history.xml
│ ├── ic_menu_home.xml
│ ├── ic_menu_rank.xml
│ ├── ic_menu_sort.xml
│ ├── ic_menu_sub.xml
│ ├── ic_refresh.xml
│ ├── ic_setting_search.xml
│ ├── ic_settings.xml
│ ├── ic_success.xml
│ ├── ic_time.xml
│ ├── mask_blackbottom.xml
│ ├── mask_blacktop.xml
│ ├── rndbg.xml
│ ├── rndbg_checked.xml
│ ├── rndbg_error.xml
│ ├── rndbg_white.xml
│ └── toggle_button.xml
│ ├── drawable-nodpi
│ ├── illust_57793944_20190427_134853.webp
│ ├── img_defmask.webp
│ ├── img_hot.webp
│ ├── img_hot_serial.png
│ ├── img_latest_pub.png
│ ├── img_master_work.webp
│ ├── img_novel_bill.png
│ ├── img_novel_eye.webp
│ ├── kohima.webp
│ └── line_colorful.webp
│ ├── font
│ ├── calibri.ttf
│ ├── gotham.ttf
│ └── nisi.ttf
│ ├── layout
│ ├── activity_login.xml
│ ├── activity_main.xml
│ ├── activity_viewmanga.xml
│ ├── anchor_popular.xml
│ ├── app_bar_main.xml
│ ├── button_tbutton.xml
│ ├── card_book.xml
│ ├── card_book_plain.xml
│ ├── content_main.xml
│ ├── dialog_progress.xml
│ ├── dialog_unzipping.xml
│ ├── div_h.xml
│ ├── fragment_book.xml
│ ├── fragment_dlcomic.xml
│ ├── fragment_download.xml
│ ├── fragment_history.xml
│ ├── fragment_home.xml
│ ├── fragment_newdownload.xml
│ ├── fragment_newest.xml
│ ├── fragment_rank.xml
│ ├── fragment_recommend.xml
│ ├── fragment_search.xml
│ ├── fragment_settings.xml
│ ├── fragment_shelf.xml
│ ├── fragment_sort.xml
│ ├── fragment_statuscardflow.xml
│ ├── fragment_topic.xml
│ ├── line_1bookline.xml
│ ├── line_2bookline.xml
│ ├── line_2chapters.xml
│ ├── line_3bookline.xml
│ ├── line_bookinfo.xml
│ ├── line_bookinfo_text.xml
│ ├── line_booktandb.xml
│ ├── line_caption.xml
│ ├── line_chapter.xml
│ ├── line_choice_list.xml
│ ├── line_finish.xml
│ ├── line_header.xml
│ ├── line_horizonal_empty.xml
│ ├── line_lazybooklines.xml
│ ├── line_rank.xml
│ ├── line_shelf.xml
│ ├── line_sort.xml
│ ├── line_text_info.xml
│ ├── line_word.xml
│ ├── nav_header_main.xml
│ ├── page_imgview.xml
│ ├── page_nested_list.xml
│ ├── page_scrollimgview.xml
│ ├── viewpage_banner.xml
│ ├── viewpage_horizonal.xml
│ ├── widget_downloadbar.xml
│ ├── widget_finalmark.xml
│ ├── widget_infodrawer.xml
│ ├── widget_newmark.xml
│ ├── widget_titlebar.xml
│ └── widget_viewmangainfo.xml
│ ├── menu
│ ├── activity_main_drawer.xml
│ └── main.xml
│ ├── mipmap-anydpi-v26
│ └── ic_launcher.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ ├── navigation
│ └── mobile_navigation.xml
│ ├── raw
│ └── lottie_loading.json
│ ├── values-night
│ └── colors.xml
│ ├── values
│ ├── arrays.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── pref_setting.xml
│ └── provider_paths.xml
├── build.gradle
├── fastlane
└── metadata
│ └── android
│ ├── en-US
│ ├── full_description.txt
│ ├── images
│ │ └── phoneScreenshots
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ ├── 5.png
│ │ │ └── 6.png
│ └── short_description.txt
│ └── zh-CN
│ ├── full_description.txt
│ └── short_description.txt
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | 拷贝漫画
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetDropDown.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetSelector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/dictionaries/fumiama.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | alphae
5 | azurewebsites
6 | comancry
7 | comandy
8 | downloaders
9 | grps
10 | hotmanga
11 | imgs
12 | kohima
13 | libcomancry
14 | libcomandy
15 | lowpan
16 | mangacopy
17 | mangafuna
18 | nisi
19 | pausable
20 | reclass
21 | reilia
22 | systembar
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.idea/dictionaries/rumia.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | copymanga
5 | fileprovider
6 | fumiama
7 | statuscardflow
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /release
3 | /debug
4 | signing.properties
5 |
--------------------------------------------------------------------------------
/app/libs/com.lapism/search-2.4.1.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/libs/com.lapism/search-2.4.1.aar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 | -keep public class * implements com.bumptech.glide.module.GlideModule
23 | -keep class * extends com.bumptech.glide.module.AppGlideModule {
24 | (...);
25 | }
26 | -keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
27 | **[] $VALUES;
28 | public *;
29 | }
30 | -keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder.InternalRewinder$** {
31 | *** rewind();
32 | }
33 |
34 | -assumenosideeffects class android.util.Log {
35 | public static *** d(...);
36 | public static *** e(...);
37 | public static *** i(...);
38 | public static *** v(...);
39 | public static *** println(...);
40 | public static *** w(...);
41 | public static *** wtf(...);
42 | }
43 |
44 | -keep class com.to.aboomy.pager2banner.* {*;}
45 | -keep class androidx.viewpager2.widget.* {*;}
46 |
47 | -dontwarn com.yalantis.ucrop**
48 | -keep class com.yalantis.ucrop** { *; }
49 | -keep interface com.yalantis.ucrop** { *; }
50 |
51 | ##---------------Begin: proguard configuration for Gson ----------
52 | # Gson uses generic type information stored in a class file when working with fields. Proguard
53 | # removes such information by default, so configure it to keep all of it.
54 | -keepattributes Signature
55 |
56 | # For using GSON @Expose annotation
57 | -keepattributes *Annotation*
58 |
59 | # Gson specific classes
60 | -dontwarn sun.misc.**
61 | #-keep class com.google.gson.stream.** { *; }
62 |
63 | # Application classes that will be serialized/deserialized over Gson
64 | -keep class top.fumiama.copymanga.json.*{ *; }
65 |
66 | # Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
67 | # JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
68 | -keep class * extends com.google.gson.TypeAdapter
69 | -keep class * implements com.google.gson.TypeAdapterFactory
70 | -keep class * implements com.google.gson.JsonSerializer
71 | -keep class * implements com.google.gson.JsonDeserializer
72 |
73 | # Prevent R8 from leaving Data object members always null
74 | -keepclassmembers,allowobfuscation class * {
75 | @com.google.gson.annotations.SerializedName ;
76 | }
77 |
78 | ##---------------End: proguard configuration for Gson ----------
79 |
80 | ## JNA Proguard rules
81 | -keep class com.sun.jna.** { *; }
82 | -keep class * implements com.sun.jna.** { *; }
83 | -dontwarn java.awt.Component
84 | -dontwarn java.awt.GraphicsEnvironment
85 | -dontwarn java.awt.HeadlessException
86 | -dontwarn java.awt.Window
87 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
20 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
38 |
41 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/LoginActivity.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga
2 |
3 | import android.os.Bundle
4 | import android.util.Log
5 | import android.view.WindowManager
6 | import android.widget.Toast
7 | import androidx.appcompat.app.AppCompatActivity
8 | import androidx.core.view.WindowCompat
9 | import androidx.lifecycle.lifecycleScope
10 | import kotlinx.android.synthetic.main.activity_login.*
11 | import kotlinx.coroutines.launch
12 | import top.fumiama.copymanga.api.Config
13 | import top.fumiama.dmzj.copymanga.R
14 | import kotlin.random.Random
15 |
16 |
17 | class LoginActivity : AppCompatActivity() {
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(R.layout.activity_login)
21 | val isLogout = !Config.token.value.isNullOrEmpty()
22 | if (isLogout) {
23 | alblogin.setText(R.string.logout)
24 | altusrnm.setText(Config.username.value)
25 | }
26 | alblogin.setOnClickListener {
27 | lifecycleScope.launch {
28 | val salt = Random.nextInt(10000)
29 | val username = altusrnm.text?.toString() ?: run {
30 | Toast.makeText(
31 | this@LoginActivity,
32 | R.string.login_null_username,
33 | Toast.LENGTH_SHORT
34 | ).show()
35 | return@launch
36 | }
37 | val pwd = altpwd.text?.toString() ?: run {
38 | Toast.makeText(this@LoginActivity, R.string.login_null_pwd, Toast.LENGTH_SHORT)
39 | .show()
40 | return@launch
41 | }
42 | if (isLogout) {
43 | MainActivity.member?.logout()
44 | MainActivity.mainWeakReference?.get()?.refreshUserInfo()
45 | Toast.makeText(
46 | this@LoginActivity,
47 | R.string.login_restart_to_apply,
48 | Toast.LENGTH_SHORT
49 | ).show()
50 | finish()
51 | return@launch
52 | }
53 | val l = MainActivity.member?.login(username, pwd, salt)
54 | Log.d("MyLA", "login return code: ${l?.code}")
55 | if (l?.code == 200) {
56 | MainActivity.mainWeakReference?.get()?.refreshUserInfo()
57 | finish()
58 | return@launch
59 | }
60 | Toast.makeText(this@LoginActivity, l?.message, Toast.LENGTH_LONG).show()
61 | }
62 | }
63 | if (Config.general_enable_transparent_system_bar.value) {
64 | WindowCompat.setDecorFitsSystemWindows(window, false)
65 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
66 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
67 | window.statusBarColor = 0
68 | window.navigationBarColor = 0
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/api/update/ByteArrayQueue.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.api.update
2 | //Fumiama 20210601
3 | //ByteArrayQueue.kt
4 | //FIFO队列
5 | class ByteArrayQueue {
6 | private var elements = byteArrayOf()
7 | val size get() = elements.size
8 | fun append(items: ByteArray) {
9 | elements += items
10 | }
11 | fun pop(num: Int = 1): ByteArray? {
12 | return if(num <= elements.size) {
13 | val re = elements.copyOfRange(0, num)
14 | elements = elements.copyOfRange(num, elements.size)
15 | re
16 | } else null
17 | }
18 | fun clear() {
19 | elements = byteArrayOf()
20 | }
21 | fun popAll(): ByteArray {
22 | val re = elements
23 | clear()
24 | return re
25 | }
26 | operator fun plusAssign(items: ByteArray) = append(items)
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/api/update/SimpleKanban.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.api.update
2 |
3 | import android.util.Log
4 | import top.fumiama.copymanga.net.Client
5 |
6 | class SimpleKanban(private val client: Client, private val pwd: String) { //must run in thread
7 | private val raw: ByteArray?
8 | get() {
9 | var times = 3
10 | var re: ByteArray
11 | var firstReceived: ByteArray
12 | do {
13 | re = byteArrayOf()
14 | if(client.initConnect()) {
15 | client.sendMessage("${pwd}catquit")
16 | client.receiveRawMessage(33) //Welcome to simple kanban server.
17 | try {
18 | firstReceived = client.receiveRawMessage(4) //le
19 | val length = convert2Int(firstReceived)
20 | Log.d("MySK", "Msg len: $length")
21 | if(firstReceived.size > 4) re += firstReceived.copyOfRange(4, firstReceived.size)
22 | re += client.receiveRawMessage(length - re.size, setProgress = true)
23 | break
24 | } catch (e: Exception) {
25 | e.printStackTrace()
26 | }
27 | client.closeConnect()
28 | }
29 | } while (times-- > 0)
30 | return if(re.isEmpty()) null else re
31 | }
32 |
33 | private fun convert2Int(buffer: ByteArray) =
34 | (buffer[3].toInt() and 0xff shl 24) or
35 | (buffer[2].toInt() and 0xff shl 16) or
36 | (buffer[1].toInt() and 0xff shl 8) or
37 | (buffer[0].toInt() and 0xff)
38 |
39 | suspend fun fetchRaw(doOnLoadFailure: suspend ()->Unit = {
40 | Log.d("MySD", "Fetch dict failed")
41 | }, doOnLoadSuccess: suspend (data: ByteArray)->Unit = {
42 | Log.d("MySD", "Fetch dict success")
43 | }) {
44 | raw?.apply {
45 | doOnLoadSuccess(this)
46 | }?:doOnLoadFailure()
47 | }
48 |
49 | operator fun get(version: Int): String =
50 | if(client.initConnect()) {
51 | client.sendMessage("${pwd}get${version}quit")
52 | client.receiveRawMessage(36) //Welcome to simple kanban server. get
53 | val r = try {
54 | val firstRecv = client.receiveRawMessage(4)
55 | if(firstRecv.decodeToString() == "null") "null"
56 | else {
57 | val length = convert2Int(firstRecv)
58 | Log.d("MySK", "Msg len: $length")
59 | var re = byteArrayOf()
60 | if(firstRecv.size > 4) re += firstRecv.copyOfRange(4, firstRecv.size)
61 | re += client.receiveRawMessage(length - re.size)
62 | if(re.isNotEmpty()) re.decodeToString() else "null"
63 | }
64 | } catch (e: Exception){
65 | e.printStackTrace()
66 | "null"
67 | }
68 | client.closeConnect()
69 | r
70 | } else "null"
71 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/BookInfoStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | import java.util.HashMap;
4 |
5 | public class BookInfoStructure extends ReturnBase {
6 | public Results results;
7 | public static class Results extends ResultsBase{
8 | public ComicStructure comic;
9 | public HashMap groups;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/BookListStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class BookListStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results {
6 | public int total;
7 | public ComicStructure[] list;
8 | public int limit;
9 | public int offset;
10 | }
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/BookQueryStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class BookQueryStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results{
6 | public Browse browse;
7 | public int collect;
8 | public boolean is_lock;
9 | public boolean is_login;
10 | public boolean is_mobile_bind;
11 | public boolean is_vip;
12 | public static class Browse {
13 | public String comic_uuid;
14 | public String comic_id;
15 | public String path_word;
16 | public String chapter_uuid;
17 | public String chapter_id;
18 | public String chapter_name;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/Chapter2Return.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class Chapter2Return extends ReturnBase {
4 | public Results results;
5 | public static class Results extends ResultsBase{
6 | public ComicStructure comic;
7 | public ChapterWithContent chapter;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ChapterStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ChapterStructure {
4 | public int index;
5 | public String uuid;
6 | public int count;
7 | public int size;
8 | public String name;
9 | public String comic_id;
10 | public String comic_path_word;
11 | public String group_id;
12 | public String group_path_word;
13 | public int type;
14 | public int img_type;
15 | public String datetime_created;
16 | public String prev;
17 | public String next;
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ChapterWithContent.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ChapterWithContent extends ChapterStructure {
4 | public UUIDUrlPair[] contents;
5 | public int[] words;
6 | public Boolean is_long;
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ComandyCapsule.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | import java.util.HashMap;
4 |
5 | public class ComandyCapsule {
6 | public int code;
7 | public String method;
8 | public String url;
9 | public HashMap headers;
10 | public String data;
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ComandyVersion.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ComandyVersion {
4 | public String body;
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ComicStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ComicStructure {
4 | public String uuid;
5 | public String name;
6 | //public String alias;
7 | public int img_type;
8 | public ValueDisplayPair region;
9 | public ValueDisplayPair status;
10 | public ValueDisplayPair reclass; // identify hotmanga
11 | public ThemeStructure[] theme;
12 | public String path_word;
13 | public ThemeStructure[] author;
14 | public String brief;
15 | public String datetime_updated;
16 | public String cover;
17 | public int popular;
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ComicStructureOld.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ComicStructureOld {
4 | public String name;
5 | public Chapters[] chapters;
6 | public static class Chapters{
7 | public String name;
8 | public String url;
9 | }
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/FilterStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class FilterStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results{
6 | public ThemeStructure[] theme;
7 | public ThemeStructure[] top;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/HistoryBookListStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class HistoryBookListStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results {
6 | public ListItem[] list;
7 | public int total;
8 | public int limit;
9 | public int offset;
10 | }
11 | public static class ListItem {
12 | public String last_chapter_id;
13 | public String last_chapter_name;
14 | public HistoryComicStructure comic;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/HistoryComicStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class HistoryComicStructure {
4 | public String uuid;
5 | public boolean b_display;
6 | public String name;
7 | public String path_word;
8 | public ThemeStructure[] author;
9 | public ThemeStructure[] theme;
10 | public String cover;
11 | public int status;
12 | public int popular;
13 | public String datetime_updated;
14 | public String last_chapter_id;
15 | public String last_chapter_name;
16 | public Browse browse;
17 |
18 | public static class Browse {
19 | public String comic_uuid;
20 | public String path_word;
21 | public String chapter_uuid;
22 | public String chapter_name;
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/IndexStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class IndexStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results{
6 | public Banners[] banners;
7 | public Topics topics;
8 | public RecComics recComics;
9 | // copymanga
10 | public RankComics rankDayComics;
11 | public RankComics rankWeekComics;
12 | public RankComics rankMonthComics;
13 | public ComicWrap[] hotComics;
14 | public ComicWrap[] newComics;
15 | public FinishComics finishComics;
16 | // hotmanga
17 | public RankComics rankWeeklyFreeComics;
18 | public WeeklyComics updateWeeklyFreeComics;
19 |
20 | public static class Banners{
21 | public int type;
22 | public String cover;
23 | public String brief;
24 | public String out_uuid;
25 | public ComicStructure comic;
26 | }
27 | public static class Topics extends InfoBase{
28 | public List[] list;
29 |
30 | public static class List{
31 | public String title;
32 | public SeriesStructure series;
33 | public String journal;
34 | public String cover;
35 | public String period;
36 | public int type;
37 | public String brief;
38 | public String path_word;
39 | public String datetime_created;
40 | }
41 | }
42 | public static class RecComics extends InfoBase{
43 | public List[] list;
44 |
45 | public static class List{
46 | public int type;
47 | public ComicStructure comic;
48 | }
49 | }
50 | public static class RankComics extends InfoBase{
51 | public InfoStructure[] list;
52 | }
53 | public static class ComicWrap{
54 | public ComicStructure comic;
55 | }
56 | public static class FinishComics extends InfoBase{
57 | public ComicStructure[] list;
58 | public String path_word;
59 | public String name;
60 | public String type;
61 | }
62 | public static class WeeklyComics extends InfoBase {
63 | public TypeBookStructure[] list;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/InfoBase.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class InfoBase {
4 | public int total;
5 | public int limit;
6 | public int offset;
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/InfoStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class InfoStructure {
4 | public int sort;
5 | public int sort_last;
6 | public int rise_sort;
7 | public int rise_num;
8 | public int date_type;
9 | public int popular;
10 | public ComicStructure comic;
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/LastBrowseStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class LastBrowseStructure {
4 | public String last_browse_id;
5 | public String last_browse_name;
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/LoginInfoStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class LoginInfoStructure extends ReturnBase{
4 | public Results results;
5 | public static class Results {
6 | public String token;
7 | public String user_id;
8 | public String username;
9 | public String nickname;
10 | public String avatar;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/NetworkStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class NetworkStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results {
6 | public String[] share;
7 | public String[][] api;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ResultsBase.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ResultsBase {
4 | public Boolean is_lock;
5 | public Boolean is_login;
6 | public Boolean is_mobile_bind;
7 | public Boolean is_vip;
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ReturnBase.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ReturnBase {
4 | public int code;
5 | public String message;
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/SeriesStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class SeriesStructure extends ThemeStructure {
4 | public String color;
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ShelfStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ShelfStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results extends InfoBase {
6 | public List[] list;
7 | public static class List {
8 | public int uuid;
9 | public boolean b_folder;
10 | public LastBrowseStructure last_browse;
11 | public HistoryComicStructure comic;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ThemeStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ThemeStructure {
4 | public String name;
5 | public String path_word;
6 | public int count;
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/TopicStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class TopicStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results {
6 | public String title;
7 | public String period;
8 | public String intro;
9 | public int type;
10 | public String datetime_created;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/TypeBookListStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class TypeBookListStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results extends InfoBase {
6 | public TypeBookStructure[] list;
7 | }
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/TypeBookStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class TypeBookStructure {
4 | public int type;
5 | public String name;
6 | public String datetime_created;
7 | public ComicStructure comic;
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/UUIDUrlPair.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class UUIDUrlPair {
4 | public String uuid;
5 | public String url;
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/ValueDisplayPair.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class ValueDisplayPair {
4 | public int value;
5 | public String display;
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/json/VolumeStructure.java:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.json;
2 |
3 | public class VolumeStructure extends ReturnBase {
4 | public Results results;
5 | public static class Results extends InfoBase{
6 | public ChapterStructure[] list;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/lib/Comancry.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.lib
2 |
3 | import android.util.Log
4 | import com.sun.jna.Memory
5 | import top.fumiama.copymanga.api.Config
6 | import top.fumiama.copymanga.lib.template.LazyLibrary
7 |
8 | class Comancry: LazyLibrary(
9 | ComancryMethods::class.java, "libcomancry.so", "API代理",
10 | Config.net_use_api_proxy, Config.comancry_version
11 | ) {
12 | private val enabled: Boolean
13 | get() {
14 | if (isInInit.get()) {
15 | Log.d("MyComancry", "$name block enabled for isInInit")
16 | return false
17 | }
18 | return isInUse.value
19 | }
20 | val status: String get() = if(enabled) {
21 | if (isInUse.value) "生效(手动)" else "生效(自动)"
22 | } else "无效"
23 |
24 | suspend fun decrypt(sd: String, data: ByteArray): String? {
25 | // 将 ByteArray 转换为 char*
26 | val nativeMemory = Memory(data.size.toLong())
27 | nativeMemory.write(0, data, 0, data.size) // 将 byteArray 写入内存
28 | Log.d("MyComancry", "get data len ${data.size}")
29 | return getInstance()?.decrypt(sd, nativeMemory, data.size)
30 | }
31 | companion object {
32 | val instance = Comancry()
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/lib/ComancryMethods.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.lib
2 |
3 | import com.sun.jna.Library
4 | import com.sun.jna.Pointer
5 |
6 | interface ComancryMethods : Library {
7 | fun decrypt(sd: String, data: Pointer, len: Int): String?
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/lib/Comandy.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.lib
2 |
3 | import android.util.Log
4 | import top.fumiama.copymanga.api.Config
5 | import top.fumiama.copymanga.lib.template.LazyLibrary
6 | import top.fumiama.copymanga.net.DownloadTools
7 |
8 | class Comandy: LazyLibrary(
9 | ComandyMethods::class.java, "libcomandy.so", "网络增强",
10 | Config.net_use_comandy, Config.comandy_version
11 | ) {
12 | private var mEnabled: Boolean? = null
13 | val enabled: Boolean
14 | get() {
15 | if (isInInit.get()) {
16 | Log.d("MyComandy", "$name block enabled for isInInit")
17 | return false
18 | }
19 | if (mEnabled != true && DownloadTools.failTimes.get() >= 16) {
20 | mEnabled = true
21 | return true
22 | }
23 | if (mEnabled != null) return mEnabled!!
24 | val v = isInUse.value
25 | mEnabled = v
26 | return v
27 | }
28 | val status: String get() = if(enabled) {
29 | if (isInUse.value) "生效(手动)" else "生效(自动)"
30 | } else "无效"
31 |
32 | companion object {
33 | val instance = Comandy()
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/lib/ComandyMethods.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.lib
2 |
3 | import com.sun.jna.Library
4 |
5 | interface ComandyMethods : Library {
6 | // fun add_dns(para: String?, is_ipv6: Int): String?
7 |
8 | fun request(para: String): String?
9 |
10 | fun progress(para: String): Int
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/net/Proxy.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.net
2 |
3 | import android.util.Log
4 | import kotlinx.coroutines.Dispatchers
5 | import kotlinx.coroutines.withContext
6 | import top.fumiama.copymanga.MainActivity
7 | import top.fumiama.copymanga.api.Config.proxy_key
8 | import top.fumiama.copymanga.lib.Comancry
9 | import java.net.URLEncoder
10 | import java.nio.charset.Charset
11 |
12 | class Proxy(id: Int, private val apiRegex: Regex) {
13 | private val code get() = proxy_key.value
14 | private val proxyApiUrl = MainActivity.mainWeakReference?.get()?.getString(id)
15 | private val sourceDir = MainActivity.mainWeakReference?.get()?.applicationInfo?.sourceDir?.substringBeforeLast("/")?:""
16 | private val enabled: Boolean get() = code.isNotEmpty() and sourceDir.isNotEmpty() and !proxyApiUrl.isNullOrEmpty()
17 |
18 | fun wrap(u: String): String {
19 | if(!apiRegex.containsMatchIn(u)) {
20 | Log.d("MyP", "[N] wrap: $u")
21 | return u
22 | }
23 | if(enabled) {
24 | val wu = proxyApiUrl?.format(code, URLEncoder.encode(u, Charset.defaultCharset().name()))
25 | ?:u
26 | Log.d("MyP", "[M] wrap: $wu")
27 | return wu
28 | }
29 | Log.d("MyP", "[C] wrap: $u")
30 | //return proxyApiUrl?.format(URLEncoder.encode(u, Charset.defaultCharset().name()))?:u
31 | return u
32 | }
33 |
34 | suspend fun comancry(u: String, use: suspend (String) -> ByteArray?): ByteArray? {
35 | if(!apiRegex.containsMatchIn(u)) {
36 | Log.d("MyP", "[N] comancry: $u")
37 | return use(u)
38 | }
39 | if(enabled) {
40 | val wu = proxyApiUrl?.format(code,
41 | withContext(Dispatchers.IO) {
42 | URLEncoder.encode(u, Charset.defaultCharset().name())
43 | })
44 | ?:u
45 | Log.d("MyP", "[M] comancry: $wu, sd: $sourceDir")
46 | return use(wu)?.let { data ->
47 | Log.d("MyP", "[M] comancry: decrypt ${data.size} bytes data")
48 | Comancry.instance.decrypt(sourceDir, data)?.encodeToByteArray()
49 | }
50 | }
51 | Log.d("MyP", "[C] comancry: $u")
52 | return use(u)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/net/Resolution.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.net
2 |
3 | import top.fumiama.copymanga.api.Config
4 |
5 | class Resolution(private val original: Regex) {
6 | private val imageResolution: Int
7 | get() = Config.net_img_resolution.value.let {
8 | if (it.isNotEmpty()) it.toInt() else 1500
9 | }
10 | fun wrap(u: String) : String = u.replace(original, "c${imageResolution}x.")
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/net/template/PausableDownloader.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.net.template
2 |
3 | import android.util.Log
4 | import kotlinx.coroutines.Dispatchers
5 | import kotlinx.coroutines.delay
6 | import kotlinx.coroutines.withContext
7 | import top.fumiama.copymanga.api.Config
8 | import top.fumiama.copymanga.net.DownloadTools
9 | import kotlin.random.Random
10 |
11 | class PausableDownloader(private val url: String, private val waitMilliseconds: Long = 0, private val isApi: Boolean = true, private val whenFinish: (suspend (result: ByteArray)->Unit)? = null) {
12 | var exit = false
13 | suspend fun run(): Boolean = withContext(Dispatchers.IO) {
14 | var c = 0
15 | while (!exit && c++ < 3) {
16 | try {
17 | val data = (if (isApi) Config.apiProxy?.comancry(url) {
18 | DownloadTools.getHttpContent(it, Config.referer)
19 | } else null)?:DownloadTools.getHttpContent(url, Config.referer)
20 | whenFinish?.let { it(data) }
21 | return@withContext true
22 | } catch (e: Exception) {
23 | e.printStackTrace()
24 | if (waitMilliseconds > 0) delay(200+Random.nextLong(waitMilliseconds))
25 | }
26 | }
27 | Log.d("MyPD", "found exit = $exit")
28 | return@withContext false
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/storage/FileUtils.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.storage
2 |
3 | import android.content.Context
4 | import android.net.Uri
5 | import androidx.activity.result.ActivityResultLauncher
6 | import androidx.activity.result.contract.ActivityResultContracts
7 | import androidx.fragment.app.Fragment
8 | import java.io.BufferedOutputStream
9 | import java.io.File
10 | import java.io.FileInputStream
11 | import java.util.zip.ZipEntry
12 | import java.util.zip.ZipOutputStream
13 |
14 | object FileUtils {
15 | fun recursiveRemove(f: File) {
16 | if (f.isDirectory) f.listFiles()?.let {
17 | for (i in it)
18 | if (i.isDirectory) recursiveRemove(i)
19 | else i.delete()
20 | }
21 | f.delete()
22 | }
23 | fun sizeOf(f: File): Long{
24 | var size = 0L
25 | if (f.isDirectory) f.listFiles()?.apply {
26 | for (i in this)
27 | size += if (i.isDirectory) sizeOf(i) else i.length()
28 | }
29 | return size
30 | }
31 | fun registerZipExportLauncher(
32 | fragment: Fragment,
33 | callback: (Uri?) -> Unit
34 | ): ActivityResultLauncher {
35 | return fragment.registerForActivityResult(ActivityResultContracts.CreateDocument("application/zip"), callback)
36 | }
37 | fun compressToUserFile(
38 | context: Context,
39 | sourceDir: File,
40 | targetUri: Uri,
41 | setProgress: (Int) -> Unit = {}
42 | ) {
43 | val allFiles = collectAllFiles(sourceDir)
44 | val totalFiles = allFiles.size
45 | var filesDone = 0
46 |
47 | setProgress(0) // 确保初始进度为0%
48 |
49 | context.contentResolver.openOutputStream(targetUri)?.use { outputStream ->
50 | ZipOutputStream(BufferedOutputStream(outputStream)).use { zipOut ->
51 | for (file in allFiles) {
52 | val relativePath = sourceDir.toURI().relativize(file.toURI()).path
53 | val entry = ZipEntry(relativePath)
54 | zipOut.putNextEntry(entry)
55 |
56 | FileInputStream(file).use { input ->
57 | input.copyTo(zipOut)
58 | }
59 |
60 | zipOut.closeEntry()
61 | filesDone++
62 | val progress = (filesDone * 100 / totalFiles).coerceIn(0, 100)
63 | setProgress(progress)
64 | }
65 | }
66 | }
67 |
68 | setProgress(100) // 确保最终进度为100%
69 | }
70 |
71 | private fun collectAllFiles(root: File): List {
72 | val files = mutableListOf()
73 | root.walkTopDown().forEach {
74 | if (it.isFile) files.add(it)
75 | }
76 | return files
77 | }
78 |
79 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/storage/PreferenceBoolean.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.storage
2 |
3 | import android.util.Log
4 | import androidx.preference.PreferenceManager
5 | import top.fumiama.copymanga.MainActivity
6 |
7 | data class PreferenceBoolean(private val key: String, private var default: Boolean) {
8 | val value: Boolean
9 | get() {
10 | MainActivity.mainWeakReference?.get()?.let {
11 | PreferenceManager.getDefaultSharedPreferences(it).apply {
12 | getBoolean(key, default).let { v ->
13 | Log.d("MyPB", "get key $key value $v")
14 | return v
15 | }
16 | }
17 | }
18 | return default
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/storage/PreferenceInt.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.storage
2 |
3 | import android.util.Log
4 | import androidx.preference.PreferenceManager
5 | import top.fumiama.copymanga.MainActivity
6 |
7 | data class PreferenceInt(private val key: String, private var default: Int) {
8 | val value: Int
9 | get() {
10 | MainActivity.mainWeakReference?.get()?.let {
11 | PreferenceManager.getDefaultSharedPreferences(it).apply {
12 | getInt(key, default).let { v ->
13 | Log.d("MyPI", "get key $key value $v")
14 | return v
15 | }
16 | }
17 | }
18 | return default
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/storage/PreferenceString.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.storage
2 |
3 | import android.util.Log
4 | import androidx.preference.PreferenceManager
5 | import top.fumiama.copymanga.MainActivity
6 |
7 | data class PreferenceString(private val key: String, private var default: String?, private val defaultID: Int) {
8 | constructor(key: Int, default: String?, defaultID: Int): this(
9 | MainActivity.mainWeakReference?.get()?.getString(key) ?:"", default, defaultID)
10 | constructor(key: String, default: Int): this(key, null, default)
11 | constructor(key: Int): this(key, "", 0)
12 |
13 | private val defaultField: String
14 | get() {
15 | if (default != null) return default!!
16 | MainActivity.mainWeakReference?.get()?.let {
17 | default = it.getString(defaultID)
18 | }
19 | return default?:""
20 | }
21 | val value: String
22 | get() {
23 | MainActivity.mainWeakReference?.get()?.let {
24 | PreferenceManager.getDefaultSharedPreferences(it).apply {
25 | getString(key, null)?.let { v ->
26 | if (v.isNotEmpty()) {
27 | Log.d("MyPS", "get key $key value $v")
28 | return v
29 | }
30 | }
31 | }
32 | }
33 | Log.d("MyPS", "get default key $key value $defaultField")
34 | return defaultField
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/storage/PropertiesTools.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.storage
2 | //PropertiesTools.kt
3 | //created by fumiama 20200724
4 | import android.util.Log
5 | import java.io.File
6 | import java.io.InputStream
7 | import java.util.*
8 |
9 | class PropertiesTools(private val f: File):Properties() {
10 | private var cache = hashMapOf()
11 |
12 | init {
13 | if(!f.exists()) {
14 | if(f.parentFile?.exists() != true) f.parentFile?.mkdirs()
15 | if(f.parentFile?.canWrite() != true) f.parentFile?.setWritable(true)
16 | createNew(f)
17 | } else if(f.isDirectory) {
18 | if(f.parentFile?.canWrite() != true) f.parentFile?.setWritable(true)
19 | f.delete()
20 | createNew(f)
21 | }
22 | if(f.parentFile?.canWrite() != true) f.parentFile?.setWritable(true)
23 | if(f.parentFile?.canRead() != true) f.parentFile?.setReadable(true)
24 | }
25 |
26 | private fun createNew(f: File) {
27 | f.createNewFile()
28 | f.outputStream().use { o ->
29 | this.storeToXML(o, "store")
30 | }
31 | Log.d("MyPT", "Generate new prop.")
32 | }
33 |
34 | private fun loadFromXml(`in`: InputStream?): PropertiesTools {
35 | this.loadFromXML(`in`)
36 | return this
37 | }
38 |
39 | private fun setProp(key: String?, value: String?): PropertiesTools {
40 | this.setProperty(key, value)
41 | return this
42 | }
43 |
44 | operator fun get(key: String): String{
45 | return if(cache.containsKey(key)) cache[key]?:"null"
46 | else {
47 | f.inputStream().use { i ->
48 | val re = this.loadFromXml(i).getProperty(key)?:"null"
49 | Log.d("MyPT", "Read $key = $re")
50 | cache[key] = re
51 | re
52 | }
53 | }
54 | }
55 |
56 | operator fun set(key: String, value: String) {
57 | cache[key] = value
58 | f.outputStream().use { o ->
59 | this.setProp(key, value).storeToXML(o, "store")
60 | }
61 | Log.d("MyPT", "Set $key = $value")
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/storage/UserPreferenceInt.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.storage
2 |
3 | import android.util.Log
4 | import androidx.appcompat.app.AppCompatActivity.MODE_PRIVATE
5 | import androidx.core.content.edit
6 | import top.fumiama.copymanga.MainActivity
7 |
8 | data class UserPreferenceInt(private val key: String, private var default: Int) {
9 | var value: Int? = null
10 | get() {
11 | field?.let {
12 | Log.d("MyUPI", "get cached key $key value $it")
13 | return it
14 | }
15 | MainActivity.mainWeakReference?.get()?.let {
16 | it.getPreferences(MODE_PRIVATE).apply {
17 | getInt(key, default).let { v ->
18 | field = v
19 | Log.d("MyUPI", "get new key $key value $v")
20 | return v
21 | }
22 | }
23 | }
24 | Log.d("MyUPI", "get default key $key value $default")
25 | return default
26 | }
27 | set(value) {
28 | if (value == null) {
29 | Log.d("MyUPI", "remove key $key")
30 | MainActivity.mainWeakReference?.get()?.let {
31 | it.getPreferences(MODE_PRIVATE).apply {
32 | edit(commit = true) { remove(key) }
33 | }
34 | }
35 | field = default
36 | return
37 | }
38 | field = value
39 | Log.d("MyUPI", "set key $key value $value")
40 | MainActivity.mainWeakReference?.get()?.let {
41 | it.getPreferences(MODE_PRIVATE).apply {
42 | edit(commit = true) { putInt(key, value) }
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/storage/UserPreferenceString.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.storage
2 |
3 | import android.util.Log
4 | import androidx.appcompat.app.AppCompatActivity.MODE_PRIVATE
5 | import androidx.core.content.edit
6 | import top.fumiama.copymanga.MainActivity
7 |
8 | data class UserPreferenceString(private val key: String, private var default: String?, private val defaultID: Int?) {
9 | constructor(key: String): this(key, "", 0)
10 | constructor(key: String, default: Int): this(key, null, default)
11 | constructor(key: String, default: String): this(key, default, 0)
12 | private val defaultField: String?
13 | get() {
14 | default?.let { return it }
15 | defaultID?.let { id ->
16 | MainActivity.mainWeakReference?.get()?.let {
17 | default = it.getString(id)
18 | }
19 | }
20 | return default
21 | }
22 | var value: String? = null
23 | get() {
24 | field?.let {
25 | Log.d("MyUPS", "get cached key $key value $it")
26 | return it
27 | }
28 | MainActivity.mainWeakReference?.get()?.let {
29 | it.getPreferences(MODE_PRIVATE).apply {
30 | getString(key, null)?.let { v ->
31 | if (v.isNotEmpty()) {
32 | field = v
33 | Log.d("MyUPS", "get new key $key value $v")
34 | return v
35 | }
36 | }
37 | }
38 | }
39 | field = defaultField
40 | Log.d("MyUPS", "get default key $key value $field")
41 | return field
42 | }
43 | set(value) {
44 | if (value == null) {
45 | Log.d("MyUPS", "get remove key $key")
46 | MainActivity.mainWeakReference?.get()?.let {
47 | it.getPreferences(MODE_PRIVATE).apply {
48 | edit(commit = true) { remove(key) }
49 | }
50 | }
51 | field = defaultField
52 | return
53 | }
54 | field = value
55 | Log.d("MyUPS", "set key $key value $value")
56 | MainActivity.mainWeakReference?.get()?.let {
57 | it.getPreferences(MODE_PRIVATE).apply {
58 | edit(commit = true) { putString(key, value) }
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/strings/Chinese.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.strings
2 |
3 | object Chinese {
4 | /**
5 | * 如果输入字符串中已包含汉字,直接返回。
6 | * 否则尝试以 UTF8 重新解码。
7 | */
8 | fun fixEncodingIfNeeded(input: String): String {
9 | // 如果本身包含汉字,直接返回
10 | if (containsChinese(input)) {
11 | return input
12 | }
13 |
14 | return try {
15 | val decoded = input.toByteArray(Charsets.ISO_8859_1).decodeToString()
16 |
17 | // 检测解码后的是否包含汉字
18 | if (containsChinese(decoded)) {
19 | decoded
20 | } else {
21 | input // 解码后也没有汉字,说明可能不是编码问题
22 | }
23 | } catch (e: Exception) {
24 | input
25 | }
26 | }
27 |
28 | /**
29 | * 简单检测字符串是否包含常见 CJK(中日韩)汉字。
30 | */
31 | fun containsChinese(text: String): Boolean {
32 | val regex = Regex("[\u4E00-\u9FFF]")
33 | return regex.containsMatchIn(text)
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/cardflow/author/AuthorFragment.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.cardflow.author
2 |
3 | import top.fumiama.copymanga.view.template.ThemeCardFlow
4 | import top.fumiama.dmzj.copymanga.R
5 |
6 | @ExperimentalStdlibApi
7 | class AuthorFragment : ThemeCardFlow(R.string.authorApiUrl, R.id.action_nav_author_to_nav_book)
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/cardflow/caption/CaptionFragment.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.cardflow.caption
2 |
3 | import top.fumiama.copymanga.view.template.ThemeCardFlow
4 | import top.fumiama.dmzj.copymanga.R
5 |
6 | @ExperimentalStdlibApi
7 | class CaptionFragment : ThemeCardFlow(R.string.captionApiUrl, R.id.action_nav_caption_to_nav_book)
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/cardflow/finish/FinishFragment.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.cardflow.finish
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import top.fumiama.copymanga.view.template.StatusCardFlow
6 | import top.fumiama.dmzj.copymanga.R
7 | import kotlinx.android.synthetic.main.line_finish.*
8 |
9 | @ExperimentalStdlibApi
10 | class FinishFragment : StatusCardFlow(
11 | R.string.finishApiUrl, R.id.action_nav_finish_to_nav_book, R.layout.fragment_statuscardflow) {
12 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
13 | super.onViewCreated(view, savedInstanceState)
14 | lineUpdate = line_finish_time
15 | lineHot = line_finish_pop
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/cardflow/history/HistoryFragment.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.cardflow.history
2 |
3 | import android.os.Bundle
4 | import android.widget.Toast
5 | import androidx.navigation.fragment.findNavController
6 | import top.fumiama.copymanga.MainActivity
7 | import top.fumiama.copymanga.view.template.InfoCardLoader
8 | import top.fumiama.copymanga.api.Config
9 | import top.fumiama.dmzj.copymanga.R
10 |
11 | @OptIn(ExperimentalStdlibApi::class)
12 | class HistoryFragment : InfoCardLoader(R.layout.fragment_history, R.id.action_nav_history_to_nav_book, isHistoryBook = true) {
13 | override fun getApiUrl() =
14 | getString(R.string.historyApiUrl).format(Config.myHostApiUrl.random(), page * 21, Config.platform.value)
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | if (MainActivity.member?.hasLogin != true) {
18 | Toast.makeText(context, R.string.noLogin, Toast.LENGTH_SHORT).show()
19 | findNavController().popBackStack()
20 | }
21 | super.onCreate(savedInstanceState)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/cardflow/newest/NewestFragment.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.cardflow.newest
2 |
3 | import top.fumiama.copymanga.view.template.InfoCardLoader
4 | import top.fumiama.copymanga.api.Config
5 | import top.fumiama.dmzj.copymanga.R
6 |
7 | @ExperimentalStdlibApi
8 | class NewestFragment : InfoCardLoader(R.layout.fragment_newest, R.id.action_nav_newest_to_nav_book, true) {
9 | override fun getApiUrl() =
10 | getString(R.string.newestApiUrl).format(Config.myHostApiUrl.random(), page * 21, Config.platform.value)
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/cardflow/recommend/RecFragment.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.cardflow.recommend
2 |
3 | import top.fumiama.copymanga.view.template.InfoCardLoader
4 | import top.fumiama.copymanga.api.Config
5 | import top.fumiama.dmzj.copymanga.R
6 |
7 | @ExperimentalStdlibApi
8 | class RecFragment : InfoCardLoader(R.layout.fragment_recommend, R.id.action_nav_recommend_to_nav_book, true) {
9 | override fun getApiUrl() =
10 | getString(R.string.recommendApiUrl).format(Config.myHostApiUrl.random(), page * 21, Config.platform.value)
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/cardflow/search/SearchFragment.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.cardflow.search
2 |
3 | import android.os.Bundle
4 | import android.util.Log
5 | import top.fumiama.copymanga.view.template.InfoCardLoader
6 | import top.fumiama.copymanga.api.Config
7 | import top.fumiama.dmzj.copymanga.R
8 | import java.net.URLEncoder
9 | import java.nio.charset.Charset
10 |
11 | @ExperimentalStdlibApi
12 | class SearchFragment : InfoCardLoader(R.layout.fragment_search, R.id.action_nav_search_to_nav_book) {
13 | private var query: String? = null
14 | private var type: String? = null
15 | override fun getApiUrl() =
16 | getString(R.string.searchApiUrl).format(Config.myHostApiUrl.random(), page * 21, query, type, Config.platform.value)
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | if (isFirstInflate) {
21 | query = arguments?.getCharSequence("query")?.toString()?.let { q -> URLEncoder.encode(q, Charset.defaultCharset().name()) }
22 | type = arguments?.getString("type")
23 | Log.d("MySF", "get query=$query, type=$type")
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/cardflow/topic/TopicFragment.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.cardflow.topic
2 |
3 | import android.os.Bundle
4 | import androidx.lifecycle.lifecycleScope
5 | import com.google.gson.Gson
6 | import kotlinx.android.synthetic.main.app_bar_main.*
7 | import kotlinx.android.synthetic.main.fragment_topic.*
8 | import kotlinx.coroutines.Dispatchers
9 | import kotlinx.coroutines.launch
10 | import kotlinx.coroutines.withContext
11 | import top.fumiama.copymanga.json.TopicStructure
12 | import top.fumiama.copymanga.net.template.PausableDownloader
13 | import top.fumiama.copymanga.view.template.InfoCardLoader
14 | import top.fumiama.copymanga.api.Config
15 | import top.fumiama.dmzj.copymanga.R
16 |
17 | @ExperimentalStdlibApi
18 | class TopicFragment : InfoCardLoader(R.layout.fragment_topic, R.id.action_nav_topic_to_nav_book) {
19 | private var type = 1
20 | override fun getApiUrl() =
21 | getString(R.string.topicContentApiUrl).format(Config.myHostApiUrl.random(), arguments?.getString("path"), type, offset, Config.platform.value)
22 |
23 | override fun onCreate(savedInstanceState: Bundle?) {
24 | super.onCreate(savedInstanceState)
25 | lifecycleScope.launch {
26 | setProgress(5)
27 | PausableDownloader(getString(R.string.topicApiUrl).format(Config.myHostApiUrl.random(), arguments?.getString("path"), Config.platform.value)) { data ->
28 | setProgress(10)
29 | withContext(Dispatchers.IO) {
30 | if(ad?.exit == true) return@withContext
31 | data.inputStream().use { i ->
32 | val r = i.reader()
33 | Gson().fromJson(r, TopicStructure::class.java)?.apply {
34 | if(ad?.exit == true) return@withContext
35 | withContext(Dispatchers.Main) withMain@ {
36 | setProgress(15)
37 | if(ad?.exit == true) return@withMain
38 | activity?.toolbar?.title = results.title
39 | ftttime.text = results.datetime_created
40 | fttintro.text = results.intro
41 | type = results.type
42 | }
43 | }
44 | }
45 | }
46 | }.run()
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/ui/vm/PagesManager.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.ui.vm
2 |
3 | import android.widget.Toast
4 | import top.fumiama.copymanga.api.manga.Reader
5 | import top.fumiama.dmzj.copymanga.R
6 | import java.lang.ref.WeakReference
7 |
8 | class PagesManager(private val w: WeakReference) {
9 | val v get() = w.get()
10 | private var isEndL = false
11 | private var isEndR = false
12 | private val canGoPrevious get() = (v?.pageNum ?: 0) > 1
13 | private val canGoNext get() = (v?.pageNum ?: 0) < (v?.realCount ?: 0)
14 | @ExperimentalStdlibApi
15 | fun toPreviousPage(){
16 | toPage(v?.r2l==true)
17 | }
18 | @ExperimentalStdlibApi
19 | fun toNextPage(){
20 | toPage(v?.r2l!=true)
21 | }
22 | @ExperimentalStdlibApi
23 | fun toPage(goNext:Boolean) {
24 | v?.let { v ->
25 | if (v.clicked == 1) {
26 | v.hideDrawer()
27 | return
28 | }
29 | if (if(goNext) canGoNext else canGoPrevious) {
30 | if(goNext) {
31 | v.scrollForward()
32 | isEndR = false
33 | } else {
34 | v.scrollBack()
35 | isEndL = false
36 | }
37 | return
38 | }
39 | val chapterPosition = v.position + if(goNext) 1 else -1
40 | if (v.urlArray.isEmpty()) return
41 | if(chapterPosition < 0 || chapterPosition >= v.urlArray.size) {
42 | Toast.makeText(v.applicationContext, R.string.end_of_chapter, Toast.LENGTH_SHORT).show()
43 | return
44 | }
45 | if (if(goNext) isEndR else isEndL) {
46 | //if(v.zipFirst) intent.putExtra("callFrom", "zipFirst")
47 | v.tt.canDo = false
48 | //ViewMangaActivity.dlhandler = null
49 | v.comicName?.let { Reader.start2viewManga(it, chapterPosition, v.urlArray, v.uuidArray, goNext) }
50 | v.finish()
51 | return
52 | }
53 | val hint = if(goNext) R.string.press_again_to_load_next_chapter else R.string.press_again_to_load_previous_chapter
54 | Toast.makeText(v.applicationContext, hint, Toast.LENGTH_SHORT).show()
55 | if(goNext) isEndR = true
56 | else isEndL = true
57 | }
58 | }
59 | fun toggleDrawer() {
60 | v?.apply {
61 | when(clicked) {
62 | 0 -> showDrawer()
63 | 1 -> hideDrawer()
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/ChapterToggleButton.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.widget.ToggleButton
6 |
7 | class ChapterToggleButton: ToggleButton {
8 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)
9 | constructor(context: Context?, attrs: AttributeSet?): super(context, attrs)
10 | constructor(context: Context?): super(context, null)
11 |
12 | var url: CharSequence? = null
13 | var caption: CharSequence? = null
14 | var index: Int = 0
15 | var uuid: CharSequence? = null
16 | var chapterName: CharSequence = "null"
17 | set(value) {
18 | textOn = value
19 | textOff = value
20 | text = value
21 | field = value
22 | }
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/Font.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view
2 |
3 | import android.graphics.Typeface
4 | import androidx.core.content.res.ResourcesCompat
5 | import top.fumiama.copymanga.MainActivity
6 | import top.fumiama.dmzj.copymanga.R
7 |
8 | object Font {
9 | var nisiTypeFace: Typeface? = null
10 | get() {
11 | if (field != null) return field
12 | field = MainActivity.mainWeakReference?.get()?.let {
13 | ResourcesCompat.getFont(it.applicationContext, R.font.nisi)
14 | }
15 | return field
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/LazyScrollView.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.util.AttributeSet
6 | import android.view.MotionEvent
7 | import android.view.View
8 | import androidx.core.widget.NestedScrollView
9 |
10 | @SuppressLint("ClickableViewAccessibility")
11 | class LazyScrollView : NestedScrollView {
12 | private val view: View?
13 | get() = getChildAt(0)
14 |
15 | constructor(context: Context) : super(context)
16 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
17 | constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle)
18 |
19 | init {
20 | setOnTouchListener { _, event ->
21 | when (event.action) {
22 | MotionEvent.ACTION_UP -> this.postDelayed({
23 | if (view != null && onScrollListener != null) {
24 | if (onScrollListener != null) {
25 | //Log.d("MyS", "view?.measuredHeight: ${view?.measuredHeight}, scrollY: $scrollY, height: $height")
26 | when {
27 | view?.measuredHeight?:0 <= scrollY + height -> onScrollListener?.onBottom()
28 | scrollY == 0 -> onScrollListener?.onTop()
29 | else -> onScrollListener?.onScroll()
30 | }
31 | }
32 | }
33 | }, 233)
34 | }
35 | false
36 | }
37 | }
38 | /**
39 | * 定义接口
40 | * @author admin
41 | */
42 | interface OnScrollListener {
43 | fun onBottom()
44 | fun onTop()
45 | fun onScroll()
46 | }
47 | var onScrollListener: OnScrollListener? = null
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/MangaCardView.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import androidx.cardview.widget.CardView
6 |
7 | class MangaCardView :CardView {
8 | constructor(context: Context): super(context)
9 | constructor(context: Context, attrs: AttributeSet?): super (context, attrs)
10 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)
11 |
12 | var name = ""
13 | var append: String? = null
14 | var headImageUrl: String? = null
15 | //var uuid: String? = null
16 | var path: String? = null
17 | var isFinish = false
18 | var isNew = false
19 | var index = 0
20 | var chapterUUID: String? = null
21 | var pageNumber: Int? = null
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/OverScrollView.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import com.akscorp.overscrollablescrollview.OverscrollableNestedScrollView
6 | import kotlinx.android.synthetic.main.app_bar_main.*
7 | import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
8 |
9 | open class OverScrollView :OverscrollableNestedScrollView{
10 | constructor(context: Context) : super(context)
11 |
12 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
13 |
14 | constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
15 |
16 | override fun isAchieveTop(): Boolean {
17 | val re = super.isAchieveTop()
18 | if(re) mainWeakReference?.get()?.appbar?.setExpanded(true)
19 | return re
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/ScrollRefreshView.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import androidx.core.widget.NestedScrollView
6 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
7 |
8 | class ScrollRefreshView : NestedScrollView {
9 | constructor(context: Context) : super(context)
10 |
11 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
12 |
13 | constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(
14 | context,
15 | attrs,
16 | defStyle
17 | )
18 |
19 | var swipeRefreshLayout: SwipeRefreshLayout? = null
20 |
21 | override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
22 | super.onScrollChanged(l, t, oldl, oldt)
23 | if(swipeRefreshLayout?.isRefreshing == false) {
24 | swipeRefreshLayout?.isEnabled = t == 0
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/interaction/Navigate.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view.interaction
2 |
3 | import android.os.Bundle
4 | import androidx.navigation.NavController
5 |
6 | object Navigate {
7 | fun safeNavigateTo(navController: NavController, id: Int, bundle: Bundle? = null) {
8 | navController.currentDestination?.getAction(id)?.let {
9 | navController.navigate(id, bundle)
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/interaction/TimeThread.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view.interaction
2 |
3 | import android.os.Handler
4 |
5 | class TimeThread(private val handler: Handler, private val msg: Int, private val interval: Long = 3000) : Thread() {
6 | var canDo = false
7 | override fun run() {
8 | while (canDo) {
9 | try {
10 | handler.sendEmptyMessage(msg)
11 | sleep(interval)
12 | } catch (e: InterruptedException) {
13 | e.printStackTrace()
14 | }
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/operation/GlideBlurTransformation.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view.operation
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import android.renderscript.Allocation
6 | import android.renderscript.Element
7 | import android.renderscript.RenderScript
8 | import android.renderscript.ScriptIntrinsicBlur
9 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
10 | import com.bumptech.glide.load.resource.bitmap.CenterCrop
11 |
12 | class GlideBlurTransformation(private val context: Context) : CenterCrop() {
13 | override fun transform(
14 | pool: BitmapPool,
15 | toTransform: Bitmap,
16 | outWidth: Int,
17 | outHeight: Int
18 | ): Bitmap {
19 | val bitmap = super.transform(pool, toTransform, outWidth, outHeight)
20 | return blurBitmap(context, bitmap, 25f, outWidth / 2, outHeight / 2)
21 | }
22 |
23 | private fun blurBitmap(
24 | context: Context?,
25 | image: Bitmap?,
26 | blurRadius: Float,
27 | outWidth: Int,
28 | outHeight: Int
29 | ): Bitmap {
30 | // 将缩小后的图片做为预渲染的图片
31 | val inputBitmap = Bitmap.createScaledBitmap(image!!, outWidth, outHeight, false)
32 | // 创建一张渲染后的输出图片
33 | val outputBitmap = Bitmap.createBitmap(inputBitmap)
34 | // 创建RenderScript内核对象
35 | val rs = RenderScript.create(context)
36 | // 创建一个模糊效果的RenderScript的工具对象
37 | val blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
38 | // 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间
39 | // 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去
40 | val tmpIn = Allocation.createFromBitmap(rs, inputBitmap)
41 | val tmpOut = Allocation.createFromBitmap(rs, outputBitmap)
42 | // 设置渲染的模糊程度, 25f是最大模糊度
43 | blurScript.setRadius(blurRadius)
44 | // 设置blurScript对象的输入内存
45 | blurScript.setInput(tmpIn)
46 | // 将输出数据保存到输出内存中
47 | blurScript.forEach(tmpOut)
48 | // 将数据填充到Allocation中
49 | tmpOut.copyTo(outputBitmap)
50 | return outputBitmap
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/operation/GlideHideLottieViewListener.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view.operation
2 |
3 | import android.graphics.drawable.Drawable
4 | import android.view.View
5 | import com.airbnb.lottie.LottieAnimationView
6 | import com.bumptech.glide.load.DataSource
7 | import com.bumptech.glide.load.engine.GlideException
8 | import com.bumptech.glide.request.RequestListener
9 | import com.bumptech.glide.request.target.Target
10 | import java.lang.ref.WeakReference
11 |
12 | class GlideHideLottieViewListener(private val wla: WeakReference, private val runAfterLoad: (() -> Unit)? = null): RequestListener {
13 | override fun onLoadFailed(
14 | e: GlideException?,
15 | model: Any?,
16 | target: Target,
17 | isFirstResource: Boolean
18 | ): Boolean {
19 | return false
20 | }
21 |
22 | override fun onResourceReady(
23 | resource: Drawable,
24 | model: Any,
25 | target: Target?,
26 | dataSource: DataSource,
27 | isFirstResource: Boolean
28 | ): Boolean {
29 | wla.get()?.apply {
30 | pauseAnimation()
31 | visibility = View.GONE
32 | runAfterLoad?.let { it() }
33 | }
34 | return false
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/template/ActivityTemplate.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view.template
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import androidx.appcompat.app.AppCompatActivity
6 | import androidx.core.content.edit
7 | import top.fumiama.copymanga.view.interaction.UITools
8 |
9 | open class ActivityTemplate: AppCompatActivity() {
10 | lateinit var toolsBox: UITools
11 | val pb = BoolPref()
12 | private val allFullScreen
13 | get() = getPreferences(MODE_PRIVATE).getBoolean("allFullScreen", false)
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | toolsBox = UITools(this)
18 | }
19 |
20 | override fun onWindowFocusChanged(hasFocus: Boolean) {
21 | super.onWindowFocusChanged(hasFocus)
22 | if(allFullScreen) window.decorView.systemUiVisibility =
23 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
24 | }
25 |
26 | inner class BoolPref {
27 | operator fun get(key: String) = getPreferences(MODE_PRIVATE).getBoolean(key, false)
28 | operator fun set(key: String, value: Boolean) = getPreferences(MODE_PRIVATE).edit {
29 | putBoolean(key, value)
30 | apply()
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/template/ThemeCardFlow.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view.template
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import kotlinx.android.synthetic.main.app_bar_main.*
6 | import kotlinx.android.synthetic.main.line_finish.*
7 | import top.fumiama.copymanga.api.Config
8 | import top.fumiama.dmzj.copymanga.R
9 |
10 | @ExperimentalStdlibApi
11 | open class ThemeCardFlow(private val api: Int, nav: Int) : StatusCardFlow(0, nav, R.layout.fragment_statuscardflow) {
12 | private var theme = ""
13 | override fun getApiUrl() =
14 | getString(api).format(
15 | Config.myHostApiUrl.random(),
16 | page * 21,
17 | sortWay[sortValue],
18 | theme,
19 | Config.platform.value,
20 | )
21 |
22 | override fun onCreate(savedInstanceState: Bundle?) {
23 | super.onCreate(savedInstanceState)
24 | arguments?.apply {
25 | getString("path")?.apply { theme = this }
26 | getString("name")?.apply {
27 | activity?.toolbar?.title = this
28 | }
29 | }
30 | }
31 |
32 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
33 | super.onViewCreated(view, savedInstanceState)
34 | lineUpdate = line_finish_time
35 | lineHot = line_finish_pop
36 | }
37 |
38 | override fun onResume() {
39 | super.onResume()
40 | arguments?.getString("name")?.apply {
41 | activity?.toolbar?.title = this
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/top/fumiama/copymanga/view/template/TitleActivityTemplate.kt:
--------------------------------------------------------------------------------
1 | package top.fumiama.copymanga.view.template
2 |
3 | import android.os.Bundle
4 | import kotlinx.android.synthetic.main.widget_titlebar.*
5 |
6 | open class TitleActivityTemplate: ActivityTemplate() {
7 | override fun onCreate(savedInstanceState: Bundle?) {
8 | super.onCreate(savedInstanceState)
9 | ilogo.setOnClickListener {
10 | onBackPressed()
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_right_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_left_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/bg_rnd_green.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/buttonshapewhitebg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_anchor_down.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_author.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_circle.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_data.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_email_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_hot.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_line_more.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_locate.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_lock_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_menu_del.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_menu_download.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_menu_history.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_menu_home.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_menu_rank.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_menu_sort.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_menu_sub.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_refresh.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_setting_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_success.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/ic_time.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/mask_blackbottom.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/mask_blacktop.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/rndbg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/rndbg_checked.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/rndbg_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/rndbg_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-anydpi/toggle_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/illust_57793944_20190427_134853.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/illust_57793944_20190427_134853.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/img_defmask.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/img_defmask.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/img_hot.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/img_hot.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/img_hot_serial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/img_hot_serial.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/img_latest_pub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/img_latest_pub.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/img_master_work.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/img_master_work.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/img_novel_bill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/img_novel_bill.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/img_novel_eye.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/img_novel_eye.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/kohima.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/kohima.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/line_colorful.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/drawable-nodpi/line_colorful.webp
--------------------------------------------------------------------------------
/app/src/main/res/font/calibri.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/font/calibri.ttf
--------------------------------------------------------------------------------
/app/src/main/res/font/gotham.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/font/gotham.ttf
--------------------------------------------------------------------------------
/app/src/main/res/font/nisi.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/font/nisi.ttf
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_viewmanga.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
28 |
29 |
40 |
41 |
42 |
43 |
51 |
52 |
61 |
62 |
71 |
72 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/anchor_popular.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
23 |
24 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
20 |
21 |
27 |
28 |
29 |
30 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/button_tbutton.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/card_book_plain.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
24 |
25 |
28 |
29 |
38 |
39 |
51 |
52 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
23 |
24 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
26 |
27 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_unzipping.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/div_h.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_book.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
24 |
25 |
33 |
34 |
35 |
46 |
47 |
52 |
53 |
60 |
61 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_dlcomic.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
18 |
19 |
20 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_download.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_history.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
17 |
18 |
27 |
28 |
33 |
34 |
35 |
36 |
37 |
38 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_newdownload.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_newest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_rank.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_recommend.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_shelf.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sort.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_statuscardflow.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_topic.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
18 |
19 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_2chapters.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_bookinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
24 |
25 |
35 |
36 |
45 |
46 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_booktandb.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
19 |
20 |
32 |
33 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_caption.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_chapter.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
24 |
25 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_choice_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_finish.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
25 |
26 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
26 |
27 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_horizonal_empty.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_lazybooklines.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
45 |
46 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_rank.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
25 |
26 |
31 |
32 |
37 |
38 |
43 |
44 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_shelf.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
25 |
26 |
35 |
36 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_sort.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
25 |
26 |
35 |
36 |
45 |
46 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_text_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/line_word.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
22 |
23 |
34 |
35 |
42 |
43 |
50 |
51 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
20 |
21 |
31 |
32 |
41 |
42 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/page_imgview.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/page_nested_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/page_scrollimgview.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/viewpage_banner.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_downloadbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
25 |
26 |
29 |
30 |
42 |
43 |
54 |
55 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_finalmark.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_newmark.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_titlebar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
22 |
23 |
34 |
35 |
44 |
45 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_viewmangainfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
29 |
30 |
38 |
39 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
13 |
17 |
21 |
22 |
25 |
29 |
33 |
34 |
37 |
41 |
42 |
45 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
11 |
18 |
25 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2ca9e1
4 | #000000
5 | #00a3af
6 | #c1e4e9
7 | #f2faff
8 | #00beff
9 | #81caf8
10 | #c7eaff
11 | #BFEA88
12 | #ffffff
13 | #F6837A
14 | #E1E1E1
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - 全部
5 | - 名称
6 | - 作者
7 | - 汉化组
8 |
9 |
10 | - 周日
11 | - 周一
12 | - 周二
13 | - 周三
14 | - 周四
15 | - 周五
16 | - 周六
17 |
18 |
19 | - 1500
20 | - 1200
21 | - 800
22 |
23 |
24 | - @string/menu_home
25 | - @string/menu_sort
26 | - @string/menu_rank
27 | - @string/menu_sub
28 | - @string/menu_history
29 | - @string/menu_download
30 | - @string/action_settings
31 |
32 |
33 | - 0
34 | - 1
35 | - 2
36 | - 3
37 | - 4
38 | - 5
39 | - 6
40 |
41 |
42 | - 跟随系统
43 | - 浅色
44 | - 深色
45 |
46 |
47 | - 0
48 | - 1
49 | - 2
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2ca9e1
4 | #007bbb
5 | #00a3af
6 | #c1e4e9
7 | #f2faff
8 | #00beff
9 | #81caf8
10 | #c7eaff
11 | #BFEA88
12 | #ffffff
13 | #F6837A
14 | #E1E1E1
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 8dp
6 | 176dp
7 | 32dp
8 | 24dp
9 | 16dp
10 | 64dp
11 | 0.8
12 |
13 | 16dp
14 | 4dp
15 | 8dp
16 | 128dp
17 |
18 | 16dp
19 |
20 | 64dp
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
18 |
19 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext.kotlin_version = "$cm_kotlin_version"
4 | repositories {
5 | google()
6 | mavenCentral()
7 | maven { url 'https://maven.google.com' }
8 | maven { url "https://jitpack.io" }
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:8.3.2'
12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | mavenCentral()
23 | maven { url "https://jitpack.io" }
24 | }
25 | }
26 |
27 | tasks.register('clean', Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | Third-party client for copymanga with better reading/downloading experience.
2 | Features
3 | 1. Browse homepage, category, rank, my downloads, tag, and author.
4 | 2. View, search and read manga; log reading progress.
5 | 3. Download manga. But due to force majeure, the downloading is slow and error-prone. This is not due to bad optimization, absolutely not.
6 | 4. Read downloaded manga.
7 | 5. Check update.
8 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Third-party client for copymanga with better reading/downloading experience
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-CN/full_description.txt:
--------------------------------------------------------------------------------
1 | 拷贝漫画的第三方 APP,优化阅读/下载体验
2 | 功能
3 | 1. 浏览主页、分类、排行、我的下载、标签、作者。
4 | 2. 查看、搜索漫画并直接阅读;记录漫画与章节的阅读进度。
5 | 3. 下载漫画。但是由于不可抗力,下载速度较慢且容易出错,这绝对不是优化的原因,绝对不是。
6 | 4. 阅读下载的漫画。
7 | 5. 检查更新。
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-CN/short_description.txt:
--------------------------------------------------------------------------------
1 | 拷贝漫画的第三方 APP,优化阅读/下载体验
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 | android.enableR8.fullMode=true
23 | android.defaults.buildfeatures.buildconfig=true
24 | android.nonTransitiveRClass=false
25 | android.nonFinalResIds=false
26 | cm_kotlin_version=1.7.10
27 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/copymanga/d04e03132846f52498f40a7be680fce098f359c8/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 04 18:15:43 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | plugins {
3 | id 'kotlin-android' version "$cm_kotlin_version"
4 | }
5 | }
6 |
7 | include ':app'
8 | rootProject.name = "拷贝漫画"
--------------------------------------------------------------------------------