Merge branch 'master' of github.com:AndyBernie/legado into master

pull/341/head
AndyBernie 5 years ago
commit 12b17cc37f
  1. 24
      app/src/main/assets/httpTTS.json
  2. 5
      app/src/main/assets/updateLog.md
  3. 5
      app/src/main/java/io/legado/app/App.kt
  4. 9
      app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt
  5. 6
      app/src/main/java/io/legado/app/data/entities/ReadRecordShow.kt
  6. 19
      app/src/main/java/io/legado/app/help/DefaultValueHelp.kt
  7. 10
      app/src/main/java/io/legado/app/help/JsExtensions.kt
  8. 13
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  9. 4
      app/src/main/java/io/legado/app/model/localBook/AnalyzeTxtFile.kt
  10. 5
      app/src/main/java/io/legado/app/model/webBook/BookList.kt
  11. 9
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  12. 2
      app/src/main/java/io/legado/app/ui/about/AboutFragment.kt
  13. 14
      app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt
  14. 5
      app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt
  15. 5
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt
  16. 5
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt
  17. 5
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt
  18. 5
      app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt
  19. 5
      app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt
  20. 5
      app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt
  21. 5
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt
  22. 5
      app/src/main/java/io/legado/app/ui/book/chapterlist/BookmarkFragment.kt
  23. 11
      app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt
  24. 5
      app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt
  25. 5
      app/src/main/java/io/legado/app/ui/book/download/DownloadActivity.kt
  26. 3
      app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt
  27. 3
      app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt
  28. 3
      app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt
  29. 5
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  30. 3
      app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt
  31. 3
      app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt
  32. 29
      app/src/main/java/io/legado/app/ui/book/read/Help.kt
  33. 15
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  34. 11
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt
  35. 34
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt
  36. 3
      app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt
  37. 11
      app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt
  38. 5
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  39. 3
      app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt
  40. 6
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  41. 13
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt
  42. 7
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt
  43. 3
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt
  44. 5
      app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt
  45. 3
      app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt
  46. 3
      app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt
  47. 5
      app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt
  48. 3
      app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt
  49. 5
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt
  50. 5
      app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt
  51. 3
      app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt
  52. 5
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt
  53. 3
      app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt
  54. 5
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt
  55. 31
      app/src/main/res/layout/item_chapter_list.xml
  56. 11
      app/src/main/res/menu/speak_engine.xml

@ -2,61 +2,61 @@
{
"id": 1598233029304,
"name": "度小美",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029305,
"name": "度小宇",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029306,
"name": "度逍遥",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029307,
"name": "度丫丫",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029308,
"name": "度小娇",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029309,
"name": "度米朵",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029310,
"name": "度博文",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029311,
"name": "度小童",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029312,
"name": "度小萌",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029313,
"name": "百度骚男",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=11&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=11&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029314,
"name": "百度评书",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
},
{
"id": 1598233029315,
"name": "百度主持",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}"
}
]

@ -3,6 +3,11 @@
* 关注合作公众号 **[小说拾遗]()** 获取好看的小说。
- 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
**2020/08/26**
* js添加java.encodeURI(speakText),用于解决js编码时有~的语句朗读不出来
* 修复书名太长删除阅读记录按钮不显示的bug
* 完成本地书籍编码选择
**2020/08/25**
* 阅读记录可以删除了
* 修复翻页模式选择颜色问题

@ -37,11 +37,10 @@ class App : MultiDexApplication() {
private set
lateinit var androidId: String
var versionCode = 0
var versionName = ""
}
var versionCode = 0
var versionName = ""
override fun onCreate() {
super.onCreate()
INSTANCE = this

@ -2,6 +2,7 @@ package io.legado.app.data.dao
import androidx.room.*
import io.legado.app.data.entities.ReadRecord
import io.legado.app.data.entities.ReadRecordShow
@Dao
interface ReadRecordDao {
@ -9,12 +10,18 @@ interface ReadRecordDao {
@get:Query("select * from readRecord")
val all: List<ReadRecord>
@get:Query("select bookName, sum(readTime) as readTime from readRecord group by bookName")
val allShow: List<ReadRecordShow>
@get:Query("select sum(readTime) from readRecord")
val allTime: Long
@Query("select sum(readTime) from readRecord where bookName = :bookName")
fun getReadTime(bookName: String): Long?
@Query("select readTime from readRecord where androidId = :androidId and bookName = :bookName")
fun getReadTime(androidId: String, bookName: String): Long?
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(vararg readRecord: ReadRecord)
@ -24,4 +31,6 @@ interface ReadRecordDao {
@Delete
fun delete(vararg record: ReadRecord)
@Query("delete from readRecord where bookName = :bookName")
fun deleteByName(bookName: String)
}

@ -0,0 +1,6 @@
package io.legado.app.data.entities
data class ReadRecordShow(
var bookName: String = "",
var readTime: Long = 0L
)

@ -0,0 +1,19 @@
package io.legado.app.help
import io.legado.app.App
import io.legado.app.data.entities.HttpTTS
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
object DefaultValueHelp {
fun initHttpTTS() {
val json = String(App.INSTANCE.assets.open("httpTTS.json").readBytes())
GSON.fromJsonArray<HttpTTS>(json)?.let {
App.db.httpTTSDao().insert(*it.toTypedArray())
}
}
}

@ -6,6 +6,7 @@ import io.legado.app.constant.AppConst.dateFormat
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.utils.EncoderUtils
import io.legado.app.utils.MD5Utils
import java.net.URLEncoder
import java.util.*
@Keep
@ -52,10 +53,19 @@ interface JsExtensions {
fun timeFormat(time: Long): String {
return dateFormat.format(Date(time))
}
//utf8编码转gbk编码
fun utf8ToGbk(str: String): String {
val utf8 = String(str.toByteArray(charset("UTF-8")))
val unicode = String(utf8.toByteArray(), charset("UTF-8"))
return String(unicode.toByteArray(charset("GBK")))
}
fun encodeURI(str: String): String {
return try {
URLEncoder.encode(str, "UTF-8")
} catch (e: Exception) {
""
}
}
}

@ -135,7 +135,18 @@ object Restore {
App.db.txtTocRule().insert(*it.toTypedArray())
}
fileToListT<ReadRecord>(path, "readRecord.json")?.let {
App.db.readRecordDao().insert(*it.toTypedArray())
it.forEach { readRecord ->
//判断是不是本机记录
if (readRecord.androidId != App.androidId) {
App.db.readRecordDao().insert(readRecord)
} else {
val time = App.db.readRecordDao()
.getReadTime(readRecord.androidId, readRecord.bookName)
if (time == null || time < readRecord.readTime) {
App.db.readRecordDao().insert(readRecord)
}
}
}
}
fileToListT<HttpTTS>(path, "httpTTS.json")?.let {
App.db.httpTTSDao().insert(*it.toTypedArray())

@ -20,7 +20,9 @@ class AnalyzeTxtFile {
@Throws(Exception::class)
fun analyze(book: Book): ArrayList<BookChapter> {
val bookFile = getBookFile(book)
book.charset = EncodingDetect.getEncode(bookFile)
if (book.charset == null) {
book.charset = EncodingDetect.getEncode(bookFile)
}
charset = book.fileCharset()
val rulePattern = if (book.tocUrl.isNotEmpty()) {
Pattern.compile(book.tocUrl, Pattern.MULTILINE)

@ -11,6 +11,7 @@ import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.utils.NetworkUtils
import io.legado.app.utils.StringUtils.wordCountFormat
import io.legado.app.utils.htmlFormat
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.isActive
@ -161,7 +162,7 @@ object BookList {
Debug.log(bookSource.bookSourceUrl, "${searchBook.latestChapterTitle}")
if (!scope.isActive) throw CancellationException()
Debug.log(bookSource.bookSourceUrl, "┌获取简介")
searchBook.intro = analyzeRule.getString(intro)
searchBook.intro = analyzeRule.getString(intro).htmlFormat()
Debug.log(bookSource.bookSourceUrl, "${searchBook.intro}", true)
if (!scope.isActive) throw CancellationException()
Debug.log(bookSource.bookSourceUrl, "┌获取封面链接")
@ -221,7 +222,7 @@ object BookList {
Debug.log(bookSource.bookSourceUrl, "${searchBook.latestChapterTitle}", log)
if (!scope.isActive) throw CancellationException()
Debug.log(bookSource.bookSourceUrl, "┌获取简介", log)
searchBook.intro = analyzeRule.getString(ruleIntro)
searchBook.intro = analyzeRule.getString(ruleIntro).htmlFormat()
Debug.log(bookSource.bookSourceUrl, "${searchBook.intro}", log, true)
if (!scope.isActive) throw CancellationException()
Debug.log(bookSource.bookSourceUrl, "┌获取封面链接", log)

@ -376,6 +376,14 @@ object ReadBook {
private val imageStyle get() = webBook?.bookSource?.ruleContent?.imageStyle
fun setCharset(charset: String) {
book?.let {
it.charset = charset
callBack?.loadChapterList(it)
}
saveRead()
}
fun saveRead() {
Coroutine.async {
book?.let { book ->
@ -392,6 +400,7 @@ object ReadBook {
}
interface CallBack {
fun loadChapterList(book: Book)
fun upContent(relativePosition: Int = 0, resetPageOffset: Boolean = true)
fun upView()
fun pageChanged()

@ -34,7 +34,7 @@ class AboutFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.about)
findPreference<Preference>("check_update")?.summary =
"${getString(R.string.version)} ${App.INSTANCE.versionName}"
"${getString(R.string.version)} ${App.versionName}"
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

@ -8,7 +8,7 @@ import io.legado.app.R
import io.legado.app.base.BaseActivity
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.ReadRecord
import io.legado.app.data.entities.ReadRecordShow
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.okButton
@ -45,7 +45,7 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) {
withContext(Main) {
tv_read_time.text = formatDuring(allTime)
}
val readRecords = App.db.readRecordDao().all
val readRecords = App.db.readRecordDao().allShow
withContext(Main) {
adapter.setItems(readRecords)
}
@ -53,9 +53,13 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) {
}
inner class RecordAdapter(context: Context) :
SimpleRecyclerAdapter<ReadRecord>(context, R.layout.item_read_record) {
SimpleRecyclerAdapter<ReadRecordShow>(context, R.layout.item_read_record) {
override fun convert(holder: ItemViewHolder, item: ReadRecord, payloads: MutableList<Any>) {
override fun convert(
holder: ItemViewHolder,
item: ReadRecordShow,
payloads: MutableList<Any>
) {
holder.itemView.apply {
tv_book_name.text = item.bookName
tv_read_time.text = formatDuring(item.readTime)
@ -69,7 +73,7 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) {
alert(R.string.delete, R.string.sure_del) {
okButton {
getItem(holder.layoutPosition)?.let {
App.db.readRecordDao().delete(it)
App.db.readRecordDao().deleteByName(it.bookName)
initData()
}
}

@ -2,7 +2,6 @@ package io.legado.app.ui.association
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.Observer
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Theme
@ -23,12 +22,12 @@ class FileAssociationActivity : VMBaseActivity<FileAssociationViewModel>(
override fun onActivityCreated(savedInstanceState: Bundle?) {
rotate_loading.show()
viewModel.errorLiveData.observe(this, Observer {
viewModel.errorLiveData.observe(this, {
rotate_loading.hide()
toast(it)
finish()
})
viewModel.successLiveData.observe(this, Observer {
viewModel.successLiveData.observe(this, {
rotate_loading.hide()
startActivity(it)
finish()

@ -9,7 +9,6 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
@ -41,11 +40,11 @@ class ImportBookSourceActivity : VMBaseActivity<ImportBookSourceViewModel>(
override fun onActivityCreated(savedInstanceState: Bundle?) {
rotate_loading.show()
viewModel.errorLiveData.observe(this, Observer {
viewModel.errorLiveData.observe(this, {
rotate_loading.hide()
errorDialog(it)
})
viewModel.successLiveData.observe(this, Observer {
viewModel.successLiveData.observe(this, {
rotate_loading.hide()
if (it > 0) {
successDialog()

@ -1,7 +1,6 @@
package io.legado.app.ui.association
import android.os.Bundle
import androidx.lifecycle.Observer
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
@ -26,11 +25,11 @@ class ImportReplaceRuleActivity : VMBaseActivity<ImportReplaceRuleViewModel>(
override fun onActivityCreated(savedInstanceState: Bundle?) {
rotate_loading.show()
viewModel.errorLiveData.observe(this, Observer {
viewModel.errorLiveData.observe(this, {
rotate_loading.hide()
errorDialog(it)
})
viewModel.successLiveData.observe(this, Observer {
viewModel.successLiveData.observe(this, {
rotate_loading.hide()
if (it.size > 0) {
successDialog(it)

@ -9,7 +9,6 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
@ -41,11 +40,11 @@ class ImportRssSourceActivity : VMBaseActivity<ImportRssSourceViewModel>(
override fun onActivityCreated(savedInstanceState: Bundle?) {
rotate_loading.show()
viewModel.errorLiveData.observe(this, Observer {
viewModel.errorLiveData.observe(this, {
rotate_loading.hide()
errorDialog(it)
})
viewModel.successLiveData.observe(this, Observer {
viewModel.successLiveData.observe(this, {
rotate_loading.hide()
if (it > 0) {
successDialog()

@ -8,7 +8,6 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.SeekBar
import androidx.lifecycle.Observer
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions.bitmapTransform
@ -48,8 +47,8 @@ class AudioPlayActivity :
override fun onActivityCreated(savedInstanceState: Bundle?) {
title_bar.transparent()
AudioPlay.titleData.observe(this, Observer { title_bar.title = it })
AudioPlay.coverData.observe(this, Observer { upCover(it) })
AudioPlay.titleData.observe(this, { title_bar.title = it })
AudioPlay.coverData.observe(this, { upCover(it) })
viewModel.initData(intent)
initView()
}

@ -5,7 +5,6 @@ import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.widget.PopupMenu
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
@ -94,7 +93,7 @@ class ArrangeBookActivity : VMBaseActivity<ArrangeBookViewModel>(R.layout.activi
private fun initGroupData() {
groupLiveData?.removeObservers(this)
groupLiveData = App.db.bookGroupDao().liveDataAll()
groupLiveData?.observe(this, Observer {
groupLiveData?.observe(this, {
groupList.clear()
groupList.addAll(it)
adapter.notifyDataSetChanged()
@ -112,7 +111,7 @@ class ArrangeBookActivity : VMBaseActivity<ArrangeBookViewModel>(R.layout.activi
AppConst.bookGroupNone.groupId -> App.db.bookDao().observeNoGroup()
else -> App.db.bookDao().observeByGroup(groupId)
}
booksLiveData?.observe(this, Observer { list ->
booksLiveData?.observe(this, { list ->
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime }
2 -> list.sortedBy { it.name }

@ -8,7 +8,6 @@ import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import io.legado.app.R
@ -83,7 +82,7 @@ class ChangeCoverDialog : BaseDialogFragment(),
override fun observeLiveBus() {
super.observeLiveBus()
viewModel.searchStateData.observe(viewLifecycleOwner, Observer {
viewModel.searchStateData.observe(viewLifecycleOwner, {
refresh_progress_bar.isAutoLoading = it
if (it) {
stopMenuItem?.setIcon(R.drawable.ic_stop_black_24dp)
@ -92,7 +91,7 @@ class ChangeCoverDialog : BaseDialogFragment(),
}
tool_bar.menu.applyTint(requireContext(), Theme.getTheme())
})
viewModel.searchBooksLiveData.observe(viewLifecycleOwner, Observer {
viewModel.searchBooksLiveData.observe(viewLifecycleOwner, {
val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it))
adapter.setItems(it)
diffResult.dispatchUpdatesTo(adapter)

@ -9,7 +9,6 @@ import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -135,7 +134,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
}
private fun initLiveData() {
viewModel.searchStateData.observe(viewLifecycleOwner, Observer {
viewModel.searchStateData.observe(viewLifecycleOwner, {
refresh_progress_bar.isAutoLoading = it
if (it) {
stopMenuItem?.setIcon(R.drawable.ic_stop_black_24dp)
@ -144,7 +143,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
}
tool_bar.menu.applyTint(requireContext())
})
viewModel.searchBooksLiveData.observe(viewLifecycleOwner, Observer {
viewModel.searchBooksLiveData.observe(viewLifecycleOwner, {
val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it))
adapter.setItems(it)
diffResult.dispatchUpdatesTo(adapter)

@ -8,7 +8,6 @@ import android.os.Bundle
import android.view.View
import android.widget.EditText
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import androidx.recyclerview.widget.LinearLayoutManager
@ -59,7 +58,7 @@ class BookmarkFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_
LivePagedListBuilder(
App.db.bookmarkDao().observeByBook(book.bookUrl, book.name, book.author), 20
).build()
bookmarkLiveData?.observe(viewLifecycleOwner, Observer { adapter.submitList(it) })
bookmarkLiveData?.observe(viewLifecycleOwner, { adapter.submitList(it) })
}
}
@ -74,7 +73,7 @@ class BookmarkFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_
newText
), 20
).build()
bookmarkLiveData?.observe(viewLifecycleOwner, Observer { adapter.submitList(it) })
bookmarkLiveData?.observe(viewLifecycleOwner, { adapter.submitList(it) })
}
}

@ -1,7 +1,7 @@
package io.legado.app.ui.book.chapterlist
import android.content.Context
import android.widget.TextView
import android.view.View
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
@ -33,12 +33,12 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
tv_tag.visible()
}
upHasCache(
tv_chapter_name,
this,
cacheFileNames.contains(BookHelp.formatChapterName(item))
)
} else {
upHasCache(
tv_chapter_name,
this,
cacheFileNames.contains(BookHelp.formatChapterName(item))
)
}
@ -53,8 +53,9 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
}
}
private fun upHasCache(textView: TextView, contains: Boolean) {
textView.paint.isFakeBoldText = contains
private fun upHasCache(itemView: View, contains: Boolean) = itemView.apply {
tv_chapter_name.paint.isFakeBoldText = contains
iv_checked.visible(contains)
}
interface Callback {

@ -6,7 +6,6 @@ import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.VMBaseFragment
@ -89,7 +88,7 @@ class ChapterListFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragme
private fun initDoc() {
tocLiveData?.removeObservers(this@ChapterListFragment)
tocLiveData = App.db.bookChapterDao().observeByBook(viewModel.bookUrl)
tocLiveData?.observe(viewLifecycleOwner, Observer {
tocLiveData?.observe(viewLifecycleOwner, {
adapter.setItems(it)
if (!scrollToDurChapter) {
mLayoutManager.scrollToPositionWithOffset(durChapterIndex, 0)
@ -124,7 +123,7 @@ class ChapterListFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragme
} else {
tocLiveData?.removeObservers(this)
tocLiveData = App.db.bookChapterDao().liveDataSearch(viewModel.bookUrl, newText)
tocLiveData?.observe(viewLifecycleOwner, Observer {
tocLiveData?.observe(viewLifecycleOwner, {
adapter.setItems(it)
})
}

@ -6,7 +6,6 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import io.legado.app.App
@ -129,7 +128,7 @@ class DownloadActivity : VMBaseActivity<DownloadViewModel>(R.layout.activity_dow
AppConst.bookGroupNone.groupId -> App.db.bookDao().observeNoGroup()
else -> App.db.bookDao().observeByGroup(groupId)
}
booksLiveData?.observe(this, Observer { list ->
booksLiveData?.observe(this, { list ->
val booksDownload = list.filter {
it.isOnLineTxt()
}
@ -147,7 +146,7 @@ class DownloadActivity : VMBaseActivity<DownloadViewModel>(R.layout.activity_dow
private fun initGroupData() {
groupLiveData?.removeObservers(this)
groupLiveData = App.db.bookGroupDao().liveDataAll()
groupLiveData?.observe(this, Observer {
groupLiveData?.observe(this, {
groupList.clear()
groupList.addAll(it)
adapter.notifyDataSetChanged()

@ -1,7 +1,6 @@
package io.legado.app.ui.book.explore
import android.os.Bundle
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
@ -27,7 +26,7 @@ class ExploreShowActivity : VMBaseActivity<ExploreShowViewModel>(R.layout.activi
override fun onActivityCreated(savedInstanceState: Bundle?) {
title_bar.title = intent.getStringExtra("exploreName")
initRecyclerView()
viewModel.booksData.observe(this, Observer { upData(it) })
viewModel.booksData.observe(this, { upData(it) })
viewModel.initData(intent)
}

@ -10,7 +10,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
@ -78,7 +77,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
tv_ok.setTextColor(requireContext().accentColor)
tv_ok.visible()
tv_ok.onClick { dismiss() }
App.db.bookGroupDao().liveDataAll().observe(viewLifecycleOwner, Observer {
App.db.bookGroupDao().liveDataAll().observe(viewLifecycleOwner, {
val diffResult =
DiffUtil.calculateDiff(GroupDiffCallBack(ArrayList(adapter.getItems()), it))
adapter.setItems(it, diffResult)

@ -11,7 +11,6 @@ import android.view.ViewGroup
import android.widget.EditText
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -113,7 +112,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
private fun initData() {
App.db.bookGroupDao().liveDataAll().observe(viewLifecycleOwner, Observer {
App.db.bookGroupDao().liveDataAll().observe(viewLifecycleOwner, {
adapter.setItems(it)
})
}

@ -9,7 +9,6 @@ import android.view.Menu
import android.view.MenuItem
import android.widget.CheckBox
import android.widget.LinearLayout
import androidx.lifecycle.Observer
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions.bitmapTransform
@ -66,8 +65,8 @@ class BookInfoActivity :
scroll_view.setBackgroundColor(backgroundColor)
fl_action.setBackgroundColor(bottomBackground)
tv_shelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground)))
viewModel.bookData.observe(this, Observer { showBook(it) })
viewModel.chapterListData.observe(this, Observer { upLoading(false, it) })
viewModel.bookData.observe(this, { showBook(it) })
viewModel.chapterListData.observe(this, { upLoading(false, it) })
viewModel.initData(intent)
initOnClick()
}

@ -7,7 +7,6 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.Observer
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.data.entities.Book
@ -30,7 +29,7 @@ class BookInfoEditActivity :
get() = getViewModel(BookInfoEditViewModel::class.java)
override fun onActivityCreated(savedInstanceState: Bundle?) {
viewModel.bookData.observe(this, Observer { upView(it) })
viewModel.bookData.observe(this, { upView(it) })
if (viewModel.bookData.value == null) {
intent.getStringExtra("bookUrl")?.let {
viewModel.loadBook(it)

@ -12,7 +12,6 @@ import android.view.View
import androidx.appcompat.widget.PopupMenu
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
@ -114,7 +113,7 @@ class ImportBookActivity : VMBaseActivity<ImportBookViewModel>(R.layout.activity
private fun initData() {
localUriLiveData?.removeObservers(this)
localUriLiveData = App.db.bookDao().observeLocalUri()
localUriLiveData?.observe(this, Observer {
localUriLiveData?.observe(this, {
adapter.upBookHas(it)
})
}

@ -14,15 +14,13 @@ import io.legado.app.R
import io.legado.app.data.entities.Bookmark
import io.legado.app.help.AppConfig
import io.legado.app.help.ReadBookConfig
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.customView
import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.yesButton
import io.legado.app.lib.dialogs.*
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.ThemeStore
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.service.help.Download
import io.legado.app.service.help.ReadBook
import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.applyTint
import io.legado.app.utils.requestInputMethod
import kotlinx.android.synthetic.main.dialog_download_choice.view.*
@ -181,4 +179,27 @@ object Help {
noButton()
}.show().applyTint().requestInputMethod()
}
@SuppressLint("InflateParams")
fun showCharsetConfig(context: Context) = with(context) {
val charsets =
arrayListOf("UTF-8", "GB2312", "GBK", "Unicode", "UTF-16", "UTF-16LE", "ASCII")
alert(R.string.set_charset) {
var editText: AutoCompleteTextView? = null
customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view
edit_view.setFilterValues(charsets)
edit_view.setText(ReadBook.book?.charset)
}
}
okButton {
val text = editText?.text?.toString()
text?.let {
ReadBook.setCharset(it)
}
}
cancelButton()
}.show().applyTint()
}
}

@ -14,7 +14,6 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.core.view.get
import androidx.core.view.isVisible
import androidx.core.view.size
import androidx.lifecycle.Observer
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
import io.legado.app.BuildConfig
import io.legado.app.R
@ -108,11 +107,11 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
initView()
upScreenTimeOut()
ReadBook.callBack = this
ReadBook.titleDate.observe(this, Observer {
ReadBook.titleDate.observe(this) {
title_bar.title = it
upMenu()
upView()
})
}
viewModel.initData(intent)
}
@ -128,6 +127,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
override fun onResume() {
super.onResume()
ReadBook.readStartTime = System.currentTimeMillis()
upSystemUiVisibility()
timeBatteryReceiver = TimeBatteryReceiver.register(this)
page_view.upTime()
@ -251,8 +251,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
R.id.menu_copy_text ->
TextDialog.show(supportFragmentManager, ReadBook.curTextChapter?.getContent())
R.id.menu_update_toc -> ReadBook.book?.let {
ReadBook.upMsg(getString(R.string.toc_updateing))
viewModel.loadChapterList(it)
loadChapterList(it)
}
R.id.menu_enable_replace -> ReadBook.book?.let {
it.useReplaceRule = !it.useReplaceRule
@ -275,6 +274,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
Pair("loginUrl", it.loginUrl)
)
}
R.id.menu_set_charset -> Help.showCharsetConfig(this)
}
return super.onCompatOptionsItemSelected(item)
}
@ -515,6 +515,11 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
return false
}
override fun loadChapterList(book: Book) {
ReadBook.upMsg(getString(R.string.toc_updateing))
viewModel.loadChapterList(book)
}
/**
* 内容加载完成
*/

@ -39,18 +39,20 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
}
lateinit var adapter: Adapter
lateinit var viewModel: SpeakEngineViewModel
private var httpTTSData: LiveData<List<HttpTTS>>? = null
var engineId = App.INSTANCE.getPrefLong(PreferKey.speakEngine)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewModel = getViewModel(SpeakEngineViewModel::class.java)
return inflater.inflate(R.layout.dialog_recycler_view, container)
}
lateinit var adapter: Adapter
private var httpTTSData: LiveData<List<HttpTTS>>? = null
var engineId = App.INSTANCE.getPrefLong(PreferKey.speakEngine)
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
initView()
initMenu()
@ -97,6 +99,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_add -> editHttpTTS()
R.id.menu_default -> viewModel.importDefault()
}
return true
}

@ -0,0 +1,34 @@
package io.legado.app.ui.book.read.config
import android.app.Application
import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.TxtTocRule
import io.legado.app.help.DefaultValueHelp
import io.legado.app.help.http.HttpHelper
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
class SpeakEngineViewModel(application: Application) : BaseViewModel(application) {
fun importDefault() {
execute {
DefaultValueHelp.initHttpTTS()
}
}
fun importOnLine(url: String, finally: (msg: String) -> Unit) {
execute {
HttpHelper.simpleGetAsync(url)?.let { json ->
GSON.fromJsonArray<TxtTocRule>(json)?.let {
App.db.txtTocRule().insert(*it.toTypedArray())
}
}
}.onSuccess {
finally("导入成功")
}.onError {
finally("导入失败")
}
}
}

@ -11,7 +11,6 @@ import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -104,7 +103,7 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private fun initData() {
tocRegexLiveData?.removeObservers(viewLifecycleOwner)
tocRegexLiveData = App.db.txtTocRule().observeAll()
tocRegexLiveData?.observe(viewLifecycleOwner, Observer { tocRules ->
tocRegexLiveData?.observe(viewLifecycleOwner, { tocRules ->
initSelectedName(tocRules)
adapter.setItems(tocRules)
})

@ -7,7 +7,6 @@ import android.view.View.GONE
import android.view.View.VISIBLE
import androidx.appcompat.widget.SearchView
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayoutManager
@ -176,17 +175,17 @@ class SearchActivity : VMBaseActivity<SearchViewModel>(R.layout.activity_book_se
}
private fun initLiveData() {
App.db.bookSourceDao().liveGroupEnabled().observe(this, Observer {
App.db.bookSourceDao().liveGroupEnabled().observe(this, {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(",", ";"))
}
upGroupMenu()
})
viewModel.searchBookLiveData.observe(this, Observer {
viewModel.searchBookLiveData.observe(this, {
upSearchItems(it)
})
viewModel.isSearchLiveData.observe(this, Observer {
viewModel.isSearchLiveData.observe(this, {
if (it) {
startSearch()
} else {
@ -254,7 +253,7 @@ class SearchActivity : VMBaseActivity<SearchViewModel>(R.layout.activity_book_se
rv_bookshelf_search.gone()
} else {
bookData = App.db.bookDao().liveDataSearch(key)
bookData?.observe(this, Observer {
bookData?.observe(this, {
if (it.isEmpty()) {
tv_book_show.gone()
rv_bookshelf_search.gone()
@ -272,7 +271,7 @@ class SearchActivity : VMBaseActivity<SearchViewModel>(R.layout.activity_book_se
} else {
App.db.searchKeywordDao().liveDataSearch(key)
}
historyData?.observe(this, Observer {
historyData?.observe(this, {
historyKeyAdapter.setItems(it)
if (it.isEmpty()) {
tv_clear_history.invisible()

@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
@ -164,7 +163,7 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
App.db.bookSourceDao().liveDataSearch("%$searchKey%")
}
}
bookSourceLiveDate?.observe(this, Observer { data ->
bookSourceLiveDate?.observe(this, { data ->
val sourceList = when (sort) {
1 -> data.sortedBy { it.weight }
2 -> data.sortedBy { it.bookSourceName }
@ -179,7 +178,7 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
}
private fun initLiveDataGroup() {
App.db.bookSourceDao().liveGroup().observe(this, Observer {
App.db.bookSourceDao().liveGroup().observe(this, {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(",", ";"))

@ -11,7 +11,6 @@ import android.view.ViewGroup
import android.widget.EditText
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
@ -69,7 +68,7 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
}
private fun initData() {
App.db.bookSourceDao().liveGroup().observe(viewLifecycleOwner, Observer {
App.db.bookSourceDao().liveGroup().observe(viewLifecycleOwner, {
val groups = linkedSetOf<String>()
it.map { group ->
groups.addAll(group.splitNotBlank(",", ";"))

@ -93,8 +93,8 @@ class MainActivity : VMBaseActivity<MainViewModel>(R.layout.activity_main),
}
private fun upVersion() {
if (getPrefInt(PreferKey.versionCode) != App.INSTANCE.versionCode) {
putPrefInt(PreferKey.versionCode, App.INSTANCE.versionCode)
if (getPrefInt(PreferKey.versionCode) != App.versionCode) {
putPrefInt(PreferKey.versionCode, App.versionCode)
if (!BuildConfig.DEBUG) {
val log = String(assets.open("updateLog.md").readBytes())
TextDialog.show(supportFragmentManager, log, TextDialog.MD, 5000, true)
@ -168,7 +168,7 @@ class MainActivity : VMBaseActivity<MainViewModel>(R.layout.activity_main),
}
}
private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) :
private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItemPosition(`object`: Any): Int {

@ -6,13 +6,16 @@ import io.legado.app.base.BaseViewModel
import io.legado.app.constant.BookType
import io.legado.app.constant.EventBus
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.HttpTTS
import io.legado.app.data.entities.RssSource
import io.legado.app.help.AppConfig
import io.legado.app.help.DefaultValueHelp
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Restore
import io.legado.app.model.WebBook
import io.legado.app.utils.*
import io.legado.app.utils.FileUtils
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.postEvent
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.delay
@ -96,11 +99,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
execute {
FileUtils.deleteFile(FileUtils.getPath(context.cacheDir, "Fonts"))
if (App.db.httpTTSDao().count == 0) {
@Suppress("BlockingMethodInNonBlockingContext")
val json = String(App.INSTANCE.assets.open("httpTTS.json").readBytes())
GSON.fromJsonArray<HttpTTS>(json)?.let {
App.db.httpTTSDao().insert(*it.toTypedArray())
}
DefaultValueHelp.initHttpTTS()
}
}
}

@ -11,7 +11,6 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import com.google.android.material.tabs.TabLayout
import io.legado.app.App
import io.legado.app.R
@ -114,7 +113,7 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
private fun initBookGroupData() {
bookGroupLiveData?.removeObservers(viewLifecycleOwner)
bookGroupLiveData = App.db.bookGroupDao().liveDataAll()
bookGroupLiveData?.observe(viewLifecycleOwner, Observer {
bookGroupLiveData?.observe(viewLifecycleOwner, {
viewModel.checkGroup(it)
launch {
synchronized(this) {
@ -152,7 +151,7 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
})
noGroupLiveData?.removeObservers(viewLifecycleOwner)
noGroupLiveData = App.db.bookDao().observeNoGroupSize()
noGroupLiveData?.observe(viewLifecycleOwner, Observer {
noGroupLiveData?.observe(viewLifecycleOwner, {
if (it > 0 && !showGroupNone && AppConfig.bookGroupNoneShow) {
showGroupNone = true
upGroup()
@ -270,7 +269,7 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
fragmentMap[selectedGroup?.groupId]?.gotoTop()
}
private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) :
private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getPageTitle(position: Int): CharSequence? {

@ -3,7 +3,6 @@ package io.legado.app.ui.main.bookshelf.books
import android.os.Bundle
import android.view.View
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
@ -106,7 +105,7 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
AppConst.bookGroupNone.groupId -> App.db.bookDao().observeNoGroup()
else -> App.db.bookDao().observeByGroup(groupId)
}
bookshelfLiveData?.observe(this, Observer { list ->
bookshelfLiveData?.observe(this, { list ->
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime }
2 -> list.sortedBy { it.name }

@ -7,7 +7,6 @@ import android.view.SubMenu
import android.view.View
import androidx.appcompat.widget.SearchView
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -93,7 +92,7 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_find_
private fun initGroupData() {
liveGroup?.removeObservers(viewLifecycleOwner)
liveGroup = App.db.bookSourceDao().liveGroupExplore()
liveGroup?.observe(viewLifecycleOwner, Observer {
liveGroup?.observe(viewLifecycleOwner, {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(",", ";"))
@ -109,7 +108,7 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_find_
} else {
App.db.bookSourceDao().liveExplore("%$key%")
}
liveExplore?.observe(viewLifecycleOwner, Observer {
liveExplore?.observe(viewLifecycleOwner, {
val diffResult = DiffUtil
.calculateDiff(ExploreDiffCallBack(ArrayList(adapter.getItems()), it))
adapter.setItems(it)

@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import io.legado.app.App
import io.legado.app.R
@ -56,7 +55,7 @@ class RssFragment : VMBaseFragment<RssSourceViewModel>(R.layout.fragment_rss),
}
private fun initData() {
App.db.rssSourceDao().liveEnabled().observe(viewLifecycleOwner, Observer {
App.db.rssSourceDao().liveEnabled().observe(viewLifecycleOwner, {
if (it.isEmpty()) {
getViewModelOfActivity(MainViewModel::class.java).initRss()
}

@ -11,7 +11,6 @@ import android.view.ViewGroup
import android.widget.EditText
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
@ -69,7 +68,7 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
recycler_view.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter
App.db.replaceRuleDao().liveGroup().observe(viewLifecycleOwner, Observer {
App.db.replaceRuleDao().liveGroup().observe(viewLifecycleOwner, {
val groups = linkedSetOf<String>()
it.map { group ->
groups.addAll(group.splitNotBlank(",", ";"))

@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
@ -133,7 +132,7 @@ class ReplaceRuleActivity : VMBaseActivity<ReplaceRuleViewModel>(R.layout.activi
} else {
App.db.replaceRuleDao().liveDataSearch(key)
}
replaceRuleLiveData?.observe(this, Observer {
replaceRuleLiveData?.observe(this, {
if (dataInit) {
setResult(Activity.RESULT_OK)
}
@ -146,7 +145,7 @@ class ReplaceRuleActivity : VMBaseActivity<ReplaceRuleViewModel>(R.layout.activi
}
private fun observeGroupData() {
App.db.replaceRuleDao().liveGroup().observe(this, Observer {
App.db.replaceRuleDao().liveGroup().observe(this, {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(",", ";"))

@ -11,7 +11,6 @@ import android.widget.EditText
import android.widget.PopupWindow
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Observer
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.AppConst
@ -71,7 +70,7 @@ class ReplaceEditDialog : BaseDialogFragment(),
tool_bar.inflateMenu(R.menu.replace_edit)
tool_bar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this)
viewModel.replaceRuleData.observe(viewLifecycleOwner, Observer {
viewModel.replaceRuleData.observe(viewLifecycleOwner, {
upReplaceView(it)
})
arguments?.let {

@ -3,7 +3,6 @@ package io.legado.app.ui.rss.article
import android.os.Bundle
import android.view.View
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -87,7 +86,7 @@ class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragme
activityViewModel.url?.let {
rssArticlesData?.removeObservers(this)
rssArticlesData = App.db.rssArticleDao().liveByOriginSort(it, viewModel.sortName)
rssArticlesData?.observe(viewLifecycleOwner, Observer { list ->
rssArticlesData?.observe(viewLifecycleOwner, { list ->
adapter.setItems(list)
})
}
@ -104,7 +103,7 @@ class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragme
}
override fun observeLiveBus() {
viewModel.loadFinally.observe(viewLifecycleOwner, Observer {
viewModel.loadFinally.observe(viewLifecycleOwner, {
refresh_recycler_view.stopLoading()
if (it) {
loadMoreView.startLoad()

@ -8,7 +8,6 @@ import android.view.MenuItem
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import androidx.lifecycle.Observer
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
@ -30,7 +29,7 @@ class RssSortActivity : VMBaseActivity<RssSortViewModel>(R.layout.activity_rss_a
adapter = TabFragmentPageAdapter(supportFragmentManager)
tab_layout.setupWithViewPager(view_pager)
view_pager.adapter = adapter
viewModel.titleLiveData.observe(this, Observer {
viewModel.titleLiveData.observe(this, {
title_bar.title = it
})
viewModel.initData(intent) {
@ -85,7 +84,7 @@ class RssSortActivity : VMBaseActivity<RssSortViewModel>(R.layout.activity_rss_a
}
}
private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) :
private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItemPosition(`object`: Any): Int {

@ -2,7 +2,6 @@ package io.legado.app.ui.rss.favorites
import android.os.Bundle
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
@ -37,7 +36,7 @@ class RssFavoritesActivity : BaseActivity(R.layout.activity_rss_favorites),
private fun initData() {
liveData?.removeObservers(this)
liveData = App.db.rssStarDao().liveAll()
liveData?.observe(this, Observer {
liveData?.observe(this, {
adapter.setItems(it)
})
}

@ -8,7 +8,6 @@ import android.os.Bundle
import android.view.*
import android.webkit.*
import androidx.core.view.size
import androidx.lifecycle.Observer
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.lib.theme.DrawableUtils
@ -155,7 +154,7 @@ class ReadRssActivity : VMBaseActivity<ReadRssViewModel>(R.layout.activity_rss_r
@SuppressLint("SetJavaScriptEnabled")
private fun initLiveData() {
viewModel.contentLiveData.observe(this, Observer { content ->
viewModel.contentLiveData.observe(this, { content ->
viewModel.rssArticle?.let {
upJavaScriptEnable()
val url = NetworkUtils.getAbsoluteURL(it.origin, it.link)
@ -179,7 +178,7 @@ class ReadRssActivity : VMBaseActivity<ReadRssViewModel>(R.layout.activity_rss_r
}
}
})
viewModel.urlLiveData.observe(this, Observer {
viewModel.urlLiveData.observe(this, {
upJavaScriptEnable()
web_view.loadUrl(it.url, it.headerMap)
})

@ -10,7 +10,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
@ -63,7 +62,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
tv_ok.setTextColor(requireContext().accentColor)
tv_ok.visible()
tv_ok.onClick { dismiss() }
App.db.rssSourceDao().liveGroup().observe(viewLifecycleOwner, Observer {
App.db.rssSourceDao().liveGroup().observe(viewLifecycleOwner, {
val groups = linkedSetOf<String>()
it.map { group ->
groups.addAll(group.splitNotBlank(",", ";"))

@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
@ -142,7 +141,7 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
}
private fun initLiveDataGroup() {
App.db.rssSourceDao().liveGroup().observe(this, Observer {
App.db.rssSourceDao().liveGroup().observe(this, {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(",", ";"))
@ -195,7 +194,7 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
} else {
App.db.rssSourceDao().liveSearch("%$key%")
}
sourceLiveData?.observe(this, Observer {
sourceLiveData?.observe(this, {
val diffResult = DiffUtil
.calculateDiff(DiffCallBack(adapter.getItems(), it))
adapter.setItems(it, diffResult)

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -8,16 +9,34 @@
<TextView
android:id="@+id/tv_chapter_name"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true" />
android:singleLine="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/iv_checked" />
<TextView
android:id="@+id/tv_tag"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="12sp"
android:visibility="gone"
android:singleLine="true" />
android:singleLine="true"
app:layout_constraintTop_toBottomOf="@+id/tv_chapter_name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/iv_checked" />
</LinearLayout>
<ImageView
android:id="@+id/iv_checked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_check"
android:visibility="invisible"
android:contentDescription="@string/success"
app:tint="@color/primaryText"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -1,11 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
<menu xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_add"
android:icon="@drawable/ic_add"
android:title="@string/add"
app:showAsAction="always" />
app:showAsAction="always"
tools:ignore="AlwaysShowAction" />
<item
android:id="@+id/menu_default"
android:title="@string/import_default_rule"
app:showAsAction="never" />
</menu>
Loading…
Cancel
Save