feat: integrate pixel teacher presence and resilient classroom preview

This commit is contained in:
鲨鱼辣椒
2026-09-23 18:23:53 +08:00
parent 12d800ec51
commit 7951cca700
60 changed files with 3313 additions and 180 deletions

View File

@@ -18,7 +18,7 @@ import type { CodingConversationMetadata } from '@/types/coding-project';
import { CodingConversationRenameDialog } from './CodingConversationRenameDialog';
import { createLocalConversationSnapshot } from './coding-chat-snapshot';
export function CodingProjectConversations({ projectId }: { projectId: string }) {
export function CodingProjectConversations({ projectId, compact = false }: { projectId: string; compact?: boolean }) {
const navigate = useNavigate();
const conversations = useCodingWorkspaceStore((state) => state.conversations);
const activeProjectId = useCodingWorkspaceStore((state) => state.activeProjectId);
@@ -67,15 +67,16 @@ export function CodingProjectConversations({ projectId }: { projectId: string })
<div
role="group"
aria-label="项目会话"
className="ml-5 py-1 pl-1"
className={compact ? "py-1" : "ml-5 py-1 pl-1"}
data-testid="project-conversations"
>
<div className="flex items-center gap-1 text-muted-foreground">
<button
type="button"
aria-label="新建对话"
title="新建对话"
disabled={!!busy}
className="flex flex-1 items-center gap-1.5 rounded px-2 py-2 text-xs hover:bg-surface-tertiary"
className={`flex flex-1 items-center gap-1.5 rounded py-2 text-xs hover:bg-surface-tertiary ${compact ? "justify-center px-1" : "px-2"}`}
onClick={() =>
void act('new', async () => {
const workspace = codingWorkspaceStore.getState();
@@ -88,16 +89,17 @@ export function CodingProjectConversations({ projectId }: { projectId: string })
}
>
<MessageSquarePlus className="h-3.5 w-3.5" />
新对话
{!compact && '新对话'}
</button>
<button
aria-label={archived ? '返回最近对话' : '查看归档对话'}
title={archived ? '返回最近对话' : '查看归档对话'}
onClick={() => setArchived(!archived)}
className="p-2"
>
<Archive className="h-3.5 w-3.5" />
</button>
<button aria-label="项目设置" onClick={() => navigate('/project-config')} className="p-2">
<button aria-label="项目设置" title="项目设置" onClick={() => navigate('/project-config')} className="p-2">
<Settings2 className="h-3.5 w-3.5" />
</button>
</div>
@@ -122,6 +124,7 @@ export function CodingProjectConversations({ projectId }: { projectId: string })
<button
className="flex min-w-0 flex-1 items-center gap-1.5 px-2 py-2 text-left text-xs"
aria-label={item.title}
title={item.title}
aria-current={selected === item.id ? 'page' : undefined}
onClick={() => void act(item.id, () => select(item))}
>