feat(community): recommended for home & added discover tab (#11290)

This commit is contained in:
Neko
2026-01-09 17:34:28 +08:00
committed by GitHub
parent ef600809c2
commit 8db248c395
11 changed files with 36 additions and 11 deletions

View File

@@ -152,6 +152,8 @@
"like": "喜欢",
"mcp.categories.all.description": "全部 MCP Servers",
"mcp.categories.all.name": "全部",
"mcp.categories.discover.description": "推荐和热门的 MCP 服务",
"mcp.categories.discover.name": "发现推荐",
"mcp.categories.business.description": "商业与企业服务",
"mcp.categories.business.name": "商业服务",
"mcp.categories.developer.description": "开发相关的技能与服务",
@@ -338,6 +340,7 @@
"mcp.hero.subTitle": "开源 & 开箱即用",
"mcp.hero.title": "面向 AI 的开源 MCP 社区",
"mcp.sorts.createdAt": "最近新增",
"mcp.sorts.discover": "推荐",
"mcp.sorts.installCount": "安装数",
"mcp.sorts.isFeatured": "推荐技能",
"mcp.sorts.isValidated": "已验证技能",

View File

@@ -204,7 +204,7 @@
"@lobehub/desktop-ipc-typings": "workspace:*",
"@lobehub/editor": "^3.8.0",
"@lobehub/icons": "^4.0.2",
"@lobehub/market-sdk": "0.28.0",
"@lobehub/market-sdk": "0.28.1",
"@lobehub/tts": "^4.0.2",
"@lobehub/ui": "^4.11.6",
"@modelcontextprotocol/sdk": "^1.25.1",
@@ -366,7 +366,7 @@
"@lobechat/types": "workspace:*",
"@lobehub/i18n-cli": "^1.26.0",
"@lobehub/lint": "^1.26.3",
"@lobehub/market-types": "^1.11.5",
"@lobehub/market-types": "^1.12.3",
"@lobehub/seo-cli": "^1.7.0",
"@next/bundle-analyzer": "^16.1.1",
"@next/eslint-plugin-next": "^16.1.1",

View File

@@ -8,8 +8,8 @@
"@lobechat/python-interpreter": "workspace:*",
"@lobechat/web-crawler": "workspace:*",
"@lobehub/chat-plugin-sdk": "^1.32.4",
"@lobehub/market-sdk": "0.28.0",
"@lobehub/market-types": "^1.11.4",
"@lobehub/market-sdk": "0.28.1",
"@lobehub/market-types": "^1.12.3",
"model-bank": "workspace:*",
"type-fest": "^4.41.0",
"zustand": "5.0.4"

View File

@@ -5,6 +5,7 @@ export enum McpCategory {
All = 'all',
Business = 'business',
Developer = 'developer',
Discover = 'discover',
GamingEntertainment = 'gaming-entertainment',
HealthWellness = 'health-wellness',
Lifestyle = 'lifestyle',
@@ -26,7 +27,8 @@ export enum McpSorts {
IsFeatured = 'isFeatured',
IsValidated = 'isValidated',
RatingCount = 'ratingCount',
UpdatedAt = 'updatedAt',
Recommended = 'recommended',
UpdatedAt = 'updatedAt'
}
export enum McpNavKey {

View File

@@ -4,6 +4,7 @@ import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { useDiscoverStore } from '@/store/discover';
import { McpSorts } from '@/types/discover';
import Title from '../../components/Title';
import AssistantList from '../assistant/features/List';
@@ -23,6 +24,7 @@ const HomePage = memo(() => {
const { data: mcpList, isLoading: pluginLoading } = useMcpList({
page: 1,
pageSize: 12,
sort: McpSorts.Recommended,
});
if (assistantLoading || pluginLoading || !assistantList || !mcpList) return <Loading />;

View File

@@ -125,6 +125,10 @@ const SortButton = memo(() => {
}
case DiscoverTab.Mcp: {
return [
{
key: McpSorts.Recommended,
label: t('mcp.sorts.recommended'),
},
{
key: McpSorts.IsFeatured,
label: t('mcp.sorts.isFeatured'),

View File

@@ -10,13 +10,13 @@ import { withSuspense } from '@/components/withSuspense';
import { useCategory } from '@/hooks/useMCPCategory';
import { useQuery } from '@/hooks/useQuery';
import { useDiscoverStore } from '@/store/discover';
import { McpCategory } from '@/types/discover';
import { McpCategory, McpSorts } from '@/types/discover';
import CategoryMenu from '../../../../components/CategoryMenu';
const Category = memo(() => {
const useMcpCategories = useDiscoverStore((s) => s.useMcpCategories);
const { category = 'all', q } = useQuery() as { category?: McpCategory; q?: string };
const { category = McpCategory.Discover, q } = useQuery() as { category?: McpCategory; q?: string };
const { data: items = [] } = useMcpCategories({ q });
const navigate = useNavigate();
const cates = useCategory();
@@ -24,7 +24,11 @@ const Category = memo(() => {
const genUrl = (key: McpCategory) =>
qs.stringifyUrl(
{
query: { category: key === McpCategory.All ? null : key, q },
query: {
category: [McpCategory.All, McpCategory.Discover].includes(key) ? null : key,
q,
sort: key === McpCategory.Discover ? McpSorts.Recommended : null,
},
url: '/community/mcp',
},
{ skipNull: true },

View File

@@ -5,7 +5,7 @@ import { memo } from 'react';
import { useQuery } from '@/hooks/useQuery';
import { useDiscoverStore } from '@/store/discover';
import { DiscoverTab, type McpQueryParams } from '@/types/discover';
import { DiscoverTab, McpSorts, type McpQueryParams } from '@/types/discover';
import Pagination from '../features/Pagination';
import List from './features/List';
@@ -20,7 +20,7 @@ const McpPage = memo(() => {
page,
pageSize: 21,
q,
sort,
sort: sort ?? McpSorts.Recommended,
});
if (isLoading || !data) return <Loading />;

View File

@@ -2,6 +2,7 @@ import {
BriefcaseIcon,
CheckSquareIcon,
CloudIcon,
CompassIcon,
CodeIcon,
CoffeeIcon,
DollarSignIcon,
@@ -25,6 +26,12 @@ export const useCategory = () => {
const { t } = useTranslation('discover');
return useMemo(
() => [
{
icon: CompassIcon,
key: McpCategory.Discover,
label: t('mcp.categories.discover.name'),
title: t('mcp.categories.discover.description'),
},
{
icon: LayoutPanelTopIcon,
key: McpCategory.All,

View File

@@ -165,6 +165,8 @@ export default {
'mcp.categories.business.name': 'Business Services',
'mcp.categories.developer.description': 'Developer-related Tools and Services',
'mcp.categories.developer.name': 'Developer Tools',
'mcp.categories.discover.description': 'Recommended and trending MCP servers',
'mcp.categories.discover.name': 'Discover',
'mcp.categories.gaming-entertainment.description': 'Games, Entertainment, and Leisure Activities',
'mcp.categories.gaming-entertainment.name': 'Gaming & Entertainment',
'mcp.categories.health-wellness.description': 'Health, Fitness, and Wellness',
@@ -380,6 +382,7 @@ export default {
'mcp.sorts.isValidated': 'Validated Skills',
'mcp.sorts.promptsCount': 'Number of Prompts',
'mcp.sorts.ratingCount': 'Number of Ratings',
'mcp.sorts.recommended': 'Recommended',
'mcp.sorts.resourcesCount': 'Number of Resources',
'mcp.sorts.toolsCount': 'Number of Tools',
'mcp.sorts.updatedAt': 'Recently Updated',

View File

@@ -36,7 +36,7 @@ export const createMCPSlice: StateCreator<
);
},
useFetchMcpList: (params: any) => {
useFetchMcpList: (params) => {
const locale = globalHelpers.getCurrentLanguage();
return useClientDataSWR(
['mcp-list', locale, ...Object.values(params)].filter(Boolean).join('-'),