合并上游更改
感谢:@821938089、@zhongerxll、@youke2580c、@Leroy-X、@Dark-Tide、@lhjgege、@3harmony、@mgz0227
This commit is contained in:
87 files changed
+800
-365
No files matched your search
@@ -31,6 +31,22 @@ import splitties.init.appCtx
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
@Suppress("unused")
|
||||
object AudioPlay : CoroutineScope by MainScope() {
|
||||
|
||||
enum class PlayMode(val iconRes: Int) {
|
||||
LIST_END_STOP(R.drawable.ic_play_mode_list_end_stop),
|
||||
RANDOM(R.drawable.ic_play_mode_random),
|
||||
LIST_LOOP(R.drawable.ic_play_mode_list_loop);
|
||||
|
||||
fun next(): PlayMode {
|
||||
return when (this) {
|
||||
LIST_END_STOP -> RANDOM
|
||||
RANDOM -> LIST_LOOP
|
||||
LIST_LOOP -> LIST_END_STOP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var playMode = PlayMode.LIST_END_STOP
|
||||
var status = Status.STOP
|
||||
private var activityContext: Context? = null
|
||||
private var serviceContext: Context? = null
|
||||
@@ -48,6 +64,11 @@ object AudioPlay : CoroutineScope by MainScope() {
|
||||
var bookSource: BookSource? = null
|
||||
val loadingChapters = arrayListOf<Int>()
|
||||
|
||||
fun changePlayMode() {
|
||||
playMode = playMode.next()
|
||||
postEvent(EventBus.PLAY_MODE_CHANGED, playMode)
|
||||
}
|
||||
|
||||
fun upData(book: Book) {
|
||||
AudioPlay.book = book
|
||||
chapterSize = appDb.bookChapterDao.getChapterCount(book.bookUrl)
|
||||
@@ -259,12 +280,32 @@ object AudioPlay : CoroutineScope by MainScope() {
|
||||
|
||||
fun next() {
|
||||
stopPlay()
|
||||
if (durChapterIndex + 1 < simulatedChapterSize) {
|
||||
durChapterIndex += 1
|
||||
durChapterPos = 0
|
||||
durPlayUrl = ""
|
||||
saveRead()
|
||||
loadPlayUrl()
|
||||
when (playMode) {
|
||||
PlayMode.LIST_END_STOP -> {
|
||||
if (durChapterIndex + 1 < simulatedChapterSize) {
|
||||
durChapterIndex += 1
|
||||
durChapterPos = 0
|
||||
durPlayUrl = ""
|
||||
saveRead()
|
||||
loadPlayUrl()
|
||||
}
|
||||
}
|
||||
|
||||
PlayMode.RANDOM -> {
|
||||
durChapterIndex = (0 until simulatedChapterSize).random()
|
||||
durChapterPos = 0
|
||||
durPlayUrl = ""
|
||||
saveRead()
|
||||
loadPlayUrl()
|
||||
}
|
||||
|
||||
PlayMode.LIST_LOOP -> {
|
||||
durChapterIndex = (durChapterIndex + 1) % simulatedChapterSize
|
||||
durChapterPos = 0
|
||||
durPlayUrl = ""
|
||||
saveRead()
|
||||
loadPlayUrl()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,6 @@ object BookCover {
|
||||
/**
|
||||
* 加载漫画图片
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun loadManga(
|
||||
context: Context,
|
||||
path: String?,
|
||||
@@ -155,8 +154,9 @@ object BookCover {
|
||||
.skipMemoryCache(true).let {
|
||||
if (transformation != null) {
|
||||
it.transform(transformation)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
it
|
||||
}
|
||||
.transition(DrawableTransitionOptions.withCrossFade())
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import io.legato.kazusa.data.entities.BookSource
|
||||
import io.legato.kazusa.exception.ConcurrentException
|
||||
import io.legato.kazusa.help.book.BookHelp
|
||||
import io.legato.kazusa.help.book.isLocal
|
||||
import io.legato.kazusa.help.coroutine.CompositeCoroutine
|
||||
import io.legato.kazusa.help.coroutine.Coroutine
|
||||
import io.legato.kazusa.model.webBook.WebBook
|
||||
import io.legato.kazusa.service.CacheBookService
|
||||
@@ -96,15 +97,11 @@ object CacheBook {
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
successDownloadSet.clear()
|
||||
errorDownloadMap.clear()
|
||||
}
|
||||
|
||||
fun close() {
|
||||
cacheBookMap.forEach { it.value.stop() }
|
||||
cacheBookMap.clear()
|
||||
clear()
|
||||
successDownloadSet.clear()
|
||||
errorDownloadMap.clear()
|
||||
}
|
||||
|
||||
val downloadSummary: String
|
||||
@@ -146,6 +143,7 @@ object CacheBook {
|
||||
|
||||
private val waitDownloadSet = linkedSetOf<Int>()
|
||||
private val onDownloadSet = linkedSetOf<Int>()
|
||||
private val tasks = CompositeCoroutine()
|
||||
private var isStopped = false
|
||||
private var waitingRetry = false
|
||||
|
||||
@@ -158,7 +156,7 @@ object CacheBook {
|
||||
|
||||
@Synchronized
|
||||
fun isRun(): Boolean {
|
||||
return waitDownloadSet.size > 0 || onDownloadSet.size > 0
|
||||
return waitDownloadSet.isNotEmpty() || onDownloadSet.isNotEmpty()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -169,6 +167,7 @@ object CacheBook {
|
||||
@Synchronized
|
||||
fun stop() {
|
||||
waitDownloadSet.clear()
|
||||
tasks.clear()
|
||||
isStopped = true
|
||||
postEvent(EventBus.UP_DOWNLOAD, book.bookUrl)
|
||||
}
|
||||
@@ -309,6 +308,8 @@ object CacheBook {
|
||||
onCancel(chapterIndex)
|
||||
}.onFinally {
|
||||
onFinally()
|
||||
}.apply {
|
||||
tasks.add(this)
|
||||
}.start()
|
||||
}
|
||||
|
||||
|
||||
@@ -63,20 +63,8 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
var isLocalBook = true
|
||||
var chapterChanged = false
|
||||
var prevTextChapter: TextChapter? = null
|
||||
set(value) {
|
||||
field?.cancelLayout()
|
||||
field = value
|
||||
}
|
||||
var curTextChapter: TextChapter? = null
|
||||
set(value) {
|
||||
field?.cancelLayout()
|
||||
field = value
|
||||
}
|
||||
var nextTextChapter: TextChapter? = null
|
||||
set(value) {
|
||||
field?.cancelLayout()
|
||||
field = value
|
||||
}
|
||||
var bookSource: BookSource? = null
|
||||
var msg: String? = null
|
||||
private val loadingChapters = arrayListOf<Int>()
|
||||
@@ -222,6 +210,9 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
}
|
||||
|
||||
fun clearTextChapter() {
|
||||
prevTextChapter?.cancelLayout()
|
||||
curTextChapter?.cancelLayout()
|
||||
nextTextChapter?.cancelLayout()
|
||||
prevTextChapter = null
|
||||
curTextChapter = null
|
||||
nextTextChapter = null
|
||||
@@ -333,6 +324,7 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
if (durChapterIndex < simulatedChapterSize - 1) {
|
||||
durChapterPos = 0
|
||||
durChapterIndex++
|
||||
prevTextChapter?.cancelLayout()
|
||||
prevTextChapter = curTextChapter
|
||||
curTextChapter = nextTextChapter
|
||||
nextTextChapter = null
|
||||
@@ -363,6 +355,7 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
if (durChapterIndex < simulatedChapterSize - 1) {
|
||||
durChapterPos = 0
|
||||
durChapterIndex++
|
||||
prevTextChapter?.cancelLayout()
|
||||
prevTextChapter = curTextChapter
|
||||
curTextChapter = nextTextChapter
|
||||
nextTextChapter = null
|
||||
@@ -394,6 +387,7 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
if (durChapterIndex > 0) {
|
||||
durChapterPos = if (toLast) prevTextChapter?.lastReadLength ?: Int.MAX_VALUE else 0
|
||||
durChapterIndex--
|
||||
nextTextChapter?.cancelLayout()
|
||||
nextTextChapter = curTextChapter
|
||||
curTextChapter = prevTextChapter
|
||||
prevTextChapter = null
|
||||
@@ -703,6 +697,7 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
)
|
||||
when (val offset = chapter.index - durChapterIndex) {
|
||||
0 -> {
|
||||
curTextChapter?.cancelLayout()
|
||||
curTextChapter = textChapter
|
||||
callBack?.upMenuView()
|
||||
var available = false
|
||||
@@ -727,12 +722,14 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
}
|
||||
|
||||
-1 -> {
|
||||
prevTextChapter?.cancelLayout()
|
||||
prevTextChapter = textChapter
|
||||
textChapter.layoutChannel.receiveAsFlow().collect()
|
||||
if (upContent) callBack?.upContent(offset, resetPageOffset)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
nextTextChapter?.cancelLayout()
|
||||
nextTextChapter = textChapter
|
||||
for (page in textChapter.layoutChannel) {
|
||||
if (page.index > 1) {
|
||||
@@ -776,6 +773,7 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
)
|
||||
when (val offset = chapter.index - durChapterIndex) {
|
||||
0 -> {
|
||||
curTextChapter?.cancelLayout()
|
||||
curTextChapter = textChapter
|
||||
callBack?.upMenuView()
|
||||
var available = false
|
||||
@@ -800,12 +798,14 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
}
|
||||
|
||||
-1 -> {
|
||||
prevTextChapter?.cancelLayout()
|
||||
prevTextChapter = textChapter
|
||||
textChapter.layoutChannel.receiveAsFlow().collect()
|
||||
if (upContent) callBack?.upContent(offset, resetPageOffset)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
nextTextChapter?.cancelLayout()
|
||||
nextTextChapter = textChapter
|
||||
for (page in textChapter.layoutChannel) {
|
||||
if (page.index > 1) {
|
||||
@@ -858,21 +858,25 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
|
||||
fun saveRead(pageChanged: Boolean = false) {
|
||||
executor.execute {
|
||||
val book = book ?: return@execute
|
||||
book.lastCheckCount = 0
|
||||
book.durChapterTime = System.currentTimeMillis()
|
||||
val chapterChanged = book.durChapterIndex != durChapterIndex
|
||||
book.durChapterIndex = durChapterIndex
|
||||
book.durChapterPos = durChapterPos
|
||||
if (!pageChanged || chapterChanged) {
|
||||
appDb.bookChapterDao.getChapter(book.bookUrl, durChapterIndex)?.let {
|
||||
book.durChapterTitle = it.getDisplayTitle(
|
||||
ContentProcessor.get(book.name, book.origin).getTitleReplaceRules(),
|
||||
book.getUseReplaceRule()
|
||||
)
|
||||
kotlin.runCatching {
|
||||
val book = book ?: return@execute
|
||||
book.lastCheckCount = 0
|
||||
book.durChapterTime = System.currentTimeMillis()
|
||||
val chapterChanged = book.durChapterIndex != durChapterIndex
|
||||
book.durChapterIndex = durChapterIndex
|
||||
book.durChapterPos = durChapterPos
|
||||
if (!pageChanged || chapterChanged) {
|
||||
appDb.bookChapterDao.getChapter(book.bookUrl, durChapterIndex)?.let {
|
||||
book.durChapterTitle = it.getDisplayTitle(
|
||||
ContentProcessor.get(book.name, book.origin).getTitleReplaceRules(),
|
||||
book.getUseReplaceRule()
|
||||
)
|
||||
}
|
||||
}
|
||||
appDb.bookDao.update(book)
|
||||
}.onFailure {
|
||||
AppLog.put("保存书籍阅读进度信息出错\n$it", it)
|
||||
}
|
||||
appDb.bookDao.update(book)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -327,21 +327,25 @@ object ReadManga : CoroutineScope by MainScope() {
|
||||
|
||||
fun saveRead(pageChanged: Boolean = false) {
|
||||
executor.execute {
|
||||
val book = book ?: return@execute
|
||||
book.lastCheckCount = 0
|
||||
book.durChapterTime = System.currentTimeMillis()
|
||||
val chapterChanged = book.durChapterIndex != durChapterIndex
|
||||
book.durChapterIndex = durChapterIndex
|
||||
book.durChapterPos = durChapterPos
|
||||
if (!pageChanged || chapterChanged) {
|
||||
appDb.bookChapterDao.getChapter(book.bookUrl, durChapterIndex)?.let {
|
||||
book.durChapterTitle = it.getDisplayTitle(
|
||||
ContentProcessor.get(book.name, book.origin).getTitleReplaceRules(),
|
||||
book.getUseReplaceRule()
|
||||
)
|
||||
kotlin.runCatching {
|
||||
val book = book ?: return@execute
|
||||
book.lastCheckCount = 0
|
||||
book.durChapterTime = System.currentTimeMillis()
|
||||
val chapterChanged = book.durChapterIndex != durChapterIndex
|
||||
book.durChapterIndex = durChapterIndex
|
||||
book.durChapterPos = durChapterPos
|
||||
if (!pageChanged || chapterChanged) {
|
||||
appDb.bookChapterDao.getChapter(book.bookUrl, durChapterIndex)?.let {
|
||||
book.durChapterTitle = it.getDisplayTitle(
|
||||
ContentProcessor.get(book.name, book.origin).getTitleReplaceRules(),
|
||||
book.getUseReplaceRule()
|
||||
)
|
||||
}
|
||||
}
|
||||
appDb.bookDao.update(book)
|
||||
}.onFailure {
|
||||
AppLog.put("保存漫画阅读进度信息出错\n$it", it)
|
||||
}
|
||||
appDb.bookDao.update(book)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ import io.legato.kazusa.help.http.postForm
|
||||
import io.legato.kazusa.help.http.postJson
|
||||
import io.legato.kazusa.help.http.postMultipart
|
||||
import io.legato.kazusa.help.source.getShareScope
|
||||
import io.legato.kazusa.model.Debug
|
||||
import io.legato.kazusa.utils.EncoderUtils
|
||||
import io.legato.kazusa.utils.GSON
|
||||
import io.legato.kazusa.utils.GSONStrict
|
||||
@@ -225,32 +224,32 @@ class AnalyzeUrl(
|
||||
if (urlOption == null) {
|
||||
urlOption = GSON.fromJsonObject<UrlOption>(urlOptionStr).getOrNull()
|
||||
if (urlOption != null) {
|
||||
Debug.log("≡链接参数 JSON 格式不规范,请改为规范格式")
|
||||
log("链接参数 JSON 格式不规范,请改为规范格式")
|
||||
}
|
||||
}
|
||||
urlOption?.let { option ->
|
||||
option.getMethod()?.let {
|
||||
if (it.equals("POST", true)) method = RequestMethod.POST
|
||||
}
|
||||
option.getHeaderMap()?.forEach { entry ->
|
||||
headerMap[entry.key.toString()] = entry.value.toString()
|
||||
}
|
||||
option.getBody()?.let {
|
||||
body = it
|
||||
}
|
||||
type = option.getType()
|
||||
charset = option.getCharset()
|
||||
retry = option.getRetry()
|
||||
useWebView = option.useWebView()
|
||||
webJs = option.getWebJs()
|
||||
option.getJs()?.let { jsStr ->
|
||||
evalJS(jsStr, url)?.toString()?.let {
|
||||
url = it
|
||||
}
|
||||
option.getMethod()?.let {
|
||||
if (it.equals("POST", true)) method = RequestMethod.POST
|
||||
}
|
||||
option.getHeaderMap()?.forEach { entry ->
|
||||
headerMap[entry.key.toString()] = entry.value.toString()
|
||||
}
|
||||
option.getBody()?.let {
|
||||
body = it
|
||||
}
|
||||
type = option.getType()
|
||||
charset = option.getCharset()
|
||||
retry = option.getRetry()
|
||||
useWebView = option.useWebView()
|
||||
webJs = option.getWebJs()
|
||||
option.getJs()?.let { jsStr ->
|
||||
evalJS(jsStr, url)?.toString()?.let {
|
||||
url = it
|
||||
}
|
||||
serverID = option.getServerID()
|
||||
webViewDelayTime = max(0, option.getWebViewDelayTime() ?: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
urlNoQuery = url
|
||||
when (method) {
|
||||
@@ -458,7 +457,7 @@ class AnalyzeUrl(
|
||||
else -> get(urlNoQuery, encodedQuery)
|
||||
}
|
||||
}.let {
|
||||
val isXml = it.raw.body?.contentType()?.toString()
|
||||
val isXml = it.raw.body.contentType()?.toString()
|
||||
?.matches(AppPattern.xmlContentTypeRegex) == true
|
||||
if (isXml && it.body?.trim()?.startsWith("<?xml", true) == false) {
|
||||
StrResponse(it.raw, "<?xml version=\"1.0\"?>" + it.body)
|
||||
@@ -553,7 +552,7 @@ class AnalyzeUrl(
|
||||
getByteArrayIfDataUri()?.let {
|
||||
return it
|
||||
}
|
||||
return getResponseAwait().body!!.bytes()
|
||||
return getResponseAwait().body.bytes()
|
||||
}
|
||||
|
||||
fun getByteArray(): ByteArray {
|
||||
@@ -569,7 +568,7 @@ class AnalyzeUrl(
|
||||
getByteArrayIfDataUri()?.let {
|
||||
return ByteArrayInputStream(it)
|
||||
}
|
||||
return getResponseAwait().body!!.byteStream()
|
||||
return getResponseAwait().body.byteStream()
|
||||
}
|
||||
|
||||
fun getInputStream(): InputStream {
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.legato.kazusa.model.localBook
|
||||
|
||||
import android.net.Uri
|
||||
import android.util.Base64
|
||||
import androidx.core.net.toUri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import com.script.ScriptBindings
|
||||
import com.script.rhino.RhinoScriptEngine
|
||||
@@ -103,7 +104,7 @@ object LocalBook {
|
||||
|
||||
fun getLastModified(book: Book): Result<Long> {
|
||||
return kotlin.runCatching {
|
||||
val uri = Uri.parse(book.bookUrl)
|
||||
val uri = book.bookUrl.toUri()
|
||||
if (uri.isContentScheme()) {
|
||||
return@runCatching DocumentFile.fromSingleUri(appCtx, uri)!!.lastModified()
|
||||
}
|
||||
@@ -144,6 +145,9 @@ object LocalBook {
|
||||
val list = ArrayList(LinkedHashSet(chapters))
|
||||
list.forEachIndexed { index, bookChapter ->
|
||||
bookChapter.index = index
|
||||
if (bookChapter.title.isEmpty()) {
|
||||
bookChapter.title = "无标题章节"
|
||||
}
|
||||
}
|
||||
val replaceRules = ContentProcessor.get(book).getTitleReplaceRules()
|
||||
book.durChapterTitle = list.getOrElse(book.durChapterIndex) { list.last() }
|
||||
@@ -191,6 +195,9 @@ object LocalBook {
|
||||
return StringEscapeUtils.unescapeHtml4(content)
|
||||
}
|
||||
}
|
||||
if (content.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
@@ -374,7 +381,7 @@ object LocalBook {
|
||||
}
|
||||
if (deleteOriginal) {
|
||||
if (book.bookUrl.isContentScheme()) {
|
||||
val uri = Uri.parse(book.bookUrl)
|
||||
val uri = book.bookUrl.toUri()
|
||||
DocumentFile.fromSingleUri(appCtx, uri)?.delete()
|
||||
} else {
|
||||
FileUtils.delete(book.bookUrl)
|
||||
@@ -419,7 +426,7 @@ object LocalBook {
|
||||
inputStream.use {
|
||||
val defaultBookTreeUri = AppConfig.defaultBookTreeUri
|
||||
if (defaultBookTreeUri.isNullOrBlank()) throw NoBooksDirException()
|
||||
val treeUri = Uri.parse(defaultBookTreeUri)
|
||||
val treeUri = defaultBookTreeUri.toUri()
|
||||
return if (treeUri.isContentScheme()) {
|
||||
val treeDoc = DocumentFile.fromTreeUri(appCtx, treeUri)
|
||||
var doc = treeDoc!!.findFile(fileName)
|
||||
|
||||
@@ -229,7 +229,7 @@ class MobiFile(var book: Book) {
|
||||
break
|
||||
}
|
||||
section = section.next ?: break
|
||||
if (section.linear) {
|
||||
if (!section.linear) {
|
||||
continue
|
||||
}
|
||||
if (section.href == nextSectionHref) {
|
||||
|
||||
@@ -215,6 +215,7 @@ class TextFile(private var book: Book) {
|
||||
val curChapter = BookChapter()
|
||||
curChapter.title = matcher.group()
|
||||
curChapter.start = curOffset + chapterLength
|
||||
curChapter.end = curChapter.start
|
||||
toc.add(curChapter)
|
||||
lastChapterWordCount = 0
|
||||
} else if (seekPos == 0 && chapterStart != 0) {
|
||||
@@ -242,6 +243,7 @@ class TextFile(private var book: Book) {
|
||||
val curChapter = BookChapter()
|
||||
curChapter.title = matcher.group()
|
||||
curChapter.start = curOffset + chapterLength
|
||||
curChapter.end = curChapter.start
|
||||
toc.add(curChapter)
|
||||
} else { //否则就block分割之后,上一个章节的剩余内容
|
||||
//获取上一章节
|
||||
@@ -257,6 +259,7 @@ class TextFile(private var book: Book) {
|
||||
val curChapter = BookChapter()
|
||||
curChapter.title = matcher.group()
|
||||
curChapter.start = lastChapter.end
|
||||
curChapter.end = curChapter.start
|
||||
toc.add(curChapter)
|
||||
}
|
||||
bookWordCount += chapterContent.length
|
||||
@@ -275,6 +278,7 @@ class TextFile(private var book: Book) {
|
||||
val curChapter = BookChapter()
|
||||
curChapter.title = matcher.group()
|
||||
curChapter.start = lastChapter.end
|
||||
curChapter.end = curChapter.start
|
||||
toc.add(curChapter)
|
||||
} else { //如果章节不存在则创建章节
|
||||
val curChapter = BookChapter()
|
||||
|
||||
@@ -17,8 +17,10 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -39,7 +41,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
private var bookSourceParts = emptyList<BookSourcePart>()
|
||||
private var searchBooks = arrayListOf<SearchBook>()
|
||||
private var searchJob: Job? = null
|
||||
|
||||
private var workingState = MutableStateFlow(true)
|
||||
|
||||
private fun initSearchPool() {
|
||||
searchPool?.close()
|
||||
@@ -82,6 +84,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
bs.getBookSource()?.let {
|
||||
emit(it)
|
||||
}
|
||||
workingState.first { it }
|
||||
}
|
||||
}.onStart {
|
||||
callBack.onSearchStart()
|
||||
@@ -191,6 +194,14 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
|
||||
mSearchId = 0L
|
||||
}
|
||||
|
||||
fun pause() {
|
||||
workingState.value = false
|
||||
}
|
||||
|
||||
fun resume() {
|
||||
workingState.value = true
|
||||
}
|
||||
|
||||
interface CallBack {
|
||||
fun getSearchScope(): SearchScope
|
||||
fun onSearchStart()
|
||||
|
||||
Reference in new issue
Block a user