From 501222b79b4ead8de57e2f7abfe45729144034d7 Mon Sep 17 00:00:00 2001 From: 8f23 Date: Fri, 1 Mar 2024 14:30:29 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=89=8B=E5=8A=A8?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=BC=B9=E5=B9=95=E7=9A=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fragment/bind_danmu/BindDanmuSourceFragmentViewModel.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/local_component/src/main/java/com/xyoye/local_component/ui/fragment/bind_danmu/BindDanmuSourceFragmentViewModel.kt b/local_component/src/main/java/com/xyoye/local_component/ui/fragment/bind_danmu/BindDanmuSourceFragmentViewModel.kt index 29baf03ca..010d664a5 100644 --- a/local_component/src/main/java/com/xyoye/local_component/ui/fragment/bind_danmu/BindDanmuSourceFragmentViewModel.kt +++ b/local_component/src/main/java/com/xyoye/local_component/ui/fragment/bind_danmu/BindDanmuSourceFragmentViewModel.kt @@ -89,6 +89,10 @@ class BindDanmuSourceFragmentViewModel : BaseViewModel() { hideLoading() _searchedAnimeFlow.emit(result) + // 自动选择第一个动画。 + if (result.isNotEmpty()) { + _selectedAnimeFlow.emit(result[0]) + } } } From d7f085e869b153048aa564670b64a13e78978ccc Mon Sep 17 00:00:00 2001 From: 8f23 Date: Fri, 1 Mar 2024 17:29:09 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=B8=BA=E6=89=8B=E5=8A=A8=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=BC=B9=E5=B9=95/=E5=AD=97=E5=B9=95=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=8A=A8=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E5=8E=86=E5=8F=B2=E6=90=9C=E7=B4=A2=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E7=9A=84=E7=89=B9=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bind_source/BindExtraSourceViewModel.kt | 86 ++++++++++++++++++- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/local_component/src/main/java/com/xyoye/local_component/ui/activities/bind_source/BindExtraSourceViewModel.kt b/local_component/src/main/java/com/xyoye/local_component/ui/activities/bind_source/BindExtraSourceViewModel.kt index 25a6e2028..5802c1b5e 100644 --- a/local_component/src/main/java/com/xyoye/local_component/ui/activities/bind_source/BindExtraSourceViewModel.kt +++ b/local_component/src/main/java/com/xyoye/local_component/ui/activities/bind_source/BindExtraSourceViewModel.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import org.json.JSONObject +import java.util.LinkedList /** @@ -26,10 +27,14 @@ import org.json.JSONObject class BindExtraSourceViewModel : BaseViewModel() { companion object { - private const val MAX_CACHE_SIZE = 50 + private const val MAX_SEGMENT_CACHE_SIZE = 50 + private const val MAX_SEARCH_TEXT_CACHE_SIZE = 25 // 分词结果缓存 - private val segmentCache = LruCache>(MAX_CACHE_SIZE) + private val segmentCache = LruCache>(MAX_SEGMENT_CACHE_SIZE) + + // 搜索记录缓存,格式为 。 + private val searchTextCache = LinkedList>() } private lateinit var storageFile: StorageFile @@ -43,7 +48,7 @@ class BindExtraSourceViewModel : BaseViewModel() { }.stateIn(viewModelScope, SharingStarted.Lazily, storageFile) } - private val _searchTextFlow = MutableSharedFlow() + private val _searchTextFlow = MutableSharedFlow(1) val searchTextFlow = _searchTextFlow.collectable private val _segmentTitleLiveData = MediatorLiveData>() @@ -51,12 +56,19 @@ class BindExtraSourceViewModel : BaseViewModel() { fun setStorageFile(storageFile: StorageFile) { this.storageFile = storageFile + val cachedSearchText: String? = matchSearchTextCache(storageFile) + if (cachedSearchText != null) { + viewModelScope.launch { + _searchTextFlow.emit(cachedSearchText) + } + } } fun setSearchText(text: String) { viewModelScope.launch { _searchTextFlow.emit(text) } + addSearchTextCache(storageFile, text) } fun segmentTitle(storageFile: StorageFile) { @@ -110,4 +122,72 @@ class BindExtraSourceViewModel : BaseViewModel() { } return words } + + private fun matchSearchTextCache(target: StorageFile): String? { + for (cachedTriple in searchTextCache) { + val cachedFileDir: String = cachedTriple.first + val cachedFileName: String = cachedTriple.second + val cachedText: String = cachedTriple.third + val targetDir = parseFileDir(target.filePath()) + val targetName = target.fileName() + if (!target.isFile()) { + continue + } + // 比较所在目录。 + if (targetDir != cachedFileDir) { + continue + } + // 比较文件名。 + var ptr = 0 + val diff = LinkedList() + while (ptr < targetName.length || ptr < cachedFileName.length) { + val a = if (ptr < targetName.length) targetName[ptr] else '*' + val b = if (ptr < cachedFileName.length) cachedFileName[ptr] else '*' + if (a != b) { + diff.addLast(ptr) + } + ptr++ + } + if (diff.size == 0) { + // 无差异。 + return cachedText + } + if (diff.size > 2) { + // 差异过多。 + continue + } + if (diff.any { !targetName[it].isDigit() || !cachedFileName[it].isDigit() }) { + // 差异包含数字以外的内容。 + continue + } + if (diff.size == 2 && (diff[1] - diff[0] != 1)) { + // 多段不相邻差异。 + continue + } + // 命中缓存。 + if (cachedText.matches(Regex(".* \\d{1,2}$"))) { + // 缓存搜索结果末尾包含集数,删除集数内容。 + // 不作替换处理是避免错误处理文件名中类似"11"、"12"这样的差异。 + return cachedText.replace(Regex(" \\d{1,2}$"), "") + } + return cachedText + } + return null + } + + private fun addSearchTextCache(file: StorageFile, text: String) { + val dir = parseFileDir(file.filePath()) + val name = file.fileName() + searchTextCache.addFirst(Triple(dir, name, text)) + if (searchTextCache.size > MAX_SEARCH_TEXT_CACHE_SIZE) { + searchTextCache.removeLast() + } + } + + private fun parseFileDir(fullPath: String): String { + if (fullPath.contains(Regex("/"))) { + return fullPath.replace(Regex("/[^/]*$"), "") + } + return "/" + } } \ No newline at end of file From 320ed5e2bf72ec111f3f4f793be56b0da47b3b57 Mon Sep 17 00:00:00 2001 From: xyoye Date: Sat, 9 Mar 2024 22:01:11 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=8C=E5=96=84:=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=90=9C=E7=B4=A2=E6=96=87=E5=AD=97=E6=98=BE?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/activities/bind_source/BindExtraSourceActivity.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/local_component/src/main/java/com/xyoye/local_component/ui/activities/bind_source/BindExtraSourceActivity.kt b/local_component/src/main/java/com/xyoye/local_component/ui/activities/bind_source/BindExtraSourceActivity.kt index 6d5bb1411..3d2218b10 100644 --- a/local_component/src/main/java/com/xyoye/local_component/ui/activities/bind_source/BindExtraSourceActivity.kt +++ b/local_component/src/main/java/com/xyoye/local_component/ui/activities/bind_source/BindExtraSourceActivity.kt @@ -129,6 +129,10 @@ class BindExtraSourceActivity : VideoItemLayout.initVideoLayout(dataBinding, it) } + viewModel.searchTextFlow.collectAtStarted(this) { + dataBinding.searchEt.setText(it) + } + viewModel.segmentTitleLiveData.observe(this) { SegmentWordDialog(this, it) { searchText -> dataBinding.searchEt.setText(searchText)