diff --git a/app/build.gradle b/app/build.gradle index 71aab6b30..4542baf8e 100644 --- a/app/build.gradle +++ b/app/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' } \ No newline at end of file diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 2d7ed84c1..77ec900db 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -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) diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index 5791d7007..019325cd0 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -26,7 +26,6 @@ class App : MultiDexApplication() { createNotificationChannels() applyDayNight(this) LiveEventBus.config() - .supportBroadcast(this) .lifecycleObserverAlwaysActive(true) .autoClear(false) registerActivityLifecycleCallbacks(ActivityHelp) diff --git a/app/src/main/java/io/legado/app/base/BaseService.kt b/app/src/main/java/io/legado/app/base/BaseService.kt index 192737447..1ed5077c3 100644 --- a/app/src/main/java/io/legado/app/base/BaseService.kt +++ b/app/src/main/java/io/legado/app/base/BaseService.kt @@ -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() diff --git a/app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt b/app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt index 6cb5892b5..1577e6bda 100644 --- a/app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt +++ b/app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt @@ -24,6 +24,10 @@ class Coroutine( return Coroutine(scope, context, block) } + fun cancel() { + DEFAULT.cancel() + } + } private val job: Job diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt b/app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt index 414b0d891..2b6462827 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/RuleAnalyzer.kt @@ -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) diff --git a/app/src/main/java/io/legado/app/service/DownloadService.kt b/app/src/main/java/io/legado/app/service/DownloadService.kt index 990271808..156f9eccf 100644 --- a/app/src/main/java/io/legado/app/service/DownloadService.kt +++ b/app/src/main/java/io/legado/app/service/DownloadService.kt @@ -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) diff --git a/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt b/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt index bccf89319..0bdebe5a0 100644 --- a/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt +++ b/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt @@ -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() diff --git a/app/src/main/java/io/legado/app/service/TTSReadAloudService.kt b/app/src/main/java/io/legado/app/service/TTSReadAloudService.kt index 60cb11bdf..d814d4e09 100644 --- a/app/src/main/java/io/legado/app/service/TTSReadAloudService.kt +++ b/app/src/main/java/io/legado/app/service/TTSReadAloudService.kt @@ -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() diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index 31adc1e33..569f50430 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -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) diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt index a67c7e7f8..4cadba770 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt @@ -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) } } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt index 0658d5b5a..911eb3ad0 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt @@ -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) } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index d0f138e1f..ce1f7e710 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -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 diff --git a/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt b/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt index 906fc8ebc..75f8e30b0 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt @@ -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 + private val moreMenuItems: List 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(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 + ) { + 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) } } diff --git a/app/src/main/java/io/legado/app/ui/book/search/HistoryKeyAdapter.kt b/app/src/main/java/io/legado/app/ui/book/search/HistoryKeyAdapter.kt index 660410c44..f7bbd8297 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/HistoryKeyAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/HistoryKeyAdapter.kt @@ -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) } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt index 8d6da964f..03f1deb8e 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt @@ -366,4 +366,8 @@ class SearchActivity : VMBaseActivity= 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) diff --git a/app/src/main/java/io/legado/app/utils/EventBusExtensions.kt b/app/src/main/java/io/legado/app/utils/EventBusExtensions.kt index c0aedf8b3..0293e4893 100644 --- a/app/src/main/java/io/legado/app/utils/EventBusExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/EventBusExtensions.kt @@ -13,11 +13,15 @@ inline fun eventObservable(tag: String): Observable { } inline fun postEvent(tag: String, event: EVENT) { - LiveEventBus.get(tag).post(event) + LiveEventBus.get(tag).post(event) } inline fun postEventDelay(tag: String, event: EVENT, delay: Long) { - LiveEventBus.get(tag).postDelay(event, delay) + LiveEventBus.get(tag).postDelay(event, delay) +} + +inline fun postEventOrderly(tag: String, event: EVENT) { + LiveEventBus.get(tag).postOrderly(event) } inline fun AppCompatActivity.observeEvent( @@ -32,7 +36,6 @@ inline fun AppCompatActivity.observeEvent( } } - inline fun AppCompatActivity.observeEventSticky( vararg tags: String, noinline observer: (EVENT) -> Unit @@ -67,5 +70,4 @@ inline fun Fragment.observeEventSticky( tags.forEach { eventObservable(it).observeSticky(this, o) } -} - +} \ No newline at end of file diff --git a/app/src/main/res/layout/popup_action_menu.xml b/app/src/main/res/layout/popup_action_menu.xml index 74b43c301..ab9a681b8 100644 --- a/app/src/main/res/layout/popup_action_menu.xml +++ b/app/src/main/res/layout/popup_action_menu.xml @@ -1,9 +1,46 @@ - \ No newline at end of file + android:orientation="vertical"> + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/content_select_action.xml b/app/src/main/res/menu/content_select_action.xml index 63a4bb184..dda5324dd 100644 --- a/app/src/main/res/menu/content_select_action.xml +++ b/app/src/main/res/menu/content_select_action.xml @@ -1,5 +1,6 @@ - + + android:title="@string/search_content" + app:showAsAction="never" /> + android:title="@string/browser" + app:showAsAction="never" /> + android:title="@string/share" + app:showAsAction="never" /> \ No newline at end of file diff --git a/build.gradle b/build.gradle index 3663614be..4e78684d5 100644 --- a/build.gradle +++ b/build.gradle @@ -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' } }