BUG fix: category
This commit is contained in:
parent
3240c39eaf
commit
1325eca5f9
|
@ -9,34 +9,25 @@ import { useTempHomeStore } from '@/store/temp/home'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
const { searchHistory } = storeToRefs(usePersistKUNGalgameHomeStore())
|
const { searchHistory } = storeToRefs(usePersistKUNGalgameHomeStore())
|
||||||
const { keywords, category } = storeToRefs(useTempHomeStore())
|
const { keywords } = storeToRefs(useTempHomeStore())
|
||||||
|
|
||||||
// Value of the input field
|
|
||||||
const inputValue = ref('')
|
const inputValue = ref('')
|
||||||
// Whether to show search history
|
|
||||||
const isShowSearchHistory = ref(false)
|
const isShowSearchHistory = ref(false)
|
||||||
// Style when the input field is active
|
|
||||||
const inputActiveClass = ref({})
|
const inputActiveClass = ref({})
|
||||||
|
|
||||||
// Define props to tell the input field in which category to search for topics
|
const props = defineProps<{
|
||||||
const props = defineProps(['category'])
|
category: string[]
|
||||||
|
}>()
|
||||||
|
|
||||||
// Initialize the content of the search box to prevent content from persisting after page refresh
|
|
||||||
// Assign the topic category to be searched because the search box will be rendered on three pages
|
|
||||||
// , corresponding to three categories
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
keywords.value = ''
|
keywords.value = ''
|
||||||
category.value = props.category
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Define the debounce handling function
|
|
||||||
const debouncedSearch = debounce((inputValue: string) => {
|
const debouncedSearch = debounce((inputValue: string) => {
|
||||||
// Reset page status and loading state before searching
|
|
||||||
useTempHomeStore().resetPageStatus()
|
useTempHomeStore().resetPageStatus()
|
||||||
keywords.value = inputValue
|
keywords.value = inputValue
|
||||||
}, 300) // 300 milliseconds debounce delay
|
}, 300)
|
||||||
|
|
||||||
// When the search box is focused
|
|
||||||
const handleInputFocus = () => {
|
const handleInputFocus = () => {
|
||||||
if (searchHistory.value.length !== 0) {
|
if (searchHistory.value.length !== 0) {
|
||||||
isShowSearchHistory.value = true
|
isShowSearchHistory.value = true
|
||||||
|
@ -46,48 +37,39 @@ const handleInputFocus = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the search box is blurred
|
|
||||||
const handleInputBlur = () => {
|
const handleInputBlur = () => {
|
||||||
// Delay hiding the search history so that clicking on the search history can trigger the fill event
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
isShowSearchHistory.value = false
|
isShowSearchHistory.value = false
|
||||||
inputActiveClass.value = {}
|
inputActiveClass.value = {}
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search function logic
|
|
||||||
const search = () => {
|
const search = () => {
|
||||||
debouncedSearch(inputValue.value)
|
debouncedSearch(inputValue.value)
|
||||||
if (!searchHistory.value.includes(inputValue.value)) {
|
if (!searchHistory.value.includes(inputValue.value)) {
|
||||||
// Push the element into the array only when there are no identical elements in the array
|
|
||||||
searchHistory.value.push(inputValue.value)
|
searchHistory.value.push(inputValue.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the user presses Enter
|
|
||||||
const handleClickEnter = (event: KeyboardEvent) => {
|
const handleClickEnter = (event: KeyboardEvent) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
search()
|
search()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clicking the search button triggers the search logic
|
|
||||||
const handleClickSearch = () => {
|
const handleClickSearch = () => {
|
||||||
if (inputValue.value.trim()) {
|
if (inputValue.value.trim()) {
|
||||||
search()
|
search()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clicking on search history
|
|
||||||
const handleClickHistory = (index: number) => {
|
const handleClickHistory = (index: number) => {
|
||||||
inputValue.value = searchHistory.value[index]
|
inputValue.value = searchHistory.value[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear search history
|
|
||||||
const clearSearchHistory = () => {
|
const clearSearchHistory = () => {
|
||||||
searchHistory.value = []
|
searchHistory.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete search history
|
|
||||||
const handleDeleteHistory = (historyIndex: number) => {
|
const handleDeleteHistory = (historyIndex: number) => {
|
||||||
searchHistory.value.splice(historyIndex, 1)
|
searchHistory.value.splice(historyIndex, 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default {
|
||||||
},
|
},
|
||||||
asideActive: {
|
asideActive: {
|
||||||
fold: 'Fold Aside',
|
fold: 'Fold Aside',
|
||||||
create: 'CREATE Topic!',
|
create: 'CREATE TOPIC',
|
||||||
update: 'Update',
|
update: 'Update',
|
||||||
balance: 'P & L',
|
balance: 'P & L',
|
||||||
ranking: 'Ranking',
|
ranking: 'Ranking',
|
||||||
|
|
|
@ -18,7 +18,7 @@ export const useTempHomeStore = defineStore({
|
||||||
* @returns {HomeTopicResponseData} topicData
|
* @returns {HomeTopicResponseData} topicData
|
||||||
*/
|
*/
|
||||||
keywords: '',
|
keywords: '',
|
||||||
category: 'galgame',
|
category: ['Galgame'],
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 17,
|
limit: 17,
|
||||||
sortField: 'updated',
|
sortField: 'updated',
|
||||||
|
@ -30,7 +30,7 @@ export const useTempHomeStore = defineStore({
|
||||||
async getHomeTopic(): Promise<HomeTopicResponseData> {
|
async getHomeTopic(): Promise<HomeTopicResponseData> {
|
||||||
const requestData: HomeTopicRequestData = {
|
const requestData: HomeTopicRequestData = {
|
||||||
keywords: this.keywords,
|
keywords: this.keywords,
|
||||||
category: this.category,
|
category: JSON.stringify(this.category),
|
||||||
page: this.page,
|
page: this.page,
|
||||||
limit: this.limit,
|
limit: this.limit,
|
||||||
sortField: this.sortField,
|
sortField: this.sortField,
|
||||||
|
|
2
src/store/types/home.d.ts
vendored
2
src/store/types/home.d.ts
vendored
|
@ -1,6 +1,6 @@
|
||||||
export interface HomeStoreTemp {
|
export interface HomeStoreTemp {
|
||||||
keywords: string
|
keywords: string
|
||||||
category: string
|
category: string[]
|
||||||
page: number
|
page: number
|
||||||
limit: number
|
limit: number
|
||||||
sortField: string
|
sortField: string
|
||||||
|
|
|
@ -22,7 +22,6 @@ import ArticleContent from './components/ArticleContent.vue'
|
||||||
.article-container {
|
.article-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: 1px solid var(--kungalgame-trans-blue-4);
|
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -9,9 +9,8 @@ import { HomeTopic } from '@/api'
|
||||||
import { useTempHomeStore } from '@/store/temp/home'
|
import { useTempHomeStore } from '@/store/temp/home'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
const { page, keywords, sortField, sortOrder, isLoading } = storeToRefs(
|
const { page, keywords, category, sortField, sortOrder, isLoading } =
|
||||||
useTempHomeStore()
|
storeToRefs(useTempHomeStore())
|
||||||
)
|
|
||||||
|
|
||||||
const topics = ref<HomeTopic[]>([])
|
const topics = ref<HomeTopic[]>([])
|
||||||
const content = ref<HTMLElement>()
|
const content = ref<HTMLElement>()
|
||||||
|
@ -20,7 +19,7 @@ const getTopics = async (): Promise<HomeTopic[]> => {
|
||||||
return (await useTempHomeStore().getHomeTopic()).data
|
return (await useTempHomeStore().getHomeTopic()).data
|
||||||
}
|
}
|
||||||
|
|
||||||
watch([keywords, sortField, sortOrder], async () => {
|
watch([keywords, category, sortField, sortOrder], async () => {
|
||||||
topics.value = await getTopics()
|
topics.value = await getTopics()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -74,7 +73,6 @@ onBeforeUnmount(() => {
|
||||||
<template>
|
<template>
|
||||||
<div class="topic-container" ref="content">
|
<div class="topic-container" ref="content">
|
||||||
<TransitionGroup name="list" tag="div" v-if="topics.length">
|
<TransitionGroup name="list" tag="div" v-if="topics.length">
|
||||||
<!-- Posted within 10 hours -->
|
|
||||||
<div
|
<div
|
||||||
v-for="topic in topics"
|
v-for="topic in topics"
|
||||||
:key="topic.tid"
|
:key="topic.tid"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
import SortTopic from './SortTopic.vue'
|
import SortTopic from './SortTopic.vue'
|
||||||
|
|
||||||
|
@ -8,10 +9,16 @@ import { storeToRefs } from 'pinia'
|
||||||
import { categoryItem } from './navItem'
|
import { categoryItem } from './navItem'
|
||||||
|
|
||||||
const { category } = storeToRefs(useTempHomeStore())
|
const { category } = storeToRefs(useTempHomeStore())
|
||||||
|
const categoryIcon = ref('galgame')
|
||||||
|
|
||||||
const handleSortByCategory = (name: string) => {
|
const handleSortByCategory = (name: string) => {
|
||||||
useTempHomeStore().resetPageStatus()
|
useTempHomeStore().resetPageStatus()
|
||||||
category.value = name
|
category.value = []
|
||||||
|
categoryIcon.value = name
|
||||||
|
|
||||||
|
// Because category is [Galgame, Technique, Others], need to capitalize first letter
|
||||||
|
const capitalizeFirstLetter = name.charAt(0).toUpperCase() + name.slice(1)
|
||||||
|
category.value.push(capitalizeFirstLetter)
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconMap: Record<string, string> = {
|
const iconMap: Record<string, string> = {
|
||||||
|
@ -25,7 +32,7 @@ const iconMap: Record<string, string> = {
|
||||||
<div class="nav-article">
|
<div class="nav-article">
|
||||||
<div class="category">
|
<div class="category">
|
||||||
<span>{{ $tm('mainPage.header.category') }}</span>
|
<span>{{ $tm('mainPage.header.category') }}</span>
|
||||||
<span><Icon :icon="iconMap[category]" /></span>
|
<span><Icon :icon="iconMap[categoryIcon]" /></span>
|
||||||
|
|
||||||
<div class="category-container">
|
<div class="category-container">
|
||||||
<div class="category-submenu">
|
<div class="category-submenu">
|
||||||
|
@ -70,7 +77,8 @@ const iconMap: Record<string, string> = {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--kungalgame-trans-white-5);
|
background-color: var(--kungalgame-trans-blue-0);
|
||||||
|
border: 1px solid var(--kungalgame-blue-4);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
@ -82,6 +90,17 @@ const iconMap: Record<string, string> = {
|
||||||
margin-left: 7px;
|
margin-left: 7px;
|
||||||
color: var(--kungalgame-blue-4);
|
color: var(--kungalgame-blue-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transition: all 0.2s;
|
||||||
|
border: 1px solid var(--kungalgame-blue-4);
|
||||||
|
background-color: var(--kungalgame-blue-4);
|
||||||
|
color: var(--kungalgame-white);
|
||||||
|
|
||||||
|
& > span:nth-child(2) {
|
||||||
|
color: var(--kungalgame-white);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-container {
|
.category-container {
|
||||||
|
@ -142,19 +161,23 @@ const iconMap: Record<string, string> = {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
background-color: var(--kungalgame-trans-blue-3);
|
background-color: var(--kungalgame-trans-blue-0);
|
||||||
|
border: 1px solid var(--kungalgame-blue-4);
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
border-radius: 0 5px 0 0;
|
border-radius: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--kungalgame-font-color-3);
|
color: var(--kungalgame-font-color-3);
|
||||||
margin-left: 10px;
|
margin-left: 7px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--kungalgame-trans-blue-2);
|
transition: all 0.2s;
|
||||||
}
|
border: 1px solid var(--kungalgame-blue-4);
|
||||||
|
background-color: var(--kungalgame-blue-4);
|
||||||
|
color: var(--kungalgame-white);
|
||||||
|
|
||||||
&:active {
|
& > span:nth-child(2) {
|
||||||
background-color: var(--kungalgame-trans-blue-4);
|
color: var(--kungalgame-white);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,14 +83,27 @@ const iconMap: Record<string, string> = {
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
background-color: var(--kungalgame-trans-blue-3);
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 1px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background-color: var(--kungalgame-trans-blue-0);
|
||||||
|
border: 1px solid var(--kungalgame-blue-4);
|
||||||
|
border-radius: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-left: 10px;
|
margin-left: 7px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--kungalgame-trans-white-5);
|
transition: all 0.2s;
|
||||||
|
border: 1px solid var(--kungalgame-blue-4);
|
||||||
|
background-color: var(--kungalgame-blue-4);
|
||||||
|
color: var(--kungalgame-white);
|
||||||
|
|
||||||
|
& > span:nth-child(2) {
|
||||||
|
color: var(--kungalgame-white);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +127,7 @@ const iconMap: Record<string, string> = {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: var(--kungalgame-trans-white-2);
|
background-color: var(--kungalgame-trans-white-2);
|
||||||
box-shadow: var(--shadow);
|
box-shadow: var(--shadow);
|
||||||
border-radius: 0 0 5px 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container:hover .sort-submenu {
|
.container:hover .sort-submenu {
|
||||||
|
@ -137,6 +150,10 @@ const iconMap: Record<string, string> = {
|
||||||
&:active {
|
&:active {
|
||||||
background-color: var(--kungalgame-trans-blue-2);
|
background-color: var(--kungalgame-trans-blue-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-radius: 5px 5px 0 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-item {
|
.icon-item {
|
||||||
|
@ -174,10 +191,16 @@ const iconMap: Record<string, string> = {
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
background-color: var(--kungalgame-trans-red-3);
|
border: 1px solid var(--kungalgame-pink-4);
|
||||||
|
background-color: var(--kungalgame-pink-4);
|
||||||
|
color: var(--kungalgame-white);
|
||||||
|
|
||||||
|
& > span:nth-child(2) {
|
||||||
|
color: var(--kungalgame-white);
|
||||||
|
}
|
||||||
|
|
||||||
.filter {
|
.filter {
|
||||||
color: var(--kungalgame-red-4);
|
color: var(--kungalgame-pink-4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ const poolPageWidth = computed(() => {
|
||||||
<div class="pool">
|
<div class="pool">
|
||||||
<div class="pool-container">
|
<div class="pool-container">
|
||||||
<KUNGalgameSearchBox
|
<KUNGalgameSearchBox
|
||||||
|
:category="[]"
|
||||||
style="width: 100%; height: 40px; border-radius: 5px"
|
style="width: 100%; height: 40px; border-radius: 5px"
|
||||||
/>
|
/>
|
||||||
<Tags />
|
<Tags />
|
||||||
|
|
|
@ -12,7 +12,10 @@ import KUNGalgameSearchBox from '@/components/KUNGalgameSearchBox.vue'
|
||||||
<div class="page-title">技术交流</div>
|
<div class="page-title">技术交流</div>
|
||||||
<!-- 侧边的搜索框 -->
|
<!-- 侧边的搜索框 -->
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<KUNGalgameSearchBox style="height: 40px; width: 100%; border: none" />
|
<KUNGalgameSearchBox
|
||||||
|
:category="[]"
|
||||||
|
style="height: 40px; width: 100%; border: none"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 推荐标签 -->
|
<!-- 推荐标签 -->
|
||||||
<div class="recommend">
|
<div class="recommend">
|
||||||
|
|
Loading…
Reference in a new issue