Feature(custom): add strict search for plugin search, avoid unrelated results

This commit is contained in:
Kuingsmile
2025-12-31 17:08:51 +08:00
parent 6f44cf17b8
commit 17355168f6
5 changed files with 88 additions and 1 deletions

View File

@@ -627,6 +627,8 @@
"setResult": "Set Result",
"setSuccess": "Set Success",
"settings": "Settings",
"strictSearch": "Strict Search",
"strictSearchDescription": "Only show plugins that contain the search term in name",
"title": "Plugins",
"tryDifferentSearch": "Try Different Search Keywords",
"updateAll": "Update All Plugins",

View File

@@ -627,6 +627,8 @@
"setResult": "设置结果",
"setSuccess": "设置成功",
"settings": "设置",
"strictSearch": "严格搜索",
"strictSearchDescription": "仅显示包名包含搜索词的插件",
"title": "插件",
"tryDifferentSearch": "尝试不同的搜索关键词",
"updateAll": "更新全部插件",

View File

@@ -627,6 +627,8 @@
"setResult": "設定結果",
"setSuccess": "設定成功",
"settings": "設定",
"strictSearch": "嚴格搜索",
"strictSearchDescription": "僅顯示包名包含搜索詞的外掛",
"title": "插件",
"tryDifferentSearch": "嘗試不同的搜尋關鍵詞",
"updateAll": "更新全部插件",

View File

@@ -48,6 +48,13 @@
<XIcon :size="16" />
</button>
</div>
<div class="search-options">
<label class="strict-search-checkbox">
<input v-model="strictSearch" type="checkbox" class="checkbox-input" />
<span class="checkbox-label">{{ t('pages.plugin.strictSearch') }}</span>
<span class="checkbox-description">{{ t('pages.plugin.strictSearchDescription') }}</span>
</label>
</div>
</div>
</div>
@@ -199,6 +206,7 @@
</template>
<script lang="ts" setup>
import { useStorage } from '@vueuse/core'
import { debounce, DebouncedFunc } from 'lodash-es'
import {
AlertCircleIcon,
@@ -242,6 +250,7 @@ const loading = ref(true)
const needReload = ref(false)
const latestVersionMap = reactive<Record<string, string>>({})
const $configForm = ref<InstanceType<typeof ConfigForm> | null>(null)
const strictSearch = useStorage('plugin-strict-search', true)
function setSrc(e: Event) {
const target = e.target as HTMLImageElement
@@ -456,9 +465,12 @@ function _getSearchResult(val: string) {
fetch(`https://registry.npmjs.com/-/v1/search?text=${val}`)
.then(async (res: Response) => {
const data = await res.json()
console.log(data)
pluginList.value = data.objects
.filter((item: INPMSearchResultObject) => {
return item.package.name.includes('picgo-plugin-')
return strictSearch.value
? item.package.name.includes('picgo-plugin-') && item.package.name.includes(val)
: item.package.name.includes('picgo-plugin-')
})
.map((item: INPMSearchResultObject) => {
return handleSearchResult(item)

View File

@@ -121,7 +121,10 @@ html, body {
}
.search-container {
display: flex;
padding: 1rem 1.5rem;
flex-direction: column;
gap: 1rem;
}
.search-input-wrapper {
@@ -178,6 +181,72 @@ html, body {
background: var(--color-surface);
}
/* Search Options */
.search-options {
display: flex;
align-items: flex-start;
border-top: 1px solid var(--color-border-secondary);
padding-top: 0.5rem;
}
.strict-search-checkbox {
display: flex;
flex-direction: column;
gap: 0.25rem;
cursor: pointer;
user-select: none;
}
.checkbox-input {
display: none;
}
.checkbox-label {
position: relative;
display: flex;
align-items: center;
font-size: 0.875rem;
font-weight: 500;
color: var(--color-text);
gap: 0.5rem;
}
.checkbox-label::before {
border: 2px solid var(--color-border);
border-radius: 3px;
width: 16px;
height: 16px;
background: var(--color-surface);
transition: all 0.2s ease;
content: '';
flex-shrink: 0;
}
.checkbox-input:checked + .checkbox-label::before {
border-color: var(--color-primary);
background: var(--color-primary);
}
.checkbox-input:checked + .checkbox-label::after {
position: absolute;
left: 3px;
font-size: 10px;
font-weight: bold;
color: white;
content: '✓';
}
.checkbox-label:hover::before {
border-color: var(--color-primary);
}
.checkbox-description {
margin-left: 24px;
font-size: 0.75rem;
color: var(--color-text-secondary);
line-height: 1.4;
}
/* Notice Card */
.notice-card {
border-color: var(--color-warning);