mirror of
https://github.com/BewlyBewly/BewlyBewly.git
synced 2025-04-14 13:15:29 +00:00
refactor: improve search bar component
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<!-- TODO: refactor all that shit -->
|
||||
<script setup lang="ts">
|
||||
import { onClickOutside, useFocus, useWindowFocus, watchThrottled } from '@vueuse/core'
|
||||
import type { HistoryItem, SuggestionItem, SuggestionResponse } from './searchHistoryProvider'
|
||||
import {
|
||||
addSearchHistory,
|
||||
@@ -14,7 +15,9 @@ defineProps<{
|
||||
focusedCharacter?: string
|
||||
}>()
|
||||
|
||||
const isFocus = ref<boolean>(false)
|
||||
const inputRef = ref<HTMLInputElement | null>(null)
|
||||
const { focused: isFocus } = useFocus(inputRef)
|
||||
const isWindowFocus = useWindowFocus()
|
||||
const keyword = ref<string>('')
|
||||
const suggestions = reactive<SuggestionItem[]>([])
|
||||
const selectedIndex = ref<number>(-1)
|
||||
@@ -22,30 +25,35 @@ const searchHistory = shallowRef<HistoryItem[]>([])
|
||||
const historyItemRef = ref<HTMLElement[]>([])
|
||||
const suggestionItemRef = ref<HTMLElement[]>([])
|
||||
|
||||
watch(isFocus, async (focus) => {
|
||||
watch([isFocus, isWindowFocus], async ([focus, windowFocus]) => {
|
||||
// 延后加载搜索历史
|
||||
if (focus)
|
||||
if (focus && windowFocus)
|
||||
searchHistory.value = await getSearchHistory()
|
||||
})
|
||||
if (!windowFocus) {
|
||||
selectedIndex.value = -1
|
||||
inputRef.value?.blur()
|
||||
}
|
||||
}, { flush: 'sync' })
|
||||
|
||||
function handleInput() {
|
||||
watchThrottled(keyword, (keyword) => {
|
||||
selectedIndex.value = -1
|
||||
if (keyword.value.length > 0) {
|
||||
browser.runtime
|
||||
.sendMessage({
|
||||
contentScriptQuery: 'getSearchSuggestion',
|
||||
term: keyword.value,
|
||||
})
|
||||
.then((res: SuggestionResponse) => {
|
||||
if (!res || (res && res.code !== 0))
|
||||
return
|
||||
Object.assign(suggestions, res.result.tag)
|
||||
})
|
||||
}
|
||||
else {
|
||||
|
||||
if (keyword.length <= 0) {
|
||||
suggestions.length = 0
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
browser.runtime
|
||||
.sendMessage({
|
||||
contentScriptQuery: 'getSearchSuggestion',
|
||||
term: keyword,
|
||||
})
|
||||
.then((res: SuggestionResponse) => {
|
||||
if (!res || (res && res.code !== 0))
|
||||
return
|
||||
Object.assign(suggestions, res.result.tag)
|
||||
})
|
||||
}, { throttle: 100 })
|
||||
|
||||
async function navigateToSearchResultPage(keyword: string) {
|
||||
if (keyword) {
|
||||
@@ -78,13 +86,15 @@ function handleKeyUp() {
|
||||
suggestionItemRef.value.forEach((item, index) => {
|
||||
if (index === selectedIndex.value)
|
||||
item.classList.add('active')
|
||||
else item.classList.remove('active')
|
||||
else
|
||||
item.classList.remove('active')
|
||||
})
|
||||
|
||||
historyItemRef.value.forEach((item, index) => {
|
||||
if (index === selectedIndex.value)
|
||||
item.classList.add('active')
|
||||
else item.classList.remove('active')
|
||||
else
|
||||
item.classList.remove('active')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -142,12 +152,10 @@ async function handleClearSearchHistory() {
|
||||
w="full"
|
||||
h="full"
|
||||
content="~"
|
||||
@click="isFocus = false"
|
||||
/>
|
||||
<Transition name="mask">
|
||||
<div
|
||||
v-if="darkenOnFocus && isFocus" pos="fixed top-0 left-0" w-full h-full bg="black opacity-60"
|
||||
@click="isFocus = false"
|
||||
/>
|
||||
</Transition>
|
||||
|
||||
@@ -162,8 +170,8 @@ async function handleClearSearchHistory() {
|
||||
<Transition name="focus-character">
|
||||
<img v-show="focusedCharacter && isFocus" :src="focusedCharacter" width="100" object-contain pos="absolute right-0 bottom-40px">
|
||||
</Transition>
|
||||
|
||||
<input
|
||||
ref="inputRef"
|
||||
v-model.trim="keyword"
|
||||
rounded="60px focus:$bew-radius"
|
||||
p="l-6 r-16 y-3"
|
||||
@@ -173,12 +181,11 @@ async function handleClearSearchHistory() {
|
||||
ring="1 $bew-border-color"
|
||||
transition="all duration-300"
|
||||
type="text"
|
||||
@focus="isFocus = true"
|
||||
@input="handleInput"
|
||||
@keyup.enter.stop.passive="navigateToSearchResultPage(keyword)"
|
||||
@keyup.up.stop.passive="handleKeyUp"
|
||||
@keyup.down.stop.passive="handleKeyDown"
|
||||
@keydown.stop="() => {}"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('search_bar.placeholder')"
|
||||
@keyup.up="handleKeyUp"
|
||||
@keyup.down="handleKeyDown"
|
||||
@keyup.enter="navigateToSearchResultPage(keyword)"
|
||||
>
|
||||
<button
|
||||
p-2
|
||||
@@ -199,14 +206,13 @@ async function handleClearSearchHistory() {
|
||||
|
||||
<Transition name="result-list">
|
||||
<div
|
||||
v-if="
|
||||
isFocus
|
||||
&& searchHistory.length !== 0
|
||||
&& keyword.length === 0
|
||||
"
|
||||
id="search-history"
|
||||
v-if="isFocus"
|
||||
class="search-suggestion search-history min-h-60px"
|
||||
>
|
||||
<div class="history-list flex flex-col gap-y-2">
|
||||
<div
|
||||
v-show="keyword.length === 0 && searchHistory.length !== 0"
|
||||
class="history-list flex flex-col gap-y-2"
|
||||
>
|
||||
<div class="title p-2 pb-0 flex justify-between">
|
||||
<span>{{ $t('search_bar.history_title') }}</span>
|
||||
<button class="rounded-2 duration-300 pointer-events-auto cursor-pointer" hover="text-$bew-theme-color" text="base $bew-text-2" @click="handleClearSearchHistory">
|
||||
@@ -233,16 +239,10 @@ async function handleClearSearchHistory() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<Transition name="result-list">
|
||||
<div
|
||||
v-if="isFocus && suggestions.length !== 0 && keyword.length > 0"
|
||||
id="search-suggestion"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in suggestions"
|
||||
v-show="keyword.length > 0"
|
||||
:key="index"
|
||||
ref="suggestionItemRef"
|
||||
class="suggestion-item"
|
||||
@@ -339,7 +339,7 @@ async function handleClearSearchHistory() {
|
||||
hover:bg-$bew-fill-2;
|
||||
}
|
||||
|
||||
#search-history {
|
||||
.search-history {
|
||||
@include search-content;
|
||||
--at-apply: bg-$bew-elevated-1;
|
||||
|
||||
@@ -357,7 +357,7 @@ async function handleClearSearchHistory() {
|
||||
}
|
||||
}
|
||||
|
||||
#search-suggestion {
|
||||
.search-suggestion {
|
||||
@include search-content;
|
||||
--at-apply: bg-$bew-elevated-1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user