Merge remote-tracking branch 'origin/master' into master

# Conflicts:
#	app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt
pull/1114/head
bushixuanqi 3 years ago
commit 174d139988
  1. 26
      app/build.gradle
  2. 122
      app/src/main/assets/updateLog.md
  3. 1
      app/src/main/java/io/legado/app/App.kt
  4. 13
      app/src/main/java/io/legado/app/base/BaseService.kt
  5. 4
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  6. 12
      app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt
  7. 5
      app/src/main/java/io/legado/app/service/DownloadService.kt
  8. 7
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt
  9. 7
      app/src/main/java/io/legado/app/service/TTSReadAloudService.kt
  10. 12
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  11. 6
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt
  12. 7
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt
  13. 11
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  14. 83
      app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt
  15. 9
      app/src/main/java/io/legado/app/ui/book/search/HistoryKeyAdapter.kt
  16. 4
      app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt
  17. 4
      app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt
  18. 7
      app/src/main/java/io/legado/app/ui/dict/DictDialog.kt
  19. 12
      app/src/main/java/io/legado/app/utils/EventBusExtensions.kt
  20. 47
      app/src/main/res/layout/popup_action_menu.xml
  21. 12
      app/src/main/res/menu/content_select_action.xml
  22. 2
      build.gradle

@ -122,6 +122,10 @@ dependencies {
implementation 'androidx.multidex:multidex:2.0.1'
//kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
//
def coroutines_version = '1.5.1'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
//androidX
implementation 'androidx.appcompat:appcompat:1.3.0'
@ -162,18 +166,13 @@ dependencies {
testImplementation "androidx.room:room-testing:$room_version"
//liveEventBus
implementation 'com.jeremyliao:live-event-bus-x:1.5.7'
//
def coroutines_version = '1.4.3'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
implementation 'io.github.jeremyliao:live-event-bus-x:1.8.0'
//
implementation 'org.jsoup:jsoup:1.13.1'
//noinspection GradleDependency
implementation 'cn.wanghaomiao:JsoupXpath:2.3.2'
implementation 'com.jayway.jsonpath:json-path:2.5.0'
implementation 'com.jayway.jsonpath:json-path:2.6.0'
//JS rhino
implementation 'com.github.gedoor:rhino-android:1.5'
@ -189,7 +188,7 @@ dependencies {
implementation 'org.nanohttpd:nanohttpd-websocket:2.3.1'
//
implementation 'com.king.zxing:zxing-lite:2.0.3'
implementation 'com.github.jenly1314:zxing-lite:2.1.0'
//
implementation 'com.jaredrummler:colorpicker:1.1.0'
@ -198,12 +197,13 @@ dependencies {
implementation 'org.apache.commons:commons-text:1.9'
//MarkDown
implementation 'io.noties.markwon:core:4.6.0'
implementation 'io.noties.markwon:image-glide:4.6.0'
implementation 'io.noties.markwon:ext-tables:4.6.0'
implementation 'io.noties.markwon:html:4.6.0'
def markwonVersion = "4.6.2"
implementation "io.noties.markwon:core:$markwonVersion"
implementation "io.noties.markwon:image-glide:$markwonVersion"
implementation "io.noties.markwon:ext-tables:$markwonVersion"
implementation "io.noties.markwon:html:$markwonVersion"
//
implementation 'com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core:0.2.0'
implementation 'com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core:0.2.1'
}

@ -8,6 +8,10 @@
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则出现问题。先关闭替换净化并刷新,再观察是否正常。如果正常说明净化规则存在误杀,如果关闭后仍然出现相关问题,请点击源链接查看原文与正文是否相同,如果不同,再进行反馈。
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
**2021/07/10**
1. 阅读界面长按菜单改回原来样式
2. 解决导入书源时重命名分组和保留名称冲突的问题
**2021/07/09**
1. 发现url添加json格式, 支持设置标签样式
* 样式属性可以搜索 [FleboxLayout子元素支持的属性介绍](https://www.jianshu.com/p/3c471953e36d)
@ -77,10 +81,6 @@ chapter.html的关键字有{title}、{content}
其他html文件的关键字有{name}、{author}、{intro}、{kind}、{wordCount}
```
**2021/05/26**
* 书签绑定书名与作者
* 修复详情页目录问题
**2021/05/24**
* 反转目录后刷新内容
* 修复上下滑动会导致左右切换问题
@ -97,23 +97,6 @@ chapter.html的关键字有{title}、{content}
* 添加一种语言 ptbr translation by mezysinc
* epublib 修bug by ag2s20150909
**2021/05/12**
* 修复预下载bug
* 添加显示未读开关,书架布局中
**2021/05/11**
* 修复部分webDav bug
* 修复图片太大时会崩溃的bug
* 修复其它一些bug
**2021/05/10**
* 修复书签bug
* 修改弃用类ViewPager
**2021/05/09**
* 网页访问404依然返回body
* 添加书籍批量导出
**2021/05/08**
* 预下载章节可调整数目
* 修复低版本Android使用TTS闪退。 by ag2s20150909
@ -137,10 +120,6 @@ chapter.html的关键字有{title}、{content}
* 添加规则订阅时判断重复提醒
* 添加恢复预设布局的功能, 添加一个微信读书布局作为预设布局
**2021/04/13**
* 修复导入布局bug
* 修复订阅切换布局bug
**2021/04/08**
* 缓存时重新检查并缓存图片
* 订阅源调试添加源码查看
@ -233,9 +212,6 @@ chapter.html的关键字有{title}、{content}
* play版可以设置背景图片
* 添加几个js方法,见io.legado.app.help.JsExtensions
**2021/01/20**
* 更新在线朗读
**2021/01/18**
* 增加三星 S Pen 支持 by [dacer](https://github.com/dacer)
* 订阅添加阅读下载,可以从多个渠道下载
@ -247,9 +223,6 @@ chapter.html的关键字有{title}、{content}
* 换源刷新之前删除原搜索记录
* 优化web调试
**2021/01/05**
* 修复崩溃bug
**2021/01/03**
* 导出书单只保留书名与作者,导入时自动查找可用源
* 添加预加载设置
@ -271,23 +244,11 @@ chapter.html的关键字有{title}、{content}
* 订阅源添加单url选项,直接打开url
* 订阅源可以put,get数据
**2020/12/17**
* 继续修复bug
**2020/12/16**
* 修复上版本因更新组件引起的一些bug
* 搜索一点都不闪了
**2020/12/15**
* 修复一些引起崩溃的bug
* 修复搜书和换源可能什么分组都没有的bug
* 添加同步进度开关,默认开启,在备份与恢复里面
**2020/12/14**
* 修复bug
* 电池图标不允许改字体
* 升级js库
**2020/12/13**
* 修复bug
* 网络访问框架修改为RxHttp, 有bug及时反馈
@ -295,9 +256,6 @@ chapter.html的关键字有{title}、{content}
* 换源界面添加分组选择
* 沉浸模式时阅读界面导航栏透明
**2020/12/11**
* 修复因修改进度同步导致的bug
**2020/12/09**
* 修复bug
* 优化中文排序
@ -305,24 +263,12 @@ chapter.html的关键字有{title}、{content}
* 选择文字时优先选词
* 优化进度同步,进入书籍时同步,每次同步单本书,减少同步文件大小
**2020/12/06**
* 添加规则订阅功能,订阅界面第一个图标,可以订阅书源/订阅源/替换规则
**2020/12/04**
* 阅读进度从页数改为字数,排版变化时定位更准确
* 修改viewBinding
* 修复中文排序
* 去掉FontJs规则,可以写在替换规则里,示例可在帮助文档查看
**2020/11/30**
* 优化阅读界面设置
* 阅读界面显示信息添加时间及电量
* 阅读界面显示信息可以自定义颜色
* 修复bug
**2020/11/24**
* 修复音频bug
**2020/11/18**
* 优化导航栏
* js添加java.log(msg: String)用于调试时输出消息
@ -330,9 +276,6 @@ chapter.html的关键字有{title}、{content}
* js添加cache变量,可以用来存储token之类的临时值,可以设置保存时间,方法见io.legado.app.help.CacheManager
* 需要token的网站可以用js来写了,比如阿里tts
**2020/11/16**
* 修复导出添加替换净化引起的bug
**2020/11/15**
* 正文规则添加字体规则,返回ByteArray
* js添加方法:
@ -340,14 +283,6 @@ chapter.html的关键字有{title}、{content}
base64DecodeToByteArray(str: String?): ByteArray?
base64DecodeToByteArray(str: String?, flags: Int): ByteArray?
```
* 导出添加替换净化
* 修复正文内容TalkBack不对的bug,优化视障使用体验
**2020/11/08**
* 优化书源,订阅源导入,添加保持原名选项
* 优化使用体验,初次使用是自动弹出帮助文档
* 添加阅读界面的点击区域设置
* 滚动翻页时自动翻页也采用滚动模式
**2020/11/07**
* 详情页菜单添加拷贝URL
@ -358,22 +293,6 @@ base64DecodeToByteArray(str: String?, flags: Int): ByteArray?
* 自动分段优化 by [tumuyan](https://github.com/tumuyan)
* web支持图片显示 by [六月](https://github.com/Celeter)
**2020/11/01**
* 导入本地添加智能扫描,菜单-智能扫描,扫描当前文件夹包括子文件夹下所有文件
**2020/10/30**
* 修复bug
* 优化Android 11文件选择,本地导入
**2020/10/28**
* 修复SDK 30使用TTS问题
**2020/10/27**
* 点击书籍分组可显示书籍数量
* 升级到SDK30
* 修复8.0不显示默认背景图片的bug
* 添加排版命名
**2020/10/24**
* 修复选择错误的bug
* 修复长图最后一张不能滚动的bug
@ -386,36 +305,11 @@ java.getCookie("http://baidu.com", "userid") => 1234
* 每本书可以单独设置翻页动画,在菜单里
* 添加重新分段功能,针对每本书,在菜单里,分段代码来自[tumuyan](https://github.com/tumuyan)
**2020/10/21**
* 默认分组无书籍时自动隐藏
* 自定义翻页按键支持多个按键
**2020/10/19**
* 优化分组管理
* 修复预下载没有保存的bug
**2020/10/18**
* 优化分组管理,默认分组可以重命名了
* 修复书架空白的bug,是constraintlayout库新版本的bug
* 修复分组和崩溃bug
**2020/10/16**
* 修复排版导入背景失败bug
* 修改默认度逍遥per为5003,需要重新导入默认
* 优化规则解析
**2020/10/14**
* 优化替换规则编辑界面
* 修复网格书架间距变大bug
* 其它一些优化,bug修复
**2020/10/13**
* 更新android studio 到 4.1
* 书架整理增加滑动选择
**2020/10/12**
* 优化预下载,防止同时下载太多卡顿
**2020/10/11**
* 优化书源校验
* 语言切换bug修复 by [h11128](https://github.com/h11128)
@ -428,14 +322,6 @@ java.getCookie("http://baidu.com", "userid") => 1234
https://www.baidu.com,{"js":"java.headerMap.put('xxx', 'yyy')"}
https://www.baidu.com,{"js":"java.url=java.url+'yyyy'"}
```
* 修复bug
**2020/10/02**
* 优化规则解析
* 优化正文搜索
* 翻页动画跟随背景
* 双击发现折叠发现,再次双击滚动至顶端
* 修复bug
**2020/09/29**
* 增加了几个方法用于处理文件 by [Celeter](https://github.com/Celeter)

@ -26,7 +26,6 @@ class App : MultiDexApplication() {
createNotificationChannels()
applyDayNight(this)
LiveEventBus.config()
.supportBroadcast(this)
.lifecycleObserverAlwaysActive(true)
.autoClear(false)
registerActivityLifecycleCallbacks(ActivityHelp)

@ -3,6 +3,7 @@ package io.legado.app.base
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.annotation.CallSuper
import io.legado.app.help.coroutine.Coroutine
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -18,10 +19,22 @@ abstract class BaseService : Service(), CoroutineScope by MainScope() {
block: suspend CoroutineScope.() -> T
) = Coroutine.async(scope, context) { block() }
@CallSuper
override fun onCreate() {
super.onCreate()
}
@CallSuper
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
stopSelf()
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
@CallSuper
override fun onDestroy() {
super.onDestroy()
cancel()

@ -24,6 +24,10 @@ class Coroutine<T>(
return Coroutine(scope, context, block)
}
fun cancel() {
DEFAULT.cancel()
}
}
private val job: Job

@ -17,7 +17,7 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
val chompBalanced = if (code) ::chompCodeBalanced else ::chompRuleBalanced
fun trim() { // 修剪当前规则之前的"@"或者空白符
if(queue[pos] == '@' || queue[pos] < '!') { //为了减少不必要的去设置start或startX,先来个判断
if(queue[pos] == '@' || queue[pos] < '!') { //在while里重复设置start和startX会拖慢执行速度,所以先来个判断是否存在需要修剪的字段,最后再一次性设置start和startX
pos++
while (queue[pos] == '@' || queue[pos] < '!') pos++
start = pos //开始点推移
@ -300,10 +300,7 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
val next = if (queue[pos] == '[') ']' else ')' //平衡组末尾字符
if (!chompBalanced(queue[pos], next)) throw Error(
queue.substring(
0,
start
) + "后未平衡"
queue.substring(0,start) + "后未平衡"
) //拉出一个筛选器,不平衡则报错
} while (end > pos)
@ -360,10 +357,7 @@ class RuleAnalyzer(data: String, code: Boolean = false) {
val next = if (queue[pos] == '[') ']' else ')' //平衡组末尾字符
if (!chompBalanced(queue[pos], next)) throw Error(
queue.substring(
0,
start
) + "后未平衡"
queue.substring(0,start) + "后未平衡"
) //拉出一个筛选器,不平衡则报错
} while (end > pos)

@ -44,11 +44,6 @@ class DownloadService : BaseService() {
registerReceiver(downloadReceiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
stopSelf()
}
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(downloadReceiver)

@ -1,9 +1,7 @@
package io.legado.app.service
import android.app.PendingIntent
import android.content.Intent
import android.media.MediaPlayer
import io.legado.app.constant.EventBus
import io.legado.app.help.AppConfig
import io.legado.app.help.IntentHelp
@ -40,11 +38,6 @@ class HttpReadAloudService : BaseReadAloudService(),
player.setOnCompletionListener(this)
}
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
stopSelf()
}
override fun onDestroy() {
super.onDestroy()
task?.cancel()

@ -1,7 +1,6 @@
package io.legado.app.service
import android.app.PendingIntent
import android.content.Intent
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import io.legado.app.R
@ -29,12 +28,6 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
upSpeechRate()
}
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
clearTTS()
stopSelf()
}
override fun onDestroy() {
super.onDestroy()
clearTTS()

@ -16,10 +16,7 @@ import io.legado.app.ui.book.read.page.provider.ChapterProvider
import io.legado.app.ui.book.read.page.provider.ImageProvider
import io.legado.app.utils.msg
import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import splitties.init.appCtx
import kotlin.math.max
import kotlin.math.min
@ -139,7 +136,7 @@ object ReadBook {
callBack?.upContent()
}
loadContent(durChapterIndex.plus(1), upContent, false)
GlobalScope.launch(Dispatchers.IO) {
Coroutine.async {
val maxChapterIndex =
min(chapterSize - 1, durChapterIndex + AppConfig.preDownloadNum)
for (i in durChapterIndex.plus(2)..maxChapterIndex) {
@ -157,7 +154,10 @@ object ReadBook {
}
}
fun moveToPrevChapter(upContent: Boolean, toLast: Boolean = true): Boolean {
fun moveToPrevChapter(
upContent: Boolean,
toLast: Boolean = true
): Boolean {
if (durChapterIndex > 0) {
durChapterPos = if (toLast) prevTextChapter?.lastReadLength ?: 0 else 0
durChapterIndex--
@ -171,7 +171,7 @@ object ReadBook {
callBack?.upContent()
}
loadContent(durChapterIndex.minus(1), upContent, false)
GlobalScope.launch(Dispatchers.IO) {
Coroutine.async {
val minChapterIndex = max(0, durChapterIndex - 5)
for (i in durChapterIndex.minus(2) downTo minChapterIndex) {
delay(1000)

@ -53,9 +53,6 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
selectStatus.forEachIndexed { index, b ->
if (b) {
val source = allSources[index]
if (groupName != null) {
source.bookSourceGroup = groupName
}
if (keepName) {
checkSources[index]?.let {
source.bookSourceName = it.bookSourceName
@ -63,6 +60,9 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
source.customOrder = it.customOrder
}
}
if (groupName != null) {
source.bookSourceGroup = groupName
}
selectSource.add(source)
}
}

@ -50,15 +50,16 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {
selectStatus.forEachIndexed { index, b ->
if (b) {
val source = allSources[index]
if (groupName != null) {
source.sourceGroup = groupName
}
if (keepName) {
checkSources[index]?.let {
source.sourceName = it.sourceName
source.sourceGroup = it.sourceGroup
source.customOrder = it.customOrder
}
}
if (groupName != null) {
source.sourceGroup = groupName
}
selectSource.add(source)
}
}

@ -105,12 +105,7 @@ class ReadBookActivity : ReadBookBaseActivity(),
}
private var menu: Menu? = null
private val textActionMenu: TextActionMenu by lazy {
TextActionMenu(this, this).apply {
contentView.measure(
View.MeasureSpec.UNSPECIFIED,
View.MeasureSpec.UNSPECIFIED
)
}
TextActionMenu(this, this)
}
override val scope: CoroutineScope get() = this
@ -474,6 +469,10 @@ class ReadBookActivity : ReadBookBaseActivity(),
* 显示文本操作菜单
*/
override fun showTextActionMenu() = binding.run {
textActionMenu.contentView.measure(
View.MeasureSpec.UNSPECIFIED,
View.MeasureSpec.UNSPECIFIED
)
val popupHeight = textActionMenu.contentView.measuredHeight
val x = textMenuPosition.x.toInt()
var y = textMenuPosition.y.toInt() - popupHeight

@ -17,25 +17,24 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.view.SupportMenuInflater
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.view.menu.MenuItemImpl
import androidx.core.view.isVisible
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.databinding.ItemTextBinding
import io.legado.app.databinding.PopupActionMenuBinding
import io.legado.app.service.BaseReadAloudService
import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.sendToClip
import io.legado.app.utils.share
import io.legado.app.utils.toastOnUi
import splitties.views.onClick
import io.legado.app.utils.*
import java.util.*
@SuppressLint("RestrictedApi")
class TextActionMenu(private val context: Context, private val callBack: CallBack) :
PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT),
TextToSpeech.OnInitListener {
private val binding = PopupActionMenuBinding.inflate(LayoutInflater.from(context))
private val menu = MenuBuilder(context)
private val moreMenu = MenuBuilder(context)
private val adapter = Adapter(context)
private val visibleMenuItems: List<MenuItemImpl>
private val moreMenuItems: List<MenuItemImpl>
private val ttsListener by lazy {
TTSUtteranceListener()
}
@ -48,23 +47,71 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
isOutsideTouchable = false
isFocusable = false
SupportMenuInflater(context).inflate(R.menu.content_select_action, menu)
val myMenu = MenuBuilder(context)
val otherMenu = MenuBuilder(context)
SupportMenuInflater(context).inflate(R.menu.content_select_action, myMenu)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
onInitializeMenu(moreMenu)
onInitializeMenu(otherMenu)
}
visibleMenuItems = myMenu.visibleItems.subList(0, 5)
moreMenuItems =
myMenu.visibleItems.subList(5, myMenu.visibleItems.lastIndex) + otherMenu.visibleItems
initRecyclerView()
setOnDismissListener {
binding.ivMenuMore.setImageResource(R.drawable.ic_more_vert)
binding.recyclerViewMore.gone()
adapter.setItems(visibleMenuItems)
binding.recyclerView.visible()
}
}
private fun initRecyclerView() = with(binding) {
recyclerView.adapter = adapter
recyclerViewMore.adapter = adapter
adapter.setItems(visibleMenuItems)
ivMenuMore.visible()
ivMenuMore.setOnClickListener {
if (recyclerView.isVisible) {
ivMenuMore.setImageResource(R.drawable.ic_arrow_back)
adapter.setItems(moreMenuItems)
recyclerView.gone()
recyclerViewMore.visible()
} else {
ivMenuMore.setImageResource(R.drawable.ic_more_vert)
recyclerViewMore.gone()
adapter.setItems(visibleMenuItems)
recyclerView.visible()
}
}
}
inner class Adapter(context: Context) :
RecyclerAdapter<MenuItemImpl, ItemTextBinding>(context) {
override fun getViewBinding(parent: ViewGroup): ItemTextBinding {
return ItemTextBinding.inflate(inflater, parent, false)
}
val menuItems = menu.visibleItems + moreMenu.visibleItems
menuItems.forEach {
val textView = ItemTextBinding.inflate(LayoutInflater.from(context)).root.apply {
tag = it
text = it.title
onClick {
override fun convert(
holder: ItemViewHolder,
binding: ItemTextBinding,
item: MenuItemImpl,
payloads: MutableList<Any>
) {
with(binding) {
textView.text = item.title
}
}
override fun registerListener(holder: ItemViewHolder, binding: ItemTextBinding) {
holder.itemView.setOnClickListener {
getItem(holder.layoutPosition)?.let {
if (!callBack.onMenuItemSelected(it.itemId)) {
onMenuItemSelected(it)
}
callBack.onMenuActionFinally()
}
callBack.onMenuActionFinally()
}
binding.root.addView(textView)
}
}

@ -3,13 +3,9 @@ package io.legado.app.ui.book.search
import android.view.ViewGroup
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.data.appDb
import io.legado.app.data.entities.SearchKeyword
import io.legado.app.databinding.ItemFilletTextBinding
import io.legado.app.ui.widget.anima.explosion_field.ExplosionField
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import splitties.views.onLongClick
class HistoryKeyAdapter(activity: SearchActivity, val callBack: CallBack) :
@ -42,9 +38,7 @@ class HistoryKeyAdapter(activity: SearchActivity, val callBack: CallBack) :
onLongClick {
explosionField.explode(this, true)
getItem(holder.layoutPosition)?.let {
GlobalScope.launch(IO) {
appDb.searchKeywordDao.delete(it)
}
callBack.deleteHistory(it)
}
}
}
@ -52,5 +46,6 @@ class HistoryKeyAdapter(activity: SearchActivity, val callBack: CallBack) :
interface CallBack {
fun searchHistory(key: String)
fun deleteHistory(searchKeyword: SearchKeyword)
}
}

@ -366,4 +366,8 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
}
}
}
override fun deleteHistory(searchKeyword: SearchKeyword) {
viewModel.deleteHistory(searchKeyword)
}
}

@ -186,6 +186,10 @@ class SearchViewModel(application: Application) : BaseViewModel(application),
}
}
fun deleteHistory(searchKeyword: SearchKeyword) {
appDb.searchKeywordDao.delete(searchKeyword)
}
override fun onCleared() {
super.onCleared()
searchBookModel.close()

@ -1,5 +1,6 @@
package io.legado.app.ui.dict
import android.os.Build
import android.os.Bundle
import android.text.Html
import android.text.method.LinkMovementMethod
@ -59,7 +60,11 @@ class DictDialog : BaseDialogFragment() {
}
viewModel.dictHtmlData.observe(viewLifecycleOwner) {
binding.rotateLoading.invisible()
binding.tvDict.text = Html.fromHtml(it)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
binding.tvDict.text = Html.fromHtml(it, Html.FROM_HTML_MODE_LEGACY)
} else {
binding.tvDict.text = Html.fromHtml(it)
}
}
viewModel.dict(word)

@ -13,11 +13,15 @@ inline fun <reified EVENT> eventObservable(tag: String): Observable<EVENT> {
}
inline fun <reified EVENT> postEvent(tag: String, event: EVENT) {
LiveEventBus.get(tag).post(event)
LiveEventBus.get<EVENT>(tag).post(event)
}
inline fun <reified EVENT> postEventDelay(tag: String, event: EVENT, delay: Long) {
LiveEventBus.get(tag).postDelay(event, delay)
LiveEventBus.get<EVENT>(tag).postDelay(event, delay)
}
inline fun <reified EVENT> postEventOrderly(tag: String, event: EVENT) {
LiveEventBus.get<EVENT>(tag).postOrderly(event)
}
inline fun <reified EVENT> AppCompatActivity.observeEvent(
@ -32,7 +36,6 @@ inline fun <reified EVENT> AppCompatActivity.observeEvent(
}
}
inline fun <reified EVENT> AppCompatActivity.observeEventSticky(
vararg tags: String,
noinline observer: (EVENT) -> Unit
@ -67,5 +70,4 @@ inline fun <reified EVENT> Fragment.observeEventSticky(
tags.forEach {
eventObservable<EVENT>(it).observeSticky(this, o)
}
}
}

@ -1,9 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/shape_card_view"
android:padding="5dp"
app:flexDirection="row"
app:flexWrap="wrap" />
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_menu_more"
android:layout_width="24dp"
android:layout_height="24dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_more_vert"
android:tint="@color/primaryText"
android:visibility="gone"
android:contentDescription="@string/more_menu" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_replace"
@ -23,13 +24,16 @@
<item
android:id="@+id/menu_search_content"
android:title="@string/search_content" />
android:title="@string/search_content"
app:showAsAction="never" />
<item
android:id="@+id/menu_browser"
android:title="@string/browser" />
android:title="@string/browser"
app:showAsAction="never" />
<item
android:id="@+id/menu_share_str"
android:title="@string/share" />
android:title="@string/share"
app:showAsAction="never" />
</menu>

@ -4,6 +4,7 @@ buildscript {
ext.kotlin_version = '1.5.20'
repositories {
google()
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://plugins.gradle.org/m2/' }
@ -18,6 +19,7 @@ buildscript {
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://jitpack.io' }
}

Loading…
Cancel
Save