Skip to content

Commit

Permalink
💪 改进搜索面板和键盘的配合的使用体验
Browse files Browse the repository at this point in the history
现在Web3的搜索面板会自动排除掉空格;
对中间空格会用连接符做尝试
  • Loading branch information
Gaubee committed Jan 12, 2025
1 parent ae14c52 commit 859d616
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import org.dweb_browser.helper.clamp
import org.dweb_browser.helper.compose.compositionChainOf
import org.dweb_browser.helper.encodeURIComponent
import org.dweb_browser.helper.format
import org.dweb_browser.helper.humanTrim
import org.dweb_browser.helper.isDwebDeepLink
import org.dweb_browser.helper.isTrimEndSlashEqual
import org.dweb_browser.helper.platform.toByteArray
Expand Down Expand Up @@ -356,7 +357,7 @@ class BrowserViewModel(
* 否:将 url 进行判断封装,符合条件后,判断当前界面是否是 BrowserWebPage,然后进行搜索操作
*/
fun doIOSearchUrl(searchText: String) = lifecycleScope.launch {
val text = searchText.trim().trim('\u200B').trim()
val text = searchText.humanTrim()
if (text.isDwebDeepLink()) {
browserNMM.nativeFetch(text)
return@launch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.VisualTransformation
import kotlinx.coroutines.delay
import org.dweb_browser.browser.web.model.BrowserViewModel
Expand Down Expand Up @@ -129,7 +130,10 @@ class BrowserSearchPanel(val viewModel: BrowserViewModel) {
lineLimits = TextFieldLineLimits.SingleLine,
textStyle = LocalTextStyle.current.copy(color = searchFieldColors.focusedTextColor),
cursorBrush = SolidColor(searchFieldColors.cursorColor),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Search,
keyboardType = KeyboardType.Uri,
),
onKeyboardAction = {
focusManager.clearFocus()
suggestionActions.firstOrNull()?.invoke()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ import androidx.compose.ui.zIndex
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import org.dweb_browser.browser.BrowserI18nResource
import org.dweb_browser.browser.web.model.LocalBrowserViewModel
import org.dweb_browser.browser.web.model.page.BrowserWebPage
import org.dweb_browser.helper.humanTrim

internal enum class TabId {
Chat,
Expand Down Expand Up @@ -93,17 +95,22 @@ internal fun SearchSuggestion(
}
DisposableEffect(searchText) {
web3Searcher?.cancel(CancellationException("Cancel search"))
web3Searcher = when {
searchText.isEmpty() -> null
else -> {
val parentScope = viewModel.browserNMM.getRuntimeScope()
Web3Searcher(
coroutineContext = parentScope.coroutineContext + SupervisorJob(parentScope.coroutineContext.job),
searchText = searchText
)
val job = scope.launch {
delay(150)// 防抖
val keyword = searchText.humanTrim()
web3Searcher = when {
keyword.isEmpty() -> null
else -> {
val parentScope = viewModel.browserNMM.getRuntimeScope()
Web3Searcher(
coroutineContext = parentScope.coroutineContext + SupervisorJob(parentScope.coroutineContext.job),
searchText = keyword
)
}
}
}
onDispose {
job.cancel()
web3Searcher?.cancel(CancellationException("Cancel search"))
web3Searcher = null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import org.dweb_browser.core.std.dns.httpFetch
import org.dweb_browser.helper.Once
import org.dweb_browser.helper.commonConsumeEachArrayRange
import org.dweb_browser.helper.hexString
import org.dweb_browser.helper.isNoProtocolWebUrl
import org.dweb_browser.helper.isWebUrl
import org.dweb_browser.helper.isWebUrlOrWithoutProtocol
import org.dweb_browser.helper.toWebUrl
import org.dweb_browser.helper.utf8String
import org.dweb_browser.pure.crypto.hash.sha256
Expand All @@ -31,8 +31,18 @@ import kotlin.coroutines.CoroutineContext

internal class Web3Searcher(
override val coroutineContext: CoroutineContext,
val searchText: String,
val searchTexts: List<String>,
) : CoroutineScope {
constructor(coroutineContext: CoroutineContext, searchText: String) : this(
coroutineContext, when {
searchText.contains(' ') -> listOf(
searchText.replace(Regex("\\s+"), "-"),
searchText.replace(Regex("\\s+"), ""),
)

else -> listOf(searchText)
}
)

/**
* 这是新语法,如果你的IDE报错:
Expand Down Expand Up @@ -118,27 +128,30 @@ internal class Web3Searcher(
// 创建一个 Semaphore 来限制并发数为 5
val semaphore = Semaphore(5)
flow {
if (searchText.isWebUrl()) {
emit(searchText)
return@flow
}
if (searchText.isWebUrlOrWithoutProtocol()) {
emit("https://$searchText")
emit("https://dweb.$searchText")
}
flow {
emit("com")
emit("org")
emit("net")
}.collect { top ->
emit("https://$searchText.$top")
emit("https://www.$searchText.$top")
emit("https://dweb.$searchText.$top")
emit("https://dweb-$searchText.$top")
emit("https://$searchText-dweb.$top")
searchTexts.forEach { searchText ->
when {
searchText.isWebUrl() -> emit(searchText)
searchText.isNoProtocolWebUrl() -> {
emit("https://$searchText")
emit("https://dweb.$searchText")
}

else -> {
flow {
emit("com")
emit("org")
emit("net")
}.collect { top ->
emit("https://$searchText.$top")
emit("https://www.$searchText.$top")
emit("https://dweb.$searchText.$top")
emit("https://dweb-$searchText.$top")
emit("https://$searchText-dweb.$top")
}
}
}
}
}
.collect { originHref ->
}.collect { originHref ->
launch {
semaphore.withPermit {
val originUrl = originHref.toWebUrl() ?: return@withPermit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
package org.dweb_browser.helper

public fun String.removeInvisibleChars(): String = replace(Regex("[\\p{C}\\p{Z}&&[^\\p{Zs}]]"), "")
public fun String.removeInvisibleChars(): String = replace(Regex("[\\p{C}\\p{Z}&&[^\\p{Zs}]]"), "")

public fun String.humanTrim(): String = trim(
// 零宽字符:
'\u200B',//零宽空格 (ZWSP)
'\u200C',//零宽非连接符 (ZWNJ)
'\u200D',//零宽连接符 (ZWJ)

// 常见的空白字符:

'\u0020',// 普通空格 (Space)
'\u00A0',// 不间断空格 (Non-breaking space)
'\u1680',// 赡养符 (Ogham space mark)
'\u2000',// 到 \u200A 一系列空格(各种宽度的空格)
// 格式控制字符(这些字符主要用于控制文本格式,通常在现代文本中不再使用,但在某些场景中仍然可能出现):

'\u200B',// 零宽空格(Zero Width Space)
'\u200C',// 零宽非连接符(Zero Width Non-Joiner)
'\u200D',// 零宽连接符(Zero Width Joiner)
'\u200E',// 左到右标记(Left-to-Right Mark, LRM)
'\u200F',// 右到左标记(Right-to-Left Mark, RLM)
'\u202A',// 到 \u202E 一些文本方向控制字符(如:右到左方向标记、强制方向标记等)
// 换行符与回车符:

'\u000A',// 换行符(Line Feed, LF)
'\u000D',// 回车符(Carriage Return, CR)
'\u2028',// 行分隔符(Line Separator)
'\u2029',// 段分隔符(Paragraph Separator)

)

0 comments on commit 859d616

Please sign in to comment.