mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-06-15 06:27:53 +08:00
webui: move search component to ab-search-bar.vue
This commit is contained in:
61
webui/src/components/ab-search-bar.vue
Normal file
61
webui/src/components/ab-search-bar.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<script lang="ts" setup>
|
||||
import {ref} from 'vue';
|
||||
import {vOnClickOutside} from "@vueuse/components";
|
||||
|
||||
const showProvider = ref(false);
|
||||
const {providers, getProviders, provider, loading, onSearch} = useSearchStore();
|
||||
|
||||
onMounted(() => {
|
||||
getProviders();
|
||||
});
|
||||
|
||||
function onSelect(site: string) {
|
||||
provider.value = site;
|
||||
showProvider.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<ab-search
|
||||
:provider="provider"
|
||||
:loading="loading"
|
||||
@search="onSearch"
|
||||
@select="() => showProvider = !showProvider"
|
||||
/>
|
||||
<div
|
||||
v-show="showProvider"
|
||||
v-on-click-outside="() => showProvider = false"
|
||||
abs top-84px
|
||||
left-540px w-100px
|
||||
rounded-12px
|
||||
shadow
|
||||
bg-white
|
||||
z-99
|
||||
overflow-hidden
|
||||
>
|
||||
<div
|
||||
v-for="site in providers"
|
||||
:key="site"
|
||||
hover:bg-theme-row
|
||||
is-btn
|
||||
@click="() => onSelect(site)"
|
||||
>
|
||||
<div
|
||||
text-h3
|
||||
text-primary
|
||||
hover:text-white
|
||||
p-12px
|
||||
truncate
|
||||
>
|
||||
{{ site }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,28 +1,25 @@
|
||||
<script lang="ts" setup>
|
||||
import {Down, Search} from '@icon-park/vue-next';
|
||||
import { vOnClickOutside } from '@vueuse/components'
|
||||
import { NSpin } from 'naive-ui';
|
||||
import { watch } from 'vue';
|
||||
|
||||
defineEmits(['click']);
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
provider: string;
|
||||
loading: boolean;
|
||||
}>(),
|
||||
{
|
||||
provider: '',
|
||||
loading: false,
|
||||
}
|
||||
);
|
||||
|
||||
const {
|
||||
onSelect,
|
||||
onSearch,
|
||||
inputValue,
|
||||
selectingProvider,
|
||||
provider,
|
||||
providers,
|
||||
getProviders,
|
||||
bangumiList
|
||||
} = useSearchStore();
|
||||
defineEmits(['select', 'search']);
|
||||
|
||||
function closeModal() {
|
||||
selectingProvider.value = false;
|
||||
bangumiList.value = [];
|
||||
}
|
||||
const inputValue = ref('');
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getProviders();
|
||||
watch (inputValue, (val) => {
|
||||
console.log(val);
|
||||
});
|
||||
|
||||
</script>
|
||||
@@ -41,86 +38,47 @@ onMounted(() => {
|
||||
shadow-inner
|
||||
>
|
||||
<Search
|
||||
v-if="!loading"
|
||||
theme="outline"
|
||||
size="24"
|
||||
fill="#fff"
|
||||
is-btn
|
||||
btn-click
|
||||
@click="onSearch"
|
||||
@click="$emit('search', inputValue)"
|
||||
/>
|
||||
<NSpin v-else :size="20"/>
|
||||
|
||||
<input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
:placeholder="$t('topbar.search.placeholder')"
|
||||
input-reset
|
||||
@keyup.enter="onSearch"
|
||||
@keyup.enter="$emit('search', inputValue)"
|
||||
/>
|
||||
<div
|
||||
h-full
|
||||
f-cer
|
||||
justify-between
|
||||
px-12px
|
||||
w-100px
|
||||
is-btn
|
||||
class="provider-select"
|
||||
@click="() => selectingProvider = !selectingProvider"
|
||||
>
|
||||
<div text-h3 truncate>
|
||||
{{ provider }}
|
||||
</div>
|
||||
<div class="provider-select">
|
||||
<Down/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-show="selectingProvider"
|
||||
v-on-click-outside="closeModal"
|
||||
abs top-84px
|
||||
left-540px w-100px
|
||||
rounded-12px shadow bg-white z-99 overflow-hidden>
|
||||
<div
|
||||
v-for="site in providers"
|
||||
:key="site"
|
||||
hover:bg-theme-row
|
||||
is-btn
|
||||
@click="() => onSelect(site)"
|
||||
>
|
||||
<div
|
||||
text-h3
|
||||
text-primary
|
||||
hover:text-white
|
||||
p-12px
|
||||
truncate
|
||||
h-full
|
||||
f-cer
|
||||
justify-between
|
||||
px-12px
|
||||
w-100px
|
||||
class="provider"
|
||||
is-btn
|
||||
@click="$emit('select')"
|
||||
>
|
||||
{{ site }}
|
||||
<div text-h3 truncate>
|
||||
{{ provider }}
|
||||
</div>
|
||||
<div class="provider">
|
||||
<Down/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
abs top-84px left-200px space-y-8px z-98
|
||||
>
|
||||
<ab-bangumi-card
|
||||
v-for="(item, index) in bangumiList"
|
||||
:key="index"
|
||||
v-on-click-outside="closeModal"
|
||||
:bangumi="item"
|
||||
type="search"
|
||||
transition-opacity
|
||||
@click="$emit('click', item)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.provider-select {
|
||||
.provider {
|
||||
background: #4E2A94;
|
||||
}
|
||||
|
||||
.list-enter-active, .list-leave-active {
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -76,7 +76,7 @@ onUnmounted(() => {
|
||||
<img v-show="onSearchFocus === false" src="/images/AutoBangumi.svg" alt="AutoBangumi" h-24px rel top-2px/>
|
||||
</div>
|
||||
|
||||
<ab-search/>
|
||||
<ab-search-bar/>
|
||||
</div>
|
||||
|
||||
<div ml-auto>
|
||||
|
||||
@@ -12,10 +12,11 @@ import type {BangumiRule} from "#/bangumi";
|
||||
export function useSearchStore() {
|
||||
const bangumiList = ref<BangumiRule[]>([]);
|
||||
const inputValue = ref<string>('');
|
||||
const selectingProvider = ref<boolean>(false);
|
||||
|
||||
const providers = ref<string[]>(['mikan', 'dmhy', 'nyaa']);
|
||||
const provider = ref<string>('mikan');
|
||||
const provider = ref<string>(providers.value[0]);
|
||||
|
||||
const loading = ref<boolean>(true);
|
||||
|
||||
const input$ = new Subject<string>();
|
||||
|
||||
@@ -44,31 +45,28 @@ export function useSearchStore() {
|
||||
// 有输入更新后清理之前的搜索结果
|
||||
bangumiList.value = [];
|
||||
return input
|
||||
? apiSearch.get(input, provider.value)
|
||||
: EMPTY
|
||||
? apiSearch.get(input, provider.value)
|
||||
: EMPTY
|
||||
}),
|
||||
tap((bangumi: BangumiRule) => {
|
||||
bangumiList.value.push(bangumi);
|
||||
|
||||
}),
|
||||
).subscribe()
|
||||
|
||||
function onSearch() {
|
||||
console.log('onSearch');
|
||||
loading.value = true;
|
||||
input$.next(inputValue.value);
|
||||
}
|
||||
|
||||
function onSelect(site: string) {
|
||||
provider.value = site;
|
||||
selectingProvider.value = !selectingProvider.value
|
||||
onSearch();
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
return {
|
||||
input$,
|
||||
bangumiInfo$,
|
||||
inputValue,
|
||||
selectingProvider,
|
||||
onSelect,
|
||||
onSearch,
|
||||
loading,
|
||||
provider,
|
||||
getProviders,
|
||||
providers,
|
||||
|
||||
1
webui/types/dts/components.d.ts
vendored
1
webui/types/dts/components.d.ts
vendored
@@ -24,6 +24,7 @@ declare module '@vue/runtime-core' {
|
||||
AbRssItem: typeof import('./../../src/components/ab-rss-item.vue')['default']
|
||||
AbRule: typeof import('./../../src/components/ab-rule.vue')['default']
|
||||
AbSearch: typeof import('./../../src/components/basic/ab-search.vue')['default']
|
||||
AbSearchBar: typeof import('./../../src/components/ab-search-bar.vue')['default']
|
||||
AbSelect: typeof import('./../../src/components/basic/ab-select.vue')['default']
|
||||
AbSetting: typeof import('./../../src/components/ab-setting.vue')['default']
|
||||
AbSidebar: typeof import('./../../src/components/layout/ab-sidebar.vue')['default']
|
||||
|
||||
Reference in New Issue
Block a user