diff options
Diffstat (limited to 'packages/frontend/src')
| -rw-r--r-- | packages/frontend/src/components/MkChannelList.vue | 31 | ||||
| -rw-r--r-- | packages/frontend/src/pages/channels.vue | 62 |
2 files changed, 91 insertions, 2 deletions
diff --git a/packages/frontend/src/components/MkChannelList.vue b/packages/frontend/src/components/MkChannelList.vue new file mode 100644 index 0000000000..408eab7399 --- /dev/null +++ b/packages/frontend/src/components/MkChannelList.vue @@ -0,0 +1,31 @@ +<template> +<MkPagination :pagination="pagination"> + <template #empty> + <div class="_fullinfo"> + <img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/> + <div>{{ i18n.ts.notFound }}</div> + </div> + </template> + + <template #default="{ items }"> + <MkChannelPreview v-for="item in items" :key="item.id" class="_margin" :channel="extractor(item)"/> + </template> +</MkPagination> +</template> + +<script lang="ts" setup> +import MkChannelPreview from '@/components/MkChannelPreview.vue'; +import MkPagination, { Paging } from '@/components/MkPagination.vue'; +import { i18n } from '@/i18n'; + +const props = withDefaults(defineProps<{ + pagination: Paging; + noGap?: boolean; + extractor?: (item: any) => any; +}>(), { + extractor: (item) => item, +}); +</script> + +<style lang="scss" scoped> +</style> diff --git a/packages/frontend/src/pages/channels.vue b/packages/frontend/src/pages/channels.vue index 3a5aa00c5b..bc6a6e4952 100644 --- a/packages/frontend/src/pages/channels.vue +++ b/packages/frontend/src/pages/channels.vue @@ -2,6 +2,23 @@ <MkStickyContainer> <template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template> <MkSpacer :content-max="700"> + <div v-if="tab === 'search'"> + <div class="_gaps"> + <MkInput v-model="searchQuery" :large="true" :autofocus="true" type="search"> + <template #prefix><i class="ti ti-search"></i></template> + </MkInput> + <MkRadios v-model="searchType" @update:model-value="search()"> + <option value="nameAndDescription">{{ i18n.ts._channel.nameAndDescription }}</option> + <option value="nameOnly">{{ i18n.ts._channel.nameOnly }}</option> + </MkRadios> + <MkButton large primary gradate rounded @click="search">{{ i18n.ts.search }}</MkButton> + </div> + + <MkFoldableSection v-if="channelPagination"> + <template #header>{{ i18n.ts.searchResult }}</template> + <MkChannelList :key="key" :pagination="channelPagination"/> + </MkFoldableSection> + </div> <div v-if="tab === 'featured'"> <MkPagination v-slot="{items}" :pagination="featuredPagination"> <MkChannelPreview v-for="channel in items" :key="channel.id" class="_margin" :channel="channel"/> @@ -28,17 +45,35 @@ </template> <script lang="ts" setup> -import { computed } from 'vue'; +import { computed, onMounted } from 'vue'; import MkChannelPreview from '@/components/MkChannelPreview.vue'; +import MkChannelList from '@/components/MkChannelList.vue'; import MkPagination from '@/components/MkPagination.vue'; +import MkInput from '@/components/MkInput.vue'; +import MkRadios from '@/components/MkRadios.vue'; import MkButton from '@/components/MkButton.vue'; +import MkFoldableSection from '@/components/MkFoldableSection.vue'; import { useRouter } from '@/router'; import { definePageMetadata } from '@/scripts/page-metadata'; import { i18n } from '@/i18n'; const router = useRouter(); -let tab = $ref('featured'); +const props = defineProps<{ + query: string; + type?: string; +}>(); + +let key = $ref(''); +let tab = $ref('search'); +let searchQuery = $ref(''); +let searchType = $ref('nameAndDescription'); +let channelPagination = $ref(); + +onMounted(() => { + searchQuery = props.query ?? ''; + searchType = props.type ?? 'nameAndDescription'; +}); const featuredPagination = { endpoint: 'channels/featured' as const, @@ -58,6 +93,25 @@ const ownedPagination = { limit: 10, }; +async function search() { + const query = searchQuery.toString().trim(); + + if (query == null || query === '') return; + + const type = searchType.toString().trim(); + + channelPagination = { + endpoint: 'channels/search', + limit: 10, + params: { + query: searchQuery, + type: type, + }, + }; + + key = query + type; +} + function create() { router.push('/channels/new'); } @@ -69,6 +123,10 @@ const headerActions = $computed(() => [{ }]); const headerTabs = $computed(() => [{ + key: 'search', + title: i18n.ts.search, + icon: 'ti ti-search', +}, { key: 'featured', title: i18n.ts._channel.featured, icon: 'ti ti-comet', |