Преглед изворни кода

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

ag2s20150909 пре 4 година
родитељ
комит
79f2cf2d29
33 измењених фајлова са 137 додато и 103 уклоњено
  1. 1 1
      app/src/main/AndroidManifest.xml
  2. 6 0
      app/src/main/assets/updateLog.md
  3. 1 0
      app/src/main/java/io/legado/app/constant/AppConst.kt
  4. 0 4
      app/src/main/java/io/legado/app/data/entities/Book.kt
  5. 10 2
      app/src/main/java/io/legado/app/help/config/AppConfig.kt
  6. 29 20
      app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt
  7. 2 0
      app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt
  8. 3 1
      app/src/main/java/io/legado/app/ui/book/audio/AudioPlayViewModel.kt
  9. 4 5
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt
  10. 2 3
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt
  11. 4 5
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt
  12. 7 7
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  13. 13 9
      app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt
  14. 2 2
      app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt
  15. 18 10
      app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt
  16. 3 2
      app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt
  17. 1 1
      app/src/main/java/io/legado/app/ui/book/manage/ComposeView.kt
  18. 1 1
      app/src/main/java/io/legado/app/ui/book/manage/SourcePickerDialog.kt
  19. 1 0
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  20. 8 8
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  21. 2 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt
  22. 5 6
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt
  23. 1 1
      app/src/main/res/layout/activity_arrange_book.xml
  24. 0 0
      app/src/main/res/menu/bookshelf_manage.xml
  25. 0 0
      app/src/main/res/menu/bookshelf_menage_sel.xml
  26. 6 6
      app/src/main/res/menu/main_bookshelf.xml
  27. 1 1
      app/src/main/res/values-es-rES/strings.xml
  28. 1 1
      app/src/main/res/values-ja-rJP/strings.xml
  29. 1 1
      app/src/main/res/values-pt-rBR/strings.xml
  30. 1 1
      app/src/main/res/values-zh-rHK/strings.xml
  31. 1 1
      app/src/main/res/values-zh-rTW/strings.xml
  32. 1 1
      app/src/main/res/values-zh/strings.xml
  33. 1 1
      app/src/main/res/values/strings.xml

+ 1 - 1
app/src/main/AndroidManifest.xml

@@ -249,7 +249,7 @@
             android:screenOrientation="behind" />
         <!-- 书籍管理 -->
         <activity
-            android:name=".ui.book.arrange.ArrangeBookActivity"
+            android:name=".ui.book.manage.BookshelfManageActivity"
             android:launchMode="singleTop"
             android:screenOrientation="behind" />
         <!-- 书源调试 -->

+ 6 - 0
app/src/main/assets/updateLog.md

@@ -11,6 +11,12 @@
 * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
 * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
 
+**2022/04/07**
+
+* 实现epub的懒加载 by ag2s20150909
+* 解决txt无法导入
+* 优化换源
+
 **2022/04/05**
 
 * 更新cronet: 100.0.4896.79

+ 1 - 0
app/src/main/java/io/legado/app/constant/AppConst.kt

@@ -39,6 +39,7 @@ object AppConst {
         SimpleDateFormat("yy-MM-dd-HH-mm-ss")
     }
 
+    const val rootGroupId = -100L
     const val bookGroupAllId = -1L
     const val bookGroupLocalId = -2L
     const val bookGroupAudioId = -3L

+ 0 - 4
app/src/main/java/io/legado/app/data/entities/Book.kt

@@ -287,10 +287,6 @@ data class Book(
         newBook.customTag = customTag
         newBook.canUpdate = canUpdate
         newBook.readConfig = readConfig
-        if (appDb.bookDao.has(bookUrl) == true) {
-            delete()
-            appDb.bookDao.insert(newBook)
-        }
         return newBook
     }
 

+ 10 - 2
app/src/main/java/io/legado/app/help/config/AppConfig.kt

@@ -276,9 +276,17 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
     val autoChangeSource: Boolean
         get() = appCtx.getPrefBoolean(PreferKey.autoChangeSource, true)
 
-    val changeSourceLoadInfo get() = appCtx.getPrefBoolean(PreferKey.changeSourceLoadInfo)
+    var changeSourceLoadInfo: Boolean
+        get() = appCtx.getPrefBoolean(PreferKey.changeSourceLoadInfo)
+        set(value) {
+            appCtx.putPrefBoolean(PreferKey.changeSourceLoadInfo, value)
+        }
 
-    val changeSourceLoadToc get() = appCtx.getPrefBoolean(PreferKey.changeSourceLoadToc)
+    var changeSourceLoadToc: Boolean
+        get() = appCtx.getPrefBoolean(PreferKey.changeSourceLoadToc)
+        set(value) {
+            appCtx.putPrefBoolean(PreferKey.changeSourceLoadToc, value)
+        }
 
     val importKeepName get() = appCtx.getPrefBoolean(PreferKey.importKeepName)
 

+ 29 - 20
app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt

@@ -24,34 +24,43 @@ class FileAssociationViewModel(application: Application) : BaseAssociationViewMo
     @Suppress("BlockingMethodInNonBlockingContext")
     fun dispatchIndent(uri: Uri, finally: (title: String, msg: String) -> Unit) {
         execute {
+            lateinit var fileName: String
+            lateinit var content: String
             //如果是普通的url,需要根据返回的内容判断是什么
             if (uri.scheme == "file" || uri.scheme == "content") {
-                val content = if (uri.scheme == "file") {
-                    File(uri.path.toString()).readText()
+                if (uri.scheme == "file") {
+                    val file = File(uri.path.toString())
+                    content = file.readText()
+                    fileName = file.name
                 } else {
-                    DocumentFile.fromSingleUri(context, uri)?.readText(context)
-                } ?: throw NoStackTraceException("文件不存在")
+                    val file = DocumentFile.fromSingleUri(context, uri)
+                    content = file?.readText(context) ?: throw NoStackTraceException("文件不存在")
+                    fileName = file.name ?: ""
+                }
                 when {
-                    content.isJson() -> when {
-                        content.contains("bookSourceUrl") ->
-                            importBookSourceLive.postValue(content)
-                        content.contains("sourceUrl") ->
-                            importRssSourceLive.postValue(content)
-                        content.contains("pattern") ->
-                            importReplaceRuleLive.postValue(content)
-                        content.contains("themeName") ->
-                            importTheme(content, finally)
-                        content.contains("name") && content.contains("rule") ->
-                            importTextTocRule(content, finally)
-                        content.contains("name") && content.contains("url") ->
-                            importHttpTTS(content, finally)
-                        else -> errorLiveData.postValue("格式不对")
+                    content.isJson() -> {
+                        //暂时根据文件内容判断属于什么
+                        when {
+                            content.contains("bookSourceUrl") ->
+                                importBookSourceLive.postValue(content)
+                            content.contains("sourceUrl") ->
+                                importRssSourceLive.postValue(content)
+                            content.contains("pattern") ->
+                                importReplaceRuleLive.postValue(content)
+                            content.contains("themeName") ->
+                                importTheme(content, finally)
+                            content.contains("name") && content.contains("rule") ->
+                                importTextTocRule(content, finally)
+                            content.contains("name") && content.contains("url") ->
+                                importHttpTTS(content, finally)
+                            else -> errorLiveData.postValue("格式不对")
+                        }
                     }
-                    (uri.path ?: uri.toString()).matches(bookFileRegex) -> {
+                    fileName.matches(bookFileRegex) -> {
                         importBookLiveData.postValue(uri)
                     }
                     else -> {
-                        throw NoStackTraceException("暂未支持的本地书籍格式(TXT/UMD/EPUB)")
+                        throw NoStackTraceException("$fileName 暂未支持的本地书籍格式(TXT/UMD/EPUB)")
                     }
                 }
             } else {

+ 2 - 0
app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt

@@ -16,6 +16,7 @@ import io.legado.app.constant.BookType
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.Status
 import io.legado.app.constant.Theme
+import io.legado.app.data.appDb
 import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookChapter
 import io.legado.app.data.entities.BookSource
@@ -212,6 +213,7 @@ class AudioPlayActivity :
             launch {
                 withContext(IO) {
                     AudioPlay.book?.changeTo(book, toc)
+                    appDb.bookDao.insert(book)
                 }
                 startActivity<ReadBookActivity> {
                     putExtra("bookUrl", book.bookUrl)

+ 3 - 1
app/src/main/java/io/legado/app/ui/book/audio/AudioPlayViewModel.kt

@@ -78,7 +78,9 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application)
 
     fun changeTo(source: BookSource, book: Book, toc: List<BookChapter>) {
         execute {
-            AudioPlay.book = AudioPlay.book!!.changeTo(book, toc)
+            AudioPlay.book?.changeTo(book, toc)
+            appDb.bookDao.insert(book)
+            AudioPlay.book = book
             AudioPlay.bookSource = source
             appDb.bookChapterDao.insert(*toc.toTypedArray())
             AudioPlay.upDurChapter(book)

+ 4 - 5
app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt

@@ -16,7 +16,6 @@ import io.legado.app.R
 import io.legado.app.base.BaseDialogFragment
 import io.legado.app.constant.AppPattern
 import io.legado.app.constant.EventBus
-import io.legado.app.constant.PreferKey
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookChapter
@@ -207,12 +206,12 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
                 item.isChecked = !item.isChecked
                 viewModel.refresh()
             }
-            R.id.menu_load_toc -> {
-                putPrefBoolean(PreferKey.changeSourceLoadToc, !item.isChecked)
+            R.id.menu_load_info -> {
+                AppConfig.changeSourceLoadInfo = !item.isChecked
                 item.isChecked = !item.isChecked
             }
-            R.id.menu_load_info -> {
-                putPrefBoolean(PreferKey.changeSourceLoadInfo, !item.isChecked)
+            R.id.menu_load_toc -> {
+                AppConfig.changeSourceLoadToc = !item.isChecked
                 item.isChecked = !item.isChecked
             }
             R.id.menu_start_stop -> viewModel.startOrStopSearch()

+ 2 - 3
app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt

@@ -184,12 +184,11 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
     }
 
     private suspend fun loadBookInfo(scope: CoroutineScope, source: BookSource, book: Book) {
-        val mBook = WebBook.getBookInfoAwait(scope, source, book)
+        WebBook.getBookInfoAwait(scope, source, book)
         if (context.getPrefBoolean(PreferKey.changeSourceLoadToc)) {
-            loadBookToc(scope, source, mBook)
+            loadBookToc(scope, source, book)
         } else {
             //从详情页里获取最新章节
-            book.latestChapterTitle = mBook.latestChapterTitle
             val searchBook = book.toSearchBook()
             searchCallback?.searchSuccess(searchBook)
         }

+ 4 - 5
app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt

@@ -16,7 +16,6 @@ import io.legado.app.R
 import io.legado.app.base.BaseDialogFragment
 import io.legado.app.constant.AppPattern
 import io.legado.app.constant.EventBus
-import io.legado.app.constant.PreferKey
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookChapter
@@ -231,12 +230,12 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
                 item.isChecked = !item.isChecked
                 viewModel.refresh()
             }
-            R.id.menu_load_toc -> {
-                putPrefBoolean(PreferKey.changeSourceLoadToc, !item.isChecked)
+            R.id.menu_load_info -> {
+                AppConfig.changeSourceLoadInfo = !item.isChecked
                 item.isChecked = !item.isChecked
             }
-            R.id.menu_load_info -> {
-                putPrefBoolean(PreferKey.changeSourceLoadInfo, !item.isChecked)
+            R.id.menu_load_toc -> {
+                AppConfig.changeSourceLoadToc = !item.isChecked
                 item.isChecked = !item.isChecked
             }
             R.id.menu_start_stop -> viewModel.startOrStopSearch()

+ 7 - 7
app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt

@@ -270,7 +270,7 @@ class BookInfoActivity :
                 showDialogFragment(
                     ChangeCoverDialog(it.name, it.author)
                 )
-            }
+            } ?: toastOnUi("Book is null")
         }
         ivCover.setOnLongClickListener {
             viewModel.bookData.value?.getDisplayCover()?.let { path ->
@@ -281,7 +281,7 @@ class BookInfoActivity :
         tvRead.setOnClickListener {
             viewModel.bookData.value?.let {
                 readBook(it)
-            }
+            } ?: toastOnUi("Book is null")
         }
         tvShelf.setOnClickListener {
             if (viewModel.inBookshelf) {
@@ -297,12 +297,12 @@ class BookInfoActivity :
                 startActivity<BookSourceEditActivity> {
                     putExtra("sourceUrl", it.origin)
                 }
-            }
+            } ?: toastOnUi("Book is null")
         }
         tvChangeSource.setOnClickListener {
-            viewModel.bookData.value?.let {
-                showDialogFragment(ChangeBookSourceDialog(it.name, it.author))
-            }
+            viewModel.bookData.value?.let { book ->
+                showDialogFragment(ChangeBookSourceDialog(book.name, book.author))
+            } ?: toastOnUi("Book is null")
         }
         tvTocView.setOnClickListener {
             if (!viewModel.inBookshelf) {
@@ -320,7 +320,7 @@ class BookInfoActivity :
                 showDialogFragment(
                     GroupSelectDialog(it.group)
                 )
-            }
+            } ?: toastOnUi("Book is null")
         }
         tvAuthor.setOnClickListener {
             startActivity<SearchActivity> {

+ 13 - 9
app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt

@@ -39,17 +39,17 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
             val bookUrl = intent.getStringExtra("bookUrl") ?: ""
             appDb.bookDao.getBook(name, author)?.let {
                 inBookshelf = true
-                setBook(it)
+                upBook(it)
                 return@execute
             }
             if (bookUrl.isNotBlank()) {
                 appDb.searchBookDao.getSearchBook(bookUrl)?.toBook()?.let {
-                    setBook(it)
+                    upBook(it)
                     return@execute
                 }
             }
             appDb.searchBookDao.getFirstByNameAuthor(name, author)?.toBook()?.let {
-                setBook(it)
+                upBook(it)
                 return@execute
             }
             throw NoStackTraceException("未找到书籍")
@@ -63,12 +63,12 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
             val name = intent.getStringExtra("name") ?: ""
             val author = intent.getStringExtra("author") ?: ""
             appDb.bookDao.getBook(name, author)?.let { book ->
-                setBook(book)
+                upBook(book)
             }
         }
     }
 
-    private fun setBook(book: Book) {
+    private fun upBook(book: Book) {
         execute {
             durChapterIndex = book.durChapterIndex
             bookData.postValue(book)
@@ -176,15 +176,19 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
         }
     }
 
-    fun changeTo(source: BookSource, newBook: Book, toc: List<BookChapter>) {
+    fun changeTo(source: BookSource, book: Book, toc: List<BookChapter>) {
         changeSourceCoroutine?.cancel()
         changeSourceCoroutine = execute {
             bookSource = source
-            bookData.value!!.changeTo(newBook, toc)
-            bookData.postValue(newBook)
+            bookData.value?.changeTo(book, toc)
+            if (inBookshelf) {
+                appDb.bookDao.insert(book)
+                appDb.bookChapterDao.insert(*toc.toTypedArray())
+            }
+            bookData.postValue(book)
             chapterListData.postValue(toc)
         }.onFinally {
-            postEvent(EventBus.SOURCE_CHANGED, newBook.bookUrl)
+            postEvent(EventBus.SOURCE_CHANGED, book.bookUrl)
         }
     }
 

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookAdapter.kt → app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.book.arrange
+package io.legado.app.ui.book.manage
 
 import android.annotation.SuppressLint
 import android.content.Context
@@ -15,7 +15,7 @@ import io.legado.app.lib.theme.backgroundColor
 import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
 import io.legado.app.ui.widget.recycler.ItemTouchCallback
 
-class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
+class BookAdapter(context: Context, val callBack: CallBack) :
     RecyclerAdapter<Book, ItemArrangeBookBinding>(context),
 
     ItemTouchCallback.Callback {

+ 18 - 10
app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt → app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.book.arrange
+package io.legado.app.ui.book.manage
 
 import android.annotation.SuppressLint
 import android.os.Bundle
@@ -39,19 +39,20 @@ import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
 
-class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBookViewModel>(),
+class BookshelfManageActivity :
+    VMBaseActivity<ActivityArrangeBookBinding, BookshelfManageViewModel>(),
     PopupMenu.OnMenuItemClickListener,
     SelectActionBar.CallBack,
-    ArrangeBookAdapter.CallBack,
+    BookAdapter.CallBack,
     SourcePickerDialog.Callback,
     GroupSelectDialog.CallBack {
 
     override val binding by viewBinding(ActivityArrangeBookBinding::inflate)
-    override val viewModel by viewModels<ArrangeBookViewModel>()
+    override val viewModel by viewModels<BookshelfManageViewModel>()
     override val groupList: ArrayList<BookGroup> = arrayListOf()
     private val groupRequestCode = 22
     private val addToGroupRequestCode = 34
-    private val adapter by lazy { ArrangeBookAdapter(this, this) }
+    private val adapter by lazy { BookAdapter(this, this) }
     private var booksFlowJob: Job? = null
     private var menu: Menu? = null
     private var groupId: Long = -1
@@ -70,7 +71,7 @@ class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBo
     }
 
     override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
-        menuInflater.inflate(R.menu.arrange_book, menu)
+        menuInflater.inflate(R.menu.bookshelf_manage, menu)
         return super.onCompatCreateOptionsMenu(menu)
     }
 
@@ -107,7 +108,7 @@ class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBo
         // Note: need judge selection first, so add ItemTouchHelper after it.
         ItemTouchHelper(itemTouchCallback).attachToRecyclerView(binding.recyclerView)
         binding.selectActionBar.setMainActionText(R.string.move_to_group)
-        binding.selectActionBar.inflateMenu(R.menu.arrange_book_sel)
+        binding.selectActionBar.inflateMenu(R.menu.bookshelf_menage_sel)
         binding.selectActionBar.setOnMenuItemClickListener(this)
         binding.selectActionBar.setCallBack(this)
         binding.composeView.setContent {
@@ -139,6 +140,7 @@ class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBo
         booksFlowJob?.cancel()
         booksFlowJob = launch {
             when (groupId) {
+                AppConst.rootGroupId -> appDb.bookDao.flowNoGroup()
                 AppConst.bookGroupAllId -> appDb.bookDao.flowAll()
                 AppConst.bookGroupLocalId -> appDb.bookDao.flowLocal()
                 AppConst.bookGroupAudioId -> appDb.bookDao.flowAudio()
@@ -146,12 +148,18 @@ class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBo
                 else -> appDb.bookDao.flowByGroup(groupId)
             }.conflate().map { books ->
                 when (getPrefInt(PreferKey.bookshelfSort)) {
-                    1 -> books.sortedByDescending { it.latestChapterTime }
+                    1 -> books.sortedByDescending {
+                        it.latestChapterTime
+                    }
                     2 -> books.sortedWith { o1, o2 ->
                         o1.name.cnCompare(o2.name)
                     }
-                    3 -> books.sortedBy { it.order }
-                    else -> books.sortedByDescending { it.durChapterTime }
+                    3 -> books.sortedBy {
+                        it.order
+                    }
+                    else -> books.sortedByDescending {
+                        it.durChapterTime
+                    }
                 }
             }.conflate().collect { books ->
                 adapter.setItems(books)

+ 3 - 2
app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookViewModel.kt → app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.book.arrange
+package io.legado.app.ui.book.manage
 
 import android.app.Application
 import androidx.compose.runtime.mutableStateOf
@@ -10,7 +10,7 @@ import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.model.webBook.WebBook
 
 
-class ArrangeBookViewModel(application: Application) : BaseViewModel(application) {
+class BookshelfManageViewModel(application: Application) : BaseViewModel(application) {
 
     val batchChangeSourceState = mutableStateOf(false)
     val batchChangeSourceSize = mutableStateOf(0)
@@ -50,6 +50,7 @@ class ArrangeBookViewModel(application: Application) : BaseViewModel(application
                     .getOrNull()?.let { newBook ->
                         val toc = WebBook.getChapterListAwait(this, source, newBook)
                         book.changeTo(newBook, toc)
+                        appDb.bookDao.insert(newBook)
                         appDb.bookChapterDao.insert(*toc.toTypedArray())
                     }
             }

+ 1 - 1
app/src/main/java/io/legado/app/ui/book/arrange/ComposeView.kt → app/src/main/java/io/legado/app/ui/book/manage/ComposeView.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.book.arrange
+package io.legado.app.ui.book.manage
 
 import androidx.compose.foundation.layout.Column
 import androidx.compose.material.AlertDialog

+ 1 - 1
app/src/main/java/io/legado/app/ui/book/arrange/SourcePickerDialog.kt → app/src/main/java/io/legado/app/ui/book/manage/SourcePickerDialog.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.book.arrange
+package io.legado.app.ui.book.manage
 
 import android.content.Context
 import android.os.Bundle

+ 1 - 0
app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@@ -724,6 +724,7 @@ class ReadBookActivity : BaseReadBookActivity(),
             ReadAloud.stop(this)
             launch {
                 ReadBook.book?.changeTo(book, toc)
+                appDb.bookDao.insert(book)
             }
             startActivity<AudioPlayActivity> {
                 putExtra("bookUrl", book.bookUrl)

+ 8 - 8
app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt

@@ -195,7 +195,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
         changeSourceCoroutine?.cancel()
         changeSourceCoroutine = execute {
             ReadBook.upMsg(context.getString(R.string.loading))
-            ReadBook.book!!.changeTo(book, toc)
+            ReadBook.book?.changeTo(book, toc)
             val nextChapter = toc.getOrElse(book.durChapterIndex) {
                 toc.first()
             }
@@ -206,17 +206,17 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
                 bookChapter = toc[book.durChapterIndex],
                 nextChapterUrl = nextChapter.url
             )
+            appDb.bookDao.insert(book)
             appDb.bookChapterDao.insert(*toc.toTypedArray())
             ReadBook.resetData(book)
             ReadBook.upMsg(null)
             ReadBook.loadContent(resetPageOffset = true)
-        }.timeout(60000)
-            .onError {
-                context.toastOnUi("换源失败\n${it.localizedMessage}")
-                ReadBook.upMsg(null)
-            }.onFinally {
-                postEvent(EventBus.SOURCE_CHANGED, book.bookUrl)
-            }
+        }.onError {
+            context.toastOnUi("换源失败\n${it.localizedMessage}")
+            ReadBook.upMsg(null)
+        }.onFinally {
+            postEvent(EventBus.SOURCE_CHANGED, book.bookUrl)
+        }
     }
 
     /**

+ 2 - 2
app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt

@@ -19,10 +19,10 @@ import io.legado.app.help.DirectLinkUpload
 import io.legado.app.help.config.AppConfig
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.ui.about.AppLogDialog
-import io.legado.app.ui.book.arrange.ArrangeBookActivity
 import io.legado.app.ui.book.cache.CacheActivity
 import io.legado.app.ui.book.group.GroupManageDialog
 import io.legado.app.ui.book.local.ImportBookActivity
+import io.legado.app.ui.book.manage.BookshelfManageActivity
 import io.legado.app.ui.book.search.SearchActivity
 import io.legado.app.ui.document.HandleFileContract
 import io.legado.app.ui.main.MainViewModel
@@ -80,7 +80,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
             R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>()
             R.id.menu_add_local -> startActivity<ImportBookActivity>()
             R.id.menu_add_url -> addBookByUrl()
-            R.id.menu_arrange_bookshelf -> startActivity<ArrangeBookActivity> {
+            R.id.menu_bookshelf_manage -> startActivity<BookshelfManageActivity> {
                 putExtra("groupId", groupId)
             }
             R.id.menu_download -> startActivity<CacheActivity> {

+ 5 - 6
app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt

@@ -43,7 +43,6 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
     BaseBooksAdapter.CallBack {
 
     private val binding by viewBinding(FragmentBookshelf1Binding::bind)
-    private val rootGroupId = -100L
     private val bookshelfLayout by lazy {
         getPrefInt(PreferKey.bookshelfLayout)
     }
@@ -56,7 +55,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
     }
     private var bookGroups: List<BookGroup> = emptyList()
     private var booksFlowJob: Job? = null
-    override var groupId = rootGroupId
+    override var groupId = AppConst.rootGroupId
     override var books: List<Book> = emptyList()
 
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
@@ -121,7 +120,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
         booksFlowJob?.cancel()
         booksFlowJob = launch {
             when (groupId) {
-                rootGroupId -> appDb.bookDao.flowRoot()
+                AppConst.rootGroupId -> appDb.bookDao.flowRoot()
                 AppConst.bookGroupAllId -> appDb.bookDao.flowAll()
                 AppConst.bookGroupLocalId -> appDb.bookDao.flowLocal()
                 AppConst.bookGroupAudioId -> appDb.bookDao.flowAudio()
@@ -212,7 +211,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
     }
 
     override fun getItemCount(): Int {
-        return if (groupId == rootGroupId) {
+        return if (groupId == AppConst.rootGroupId) {
             bookGroups.size + books.size
         } else {
             books.size
@@ -220,7 +219,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
     }
 
     override fun getItemType(position: Int): Int {
-        if (groupId != rootGroupId) {
+        if (groupId != AppConst.rootGroupId) {
             return 0
         }
         if (position < bookGroups.size) {
@@ -230,7 +229,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
     }
 
     override fun getItem(position: Int): Any? {
-        if (groupId != rootGroupId) {
+        if (groupId != AppConst.rootGroupId) {
             return books.getOrNull(position)
         }
         if (position < bookGroups.size) {

+ 1 - 1
app/src/main/res/layout/activity_arrange_book.xml

@@ -9,7 +9,7 @@
         android:id="@+id/title_bar"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        app:title="@string/arrange_bookshelf"
+        app:title="@string/bookshelf_management"
         app:layout_constraintTop_toTopOf="parent" />
 
     <androidx.recyclerview.widget.RecyclerView

+ 0 - 0
app/src/main/res/menu/arrange_book.xml → app/src/main/res/menu/bookshelf_manage.xml


+ 0 - 0
app/src/main/res/menu/arrange_book_sel.xml → app/src/main/res/menu/bookshelf_menage_sel.xml


+ 6 - 6
app/src/main/res/menu/main_bookshelf.xml

@@ -28,6 +28,12 @@
         android:title="@string/add_url"
         app:showAsAction="never" />
 
+    <item
+        android:id="@+id/menu_bookshelf_manage"
+        android:icon="@drawable/ic_arrange"
+        android:title="@string/bookshelf_management"
+        app:showAsAction="never" />
+
     <item
         android:id="@+id/menu_download"
         android:icon="@drawable/ic_download_line"
@@ -46,12 +52,6 @@
         android:title="@string/bookshelf_layout"
         app:showAsAction="never" />
 
-    <item
-        android:id="@+id/menu_arrange_bookshelf"
-        android:icon="@drawable/ic_arrange"
-        android:title="@string/arrange_bookshelf"
-        app:showAsAction="never" />
-
     <item
         android:id="@+id/menu_export_bookshelf"
         android:icon="@drawable/ic_export"

+ 1 - 1
app/src/main/res/values-es-rES/strings.xml

@@ -267,7 +267,7 @@
     <string name="load_over_time">Tiempo límite de carga</string>
     <string name="join_group">Siga:%s</string>
     <string name="copy_complete">Copiado con éxito</string>
-    <string name="arrange_bookshelf">Organización de estantería</string>
+    <string name="bookshelf_management">Organización de estantería</string>
     <string name="clear_bookshelf_s">Esto borrará a todos los libros. Por favor, tenga cuidado.</string>
     <string name="search_book_source">Buscar fuentes de libros</string>
     <string name="search_rss_source">Buscar fuentes de suscripción</string>

+ 1 - 1
app/src/main/res/values-ja-rJP/strings.xml

@@ -271,7 +271,7 @@
     <string name="load_over_time">Loading timeout</string>
     <string name="join_group">Follow:%s</string>
     <string name="copy_complete">Copied successfully</string>
-    <string name="arrange_bookshelf">Bookshelf arrangement</string>
+    <string name="bookshelf_management">Bookshelf management</string>
     <string name="clear_bookshelf_s">It will delete all books. Be careful,please.</string>
     <string name="search_book_source">Search book sources</string>
     <string name="search_rss_source">Search subscription sources</string>

+ 1 - 1
app/src/main/res/values-pt-rBR/strings.xml

@@ -271,7 +271,7 @@
     <string name="load_over_time">Tempo limite de carregamento</string>
     <string name="join_group">Siga:%s</string>
     <string name="copy_complete">Copiado com sucesso</string>
-    <string name="arrange_bookshelf">A organização da estante</string>
+    <string name="bookshelf_management">A organização da estante</string>
     <string name="clear_bookshelf_s">Isto excluirá todos os livros. Por favor, tenha cuidado.</string>
     <string name="search_book_source">Pesquisar fontes de livros</string>
     <string name="search_rss_source">Buscar fontes de assinatura</string>

+ 1 - 1
app/src/main/res/values-zh-rHK/strings.xml

@@ -268,7 +268,7 @@
     <string name="load_over_time">加載超時</string>
     <string name="join_group">關注: %s</string>
     <string name="copy_complete">拷貝咗</string>
-    <string name="arrange_bookshelf">整理書架</string>
+    <string name="bookshelf_management">書架管理</string>
     <string name="clear_bookshelf_s">這將會刪除所有書籍,請謹慎操作。</string>
     <string name="search_book_source">搜索書源</string>
     <string name="search_rss_source">搜索訂閲源</string>

+ 1 - 1
app/src/main/res/values-zh-rTW/strings.xml

@@ -270,7 +270,7 @@
     <string name="load_over_time">載入超時</string>
     <string name="join_group">關注:%s</string>
     <string name="copy_complete">已複製</string>
-    <string name="arrange_bookshelf">整理書架</string>
+    <string name="bookshelf_management">書架管理</string>
     <string name="clear_bookshelf_s">這將會刪除所有書籍,請謹慎操作。</string>
     <string name="search_book_source">搜尋書源</string>
     <string name="search_rss_source">搜尋訂閱源</string>

+ 1 - 1
app/src/main/res/values-zh/strings.xml

@@ -270,7 +270,7 @@
     <string name="load_over_time">加载超时</string>
     <string name="join_group">关注:%s</string>
     <string name="copy_complete">已拷贝</string>
-    <string name="arrange_bookshelf">整理书架</string>
+    <string name="bookshelf_management">书架管理</string>
     <string name="clear_bookshelf_s">这将会删除所有书籍,请谨慎操作。</string>
     <string name="search_book_source">搜索书源</string>
     <string name="search_rss_source">搜索订阅源</string>

+ 1 - 1
app/src/main/res/values/strings.xml

@@ -271,7 +271,7 @@
     <string name="load_over_time">Loading timeout</string>
     <string name="join_group">Follow:%s</string>
     <string name="copy_complete">Copied successfully</string>
-    <string name="arrange_bookshelf">Bookshelf arrangement</string>
+    <string name="bookshelf_management">Bookshelf management</string>
     <string name="clear_bookshelf_s">It will delete all books. Be careful,please.</string>
     <string name="search_book_source">Search book sources</string>
     <string name="search_rss_source">Search subscription sources</string>