@@ -8,11 +8,11 @@ import { Input } from '@/components/ui/input'
88import { ScrollArea } from '@/components/ui/scroll-area'
99import { Select , SelectContent , SelectItem , SelectTrigger , SelectValue } from '@/components/ui/select'
1010import { Tabs , TabsList , TabsTrigger } from '@/components/ui/tabs'
11- import { AlertCircle , AlertTriangle , CheckCircle2 , Info , Loader2 , RotateCw , Search , Settings2 } from 'lucide-react'
11+ import { AlertCircle , AlertTriangle , CheckCircle2 , Info , Loader2 , Search , Settings2 } from 'lucide-react'
1212
1313import { RestartOverlay } from '@/components/restart-overlay'
1414import { useToast } from '@/hooks/use-toast'
15- import { RestartProvider , useRestart } from '@/lib/restart-context'
15+ import { RestartProvider } from '@/lib/restart-context'
1616import {
1717 checkGitStatus ,
1818 checkPluginInstalled ,
@@ -53,7 +53,6 @@ export function PluginsPage() {
5353// 内部组件:实际内容
5454function PluginsPageContent ( ) {
5555 const navigate = useNavigate ( )
56- const { triggerRestart, isRestarting } = useRestart ( )
5756 const [ restartNoticeVisible , setRestartNoticeVisible ] = useState (
5857 ( ) => localStorage . getItem ( 'plugins-restart-notice-dismissed' ) !== 'true'
5958 )
@@ -720,17 +719,8 @@ function PluginsPageContent() {
720719 < div className = "flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4" >
721720 < div >
722721 < h1 className = "text-2xl sm:text-3xl font-bold" > 插件市场</ h1 >
723- < p className = "text-muted-foreground mt-2" > 浏览和管理麦麦的插件</ p >
724722 </ div >
725723 < div className = "flex gap-2" >
726- < Button
727- variant = "outline"
728- onClick = { ( ) => triggerRestart ( ) }
729- disabled = { isRestarting }
730- >
731- < RotateCw className = { `h-4 w-4 mr-2 ${ isRestarting ? 'animate-spin' : '' } ` } />
732- 重启麦麦
733- </ Button >
734724 < Button onClick = { ( ) => navigate ( { to : '/plugin-mirrors' } ) } >
735725 < Settings2 className = "h-4 w-4 mr-2" />
736726 配置镜像源
@@ -784,81 +774,77 @@ function PluginsPageContent() {
784774
785775 { /* 搜索和筛选栏 */ }
786776 < Card className = "p-4" >
787- < div className = "flex flex-col gap-4" >
788- < div className = "flex flex-col sm:flex-row gap-4" >
789- { /* 搜索框 */ }
790- < div className = "flex-1 relative" >
791- < Search className = "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
792- < Input
793- placeholder = "搜索插件..."
794- value = { searchQuery }
795- onChange = { ( e ) => setSearchQuery ( e . target . value ) }
796- className = "pl-9"
797- />
798- </ div >
799-
800- { /* 分类筛选 */ }
801- < Select value = { categoryFilter } onValueChange = { setCategoryFilter } >
802- < SelectTrigger className = "w-full sm:w-[200px]" >
803- < SelectValue placeholder = "选择分类" />
804- </ SelectTrigger >
805- < SelectContent >
806- < SelectItem value = "all" > 全部分类</ SelectItem >
807- < SelectItem value = "Group Management" > 群组管理</ SelectItem >
808- < SelectItem value = "Entertainment & Interaction" > 娱乐互动</ SelectItem >
809- < SelectItem value = "Utility Tools" > 实用工具</ SelectItem >
810- < SelectItem value = "Content Generation" > 内容生成</ SelectItem >
811- < SelectItem value = "Multimedia" > 多媒体</ SelectItem >
812- < SelectItem value = "External Integration" > 外部集成</ SelectItem >
813- < SelectItem value = "Data Analysis & Insights" > 数据分析与洞察</ SelectItem >
814- < SelectItem value = "Other" > 其他</ SelectItem >
815- </ SelectContent >
816- </ Select >
817-
818- { /* 排序 */ }
819- < Select
820- value = { marketplaceSortBy }
821- onValueChange = { ( value ) => setMarketplaceSortBy ( value as MarketplaceSortKey ) }
822- >
823- < SelectTrigger className = "w-full sm:w-[160px]" >
824- < SelectValue placeholder = "排序" />
825- </ SelectTrigger >
826- < SelectContent >
827- < SelectItem value = "default" > 推荐排序</ SelectItem >
828- < SelectItem value = "downloads" > 下载最多</ SelectItem >
829- < SelectItem value = "likes" > 点赞最多</ SelectItem >
830- < SelectItem value = "rating" > 评分最高</ SelectItem >
831- </ SelectContent >
832- </ Select >
777+ < div className = "flex flex-col gap-4 sm:flex-row sm:items-center" >
778+ { /* 搜索框 */ }
779+ < div className = "relative w-full sm:max-w-md sm:flex-1" >
780+ < Search className = "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
781+ < Input
782+ placeholder = "搜索插件..."
783+ value = { searchQuery }
784+ onChange = { ( e ) => setSearchQuery ( e . target . value ) }
785+ className = "pl-9"
786+ />
833787 </ div >
834-
788+
789+ { /* 分类筛选 */ }
790+ < Select value = { categoryFilter } onValueChange = { setCategoryFilter } >
791+ < SelectTrigger className = "w-full sm:w-[200px]" >
792+ < SelectValue placeholder = "选择分类" />
793+ </ SelectTrigger >
794+ < SelectContent >
795+ < SelectItem value = "all" > 全部分类</ SelectItem >
796+ < SelectItem value = "Group Management" > 群组管理</ SelectItem >
797+ < SelectItem value = "Entertainment & Interaction" > 娱乐互动</ SelectItem >
798+ < SelectItem value = "Utility Tools" > 实用工具</ SelectItem >
799+ < SelectItem value = "Content Generation" > 内容生成</ SelectItem >
800+ < SelectItem value = "Multimedia" > 多媒体</ SelectItem >
801+ < SelectItem value = "External Integration" > 外部集成</ SelectItem >
802+ < SelectItem value = "Data Analysis & Insights" > 数据分析与洞察</ SelectItem >
803+ < SelectItem value = "Other" > 其他</ SelectItem >
804+ </ SelectContent >
805+ </ Select >
806+
807+ { /* 排序 */ }
808+ < Select
809+ value = { marketplaceSortBy }
810+ onValueChange = { ( value ) => setMarketplaceSortBy ( value as MarketplaceSortKey ) }
811+ >
812+ < SelectTrigger className = "w-full sm:w-[160px]" >
813+ < SelectValue placeholder = "排序" />
814+ </ SelectTrigger >
815+ < SelectContent >
816+ < SelectItem value = "default" > 推荐排序</ SelectItem >
817+ < SelectItem value = "downloads" > 下载最多</ SelectItem >
818+ < SelectItem value = "likes" > 点赞最多</ SelectItem >
819+ < SelectItem value = "rating" > 评分最高</ SelectItem >
820+ </ SelectContent >
821+ </ Select >
822+
835823 { /* 兼容性筛选 */ }
836- < div className = "flex items-center" >
837- < div className = "relative flex items-center space-x-2" >
838- < Checkbox
839- id = "compatible-only"
840- checked = { showCompatibleOnly }
841- onCheckedChange = { ( checked ) => setShowCompatibleOnly ( checked === true ) }
842- />
843- < label
844- htmlFor = "compatible-only"
845- className = "cursor-pointer text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
824+ < div className = "flex w-full flex-wrap items-center gap-x-2 gap-y-2 sm:w-auto sm:min-w-fit" >
825+ < Checkbox
826+ id = "compatible-only"
827+ checked = { showCompatibleOnly }
828+ onCheckedChange = { ( checked ) => setShowCompatibleOnly ( checked === true ) }
829+ />
830+ < label
831+ htmlFor = "compatible-only"
832+ className = "cursor-pointer text-sm font-medium leading-none whitespace-nowrap peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
833+ >
834+ 仅显示当前版本
835+ </ label >
836+ { isFetchingMarketplace && (
837+ < div
838+ className = "flex min-w-0 max-w-full items-center gap-2 rounded-md border bg-background/85 px-2 py-0.5 text-xs whitespace-nowrap shadow-sm backdrop-blur sm:max-w-80"
839+ aria-live = "polite"
846840 >
847- 只显示兼容当前版本的插件
848- </ label >
849- { isFetchingMarketplace && (
850- < div
851- className = "absolute top-1/2 left-[calc(100%+0.75rem)] z-10 flex max-w-[34rem] -translate-y-1/2 items-center gap-2 rounded-md border bg-background/85 px-2 py-0.5 text-xs whitespace-nowrap shadow-sm backdrop-blur"
852- aria-live = "polite"
853- >
854- < Loader2 className = "h-3 w-3 shrink-0 animate-spin text-muted-foreground" />
855- < span className = "shrink-0 font-medium" > 加载插件市场</ span >
856- < span className = "min-w-0 truncate text-muted-foreground" >
857- { loadProgress . message || '正在获取插件清单' }
858- </ span >
859- </ div >
860- ) }
861- </ div >
841+ < Loader2 className = "h-3 w-3 shrink-0 animate-spin text-muted-foreground" />
842+ < span className = "shrink-0 font-medium" > 加载插件市场</ span >
843+ < span className = "min-w-0 truncate text-muted-foreground" >
844+ { loadProgress . message || '正在获取插件清单' }
845+ </ span >
846+ </ div >
847+ ) }
862848 </ div >
863849 </ div >
864850 </ Card >
0 commit comments