Files
Melo/src/renderer/components/layout/Toolbar/SearchInput.vue
T
2022-10-29 11:36:35 +08:00

114 lines
3.0 KiB
Vue

<template>
<material-search-input v-model="searchText" :list="tipList" :visible-list="visibleList" @event="handleEvent" />
</template>
<script>
import music from '@renderer/utils/musicSdk'
import { debounce } from '@common/utils'
import {
ref,
watch,
nextTick,
} from '@common/utils/vueTools'
import { useRouter, useRoute } from '@common/utils/vueRouter'
import { appSetting } from '@renderer/store/setting'
import { searchText as _searchText } from '@renderer/store/search/state'
import { setSearchText } from '@renderer/store/search/action'
import { getSearchSetting } from '@renderer/utils/data'
export default {
setup() {
const searchText = ref('')
const visibleList = ref(false)
const tipList = ref([])
let isFocused = false
let prevTempSearchSource = ''
const route = useRoute()
const router = useRouter()
watch(() => route.name, (newValue, oldValue) => {
if (newValue.name != 'search') {
setTimeout(() => {
if (appSetting['odc.isAutoClearSearchInput'] && searchText.value) searchText.value = ''
if (appSetting['odc.isAutoClearSearchList']) setSearchText('')
})
}
})
watch(_searchText, (newValue, oldValue) => {
searchText.value = newValue
if (newValue !== searchText.value) searchText.value = newValue
})
watch(searchText, () => {
handleTipSearch()
})
const tipSearch = debounce(async() => {
if (searchText.value === '' && prevTempSearchSource) {
tipList.value = []
music[prevTempSearchSource].tempSearch.cancelTempSearch()
return
}
const { temp_source } = await getSearchSetting()
prevTempSearchSource = temp_source
music[prevTempSearchSource].tempSearch.search(searchText.value).then(list => {
tipList.value = list
}).catch(() => {})
}, 50)
const handleTipSearch = () => {
if (!visibleList.value && isFocused) visibleList.value = true
tipSearch()
}
const handleSearch = () => {
if (visibleList.value) visibleList.value = false
if (!searchText.value && route.path != '/search') {
setSearchText('')
return
}
setTimeout(() => {
router.push({
path: '/search',
query: {
text: searchText.value,
},
}).catch(_ => _)
}, searchText.value ? 200 : 0)
}
const handleEvent = ({ action, data }) => {
switch (action) {
case 'focus':
isFocused = true
if (!visibleList.value) visibleList.value = true
if (searchText.value) handleTipSearch()
break
case 'blur':
isFocused = false
setTimeout(() => {
if (visibleList.value) visibleList.value = false
}, 50)
break
case 'submit':
handleSearch()
break
case 'listClick':
searchText.value = tipList.value[data]
nextTick(handleSearch)
}
}
return {
searchText,
visibleList,
tipList,
handleEvent,
}
},
}
</script>