add useShallow

This commit is contained in:
2026-02-25 19:27:40 +08:00
parent 635e6a8a1b
commit 3ef9c47508
6 changed files with 53 additions and 11 deletions

View File

@@ -16,6 +16,7 @@ import {
import { Star, GitFork, FileText, Edit, FolderGit2, MoreVertical, FileText as IssueIcon, Settings, Play, Trash2, RefreshCw, BookOpen, Copy, Clock, Info, Eye, Square } from 'lucide-react' import { Star, GitFork, FileText, Edit, FolderGit2, MoreVertical, FileText as IssueIcon, Settings, Play, Trash2, RefreshCw, BookOpen, Copy, Clock, Info, Eye, Square } from 'lucide-react'
import { useRepoStore } from '../store' import { useRepoStore } from '../store'
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import { useShallow } from 'zustand/shallow'
import { myOrgs } from '../store/build' import { myOrgs } from '../store/build'
import { app, cnb } from '@/agents/app' import { app, cnb } from '@/agents/app'
import { toast } from 'sonner' import { toast } from 'sonner'
@@ -32,7 +33,13 @@ interface RepoCardProps {
export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings, onDelete, onSync }: RepoCardProps) { export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings, onDelete, onSync }: RepoCardProps) {
const [deletePopoverOpen, setDeletePopoverOpen] = useState(false) const [deletePopoverOpen, setDeletePopoverOpen] = useState(false)
const { workspaceList, getWorkspaceDetail, getList, buildUpdate, stopWorkspace } = useRepoStore(); const { workspaceList, getWorkspaceDetail, getList, buildUpdate, stopWorkspace } = useRepoStore(useShallow((state) => ({
workspaceList: state.workspaceList,
getWorkspaceDetail: state.getWorkspaceDetail,
getList: state.getList,
buildUpdate: state.buildUpdate,
stopWorkspace: state.stopWorkspace,
})));
const workspace = useMemo(() => { const workspace = useMemo(() => {
return workspaceList.find(ws => ws.slug === repo.path) return workspaceList.find(ws => ws.slug === repo.path)
}, [workspaceList, repo.path]) }, [workspaceList, repo.path])

View File

@@ -13,6 +13,7 @@ import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label' import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea' import { Textarea } from '@/components/ui/textarea'
import { useRepoStore } from '../store' import { useRepoStore } from '../store'
import { useShallow } from 'zustand/shallow'
interface CreateRepoDialogProps { interface CreateRepoDialogProps {
open: boolean open: boolean
@@ -27,7 +28,10 @@ interface FormData {
} }
export function CreateRepoDialog({ open, onOpenChange }: CreateRepoDialogProps) { export function CreateRepoDialog({ open, onOpenChange }: CreateRepoDialogProps) {
const { createRepo, refresh } = useRepoStore() const { createRepo, refresh } = useRepoStore(useShallow((state) => ({
createRepo: state.createRepo,
refresh: state.refresh,
})))
const { register, handleSubmit, reset } = useForm<FormData>() const { register, handleSubmit, reset } = useForm<FormData>()
const [isSubmitting, setIsSubmitting] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false)

View File

@@ -14,6 +14,7 @@ import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea' import { Textarea } from '@/components/ui/textarea'
import { TagsInput } from '@/components/tags-input' import { TagsInput } from '@/components/tags-input'
import { useRepoStore } from '../store' import { useRepoStore } from '../store'
import { useShallow } from 'zustand/shallow'
interface EditRepoDialogProps { interface EditRepoDialogProps {
open: boolean open: boolean
@@ -36,7 +37,10 @@ interface FormData {
} }
export function EditRepoDialog({ open, onOpenChange, repo }: EditRepoDialogProps) { export function EditRepoDialog({ open, onOpenChange, repo }: EditRepoDialogProps) {
const { updateRepoInfo, getList } = useRepoStore() const { updateRepoInfo, getList } = useRepoStore(useShallow((state) => ({
updateRepoInfo: state.updateRepoInfo,
getList: state.getList,
})))
const { register, handleSubmit, reset, setValue } = useForm<FormData>() const { register, handleSubmit, reset, setValue } = useForm<FormData>()
const [tags, setTags] = useState<string[]>([]) const [tags, setTags] = useState<string[]>([])

View File

@@ -4,6 +4,7 @@ import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label' import { Label } from '@/components/ui/label'
import { useRepoStore } from '../store' import { useRepoStore } from '../store'
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import { useShallow } from 'zustand/shallow'
import { get, set } from 'idb-keyval' import { get, set } from 'idb-keyval'
import { gitea } from '@/agents/app'; import { gitea } from '@/agents/app';
import { toast } from 'sonner' import { toast } from 'sonner'
@@ -11,7 +12,12 @@ import { toast } from 'sonner'
const SYNC_REPO_STORAGE_KEY = 'sync-repo-mapping' const SYNC_REPO_STORAGE_KEY = 'sync-repo-mapping'
export function SyncRepoDialog() { export function SyncRepoDialog() {
const { syncDialogOpen, setSyncDialogOpen, selectedSyncRepo, buildSync } = useRepoStore() const { syncDialogOpen, setSyncDialogOpen, selectedSyncRepo, buildSync } = useRepoStore(useShallow((state) => ({
syncDialogOpen: state.syncDialogOpen,
setSyncDialogOpen: state.setSyncDialogOpen,
selectedSyncRepo: state.selectedSyncRepo,
buildSync: state.buildSync,
})))
const [toRepo, setToRepo] = useState('') const [toRepo, setToRepo] = useState('')
useEffect(() => { useEffect(() => {

View File

@@ -153,7 +153,6 @@ const WorkTabContent = () => {
}) })
return ( return (
<div className="flex flex-col items-center justify-center py-2 text-neutral-400"> <div className="flex flex-col items-center justify-center py-2 text-neutral-400">
<div className='mb-2'></div>
<div className="grid grid-cols-1 gap-3 w-full max-w-sm"> <div className="grid grid-cols-1 gap-3 w-full max-w-sm">
{links.map(link => ( {links.map(link => (
<LinkItem key={link.label} label={link.label} icon={link.icon} url={link.url} /> <LinkItem key={link.label} label={link.label} icon={link.icon} url={link.url} />
@@ -164,8 +163,15 @@ const WorkTabContent = () => {
} }
export function WorkspaceDetailDialog() { export function WorkspaceDetailDialog() {
const { showWorkspaceDialog, setShowWorkspaceDialog, workspaceLink, stopWorkspace, workspaceTab, setWorkspaceTab } = useRepoStore() const { showWorkspaceDialog, setShowWorkspaceDialog, workspaceLink, stopWorkspace, workspaceTab, setWorkspaceTab, selectWorkspace } = useRepoStore(useShallow((state) => ({
showWorkspaceDialog: state.showWorkspaceDialog,
setShowWorkspaceDialog: state.setShowWorkspaceDialog,
workspaceLink: state.workspaceLink,
stopWorkspace: state.stopWorkspace,
workspaceTab: state.workspaceTab,
setWorkspaceTab: state.setWorkspaceTab,
selectWorkspace: state.selectWorkspace,
})))
const linkItems: LinkItem[] = [ const linkItems: LinkItem[] = [
{ {
key: 'webide' as LinkItemKey, key: 'webide' as LinkItemKey,
@@ -231,13 +237,12 @@ export function WorkspaceDetailDialog() {
getUrl: (data) => data.codebuddycn getUrl: (data) => data.codebuddycn
}, },
].sort((a, b) => (a.order || 0) - (b.order || 0)) ].sort((a, b) => (a.order || 0) - (b.order || 0))
console.log('workspaceLink', selectWorkspace)
return ( return (
<Dialog open={showWorkspaceDialog} onOpenChange={setShowWorkspaceDialog}> <Dialog open={showWorkspaceDialog} onOpenChange={setShowWorkspaceDialog}>
<DialogContent className="max-w-md! bg-white"> <DialogContent className="max-w-md! bg-white">
<DialogHeader> <DialogHeader>
<DialogTitle className="text-neutral-900"></DialogTitle> <DialogTitle className="text-neutral-900"></DialogTitle>
<DialogDescription className="text-neutral-500"></DialogDescription>
</DialogHeader> </DialogHeader>
{/* Tab 导航 */} {/* Tab 导航 */}
<div className="flex border-b border-neutral-200"> <div className="flex border-b border-neutral-200">

View File

@@ -1,5 +1,6 @@
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import { useRepoStore } from './store/index' import { useRepoStore } from './store/index'
import { useShallow } from 'zustand/shallow'
import { RepoCard } from './components/RepoCard' import { RepoCard } from './components/RepoCard'
import { EditRepoDialog } from './modules/EditRepoDialog' import { EditRepoDialog } from './modules/EditRepoDialog'
import { CreateRepoDialog } from './modules/CreateRepoDialog' import { CreateRepoDialog } from './modules/CreateRepoDialog'
@@ -12,7 +13,22 @@ import Fuse from 'fuse.js'
import { useNavigate } from '@tanstack/react-router' import { useNavigate } from '@tanstack/react-router'
export const App = () => { export const App = () => {
const { list, refresh, loading, editRepo, setEditRepo, workspaceList, showEditDialog, setShowEditDialog, showCreateDialog, setShowCreateDialog, startWorkspace, deleteItem, setSelectedSyncRepo, setSyncDialogOpen } = useRepoStore() const { list, refresh, loading, editRepo, setEditRepo, workspaceList, showEditDialog, setShowEditDialog, showCreateDialog, setShowCreateDialog, startWorkspace, deleteItem, setSelectedSyncRepo, setSyncDialogOpen } = useRepoStore(useShallow((state) => ({
list: state.list,
refresh: state.refresh,
loading: state.loading,
editRepo: state.editRepo,
setEditRepo: state.setEditRepo,
workspaceList: state.workspaceList,
showEditDialog: state.showEditDialog,
setShowEditDialog: state.setShowEditDialog,
showCreateDialog: state.showCreateDialog,
setShowCreateDialog: state.setShowCreateDialog,
startWorkspace: state.startWorkspace,
deleteItem: state.deleteItem,
setSelectedSyncRepo: state.setSelectedSyncRepo,
setSyncDialogOpen: state.setSyncDialogOpen,
})))
const [searchQuery, setSearchQuery] = useState('') const [searchQuery, setSearchQuery] = useState('')
const navigate = useNavigate(); const navigate = useNavigate();
useEffect(() => { useEffect(() => {