|
|
@ -14,8 +14,11 @@ import io.legado.app.constant.EventBus |
|
|
|
import io.legado.app.data.entities.Book |
|
|
|
import io.legado.app.data.entities.Book |
|
|
|
import io.legado.app.data.entities.BookChapter |
|
|
|
import io.legado.app.data.entities.BookChapter |
|
|
|
import io.legado.app.help.BookHelp |
|
|
|
import io.legado.app.help.BookHelp |
|
|
|
|
|
|
|
import io.legado.app.lib.theme.bottomBackground |
|
|
|
|
|
|
|
import io.legado.app.lib.theme.getPrimaryTextColor |
|
|
|
import io.legado.app.ui.widget.recycler.UpLinearLayoutManager |
|
|
|
import io.legado.app.ui.widget.recycler.UpLinearLayoutManager |
|
|
|
import io.legado.app.ui.widget.recycler.VerticalDivider |
|
|
|
import io.legado.app.ui.widget.recycler.VerticalDivider |
|
|
|
|
|
|
|
import io.legado.app.utils.ColorUtils |
|
|
|
import io.legado.app.utils.getViewModelOfActivity |
|
|
|
import io.legado.app.utils.getViewModelOfActivity |
|
|
|
import io.legado.app.utils.observeEvent |
|
|
|
import io.legado.app.utils.observeEvent |
|
|
|
import kotlinx.android.synthetic.main.fragment_search_list.* |
|
|
|
import kotlinx.android.synthetic.main.fragment_search_list.* |
|
|
@ -33,21 +36,16 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
|
|
|
|
|
|
|
|
lateinit var adapter: SearchListAdapter |
|
|
|
lateinit var adapter: SearchListAdapter |
|
|
|
private lateinit var mLayoutManager: UpLinearLayoutManager |
|
|
|
private lateinit var mLayoutManager: UpLinearLayoutManager |
|
|
|
private var tocLiveData: LiveData<List<BookChapter>>? = null |
|
|
|
|
|
|
|
private var searchResultCounts = 0 |
|
|
|
private var searchResultCounts = 0 |
|
|
|
|
|
|
|
|
|
|
|
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { |
|
|
|
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { |
|
|
|
viewModel.searchCallBack = this |
|
|
|
viewModel.searchCallBack = this |
|
|
|
|
|
|
|
|
|
|
|
/* set color for the bottom bar |
|
|
|
|
|
|
|
val bbg = bottomBackground |
|
|
|
val bbg = bottomBackground |
|
|
|
val btc = requireContext().getPrimaryTextColor(ColorUtils.isColorLight(bbg)) |
|
|
|
val btc = requireContext().getPrimaryTextColor(ColorUtils.isColorLight(bbg)) |
|
|
|
ll_chapter_base_info.setBackgroundColor(bbg) |
|
|
|
ll_search_base_info.setBackgroundColor(bbg) |
|
|
|
tv_current_chapter_info.setTextColor(btc) |
|
|
|
tv_current_search_info.setTextColor(btc) |
|
|
|
iv_chapter_top.setColorFilter(btc) |
|
|
|
iv_search_content_top.setColorFilter(btc) |
|
|
|
iv_chapter_bottom.setColorFilter(btc) |
|
|
|
iv_search_content_bottom.setColorFilter(btc) |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
initRecyclerView() |
|
|
|
initRecyclerView() |
|
|
|
initView() |
|
|
|
initView() |
|
|
|
initBook() |
|
|
|
initBook() |
|
|
@ -73,9 +71,8 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
@SuppressLint("SetTextI18n") |
|
|
|
@SuppressLint("SetTextI18n") |
|
|
|
private fun initBook() { |
|
|
|
private fun initBook() { |
|
|
|
launch { |
|
|
|
launch { |
|
|
|
|
|
|
|
tv_current_search_info.text = "搜索结果:$searchResultCounts" |
|
|
|
viewModel.book?.let { |
|
|
|
viewModel.book?.let { |
|
|
|
tv_current_search_info.text = |
|
|
|
|
|
|
|
"搜索结果:$searchResultCounts" |
|
|
|
|
|
|
|
initCacheFileNames(it) |
|
|
|
initCacheFileNames(it) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -101,6 +98,7 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressLint("SetTextI18n") |
|
|
|
override fun startContentSearch(newText: String?) { |
|
|
|
override fun startContentSearch(newText: String?) { |
|
|
|
if (!newText.isNullOrBlank()) { |
|
|
|
if (!newText.isNullOrBlank()) { |
|
|
|
adapter.clearItems() |
|
|
|
adapter.clearItems() |
|
|
@ -114,7 +112,9 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
val searchResults = searchChapter(newText, it) |
|
|
|
val searchResults = searchChapter(newText, it) |
|
|
|
if (searchResults.size > 0 ){ |
|
|
|
if (searchResults.size > 0 ){ |
|
|
|
searchResultCounts += searchResults.size |
|
|
|
searchResultCounts += searchResults.size |
|
|
|
|
|
|
|
|
|
|
|
withContext(Main){ |
|
|
|
withContext(Main){ |
|
|
|
|
|
|
|
tv_current_search_info.text = "搜索结果:$searchResultCounts" |
|
|
|
adapter.addItems(searchResults) |
|
|
|
adapter.addItems(searchResults) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -137,9 +137,8 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
viewModel.book?.let { bookSource -> |
|
|
|
viewModel.book?.let { bookSource -> |
|
|
|
val bookContent = BookHelp.getContent(bookSource, chapter) |
|
|
|
val bookContent = BookHelp.getContent(bookSource, chapter) |
|
|
|
if (bookContent != null){ |
|
|
|
if (bookContent != null){ |
|
|
|
//todo: 搜索替换后的正文 |
|
|
|
//todo: 搜索替换后的正文句子列表 |
|
|
|
//todo: 计算搜索结果所在的pageIndex直接跳转 |
|
|
|
/* |
|
|
|
/* replace content, let's focus on original content first |
|
|
|
|
|
|
|
chapter.title = when (AppConfig.chineseConverterType) { |
|
|
|
chapter.title = when (AppConfig.chineseConverterType) { |
|
|
|
1 -> HanLP.convertToSimplifiedChinese(chapter.title) |
|
|
|
1 -> HanLP.convertToSimplifiedChinese(chapter.title) |
|
|
|
2 -> HanLP.convertToTraditionalChinese(chapter.title) |
|
|
|
2 -> HanLP.convertToTraditionalChinese(chapter.title) |
|
|
@ -165,15 +164,16 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
} |
|
|
|
} |
|
|
|
}?.awaitAll() |
|
|
|
}?.awaitAll() |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
positions = countMatches(bookContent, query) |
|
|
|
positions = searchPosition(bookContent, query) |
|
|
|
positions?.map{ |
|
|
|
positions?.map{ |
|
|
|
|
|
|
|
val construct = constructText(bookContent, it) |
|
|
|
val result = SearchResult(index = 0, |
|
|
|
val result = SearchResult(index = 0, |
|
|
|
text = constructText(bookContent, it), |
|
|
|
text = construct[1] as String, |
|
|
|
chapterTitle = chapter.title, |
|
|
|
chapterTitle = chapter.title, |
|
|
|
query = query, |
|
|
|
query = query, |
|
|
|
pageSize = 0, // to be finished |
|
|
|
pageIndex = 0, //todo: 计算搜索结果所在的pageIndex直接跳转 |
|
|
|
chapterIndex = chapter.index, // to be finished |
|
|
|
chapterIndex = chapter.index, |
|
|
|
pageIndex = 0, // to be finished |
|
|
|
newPosition = construct[0] as Int |
|
|
|
) |
|
|
|
) |
|
|
|
searchResults.add(result) |
|
|
|
searchResults.add(result) |
|
|
|
Log.d("Jason", result.presentText) |
|
|
|
Log.d("Jason", result.presentText) |
|
|
@ -187,7 +187,7 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
return searchResults |
|
|
|
return searchResults |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun countMatches(content: String, pattern: String): List<Int> { |
|
|
|
private fun searchPosition(content: String, pattern: String): List<Int> { |
|
|
|
val position : MutableList<Int> = mutableListOf() |
|
|
|
val position : MutableList<Int> = mutableListOf() |
|
|
|
var index = content.indexOf(pattern) |
|
|
|
var index = content.indexOf(pattern) |
|
|
|
while(index >= 0){ |
|
|
|
while(index >= 0){ |
|
|
@ -197,7 +197,7 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
return position |
|
|
|
return position |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun constructText(content: String, position: Int): String{ |
|
|
|
private fun constructText(content: String, position: Int): Array<Any>{ |
|
|
|
// 构建关键词周边文字,在搜索结果里显示 |
|
|
|
// 构建关键词周边文字,在搜索结果里显示 |
|
|
|
// todo: 判断段落,只在关键词所在段落内分割 |
|
|
|
// todo: 判断段落,只在关键词所在段落内分割 |
|
|
|
// todo: 利用标点符号分割完整的句 |
|
|
|
// todo: 利用标点符号分割完整的句 |
|
|
@ -211,7 +211,9 @@ class SearchListFragment : VMBaseFragment<SearchListViewModel>(R.layout.fragment |
|
|
|
if (po2 > content.length){ |
|
|
|
if (po2 > content.length){ |
|
|
|
po2 = content.length |
|
|
|
po2 = content.length |
|
|
|
} |
|
|
|
} |
|
|
|
return "..." + content.substring(po1, po2) |
|
|
|
val newPosition = position - po1 |
|
|
|
|
|
|
|
val newText = "..." + content.substring(po1, po2) |
|
|
|
|
|
|
|
return arrayOf(newPosition, newText) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val isLocalBook: Boolean |
|
|
|
val isLocalBook: Boolean |
|
|
|