Merge remote-tracking branch 'origin/master'

pull/1217/head
ag2s20150909 3 years ago
commit e4b7b3a30a
  1. 17
      .github/workflows/legado.yml
  2. 2
      app/build.gradle
  3. 2
      app/src/main/assets/epub/chapter.html
  4. 8
      app/src/main/assets/updateLog.md
  5. 4
      app/src/main/java/io/legado/app/App.kt
  6. 13
      app/src/main/java/io/legado/app/base/BaseActivity.kt
  7. 1
      app/src/main/java/io/legado/app/constant/EventBus.kt
  8. 2
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  9. 3
      app/src/main/java/io/legado/app/data/dao/BookDao.kt
  10. 30
      app/src/main/java/io/legado/app/help/ThemeConfig.kt
  11. 25
      app/src/main/java/io/legado/app/service/AudioPlayService.kt
  12. 1
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt
  13. 1
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceDialog.kt
  14. 4
      app/src/main/java/io/legado/app/ui/book/audio/AudioPlayViewModel.kt
  15. 2
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  16. 5
      app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt
  17. 5
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceAdapter.kt
  18. 16
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt
  19. 2
      app/src/main/java/io/legado/app/ui/book/group/GroupEdit.kt
  20. 6
      app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt
  21. 8
      app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt
  22. 10
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  23. 14
      app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt
  24. 1
      app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt
  25. 13
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  26. 1
      app/src/main/java/io/legado/app/ui/book/read/ReadBookBaseActivity.kt
  27. 4
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  28. 7
      app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
  29. 4
      app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt
  30. 4
      app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt
  31. 3
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt
  32. 6
      app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt
  33. 3
      app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
  34. 6
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  35. 2
      app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt
  36. 6
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  37. 16
      app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt
  38. 6
      app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
  39. 102
      app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
  40. 2
      app/src/main/java/io/legado/app/ui/config/ThemeListDialog.kt
  41. 2
      app/src/main/java/io/legado/app/ui/document/FilePickerDialog.kt
  42. 2
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt
  43. 6
      app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt
  44. 2
      app/src/main/java/io/legado/app/ui/qrcode/QrCodeActivity.kt
  45. 12
      app/src/main/java/io/legado/app/ui/replace/GroupManageDialog.kt
  46. 1
      app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt
  47. 4
      app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt
  48. 1
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt
  49. 2
      app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt
  50. 20
      app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt
  51. 1
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt
  52. 4
      app/src/main/java/io/legado/app/ui/widget/dialog/TextDialog.kt
  53. 4
      app/src/main/java/io/legado/app/ui/widget/dialog/TextListDialog.kt
  54. 2
      app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt
  55. 4
      app/src/main/java/io/legado/app/ui/widget/prefs/IconListPreference.kt
  56. 27
      app/src/main/java/io/legado/app/utils/ActivityExtensions.kt
  57. 4
      app/src/main/java/io/legado/app/utils/BitmapUtils.kt
  58. 0
      app/src/main/java/io/legado/app/utils/JsonExtensions.kt
  59. 1
      app/src/main/res/layout-land/activity_book_info.xml
  60. 7
      app/src/main/res/layout/activity_book_info.xml
  61. 4
      app/src/main/res/layout/activity_chapter_list.xml
  62. 3
      app/src/main/res/layout/activity_import_book.xml
  63. 4
      app/src/main/res/layout/activity_main.xml
  64. 21
      app/src/main/res/layout/activity_replace_edit.xml
  65. 3
      app/src/main/res/layout/activity_replace_rule.xml
  66. 4
      app/src/main/res/layout/activity_rss_artivles.xml
  67. 12
      app/src/main/res/layout/activity_rss_source_edit.xml
  68. 3
      app/src/main/res/layout/activity_search_content.xml
  69. 6
      app/src/main/res/layout/dialog_bookmark.xml
  70. 34
      app/src/main/res/layout/dialog_bookshelf_config.xml
  71. 14
      app/src/main/res/layout/dialog_download_choice.xml
  72. 32
      app/src/main/res/layout/dialog_edit_text.xml
  73. 30
      app/src/main/res/layout/dialog_image_blurring.xml
  74. 7
      app/src/main/res/layout/dialog_recycler_view.xml
  75. 7
      app/src/main/res/layout/dialog_toc_regex_edit.xml
  76. 2
      app/src/main/res/layout/dialog_wait.xml
  77. 5
      app/src/main/res/menu/book_info.xml
  78. 1
      app/src/main/res/values-es-rES/strings.xml
  79. 1
      app/src/main/res/values-ja-rJP/strings.xml
  80. 1
      app/src/main/res/values-pt-rBR/strings.xml
  81. 4
      app/src/main/res/values-zh-rHK/arrays.xml
  82. 60
      app/src/main/res/values-zh-rHK/strings.xml
  83. 4
      app/src/main/res/values-zh-rTW/arrays.xml
  84. 10
      app/src/main/res/values-zh-rTW/strings.xml
  85. 4
      app/src/main/res/values-zh/strings.xml
  86. 4
      app/src/main/res/values/strings.xml
  87. 28
      app/src/main/res/xml/pref_config_theme.xml

@ -50,31 +50,38 @@ jobs:
echo "设置apk共存"
sed "s/'.release'/'.releaseA'/" $GITHUB_WORKSPACE/app/build.gradle -i
sed 's/.release/.releaseA/' $GITHUB_WORKSPACE/app/google-services.json -i
echo "统一版本号"
version=$(date -d "8 hour" -u +3.%y.%m%d%H%M)
sed "/def version/c def version = \"$version\"" $GITHUB_WORKSPACE/app/build.gradle -i
- name: Build With Gradle
run: |
echo "开始进行release构建"
chmod +x gradlew
./gradlew assembleAppRelease --build-cache --parallel
echo "开始进行cronet构建"
./gradlew assembleCronetRelease --build-cache --parallel
- name: Organize the files
run: |
mkdir -p ${{ github.workspace }}/apk/
cp -rf ${{ github.workspace }}/app/build/outputs/apk/*/*/*.apk ${{ github.workspace }}/apk/
- name: Upload App To Artifact
if: ${{ env.UPLOAD_ARTIFACT != 'false' }}
uses: actions/upload-artifact@v2
with:
name: legado apk
path: ${{ github.workspace }}/app/build/outputs/apk/app/release/*.apk
path: ${{ github.workspace }}/apk/*.apk
- name: Upload App To Lanzou
if: ${{ env.ylogin }}
run: |
path="$GITHUB_WORKSPACE/app/build/outputs/apk/app/release"
path="$GITHUB_WORKSPACE/apk"
files=$(ls $path)
for f in $files
do
if [[ $f == *"apk" ]]; then
file=$f
echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 文件:$file"
break
python3 $GITHUB_WORKSPACE/.github/scripts/lzy_web.py "$path/$file" "$LANZOU_FOLDER_ID"
fi
done
python3 $GITHUB_WORKSPACE/.github/scripts/lzy_web.py "$path/$file" "$LANZOU_FOLDER_ID"
echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 分享链接: https://kunfei.lanzoux.com/b0f810h4b"

@ -198,7 +198,7 @@ dependencies {
implementation('org.nanohttpd:nanohttpd-apache-fileupload:2.3.1')
//
implementation('com.github.jenly1314:zxing-lite:2.1.0')
implementation('com.github.jenly1314:zxing-lite:2.1.1')
//
implementation('com.jaredrummler:colorpicker:1.1.0')

@ -10,6 +10,8 @@
<!--<div class="logo">
<img alt="" class="logo" src="../Images/logo.png"/>
</div>-->
<br/>
<br/>
<h2 class="head">{title}</h2>
{content}
</body>

@ -2,7 +2,6 @@
* 关注公众号 **[开源阅读]** 菜单•软件下载 提前享受新版本。
* 关注合作公众号 **[小说拾遗]** 获取好看的小说。
* 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
## **必读**
@ -11,6 +10,13 @@
* 阅读只是一个转码工具,不提供内容,第一次安装app,需要自己手动导入书源,可以从公众号 **[开源阅读]**、QQ群、酷安评论里获取由书友制作分享的书源。
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则出现问题, 出现简体变化问题检查一下简繁转换是否关闭。
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
* 关于最近版本有时候界面没有数据的问题是因为把LiveData组件换成了谷歌推荐的Flow组件导致的问题,正在查找解决办法
**2021/08/06**
1. 背景图片添加模糊设置
2. 书籍信息界面添加置顶操作
3. 自动翻页时屏幕常亮
**2021/08/02**

@ -86,8 +86,4 @@ class App : MultiDexApplication() {
}
}
companion object {
var navigationBarHeight = 0
}
}

@ -2,6 +2,7 @@ package io.legado.app.base
import android.content.Context
import android.content.res.Configuration
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.os.Bundle
import android.util.AttributeSet
@ -11,7 +12,6 @@ import android.view.View
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import io.legado.app.App
import io.legado.app.R
import io.legado.app.constant.AppConst
import io.legado.app.constant.PreferKey
@ -99,13 +99,6 @@ abstract class BaseActivity<VB : ViewBinding>(
observeLiveBus()
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) {
App.navigationBarHeight = navigationBarHeight
}
}
override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration?) {
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig)
findViewById<TitleBar>(R.id.title_bar)
@ -174,8 +167,8 @@ abstract class BaseActivity<VB : ViewBinding>(
}
if (imageBg) {
try {
ThemeConfig.getBgImage(this)?.let {
window.decorView.background = it
ThemeConfig.getBgImage(this, windowSize)?.let {
window.decorView.background = BitmapDrawable(resources, it)
}
} catch (e: OutOfMemoryError) {
toastOnUi(e.localizedMessage)

@ -24,4 +24,5 @@ object EventBus {
const val CHECK_SOURCE = "checkSource"
const val CHECK_SOURCE_DONE = "checkSourceDone"
const val TIP_COLOR = "tipColor"
const val SOURCE_CHANGED = "sourceChanged"
}

@ -91,11 +91,13 @@ object PreferKey {
const val cBackground = "colorBackground"
const val cBBackground = "colorBottomBackground"
const val bgImage = "backgroundImage"
const val bgImageBlurring = "backgroundImageBlurring"
const val cNPrimary = "colorPrimaryNight"
const val cNAccent = "colorAccentNight"
const val cNBackground = "colorBackgroundNight"
const val cNBBackground = "colorBottomBackgroundNight"
const val bgImageN = "backgroundImageNight"
const val bgImageNBlurring = "backgroundImageNightBlurring"
}

@ -62,6 +62,9 @@ interface BookDao {
@get:Query("SELECT COUNT(*) FROM books")
val allBookCount: Int
@get:Query("select min(`order`) from books")
val minOrder: Int
@get:Query("select max(`order`) from books")
val maxOrder: Int

@ -1,9 +1,9 @@
package io.legado.app.help
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.DisplayMetrics
import androidx.annotation.Keep
import androidx.appcompat.app.AppCompatDelegate
import io.legado.app.R
@ -11,6 +11,7 @@ import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey
import io.legado.app.constant.Theme
import io.legado.app.lib.theme.ThemeStore
import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.utils.*
import splitties.init.appCtx
import java.io.File
@ -28,6 +29,7 @@ object ThemeConfig {
ReadBookConfig.upBg()
applyTheme(context)
initNightMode()
CoverImageView.upDefaultCover()
postEvent(EventBus.RECREATE, "")
}
@ -41,14 +43,26 @@ object ThemeConfig {
AppCompatDelegate.setDefaultNightMode(targetMode)
}
fun getBgImage(context: Context): Drawable? {
val bgPath = when (Theme.getTheme()) {
Theme.Light -> context.getPrefString(PreferKey.bgImage)
Theme.Dark -> context.getPrefString(PreferKey.bgImageN)
fun getBgImage(context: Context, metrics: DisplayMetrics): Bitmap? {
val bgCfg = when (Theme.getTheme()) {
Theme.Light -> Pair(
context.getPrefString(PreferKey.bgImage),
context.getPrefInt(PreferKey.bgImageBlurring, 0)
)
Theme.Dark -> Pair(
context.getPrefString(PreferKey.bgImageN),
context.getPrefInt(PreferKey.bgImageNBlurring, 0)
)
else -> null
} ?: return null
if (bgCfg.first.isNullOrBlank()) return null
val bgImage = BitmapUtils
.decodeBitmap(bgCfg.first!!, metrics.widthPixels, metrics.heightPixels)
?: return null
if (bgCfg.second == 0) {
return bgImage
}
if (bgPath.isNullOrBlank()) return null
return BitmapDrawable.createFromPath(bgPath)
return BitmapUtils.stackBlur(bgImage, bgCfg.second.toFloat())
}
fun upConfig() {

@ -161,17 +161,22 @@ class AudioPlayService : BaseService(),
}
private fun resume() {
pause = false
if (!mediaPlayer.isPlaying) {
mediaPlayer.start()
mediaPlayer.seekTo(position)
try {
pause = false
if (!mediaPlayer.isPlaying) {
mediaPlayer.start()
mediaPlayer.seekTo(position)
}
handler.removeCallbacks(mpRunnable)
handler.postDelayed(mpRunnable, 1000)
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PLAYING)
AudioPlay.status = Status.PLAY
postEvent(EventBus.AUDIO_STATE, Status.PLAY)
upNotification()
} catch (e: Exception) {
e.printStackTrace()
stopSelf()
}
handler.removeCallbacks(mpRunnable)
handler.postDelayed(mpRunnable, 1000)
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PLAYING)
AudioPlay.status = Status.PLAY
postEvent(EventBus.AUDIO_STATE, Status.PLAY)
upNotification()
}
private fun adjustProgress(position: Int) {

@ -176,6 +176,7 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
appDb.bookSourceDao.allGroup.forEach { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp
}

@ -172,6 +172,7 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
appDb.rssSourceDao.allGroup.forEach { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp
}

@ -4,12 +4,14 @@ import android.app.Application
import android.content.Intent
import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.constant.EventBus
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.help.BookHelp
import io.legado.app.model.webBook.WebBook
import io.legado.app.service.help.AudioPlay
import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers
@ -98,6 +100,8 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
} else {
loadChapterList(book1) { upChangeDurChapterIndex(book1, oldTocSize, it) }
}
}.onFinally {
postEvent(EventBus.SOURCE_CHANGED, book1.bookUrl)
}
}

@ -298,6 +298,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
private fun alertExportFileName() {
alert(R.string.export_file_name) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "file name js"
editView.setText(AppConfig.bookExportFileName)
}
customView { alertBinding.root }
@ -317,6 +318,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
private fun showCharsetConfig() {
alert(R.string.set_charset) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "charset name"
editView.setFilterValues(charsets)
editView.setText(AppConfig.exportCharset)
}

@ -14,9 +14,8 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.databinding.DialogChangeCoverBinding
import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
class ChangeCoverDialog : BaseDialogFragment(),
@ -45,7 +44,7 @@ class ChangeCoverDialog : BaseDialogFragment(),
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}

@ -62,6 +62,11 @@ class ChangeSourceAdapter(
when (it) {
"name" -> tvOrigin.text = item.originName
"latest" -> tvLast.text = item.getDisplayLastChapterTitle()
"upCurSource" -> if (callBack.bookUrl == item.bookUrl) {
ivChecked.visible()
} else {
ivChecked.invisible()
}
}
}
}

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.*
import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar
import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
@ -11,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.AppPattern
import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
@ -53,7 +55,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}
@ -218,12 +220,12 @@ class ChangeSourceDialog : BaseDialogFragment(),
}
override fun deleteSource(searchBook: SearchBook) {
viewModel.del(searchBook)
if (bookUrl == searchBook.bookUrl) {
viewModel.firstSourceOrNull(searchBook)?.let {
changeSource(it)
}
}
viewModel.del(searchBook)
}
private fun changeSource(searchBook: SearchBook) {
@ -259,6 +261,16 @@ class ChangeSourceDialog : BaseDialogFragment(),
}
}
override fun observeLiveBus() {
observeEvent<String>(EventBus.SOURCE_CHANGED) {
adapter.notifyItemRangeChanged(
0,
adapter.itemCount,
bundleOf(Pair("upCurSource", bookUrl))
)
}
}
interface CallBack {
val oldBook: Book?
fun changeTo(book: Book)

@ -15,7 +15,7 @@ object GroupEdit {
fun show(context: Context, layoutInflater: LayoutInflater, bookGroup: BookGroup) = context.run {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name)
textInputLayout.setHint(R.string.group_name)
editView.setText(bookGroup.groupName)
}
if (bookGroup.groupId >= 0) {

@ -28,10 +28,10 @@ import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize
import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible
import io.legado.app.utils.windowSize
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@ -43,7 +43,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}
@ -103,7 +103,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name)
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {

@ -29,9 +29,9 @@ import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize
import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@ -61,7 +61,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}
@ -125,7 +125,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name)
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {
@ -143,7 +143,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun editGroup(bookGroup: BookGroup) {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name)
textInputLayout.setHint(R.string.group_name)
editView.setText(bookGroup.groupName)
}
customView { alertBinding.root }

@ -15,6 +15,7 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions.bitmapTransform
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.AppConst
import io.legado.app.constant.BookType
import io.legado.app.constant.Theme
import io.legado.app.data.appDb
@ -36,6 +37,7 @@ import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.book.toc.TocActivityResult
import io.legado.app.ui.login.SourceLoginActivity
import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
@ -151,6 +153,14 @@ class BookInfoActivity :
viewModel.loadBookInfo(it, false)
}
}
R.id.menu_login -> viewModel.bookSource?.let {
startActivity<SourceLoginActivity> {
putExtra("sourceUrl", it.bookSourceUrl)
putExtra("loginUrl", it.loginUrl)
putExtra("userAgent", it.getHeaderMap()[AppConst.UA_NAME])
}
}
R.id.menu_top -> viewModel.topBook()
R.id.menu_copy_book_url -> viewModel.bookData.value?.bookUrl?.let {
sendToClip(it)
} ?: toastOnUi(R.string.no_book)

@ -5,6 +5,7 @@ import android.content.Intent
import androidx.lifecycle.MutableLiveData
import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.constant.EventBus
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
@ -13,6 +14,7 @@ import io.legado.app.help.BookHelp
import io.legado.app.model.localBook.LocalBook
import io.legado.app.model.webBook.WebBook
import io.legado.app.service.help.ReadBook
import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers.IO
@ -167,6 +169,8 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
upChangeDurChapterIndex(newBook, oldTocSize, it)
}
}
}.onFinally {
postEvent(EventBus.SOURCE_CHANGED, newBook.bookUrl)
}
}
@ -192,6 +196,16 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}
}
fun topBook() {
execute {
bookData.value?.let { book ->
val minOrder = appDb.bookDao.minOrder
book.order = minOrder - 1
appDb.bookDao.update(book)
}
}
}
fun saveBook(success: (() -> Unit)? = null) {
execute {
bookData.value?.let { book ->

@ -280,6 +280,7 @@ class ImportBookActivity : VMBaseActivity<ActivityImportBookBinding, ImportBookV
private fun alertImportFileName() {
alert(R.string.import_file_name) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "js"
editView.setText(AppConfig.bookImportFileName)
}
customView { alertBinding.root }

@ -150,6 +150,7 @@ class ReadBookActivity : ReadBookBaseActivity(),
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
binding.readView.upStyle()
upSystemUiVisibility()
}
@ -686,6 +687,8 @@ class ReadBookActivity : ReadBookBaseActivity(),
binding.readView.upContent(1)
autoPagePlus()
binding.readMenu.setAutoPage(true)
screenTimeOut = -1L
screenOffTimerStart()
}
}
@ -694,14 +697,15 @@ class ReadBookActivity : ReadBookBaseActivity(),
mHandler.removeCallbacks(autoPageRunnable)
binding.readView.upContent()
binding.readMenu.setAutoPage(false)
upScreenTimeOut()
}
private fun autoPagePlus() {
var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height
var scrollOffset = 1
if (delayMillis < 20) {
var delayInt=delayMillis.toInt()
if(delayInt==0)delayInt =1
var delayInt = delayMillis.toInt()
if (delayInt == 0) delayInt = 1
scrollOffset = 20 / delayInt
delayMillis = 20
}
@ -970,9 +974,8 @@ class ReadBookActivity : ReadBookBaseActivity(),
}
private fun upScreenTimeOut() {
getPrefString(PreferKey.keepLight)?.let {
screenTimeOut = it.toLong() * 1000
}
val keepLightPrefer = getPrefString(PreferKey.keepLight)?.toInt() ?: 0
screenTimeOut = keepLightPrefer * 1000L
screenOffTimerStart()
}

@ -202,6 +202,7 @@ abstract class ReadBookBaseActivity :
fun showCharsetConfig() {
alert(R.string.set_charset) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "charset"
editView.setFilterValues(charsets)
editView.setText(ReadBook.book?.charset)
}

@ -5,6 +5,7 @@ import android.content.Intent
import androidx.lifecycle.viewModelScope
import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.constant.EventBus
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
@ -20,6 +21,7 @@ import io.legado.app.service.BaseReadAloudService
import io.legado.app.service.help.ReadAloud
import io.legado.app.service.help.ReadBook
import io.legado.app.utils.msg
import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
@ -207,6 +209,8 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
upChangeDurChapterIndex(newBook, oldTocSize, it)
}
}
}.onFinally {
postEvent(EventBus.SOURCE_CHANGED, newBook.bookUrl)
}
}

@ -47,12 +47,12 @@ class BgTextConfigDialog : BaseDialogFragment() {
private var secondaryTextColor = 0
private val importFormNet = "网络导入"
private val selectBgImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
it ?: return@registerForActivityResult
setBgFromUri(it)
}
private val selectExportDir = registerForActivityResult(FilePicker()) {
it?.let {
exportConfig(it)
}
it ?: return@registerForActivityResult
exportConfig(it)
}
private val selectImportDoc = registerForActivityResult(FilePicker()) {
it ?: return@registerForActivityResult
@ -142,6 +142,7 @@ class BgTextConfigDialog : BaseDialogFragment() {
binding.ivEdit.setOnClickListener {
alert(R.string.style_name) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "name"
editView.setText(ReadBookConfig.durConfig.name)
}
customView { alertBinding.root }

@ -11,9 +11,9 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogReadPaddingBinding
import io.legado.app.help.ReadBookConfig
import io.legado.app.utils.getSize
import io.legado.app.utils.postEvent
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
class PaddingConfigDialog : BaseDialogFragment() {
@ -21,7 +21,7 @@ class PaddingConfigDialog : BaseDialogFragment() {
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.let {
it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
val attr = it.attributes

@ -19,8 +19,8 @@ import io.legado.app.lib.theme.backgroundColor
import io.legado.app.service.BaseReadAloudService
import io.legado.app.service.help.ReadAloud
import io.legado.app.utils.getPrefLong
import io.legado.app.utils.getSize
import io.legado.app.utils.postEvent
import io.legado.app.utils.windowSize
import splitties.init.appCtx
class ReadAloudConfigDialog : DialogFragment() {
@ -28,7 +28,7 @@ class ReadAloudConfigDialog : DialogFragment() {
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.let {
it.setBackgroundDrawableResource(R.color.transparent)
it.setLayout((dm.widthPixels * 0.9).toInt(), ViewGroup.LayoutParams.WRAP_CONTENT)

@ -54,7 +54,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}
@ -134,6 +134,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
?.toMutableList() ?: mutableListOf()
alert(R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls)
editView.delCallBack = {
cacheUrls.remove(it)

@ -45,7 +45,7 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.8).toInt())
}
@ -135,8 +135,8 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
cacheUrls.add(0, defaultUrl)
}
requireContext().alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
alertBinding.apply {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls)
editView.delCallBack = {
cacheUrls.remove(it)

@ -7,7 +7,6 @@ import android.view.LayoutInflater
import android.widget.FrameLayout
import androidx.core.view.isGone
import androidx.core.view.isInvisible
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.BaseActivity
import io.legado.app.constant.AppConst.timeFormat
@ -85,7 +84,7 @@ class PageView(context: Context) : FrameLayout(context) {
vwTopDivider.visible(it.showHeaderLine)
vwBottomDivider.visible(it.showFooterLine)
pageNvBar.layoutParams = pageNvBar.layoutParams.apply {
height = if (it.hideNavigationBar) 0 else App.navigationBarHeight
height = if (it.hideNavigationBar) 0 else activity?.navigationBarHeight ?: 0
}
}
contentTextView.upVisibleRect()

@ -343,8 +343,10 @@ object ChapterProvider {
}
x = x1
}
val words1 = words.copyOfRange(bodyIndent.length, words.size)
addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x, srcList)
if (words.size > bodyIndent.length) {
val words1 = words.copyOfRange(bodyIndent.length, words.size)
addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x, srcList)
}
}
/**

@ -444,7 +444,7 @@ class BookSourceEditActivity :
val rect = Rect()
// 获取当前页面窗口的显示范围
window.decorView.getWindowVisibleDisplayFrame(rect)
val screenHeight = this@BookSourceEditActivity.getSize().heightPixels
val screenHeight = this@BookSourceEditActivity.windowSize.heightPixels
val keyboardHeight = screenHeight - rect.bottom // 输入法的高度
val preShowing = mIsSoftKeyBoardShowing
if (abs(keyboardHeight) > screenHeight / 5) {

@ -327,6 +327,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
private fun checkSource() {
alert(titleResource = R.string.search_book_key) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "search word"
editView.setText(CheckSource.keyword)
}
customView { alertBinding.root }
@ -346,7 +347,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
private fun selectionAddToGroups() {
alert(titleResource = R.string.add_group) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name)
textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp
}
@ -366,7 +367,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
private fun selectionRemoveFromGroups() {
alert(titleResource = R.string.remove_group) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.setHint(R.string.group_name)
textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp
}
@ -400,6 +401,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls)
editView.delCallBack = {
cacheUrls.remove(it)

@ -24,10 +24,10 @@ import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize
import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.splitNotBlank
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@ -39,7 +39,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}
@ -87,8 +87,9 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams")
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
alertBinding.editView.setHint(R.string.group_name)
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
@ -104,9 +105,10 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams")
private fun editGroup(group: String) {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
alertBinding.editView.setHint(R.string.group_name)
alertBinding.editView.setText(group)
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
editView.setText(group)
}
customView { alertBinding.root }
yesButton {
viewModel.upGroup(group, alertBinding.editView.text?.toString())

@ -144,8 +144,10 @@ class OtherConfigFragment : BasePreferenceFragment(),
@SuppressLint("InflateParams")
private fun showUserAgentDialog() {
alert("UserAgent") {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
alertBinding.editView.setText(AppConfig.userAgent)
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "UserAgent"
editView.setText(AppConfig.userAgent)
}
customView { alertBinding.root }
okButton {
val userAgent = alertBinding.editView.text?.toString()

@ -9,6 +9,7 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.SeekBar
import androidx.documentfile.provider.DocumentFile
import androidx.preference.Preference
import io.legado.app.R
@ -17,6 +18,7 @@ import io.legado.app.constant.AppConst
import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogImageBlurringBinding
import io.legado.app.help.AppConfig
import io.legado.app.help.LauncherIconHelp
import io.legado.app.help.ThemeConfig
@ -28,6 +30,7 @@ import io.legado.app.lib.theme.ATH
import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.ui.widget.number.NumberPickerDialog
import io.legado.app.ui.widget.prefs.ColorPreference
import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
import io.legado.app.utils.*
import java.io.File
@ -134,7 +137,10 @@ class ThemeConfigFragment : BasePreferenceFragment(),
PreferKey.cNBBackground -> {
upTheme(true)
}
PreferKey.defaultCover, PreferKey.defaultCoverDark -> {
PreferKey.bgImage,
PreferKey.bgImageN,
PreferKey.defaultCover,
PreferKey.defaultCoverDark -> {
upPreferenceSummary(key, getPrefString(key))
}
}
@ -158,31 +164,9 @@ class ThemeConfigFragment : BasePreferenceFragment(),
recreateActivities()
}
"themeList" -> ThemeListDialog().show(childFragmentManager, "themeList")
"saveDayTheme", "saveNightTheme" -> saveThemeAlert(key)
PreferKey.bgImage -> if (getPrefString(PreferKey.bgImage).isNullOrEmpty()) {
selectImage.launch(requestCodeBgLight)
} else {
selector(items = arrayListOf("删除图片", "选择图片")) { _, i ->
if (i == 0) {
removePref(PreferKey.bgImage)
upTheme(false)
} else {
selectImage.launch(requestCodeBgLight)
}
}
}
PreferKey.bgImageN -> if (getPrefString(PreferKey.bgImageN).isNullOrEmpty()) {
selectImage.launch(requestCodeBgDark)
} else {
selector(items = arrayListOf("删除图片", "选择图片")) { _, i ->
if (i == 0) {
removePref(PreferKey.bgImageN)
upTheme(true)
} else {
selectImage.launch(requestCodeBgDark)
}
}
}
"saveDayTheme", "saveNightTheme" -> alertSaveTheme(key)
PreferKey.bgImage -> selectBgAction(false)
PreferKey.bgImageN -> selectBgAction(true)
PreferKey.defaultCover -> if (getPrefString(PreferKey.defaultCover).isNullOrEmpty()) {
selectImage.launch(requestCodeCover)
} else {
@ -211,9 +195,11 @@ class ThemeConfigFragment : BasePreferenceFragment(),
}
@SuppressLint("InflateParams")
private fun saveThemeAlert(key: String) {
private fun alertSaveTheme(key: String) {
alert(R.string.theme_name) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "name"
}
customView { alertBinding.root }
okButton {
alertBinding.editView.text?.toString()?.let { themeName ->
@ -231,6 +217,64 @@ class ThemeConfigFragment : BasePreferenceFragment(),
}.show()
}
private fun selectBgAction(isNight: Boolean) {
val bgKey = if (isNight) PreferKey.bgImageN else PreferKey.bgImage
val blurringKey = if (isNight) PreferKey.bgImageNBlurring else PreferKey.bgImageBlurring
val actions = arrayListOf(
getString(R.string.background_image_blurring),
getString(R.string.select_image)
)
if (!getPrefString(bgKey).isNullOrEmpty()) {
actions.add(getString(R.string.delete))
}
selector(items = actions) { _, i ->
when (i) {
0 -> alertImageBlurring(blurringKey) {
upTheme(isNight)
}
1 -> {
if (isNight) {
selectImage.launch(requestCodeBgDark)
} else {
selectImage.launch(requestCodeBgLight)
}
}
2 -> {
removePref(bgKey)
upTheme(isNight)
}
}
}
}
private fun alertImageBlurring(preferKey: String, success: () -> Unit) {
alert(R.string.background_image_blurring) {
val alertBinding = DialogImageBlurringBinding.inflate(layoutInflater).apply {
getPrefInt(preferKey, 0).let {
seekBar.progress = it
textViewValue.text = it.toString()
}
seekBar.setOnSeekBarChangeListener(object : SeekBarChangeListener {
override fun onProgressChanged(
seekBar: SeekBar,
progress: Int,
fromUser: Boolean
) {
textViewValue.text = progress.toString()
}
})
}
customView { alertBinding.root }
okButton {
alertBinding.seekBar.progress.let {
putPrefInt(preferKey, it)
success.invoke()
}
}
noButton()
}.show()
}
private fun upTheme(isNightTheme: Boolean) {
if (AppConfig.isNightTheme == isNightTheme) {
listView.post {
@ -272,7 +316,6 @@ class ThemeConfigFragment : BasePreferenceFragment(),
}.getOrNull()?.let { byteArray ->
file.writeBytes(byteArray)
putPrefString(preferenceKey, file.absolutePath)
upPreferenceSummary(preferenceKey, file.absolutePath)
success()
} ?: toastOnUi("获取文件出错")
}
@ -291,7 +334,6 @@ class ThemeConfigFragment : BasePreferenceFragment(),
file = FileUtils.createFileIfNotExist(file, preferenceKey, imgFile.name)
file.writeBytes(imgFile.readBytes())
putPrefString(preferenceKey, file.absolutePath)
upPreferenceSummary(preferenceKey, file.absolutePath)
success()
}
}

@ -26,7 +26,7 @@ class ThemeListDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}

@ -76,7 +76,7 @@ class FilePickerDialog : DialogFragment(),
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.8).toInt())
}

@ -12,7 +12,6 @@ import io.legado.app.help.DefaultData
import io.legado.app.help.LocalConfig
import io.legado.app.model.webBook.WebBook
import io.legado.app.service.help.CacheBook
import io.legado.app.utils.FileUtils
import io.legado.app.utils.postEvent
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.delay
@ -143,7 +142,6 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
fun postLoad() {
execute {
FileUtils.deleteFile(FileUtils.getPath(context.cacheDir, "Fonts"))
if (appDb.httpTTSDao.count == 0) {
DefaultData.httpTTS.let {
appDb.httpTTSDao.insert(*it.toTypedArray())

@ -65,7 +65,9 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
@SuppressLint("InflateParams")
fun addBookByUrl() {
alert(titleResource = R.string.add_book_url) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
}
customView { alertBinding.root }
okButton {
alertBinding.editView.text?.toString()?.let {
@ -122,7 +124,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
private fun importBookshelfAlert(groupId: Long) {
alert(titleResource = R.string.import_bookshelf) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "url/json"
textInputLayout.hint = "url/json"
}
customView { alertBinding.root }
okButton {

@ -20,7 +20,7 @@ class QrCodeActivity : BaseActivity<ActivityQrcodeCaptureBinding>(), OnScanResul
override val binding by viewBinding(ActivityQrcodeCaptureBinding::inflate)
private val selectQrImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
it.readBytes(this)?.let { bytes ->
it?.readBytes(this)?.let { bytes ->
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
onScanResultCallback(QRCodeUtils.parseCodeResult(bitmap))
}

@ -36,7 +36,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}
@ -88,12 +88,10 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams")
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView {
alertBinding.apply {
editView.hint = "分组名称"
}.root
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) {
@ -109,7 +107,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun editGroup(group: String) {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "分组名称"
textInputLayout.setHint(R.string.group_name)
editView.setText(group)
}
customView { alertBinding.root }

@ -255,6 +255,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_replace_rule_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls)
editView.delCallBack = {
cacheUrls.remove(it)

@ -19,9 +19,9 @@ import io.legado.app.databinding.ActivityReplaceEditBinding
import io.legado.app.lib.dialogs.selector
import io.legado.app.ui.widget.KeyboardToolPop
import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.getSize
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import kotlin.math.abs
/**
@ -166,7 +166,7 @@ class ReplaceEditActivity :
val rect = Rect()
// 获取当前页面窗口的显示范围
window.decorView.getWindowVisibleDisplayFrame(rect)
val screenHeight = this.getSize().heightPixels
val screenHeight = this.windowSize.heightPixels
val keyboardHeight = screenHeight - rect.bottom // 输入法的高度
val preShowing = mIsSoftKeyBoardShowing
if (abs(keyboardHeight) > screenHeight / 5) {

@ -43,6 +43,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
private var customWebViewCallback: WebChromeClient.CustomViewCallback? = null
private var webPic: String? = null
private val saveImage = registerForActivityResult(FilePicker()) {
it ?: return@registerForActivityResult
ACache.get(this).put(imagePathKey, it.toString())
viewModel.saveImage(webPic, it.toString())
}

@ -256,7 +256,7 @@ class RssSourceEditActivity :
val rect = Rect()
// 获取当前页面窗口的显示范围
window.decorView.getWindowVisibleDisplayFrame(rect)
val screenHeight = this@RssSourceEditActivity.getSize().heightPixels
val screenHeight = this@RssSourceEditActivity.windowSize.heightPixels
val keyboardHeight = screenHeight - rect.bottom // 输入法的高度
val preShowing = mIsSoftKeyBoardShowing
if (abs(keyboardHeight) > screenHeight / 5) {

@ -37,7 +37,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}
@ -89,12 +89,10 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams")
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView {
alertBinding.apply {
editView.setHint(R.string.group_name)
}.root
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) {
@ -109,13 +107,11 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams")
private fun editGroup(group: String) {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView {
alertBinding.apply {
editView.setHint(R.string.group_name)
editView.setText(group)
}.root
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
editView.setText(group)
}
customView { alertBinding.root }
yesButton {
viewModel.upGroup(group, alertBinding.editView.text?.toString())
}

@ -263,6 +263,7 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.hint = "url"
editView.setFilterValues(cacheUrls)
editView.delCallBack = {
cacheUrls.remove(it)

@ -8,8 +8,8 @@ import androidx.fragment.app.FragmentManager
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.databinding.DialogTextViewBinding
import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import io.noties.markwon.Markwon
import io.noties.markwon.ext.tables.TablePlugin
import io.noties.markwon.html.HtmlPlugin
@ -49,7 +49,7 @@ class TextDialog : BaseDialogFragment() {
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}

@ -13,8 +13,8 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemLogBinding
import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
class TextListDialog : BaseDialogFragment() {
@ -35,7 +35,7 @@ class TextListDialog : BaseDialogFragment() {
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}

@ -65,7 +65,7 @@ class FontSelectDialog : BaseDialogFragment(),
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}

@ -21,8 +21,8 @@ import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemIconPreferenceBinding
import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.getCompatDrawable
import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference(context, attrs) {
@ -131,7 +131,7 @@ class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference
override fun onStart() {
super.onStart()
val dm = requireActivity().getSize()
val dm = requireActivity().windowSize
dialog?.window?.setLayout(
(dm.widthPixels * 0.8).toInt(),
ViewGroup.LayoutParams.WRAP_CONTENT

@ -6,20 +6,21 @@ import android.util.DisplayMetrics
import android.view.WindowInsets
import android.view.WindowMetrics
fun Activity.getSize(): DisplayMetrics {
val displayMetrics = DisplayMetrics()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val windowMetrics: WindowMetrics = windowManager.currentWindowMetrics
val insets = windowMetrics.windowInsets
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
displayMetrics.widthPixels = windowMetrics.bounds.width() - insets.left - insets.right
displayMetrics.heightPixels = windowMetrics.bounds.height() - insets.top - insets.bottom
} else {
@Suppress("DEPRECATION")
windowManager.defaultDisplay.getMetrics(displayMetrics)
val Activity.windowSize: DisplayMetrics
get() {
val displayMetrics = DisplayMetrics()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val windowMetrics: WindowMetrics = windowManager.currentWindowMetrics
val insets = windowMetrics.windowInsets
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
displayMetrics.widthPixels = windowMetrics.bounds.width() - insets.left - insets.right
displayMetrics.heightPixels = windowMetrics.bounds.height() - insets.top - insets.bottom
} else {
@Suppress("DEPRECATION")
windowManager.defaultDisplay.getMetrics(displayMetrics)
}
return displayMetrics
}
return displayMetrics
}
/**
* 该方法需要在View完全被绘制出来之后调用否则判断不了

@ -249,7 +249,7 @@ object BitmapUtils {
/**
* 高斯模糊
*/
fun stackBlur(srcBitmap: Bitmap?): Bitmap? {
fun stackBlur(srcBitmap: Bitmap?, radius: Float = 8f): Bitmap? {
if (srcBitmap == null) return null
val rs = RenderScript.create(appCtx)
val blurredBitmap = srcBitmap.copy(Config.ARGB_8888, true)
@ -268,7 +268,7 @@ object BitmapUtils {
script.setInput(input)
//设置模糊半径
script.setRadius(8f)
script.setRadius(radius)
//启动 ScriptIntrinsicBlur
script.forEach(output)

@ -362,6 +362,7 @@
android:layout_marginTop="8dp"
android:clickable="true"
android:focusable="true"
android:minHeight="48dp"
android:paddingLeft="8dp"
android:paddingBottom="8dp"
android:text="@string/book_intro"

@ -333,16 +333,17 @@
<io.legado.app.ui.widget.text.ScrollTextView
android:id="@+id/tv_intro"
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clickable="true"
android:focusable="true"
android:minHeight="48dp"
android:paddingLeft="8dp"
android:paddingBottom="8dp"
android:text="@string/book_intro"
android:textColor="@color/secondaryText"
android:textSize="14sp"
android:paddingLeft="8dp"
android:paddingBottom="8dp"
android:visibility="visible"
tools:ignore="RtlHardcoded,RtlSymmetry" />

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@ -15,6 +16,7 @@
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
tools:ignore="SpeakableTextPresentCheck" />
</LinearLayout>

@ -69,7 +69,8 @@
<io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
tools:ignore="SpeakableTextPresentCheck" />
<TextView
android:id="@+id/tv_empty_msg"

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@ -9,7 +10,8 @@
android:id="@+id/view_pager_main"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
android:layout_weight="1"
tools:ignore="SpeakableTextPresentCheck" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation_view"

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -35,7 +36,8 @@
<io.legado.app.ui.widget.text.EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
<io.legado.app.ui.widget.text.TextInputLayout
@ -47,7 +49,8 @@
<io.legado.app.ui.widget.text.EditText
android:id="@+id/et_group"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
<io.legado.app.ui.widget.text.TextInputLayout
@ -59,7 +62,8 @@
<io.legado.app.ui.widget.text.EditText
android:id="@+id/et_replace_rule"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
<LinearLayout
@ -73,14 +77,15 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/use_regex" />
android:text="@string/use_regex"
tools:ignore="TouchTargetSizeCheck" />
<ImageView
android:id="@+id/iv_help"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_help"
app:tint="@color/secondaryText"
app:tint="@color/primaryText"
android:contentDescription="@string/help" />
</LinearLayout>
@ -94,7 +99,8 @@
<io.legado.app.ui.widget.text.EditText
android:id="@+id/et_replace_to"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
<io.legado.app.ui.widget.text.TextInputLayout
@ -106,7 +112,8 @@
<io.legado.app.ui.widget.text.EditText
android:id="@+id/et_scope"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
</LinearLayout>

@ -23,7 +23,8 @@
<io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
tools:ignore="SpeakableTextPresentCheck" />
</FrameLayout>

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
@ -19,6 +20,7 @@
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck" />
</LinearLayout>

@ -34,14 +34,16 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/is_enable" />
android:text="@string/is_enable"
tools:ignore="TouchTargetSizeCheck" />
<io.legado.app.lib.theme.view.ATECheckBox
android:id="@+id/cb_single_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/single_url" />
android:text="@string/single_url"
tools:ignore="TouchTargetSizeCheck" />
</LinearLayout>
@ -64,14 +66,16 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/enable_js" />
android:text="@string/enable_js"
tools:ignore="TouchTargetSizeCheck" />
<io.legado.app.lib.theme.view.ATECheckBox
android:id="@+id/cb_enable_base_url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/load_with_base_url" />
android:text="@string/load_with_base_url"
tools:ignore="TouchTargetSizeCheck" />
</LinearLayout>

@ -25,7 +25,8 @@
android:layout_height="0dp"
android:overScrollMode="never"
app:layout_constraintBottom_toTopOf="@+id/ll_search_base_info"
app:layout_constraintTop_toBottomOf="@id/refresh_progress_bar" />
app:layout_constraintTop_toBottomOf="@id/refresh_progress_bar"
tools:ignore="SpeakableTextPresentCheck" />
<LinearLayout
android:id="@+id/ll_search_base_info"

@ -43,7 +43,8 @@
android:id="@+id/edit_book_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/content" />
android:hint="@string/content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
@ -56,7 +57,8 @@
android:id="@+id/edit_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/note_content" />
android:hint="@string/note_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
@ -31,7 +32,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/group_style"
app:theme="@style/Spinner" />
app:theme="@style/Spinner"
tools:ignore="TouchTargetSizeCheck" />
</LinearLayout>
@ -51,27 +53,32 @@
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/layout_list" />
android:text="@string/layout_list"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/layout_grid3" />
android:text="@string/layout_grid3"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/layout_grid4" />
android:text="@string/layout_grid4"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/layout_grid5" />
android:text="@string/layout_grid5"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/layout_grid6" />
android:text="@string/layout_grid6"
tools:ignore="TouchTargetSizeCheck" />
</RadioGroup>
</LinearLayout>
@ -84,8 +91,9 @@
android:padding="6dp"
android:text="@string/show_unread"
app:layout_constraintLeft_toRightOf="@+id/ll_layout"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent" />
tools:ignore="TouchTargetSizeCheck" />
<LinearLayout
android:id="@+id/ll_sort"
@ -112,22 +120,26 @@
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/bookshelf_px_0" />
android:text="@string/bookshelf_px_0"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/bookshelf_px_1" />
android:text="@string/bookshelf_px_1"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/bookshelf_px_2" />
android:text="@string/bookshelf_px_2"
tools:ignore="TouchTargetSizeCheck" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/bookshelf_px_3" />
android:text="@string/bookshelf_px_3"
tools:ignore="TouchTargetSizeCheck" />
</RadioGroup>

@ -4,10 +4,10 @@
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:background="@color/background"
android:gravity="center"
android:orientation="horizontal">
android:orientation="horizontal"
android:padding="16dp">
<View
android:layout_width="0dp"
@ -30,6 +30,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/bg_edit"
android:hint="@string/start"
android:importantForAutofill="no"
android:inputType="number"
android:lines="1"
android:maxLength="5"
@ -40,7 +42,8 @@
android:paddingBottom="4dp"
android:textColor="@color/primaryText"
android:textCursorDrawable="@drawable/shape_text_cursor"
android:textSize="14sp" />
android:textSize="14sp"
tools:ignore="TouchTargetSizeCheck" />
<TextView
android:layout_width="wrap_content"
@ -58,6 +61,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/bg_edit"
android:hint="@string/end"
android:importantForAutofill="no"
android:inputType="number"
android:lines="1"
android:maxLength="5"
@ -68,7 +73,8 @@
android:paddingBottom="4dp"
android:textColor="@color/primaryText"
android:textCursorDrawable="@drawable/shape_text_cursor"
android:textSize="14sp" />
android:textSize="14sp"
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" />
<View
android:layout_width="0dp"

@ -1,18 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="12dp"
android:overScrollMode="ifContentScrolls">
<io.legado.app.ui.widget.text.TextInputLayout
android:id="@+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="48dp"
android:layout_marginBottom="48dp"
android:overScrollMode="ifContentScrolls">
android:layout_height="wrap_content">
<io.legado.app.ui.widget.text.AutoCompleteTextView
<io.legado.app.ui.widget.text.AutoCompleteTextView
android:id="@+id/edit_view"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
</androidx.core.widget.NestedScrollView>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/text_view_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dp"
android:layout_gravity="center_horizontal"
android:textColor="@color/primaryText"
android:textSize="17sp" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:max="25" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:text="@string/background_image_hint" />
</LinearLayout>

@ -23,7 +23,8 @@
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />
android:scrollbars="none"
tools:ignore="SpeakableTextPresentCheck" />
<io.legado.app.ui.widget.anima.RotateLoading
android:id="@+id/rotate_loading"
@ -61,6 +62,10 @@
android:visibility="gone"
tools:ignore="RtlHardcoded" />
<Space
android:layout_width="0dp"
android:layout_height="0dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -15,7 +16,8 @@
<io.legado.app.ui.widget.text.EditText
android:id="@+id/tv_rule_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
@ -27,7 +29,8 @@
<io.legado.app.ui.widget.text.EditText
android:id="@+id/tv_rule_regex"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>

@ -20,6 +20,6 @@
android:layout_height="wrap_content"
android:padding="6dp"
android:gravity="center"
android:text="执行中......"
android:text="@string/loading"
android:textColor="@color/primaryText" />
</LinearLayout>

@ -24,6 +24,11 @@
android:title="@string/login"
app:showAsAction="never" />
<item
android:id="@+id/menu_top"
android:title="@string/to_top"
app:showAsAction="never" />
<item
android:id="@+id/menu_copy_book_url"
android:title="@string/copy_book_url"

@ -847,4 +847,5 @@
<string name="null_url">URL nula</string>
<string name="dict">字典</string>
<string name="unknown_error">未知错误</string>
<string name="end">end</string>
</resources>

@ -847,4 +847,5 @@
<string name="null_url">url为空</string>
<string name="dict">字典</string>
<string name="unknown_error">未知错误</string>
<string name="end">end</string>
</resources>

@ -847,4 +847,5 @@
<string name="null_url">Nenhuma url</string>
<string name="dict">Dicionários</string>
<string name="unknown_error">未知错误</string>
<string name="end">end</string>
</resources>

@ -7,8 +7,8 @@
</string-array>
<string-array name="group_style">
<item>标签</item>
<item>文件</item>
<item>標籤</item>
<item>文件</item>
</string-array>
<string-array name="theme_mode">

@ -343,7 +343,7 @@
<string name="pt_show_all_find">顯示所有發現</string>
<string name="ps_show_all_find">關閉則只顯示勾選源的發現</string>
<string name="update_toc">更新目錄</string>
<string name="txt_toc_regex">Txt目錄正則</string>
<string name="txt_toc_regex">TXT目錄正則</string>
<string name="set_charset">設置編碼</string>
<string name="swap_sort">倒序-順序</string>
<string name="sort">排序</string>
@ -405,7 +405,7 @@
<string name="book_url_pattern">書籍 URL 正則 (bookUrlPattern)</string>
<string name="rule_book_info_init">預處理規則 (bookInfoInit)</string>
<string name="rule_toc_url">目錄 URL 規則 (tocUrl)</string>
<string name="rule_can_re_name">许修改书名作者(canReName)</string>
<string name="rule_can_re_name">許修改書名作者 (canReName)</string>
<string name="rule_next_toc_url">目錄下一頁規則 (nextTocUrl)</string>
<string name="rule_chapter_list">目錄列表規則 (chapterList)</string>
<string name="rule_chapter_name">章節名稱規則 (ChapterName)</string>
@ -414,7 +414,7 @@
<string name="rule_update_time">更新時間 (ChapterInfo)</string>
<string name="rule_book_content">正文規則 (content)</string>
<string name="rule_next_content">正文下一頁 URL 規則 (nextContentUrl)</string>
<string name="rule_web_js">WebViewJs(webJs)</string>
<string name="rule_web_js">WebViewJs (webJs)</string>
<string name="rule_source_regex">資源正則 (sourceRegex)</string>
<string name="source_icon">圖標 (sourceIcon)</string>
<string name="r_articles">列表規則 (ruleArticles)</string>
@ -672,10 +672,10 @@
<string name="contributors">開發人員</string>
<string name="contact">聯繫我們</string>
<string name="license">開源許可</string>
<string name="follow_official_account">關注公</string>
<string name="follow_official_account">關注公</string>
<string name="wechat">WeChat</string>
<string name="thanks">你的支持是我更新的動力</string>
<string name="about_official_account">众号[开源阅读]</string>
<string name="about_official_account">眾號[开源阅读]</string>
<string name="source_auto_changing">正在自動換源</string>
<string name="click_to_apply">點擊加入</string>
<string name="middle"></string>
@ -716,46 +716,46 @@
<string name="already_in_download">該書已在下載列表</string>
<string name="click_to_open">點擊打開</string>
<string name="follow_public_account_summary">關注[legado-top]點擊廣告支持我</string>
<string name="weChat_appreciation_code">微信赞赏码</string>
<string name="weChat_appreciation_code">微信讚賞碼</string>
<string name="alipay">支付寶</string>
<string name="alipay_red_envelope_search_code">支付寶紅包搜索碼</string>
<string name="alipay_red_envelope_copy">537954522 點擊複製</string>
<string name="alipay_red_envelope_qr_code">支付寶紅包二維碼</string>
<string name="alipay_payment_qr_code">支付寶收款二維碼</string>
<string name="qq_collection_qr_code">QQ收款二維碼</string>
<string name="contributors_summary">gedoor,Invinciblelee等,详情请在github中查看</string>
<string name="contributors_summary">gedoor,Invinciblelee等,詳情請在github中查看</string>
<string name="clear_cache_summary">清除已下載書籍和字體緩存</string>
<string name="default_cover">默認封面</string>
<string name="restore_ignore">恢復忽略列表</string>
<string name="restore_ignore_summary">恢復時忽略一些內容不恢復,方便不同手機配置不同</string>
<string name="read_config">閱讀界面設置</string>
<string name="rule_image_style">图片样式(imageStyle)</string>
<string name="rule_replace_regex">换规则(replaceRegex)</string>
<string name="rule_image_style">圖片樣式 (imageStyle)</string>
<string name="rule_replace_regex">換規則 (replaceRegex)</string>
<string name="group_name">分組名稱</string>
<string name="note_content">備註內容</string>
<string name="replace_enable_default_t">认启用替换净</string>
<string name="replace_enable_default_s">新加入书架的书是否启用替换净</string>
<string name="select_restore_file">选择恢复文件</string>
<string name="replace_enable_default_t">認啟用替換淨</string>
<string name="replace_enable_default_s">新加入書架的書是否啟用替換淨</string>
<string name="select_restore_file">選擇恢復文件</string>
<string name="day_background_too_dark">白天背景不能太暗</string>
<string name="day_bottom_bar_too_dark">白天底不能太暗</string>
<string name="night_background_too_light">背景不能太亮</string>
<string name="night_bottom_bar_too_light">间底栏不能太亮</string>
<string name="accent_background_diff">强调色不能和背景颜色相似</string>
<string name="accent_text_diff">强调色不能和文字颜色相似</string>
<string name="day_bottom_bar_too_dark">白天底不能太暗</string>
<string name="night_background_too_light">背景不能太亮</string>
<string name="night_bottom_bar_too_light">間底欄不能太亮</string>
<string name="accent_background_diff">強調色不能和背景顏色相似</string>
<string name="accent_text_diff">強調色不能和文字顏色相似</string>
<string name="wrong_format">格式不對</string>
<string name="error">錯誤</string>
<string name="show_brightness_view">顯示亮度調節控制項</string>
<string name="language">語言</string>
<string name="import_rss_source">匯入訂閱源</string>
<string name="donate_summary">您嘅支援我更新嘅動力</string>
<string name="about_summary">众号[开源阅读软件]</string>
<string name="donate_summary">您嘅支援我更新嘅動力</string>
<string name="about_summary">眾號[开源阅读软件]</string>
<string name="read_record">閲讀記錄</string>
<string name="read_record_summary">閱讀時間記錄</string>
<string name="local_tts">本地TTS</string>
<string name="thread_count">線程數</string>
<string name="all_read_time">總閲讀時間</string>
<string name="un_select_all">全部唔要</string>
<string name="delete_all">除所有</string>
<string name="delete_all">除所有</string>
<string name="import_str">導入</string>
<string name="export_str">導出</string>
<string name="save_theme_config">儲存主題配置</string>
@ -789,7 +789,7 @@
<string name="non_action">無操作</string>
<string name="body_title">正文標題</string>
<string name="show_hide">顯示/隱藏</string>
<string name="header_footer">页眉<![CDATA[&]]>页脚</string>
<string name="header_footer">頁眉<![CDATA[&]]>頁腳</string>
<string name="rule_subscription">規則訂閱</string>
<string name="rule_sub_empty_msg">添加大佬們提供的規則匯入地址 添加後點擊可匯入規則</string>
<string name="get_book_progress">拉取雲端進度</string>
@ -804,6 +804,9 @@
<string name="pre_download_s">預先下載%s章正文</string>
<string name="is_enabled">係咪啟用</string>
<string name="background_image">背景圖片</string>
<string name="background_image_blurring">背景圖片虛化</string>
<string name="background_image_blurring_radius">虛化半徑</string>
<string name="background_image_hint">0為停用,啓用範圍1~25\n半徑數值越大,虛化效果越高</string>
<string name="export_folder">導出資料夾</string>
<string name="export_charset">導出編碼</string>
<string name="export_to_web_dav">導出到WebDav</string>
@ -836,14 +839,15 @@
<string name="hide_when_status_bar_show">狀態欄顯示時隱藏</string>
<string name="diy_source_group">自訂源分組</string>
<string name="diy_edit_source_group">輸入自訂源分組名稱</string>
<string name="reverse_toc">转目录</string>
<string name="show_discovery">显示发现</string>
<string name="style"></string>
<string name="group_style">组样</string>
<string name="export_file_name">出文件名</string>
<string name="reverse_toc">轉目錄</string>
<string name="show_discovery">顯示發現</string>
<string name="style"></string>
<string name="group_style">組樣</string>
<string name="export_file_name">出文件名</string>
<string name="reset">重置</string>
<string name="null_url">url</string>
<string name="null_url">url</string>
<string name="dict">字典</string>
<string name="unknown_error">未知错误</string>
<string name="unknown_error">未知錯誤</string>
<string name="end">end</string>
</resources>

@ -6,8 +6,8 @@
</string-array>
<string-array name="group_style">
<item>标签</item>
<item>文件</item>
<item>標籤</item>
<item>文件</item>
</string-array>
<string-array name="text_suffix">

@ -345,7 +345,7 @@
<string name="pt_show_all_find">顯示所有發現</string>
<string name="ps_show_all_find">關閉則只顯示勾選源的發現</string>
<string name="update_toc">更新目錄</string>
<string name="txt_toc_regex">Txt目錄正則</string>
<string name="txt_toc_regex">TXT目錄正則</string>
<string name="set_charset">設定編碼</string>
<string name="swap_sort">倒序-順序</string>
<string name="sort">排序</string>
@ -807,6 +807,9 @@
<string name="pre_download_s">預先下載%s章正文</string>
<string name="is_enabled">是否啟用</string>
<string name="background_image">背景圖片</string>
<string name="background_image_blurring">背景圖片虛化</string>
<string name="background_image_blurring_radius">虛化半徑</string>
<string name="background_image_hint">0為停用,啓用範圍1~25\n半徑數值越大,虛化效果越高</string>
<string name="export_folder">匯出資料夾</string>
<string name="export_charset">匯出編碼</string>
<string name="export_to_web_dav">匯出到WebDav</string>
@ -843,8 +846,9 @@
<string name="group_style">分組樣式</string>
<string name="export_file_name">匯出檔案名</string>
<string name="reset">重設</string>
<string name="null_url">url</string>
<string name="null_url">url</string>
<string name="dict">字典</string>
<string name="unknown_error">未知错误</string>
<string name="unknown_error">未知錯誤</string>
<string name="end">end</string>
</resources>

@ -807,6 +807,9 @@
<string name="pre_download_s">预先下载%s章正文</string>
<string name="is_enabled">是否启用</string>
<string name="background_image">背景图片</string>
<string name="background_image_blurring">背景图片虚化</string>
<string name="background_image_blurring_radius">虚化半径</string>
<string name="background_image_hint">0为停用,启用范围1~25\n半径数值越大,虚化效果越高</string>
<string name="export_folder">导出文件夹</string>
<string name="export_charset">导出编码</string>
<string name="export_to_web_dav">导出到WebDav</string>
@ -847,5 +850,6 @@
<string name="dict">字典</string>
<string name="unknown_error">未知错误</string>
<string name="autobackup_fail">自动备份失败</string>
<string name="end">结束</string>
</resources>

@ -807,6 +807,9 @@
<string name="pre_download_s">Download %s chapters in advance</string>
<string name="is_enabled">Is enabled</string>
<string name="background_image">Background image</string>
<string name="background_image_blurring">Background image blurring</string>
<string name="background_image_blurring_radius">Blurring radius</string>
<string name="background_image_hint">Disabled when 0, enable range from 1 to 25\nThe greater the radius, the stronger the effect of blurring</string>
<string name="copy_book_url">Copy book URL</string>
<string name="copy_toc_url">Copy chapters URL</string>
<string name="export_folder">Export folder</string>
@ -849,5 +852,6 @@
<string name="dict">字典</string>
<string name="unknown_error">未知错误</string>
<string name="autobackup_fail">Autobackup failed</string>
<string name="end">end</string>
</resources>

@ -82,10 +82,6 @@
app:cpv_dialogType="preset"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="backgroundImage"
android:title="@string/background_image" />
<io.legado.app.ui.widget.prefs.ColorPreference
android:defaultValue="@color/md_grey_200"
android:key="colorBottomBackground"
@ -96,12 +92,13 @@
app:cpv_dialogType="preset"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="backgroundImage"
android:title="@string/background_image" />
<io.legado.app.ui.widget.prefs.Preference
android:key="defaultCover"
android:title="@string/default_cover"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
android:title="@string/default_cover" />
<io.legado.app.ui.widget.prefs.Preference
android:key="saveDayTheme"
@ -145,10 +142,6 @@
app:cpv_dialogType="preset"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="backgroundImageNight"
android:title="@string/background_image" />
<io.legado.app.ui.widget.prefs.ColorPreference
android:defaultValue="@color/md_grey_800"
android:key="colorBottomBackgroundNight"
@ -157,17 +150,20 @@
app:cpv_dialogType="preset"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="backgroundImageNight"
android:title="@string/background_image" />
<io.legado.app.ui.widget.prefs.Preference
android:key="defaultCoverDark"
android:title="@string/default_cover"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
android:title="@string/default_cover" />
<io.legado.app.ui.widget.prefs.Preference
android:key="saveNightTheme"
android:summary="@string/save_night_theme_summary"
android:title="@string/save_theme_config"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
</io.legado.app.ui.widget.prefs.PreferenceCategory>

Loading…
Cancel
Save