pull/1649/head
kunfei 3 years ago
parent e2c38639ea
commit 70121781ff
  1. 21
      app/src/main/java/io/legado/app/help/BookHelp.kt
  2. 6
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt
  3. 4
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceAdapter.kt
  4. 12
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt
  5. 6
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceViewModel.kt
  6. 7
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  7. 25
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  8. 0
      app/src/main/res/layout/dialog_book_change_source.xml
  9. 58
      app/src/main/res/layout/dialog_chapter_change_source.xml

@ -226,27 +226,6 @@ object BookHelp {
return null
}
/**
* 反转章节内容
*/
fun reverseContent(book: Book, bookChapter: BookChapter) {
if (!book.isLocalBook()) {
val file = downloadDir.getFile(
cacheFolderName,
book.getFolderName(),
bookChapter.getFileName()
)
if (file.exists()) {
val text = file.readText()
val stringBuilder = StringBuilder()
text.toStringArray().forEach {
stringBuilder.insert(0, it)
}
file.writeText(stringBuilder.toString())
}
}
}
/**
* 删除章节内容
*/

@ -19,7 +19,7 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.DialogChangeSourceBinding
import io.legado.app.databinding.DialogBookChangeSourceBinding
import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
@ -31,7 +31,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_change_source),
class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_source),
Toolbar.OnMenuItemClickListener,
ChangeBookSourceAdapter.CallBack {
@ -42,7 +42,7 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_change_sourc
}
}
private val binding by viewBinding(DialogChangeSourceBinding::bind)
private val binding by viewBinding(DialogBookChangeSourceBinding::bind)
private val groups = linkedSetOf<String>()
private val callBack: CallBack? get() = activity as? CallBack
private val viewModel: ChangeBookSourceViewModel by viewModels()

@ -74,7 +74,7 @@ class ChangeChapterSourceAdapter(
override fun registerListener(holder: ItemViewHolder, binding: ItemChangeSourceBinding) {
holder.itemView.setOnClickListener {
getItem(holder.layoutPosition)?.let {
callBack.changeTo(it)
callBack.openToc(it)
}
}
holder.itemView.onLongClick {
@ -112,7 +112,7 @@ class ChangeChapterSourceAdapter(
interface CallBack {
val bookUrl: String?
fun changeTo(searchBook: SearchBook)
fun openToc(searchBook: SearchBook)
fun topSource(searchBook: SearchBook)
fun bottomSource(searchBook: SearchBook)
fun editSource(searchBook: SearchBook)

@ -19,7 +19,7 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.DialogChangeSourceBinding
import io.legado.app.databinding.DialogChapterChangeSourceBinding
import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
@ -31,7 +31,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_change_source),
class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_change_source),
Toolbar.OnMenuItemClickListener,
ChangeChapterSourceAdapter.CallBack {
@ -42,7 +42,7 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_change_so
}
}
private val binding by viewBinding(DialogChangeSourceBinding::bind)
private val binding by viewBinding(DialogChapterChangeSourceBinding::bind)
private val groups = linkedSetOf<String>()
private val callBack: CallBack? get() = activity as? CallBack
private val viewModel: ChangeChapterSourceViewModel by viewModels()
@ -196,9 +196,8 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_change_so
return false
}
override fun changeTo(searchBook: SearchBook) {
changeSource(searchBook)
dismissAllowingStateLoss()
override fun openToc(searchBook: SearchBook) {
}
override val bookUrl: String?
@ -282,6 +281,7 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_change_so
interface CallBack {
val oldBook: Book?
fun changeTo(source: BookSource, book: Book)
fun replaceContent(content: String)
}
}

@ -11,6 +11,7 @@ import io.legado.app.constant.AppPattern
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
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.SearchBook
import io.legado.app.help.AppConfig
@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import splitties.init.appCtx
import timber.log.Timber
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors
import kotlin.math.min
@ -35,6 +37,7 @@ import kotlin.math.min
class ChangeChapterSourceViewModel(application: Application) : BaseViewModel(application) {
private val threadCount = AppConfig.threadCount
private var searchPool: ExecutorCoroutineDispatcher? = null
private val searchGroup get() = appCtx.getPrefString("searchGroup") ?: ""
val searchStateData = MutableLiveData<Boolean>()
var name: String = ""
var author: String = ""
@ -42,7 +45,7 @@ class ChangeChapterSourceViewModel(application: Application) : BaseViewModel(app
private var screenKey: String = ""
private var bookSourceList = arrayListOf<BookSource>()
private val searchBooks = ConcurrentHashSet<SearchBook>()
private val searchGroup get() = appCtx.getPrefString("searchGroup") ?: ""
private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
private var searchCallback: SourceCallback? = null
val searchDataFlow = callbackFlow {
@ -203,6 +206,7 @@ class ChangeChapterSourceViewModel(application: Application) : BaseViewModel(app
private fun loadBookToc(source: BookSource, book: Book) {
WebBook.getChapterList(viewModelScope, source, book, context = searchPool!!)
.onSuccess(IO) { chapters ->
tocMap[book.bookUrl] = chapters
book.latestChapterTitle = chapters.last().title
val searchBook: SearchBook = book.toSearchBook()
searchCallback?.searchSuccess(searchBook)

@ -71,6 +71,7 @@ class ReadBookActivity : BaseReadBookActivity(),
SearchMenu.CallBack,
ReadAloudDialog.CallBack,
ChangeBookSourceDialog.CallBack,
ChangeChapterSourceDialog.CallBack,
ReadBook.CallBack,
AutoReadDialog.CallBack,
TocRegexDialog.CallBack,
@ -689,6 +690,12 @@ class ReadBookActivity : BaseReadBookActivity(),
viewModel.changeTo(source, book)
}
override fun replaceContent(content: String) {
ReadBook.book?.let {
viewModel.saveContent(it, content)
}
}
override fun showActionMenu() {
when {
BaseReadAloudService.isRun -> showReadAloudDialog()

@ -27,6 +27,7 @@ import io.legado.app.ui.book.read.page.entities.TextChapter
import io.legado.app.ui.book.searchContent.SearchResult
import io.legado.app.utils.msg
import io.legado.app.utils.postEvent
import io.legado.app.utils.toStringArray
import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.ensureActive
@ -283,16 +284,36 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
}
}
fun reverseContent(book: Book) {
/**
* 保存内容
*/
fun saveContent(book: Book, content: String) {
execute {
appDb.bookChapterDao.getChapter(book.bookUrl, ReadBook.durChapterIndex)
?.let { chapter ->
BookHelp.reverseContent(book, chapter)
BookHelp.saveText(book, chapter, content)
ReadBook.loadContent(ReadBook.durChapterIndex, resetPageOffset = false)
}
}
}
/**
* 反转内容
*/
fun reverseContent(book: Book) {
execute {
val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, ReadBook.durChapterIndex)
?: return@execute
val content = BookHelp.getContent(book, chapter) ?: return@execute
val stringBuilder = StringBuilder()
content.toStringArray().forEach {
stringBuilder.insert(0, it)
}
BookHelp.saveText(book, chapter, stringBuilder.toString())
ReadBook.loadContent(ReadBook.durChapterIndex, resetPageOffset = false)
}
}
/**
* 内容搜索跳转
*/

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:background="@color/background">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_menu"
android:elevation="5dp"
android:theme="?attr/actionBarStyle"
app:titleTextAppearance="@style/ToolbarTitle"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:displayHomeAsUp="false"
app:fitStatusBar="false"
app:layout_constraintTop_toTopOf="parent" />
<io.legado.app.ui.widget.anima.RefreshProgressBar
android:id="@+id/refresh_progress_bar"
android:layout_width="match_parent"
android:layout_height="2dp"
app:layout_constraintTop_toBottomOf="@+id/tool_bar" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/refresh_progress_bar"
app:layout_constraintBottom_toBottomOf="parent" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/background"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/tool_bar"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.utils.widget.ImageFilterView
android:layout_width="match_parent"
android:layout_height="36dp"
android:src="@drawable/ic_arrow_down"
app:tint="@color/primaryText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_toc"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="@+id/refresh_progress_bar"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save