From f1a99fd361e28d7bdd3acac312a75af96693a3c6 Mon Sep 17 00:00:00 2001 From: niuhb <76513019+niu-hb@users.noreply.github.com> Date: Thu, 26 Dec 2024 14:14:31 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=B9=A6=E7=B1=8D=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E5=BC=80=E5=85=B3=EF=BC=8C=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=BC=80=E5=90=AF=20(#4470)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/constant/PreferKey.kt | 1 + app/src/main/java/io/legado/app/help/config/AppConfig.kt | 6 ++++++ .../java/io/legado/app/ui/book/toc/ChapterListAdapter.kt | 2 +- app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt | 6 ++++++ app/src/main/res/menu/book_toc.xml | 6 ++++++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index 2ce1bec082ad..5e8f846403b4 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -107,6 +107,7 @@ object PreferKey { const val checkSource = "checkSource" const val uploadRule = "uploadRule" const val tocUiUseReplace = "tocUiUseReplace" + const val tocCountWords = "tocCountWords" const val enableReadRecord = "enableReadRecord" const val localBookImportSort = "localBookImportSort" const val customWelcome = "customWelcome" diff --git a/app/src/main/java/io/legado/app/help/config/AppConfig.kt b/app/src/main/java/io/legado/app/help/config/AppConfig.kt index c5e8ab816dde..5fad091f9789 100644 --- a/app/src/main/java/io/legado/app/help/config/AppConfig.kt +++ b/app/src/main/java/io/legado/app/help/config/AppConfig.kt @@ -381,6 +381,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener { appCtx.putPrefBoolean(PreferKey.tocUiUseReplace, value) } + var tocCountWords: Boolean + get() = appCtx.getPrefBoolean(PreferKey.tocCountWords, true) + set(value) { + appCtx.putPrefBoolean(PreferKey.tocCountWords, value) + } + var enableReadRecord: Boolean get() = appCtx.getPrefBoolean(PreferKey.enableReadRecord, true) set(value) { diff --git a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt index e5eebd6123c6..80015d2a69f6 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt @@ -150,7 +150,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) : } else { tvTag.gone() } - if (!item.wordCount.isNullOrEmpty() && !item.isVolume) { + if (AppConfig.tocCountWords && !item.wordCount.isNullOrEmpty() && !item.isVolume) { //章节字数 tvWordCount.text = item.wordCount tvWordCount.visible() diff --git a/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt b/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt index a0003c071d17..6bd508d3a499 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt @@ -132,6 +132,8 @@ class TocActivity : VMBaseActivity(), } menu.findItem(R.id.menu_use_replace)?.isChecked = AppConfig.tocUiUseReplace + menu.findItem(R.id.menu_load_word_count)?.isChecked = + AppConfig.tocCountWords menu.findItem(R.id.menu_split_long_chapter)?.isChecked = viewModel.bookData.value?.getSplitLongChapter() == true return super.onMenuOpened(featureId, menu) @@ -165,6 +167,10 @@ class TocActivity : VMBaseActivity(), viewModel.chapterListCallBack?.upChapterList(searchView?.query?.toString()) } + R.id.menu_load_word_count -> { + AppConfig.tocCountWords = !item.isChecked + } + R.id.menu_export_bookmark -> exportDir.launch { requestCode = 1 } diff --git a/app/src/main/res/menu/book_toc.xml b/app/src/main/res/menu/book_toc.xml index 214708267bb8..d8af1015c544 100644 --- a/app/src/main/res/menu/book_toc.xml +++ b/app/src/main/res/menu/book_toc.xml @@ -42,6 +42,12 @@ android:title="@string/use_replace" app:showAsAction="never" /> + + Date: Thu, 26 Dec 2024 14:25:31 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/data/entities/rule/ExploreKind.kt | 32 ++---------- .../app/data/entities/rule/FlexChildStyle.kt | 39 ++++++++++++++ .../io/legado/app/data/entities/rule/RowUi.kt | 14 ++--- .../java/io/legado/app/help/book/BookHelp.kt | 2 +- .../app/model/webBook/BookChapterList.kt | 7 ++- .../legado/app/ui/login/SourceLoginDialog.kt | 51 +++++++++---------- .../app/ui/main/explore/ExploreAdapter.kt | 9 +--- app/src/main/res/layout/item_chapter_list.xml | 25 ++++----- 8 files changed, 95 insertions(+), 84 deletions(-) create mode 100644 app/src/main/java/io/legado/app/data/entities/rule/FlexChildStyle.kt diff --git a/app/src/main/java/io/legado/app/data/entities/rule/ExploreKind.kt b/app/src/main/java/io/legado/app/data/entities/rule/ExploreKind.kt index d010b1a4eff0..802fd31d8d91 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/ExploreKind.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/ExploreKind.kt @@ -6,37 +6,11 @@ package io.legado.app.data.entities.rule data class ExploreKind( val title: String = "", val url: String? = null, - val style: Style? = null + val style: FlexChildStyle? = null ) { - companion object { - val defaultStyle = Style() - } - - fun style(): Style { - return style ?: defaultStyle - } - - data class Style( - val layout_flexGrow: Float = 0F, - val layout_flexShrink: Float = 1F, - val layout_alignSelf: String = "auto", - val layout_flexBasisPercent: Float = -1F, - val layout_wrapBefore: Boolean = false, - ) { - - fun alignSelf(): Int { - return when (layout_alignSelf) { - "auto" -> -1 - "flex_start" -> 0 - "flex_end" -> 1 - "center" -> 2 - "baseline" -> 3 - "stretch" -> 4 - else -> -1 - } - } - + fun style(): FlexChildStyle { + return style ?: FlexChildStyle.defaultStyle } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/entities/rule/FlexChildStyle.kt b/app/src/main/java/io/legado/app/data/entities/rule/FlexChildStyle.kt new file mode 100644 index 000000000000..7efa750559ca --- /dev/null +++ b/app/src/main/java/io/legado/app/data/entities/rule/FlexChildStyle.kt @@ -0,0 +1,39 @@ +package io.legado.app.data.entities.rule + +import android.view.View +import com.google.android.flexbox.FlexboxLayout + +data class FlexChildStyle( + val layout_flexGrow: Float = 0F, + val layout_flexShrink: Float = 1F, + val layout_alignSelf: String = "auto", + val layout_flexBasisPercent: Float = -1F, + val layout_wrapBefore: Boolean = false, +) { + + fun alignSelf(): Int { + return when (layout_alignSelf) { + "auto" -> -1 + "flex_start" -> 0 + "flex_end" -> 1 + "center" -> 2 + "baseline" -> 3 + "stretch" -> 4 + else -> -1 + } + } + + fun apply(view: View) { + val lp = view.layoutParams as FlexboxLayout.LayoutParams + lp.flexGrow = layout_flexGrow + lp.flexShrink = layout_flexShrink + lp.alignSelf = alignSelf() + lp.flexBasisPercent = layout_flexBasisPercent + lp.isWrapBefore = layout_wrapBefore + } + + companion object { + val defaultStyle = FlexChildStyle() + } + +} diff --git a/app/src/main/java/io/legado/app/data/entities/rule/RowUi.kt b/app/src/main/java/io/legado/app/data/entities/rule/RowUi.kt index ff4884891c0b..482d2aa3f853 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/RowUi.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/RowUi.kt @@ -1,15 +1,13 @@ package io.legado.app.data.entities.rule -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - -@Parcelize data class RowUi( var name: String, var type: String = "text", - var action: String? = null -) : Parcelable { + var action: String? = null, + var style: FlexChildStyle? = null +) { + @Suppress("ConstPropertyName") object Type { const val text = "text" @@ -18,4 +16,8 @@ data class RowUi( } + fun style(): FlexChildStyle { + return style ?: FlexChildStyle.defaultStyle + } + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/book/BookHelp.kt b/app/src/main/java/io/legado/app/help/book/BookHelp.kt index 39833a136a13..c93bec606c64 100644 --- a/app/src/main/java/io/legado/app/help/book/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/book/BookHelp.kt @@ -148,7 +148,7 @@ object BookHelp { book.getFolderName(), bookChapter.getFileName(), ).writeText(content) - if (book.isOnLineTxt) { + if (book.isOnLineTxt && AppConfig.tocCountWords) { bookChapter.wordCount = StringUtils.wordCountFormat(content.length) appDb.bookChapterDao.update(bookChapter) } diff --git a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt index 49d4fd4ae03d..15a1aa7dc9bf 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt @@ -270,12 +270,15 @@ object BookChapterList { } private fun getWordCount(list: ArrayList, book: Book) { + if (!AppConfig.tocCountWords) { + return + } val chapterList = appDb.bookChapterDao.getChapterList(book.bookUrl) - if (chapterList.isNotEmpty()){ + if (chapterList.isNotEmpty()) { val map = chapterList.associateBy({ it.getFileName() }, { it.wordCount }) for (bookChapter in list) { val wordCount = map[bookChapter.getFileName()] - if(wordCount != null){ + if (wordCount != null) { bookChapter.wordCount = wordCount } } diff --git a/app/src/main/java/io/legado/app/ui/login/SourceLoginDialog.kt b/app/src/main/java/io/legado/app/ui/login/SourceLoginDialog.kt index 535a607dfd8e..a8ab810187c4 100644 --- a/app/src/main/java/io/legado/app/ui/login/SourceLoginDialog.kt +++ b/app/src/main/java/io/legado/app/ui/login/SourceLoginDialog.kt @@ -35,11 +35,6 @@ import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import splitties.views.onClick -import kotlin.collections.HashMap -import kotlin.collections.List -import kotlin.collections.forEachIndexed -import kotlin.collections.hashMapOf -import kotlin.collections.set class SourceLoginDialog : BaseDialogFragment(R.layout.dialog_login, true) { @@ -70,6 +65,7 @@ class SourceLoginDialog : BaseDialogFragment(R.layout.dialog_login, true) { it.textInputLayout.hint = rowUi.name it.editText.setText(loginInfo?.get(rowUi.name)) } + RowUi.Type.password -> ItemSourceEditBinding.inflate( layoutInflater, binding.root, @@ -82,37 +78,19 @@ class SourceLoginDialog : BaseDialogFragment(R.layout.dialog_login, true) { InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT it.editText.setText(loginInfo?.get(rowUi.name)) } + RowUi.Type.button -> ItemFilletTextBinding.inflate( layoutInflater, binding.root, false ).let { binding.flexbox.addView(it.root) + rowUi.style().apply(it.root) it.root.id = index + 1000 it.textView.text = rowUi.name it.textView.setPadding(16.dpToPx()) it.root.onClick { - Coroutine.async { - if (rowUi.action.isAbsUrl()) { - context?.openUrl(rowUi.action!!) - } else { - // JavaScript - rowUi.action?.let { buttonFunctionJS -> - kotlin.runCatching { - source.getLoginJs()?.let { loginJS -> - source.evalJS("$loginJS\n$buttonFunctionJS") { - put("result", getLoginData(loginUi)) - } - } - }.onFailure { e -> - AppLog.put( - "LoginUI Button ${rowUi.name} JavaScript error", - e - ) - } - } - } - } + handleButtonClick(source, rowUi, loginUi) } } } @@ -125,12 +103,14 @@ class SourceLoginDialog : BaseDialogFragment(R.layout.dialog_login, true) { val loginData = getLoginData(loginUi) login(source, loginData) } + R.id.menu_show_login_header -> alert { setTitle(R.string.login_header) source.getLoginHeader()?.let { loginHeader -> setMessage(loginHeader) } } + R.id.menu_del_login_header -> source.removeLoginHeader() R.id.menu_log -> showDialogFragment() } @@ -138,6 +118,25 @@ class SourceLoginDialog : BaseDialogFragment(R.layout.dialog_login, true) { } } + private fun handleButtonClick(source: BaseSource, rowUi: RowUi, loginUi: List) { + Coroutine.async { + if (rowUi.action.isAbsUrl()) { + context?.openUrl(rowUi.action!!) + } else if (rowUi.action != null) { + // JavaScript + val buttonFunctionJS = rowUi.action!! + val loginJS = source.getLoginJs() ?: return@async + kotlin.runCatching { + source.evalJS("$loginJS\n$buttonFunctionJS") { + put("result", getLoginData(loginUi)) + } + }.onFailure { e -> + AppLog.put("LoginUI Button ${rowUi.name} JavaScript error", e) + } + } + } + } + private fun getLoginData(loginUi: List?): HashMap { val loginData = hashMapOf() loginUi?.forEachIndexed { index, rowUi -> diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt index e84b6a943cb6..b2664cf0379d 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt @@ -91,14 +91,7 @@ class ExploreAdapter(context: Context, val callBack: CallBack) : val tv = getFlexboxChild(flexbox) flexbox.addView(tv) tv.text = kind.title - val lp = tv.layoutParams as FlexboxLayout.LayoutParams - kind.style().let { style -> - lp.flexGrow = style.layout_flexGrow - lp.flexShrink = style.layout_flexShrink - lp.alignSelf = style.alignSelf() - lp.flexBasisPercent = style.layout_flexBasisPercent - lp.isWrapBefore = style.layout_wrapBefore - } + kind.style().apply(tv) if (kind.url.isNullOrBlank()) { tv.setOnClickListener(null) } else { diff --git a/app/src/main/res/layout/item_chapter_list.xml b/app/src/main/res/layout/item_chapter_list.xml index 95f8cfa081c4..9ea8805d8db8 100644 --- a/app/src/main/res/layout/item_chapter_list.xml +++ b/app/src/main/res/layout/item_chapter_list.xml @@ -2,11 +2,11 @@ + app:layout_constraintRight_toLeftOf="@+id/iv_checked" + app:layout_constraintTop_toTopOf="parent" /> @@ -35,25 +36,25 @@ android:id="@+id/tv_tag" android:layout_width="0dp" android:layout_height="wrap_content" + android:singleLine="true" android:textSize="12sp" android:visibility="gone" - android:singleLine="true" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toBottomOf="@+id/tv_chapter_name" app:layout_constraintLeft_toRightOf="@id/tv_word_count" - app:layout_constraintRight_toLeftOf="@+id/iv_checked" /> + app:layout_constraintRight_toLeftOf="@+id/iv_checked" + app:layout_constraintTop_toBottomOf="@+id/tv_chapter_name" /> + app:layout_constraintTop_toTopOf="parent" + app:tint="@color/secondaryText" /> \ No newline at end of file From ac34ee8d1c17ee5231facf799f4ecbf4cb8d6bb5 Mon Sep 17 00:00:00 2001 From: Horis <8674809+821938089@users.noreply.github.com> Date: Thu, 26 Dec 2024 14:47:50 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/book/toc/ChapterListAdapter.kt | 1 + .../legado/app/ui/book/toc/ChapterListFragment.kt | 4 ++++ .../java/io/legado/app/ui/book/toc/TocActivity.kt | 1 + .../java/io/legado/app/ui/book/toc/TocViewModel.kt | 6 ++++++ app/src/main/res/layout/item_chapter_list.xml | 13 ++++++++++--- 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt index 80015d2a69f6..462c68eff670 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt @@ -52,6 +52,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) : && oldItem.isPay == newItem.isPay && oldItem.title == newItem.title && oldItem.tag == newItem.tag + && oldItem.wordCount == newItem.wordCount && oldItem.isVolume == newItem.isVolume } diff --git a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt index 460ae71328d7..37f87cbd3f71 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt @@ -152,6 +152,10 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragment_chapt adapter.upDisplayTitles(mLayoutManager.findFirstVisibleItemPosition()) } + override fun upAdapter() { + adapter.notifyItemRangeChanged(0, adapter.itemCount) + } + override val scope: CoroutineScope get() = lifecycleScope diff --git a/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt b/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt index 6bd508d3a499..bc7c0542af12 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt @@ -169,6 +169,7 @@ class TocActivity : VMBaseActivity(), R.id.menu_load_word_count -> { AppConfig.tocCountWords = !item.isChecked + viewModel.upChapterListAdapter() } R.id.menu_export_bookmark -> exportDir.launch { diff --git a/app/src/main/java/io/legado/app/ui/book/toc/TocViewModel.kt b/app/src/main/java/io/legado/app/ui/book/toc/TocViewModel.kt index 8914b39bbde7..316ac5bca1e2 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/TocViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/TocViewModel.kt @@ -73,6 +73,10 @@ class TocViewModel(application: Application) : BaseViewModel(application) { bookMarkCallBack?.upBookmark(newText) } + fun upChapterListAdapter() { + chapterListCallBack?.upAdapter() + } + fun saveBookmark(treeUri: Uri) { execute { val book = bookData.value @@ -119,6 +123,8 @@ class TocViewModel(application: Application) : BaseViewModel(application) { fun upChapterList(searchKey: String?) fun clearDisplayTitle() + + fun upAdapter() } interface BookmarkCallBack { diff --git a/app/src/main/res/layout/item_chapter_list.xml b/app/src/main/res/layout/item_chapter_list.xml index 9ea8805d8db8..879053eb1f5e 100644 --- a/app/src/main/res/layout/item_chapter_list.xml +++ b/app/src/main/res/layout/item_chapter_list.xml @@ -14,11 +14,18 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:singleLine="true" - app:layout_constraintBottom_toTopOf="@id/tv_word_count" + app:layout_constraintBottom_toTopOf="@id/barrier" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/iv_checked" app:layout_constraintTop_toTopOf="parent" /> + + + app:layout_constraintTop_toBottomOf="@+id/barrier" /> Date: Thu, 26 Dec 2024 18:20:15 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/web/help/md/ruleHelp.md | 27 +++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/app/src/main/assets/web/help/md/ruleHelp.md b/app/src/main/assets/web/help/md/ruleHelp.md index c4410276d374..55781fd1c8bc 100644 --- a/app/src/main/assets/web/help/md/ruleHelp.md +++ b/app/src/main/assets/web/help/md/ruleHelp.md @@ -40,22 +40,29 @@ 规则填写示范 [ { - name: "telephone", - type: "text" + "name": "telephone", + "type": "text" }, { - name: "password", - type: "password" + "name": "password", + "type": "password" }, { - name: "注册", - type: "button", - action: "http://www.yooike.com/xiaoshuo/#/register?title=%E6%B3%A8%E5%86%8C" + "name": "注册", + "type": "button", + "action": "http://www.yooike.com/xiaoshuo/#/register?title=%E6%B3%A8%E5%86%8C" }, { - name: "获取验证码", - type: "button", - action: "getVerificationCode()" + "name": "获取验证码", + "type": "button", + "action": "getVerificationCode()", + "style": { + "layout_flexGrow": 0, + "layout_flexShrink": 1, + "layout_alignSelf": "auto", + "layout_flexBasisPercent": -1, + "layout_wrapBefore": false + } } ] ```