Commit b2800f26 authored by edy's avatar edy

refactor(ui): reduce app renderer prop assembly

parent 625ebaeb
...@@ -1355,10 +1355,13 @@ export default function App() { ...@@ -1355,10 +1355,13 @@ export default function App() {
const conversationWorkspaceProps = { const conversationWorkspaceProps = {
viewMode, viewMode,
workspaceRef: conversationWorkspaceRef, workspaceRef: conversationWorkspaceRef,
messageListRef, status: {
attachmentInputRef,
skillMenuRef,
panelActions, panelActions,
showInlineStartupNotice,
chatLaunchState,
startupCurtainStatus
},
emptyState: {
selectedSkillBadge, selectedSkillBadge,
selectedSkillIsDefault: selectedSkillId === DEFAULT_SKILL.id, selectedSkillIsDefault: selectedSkillId === DEFAULT_SKILL.id,
homeLeadIcon: <LobsterClawIcon />, homeLeadIcon: <LobsterClawIcon />,
...@@ -1367,10 +1370,6 @@ export default function App() { ...@@ -1367,10 +1370,6 @@ export default function App() {
activeExpertVisualKey, activeExpertVisualKey,
activeExpertGuide, activeExpertGuide,
expertWorkspaceLogo, expertWorkspaceLogo,
renderExpertIcon,
showInlineStartupNotice,
chatLaunchState,
startupCurtainStatus,
homeIntentSuggestion: pendingHomeIntentSuggestion?.suggestion ?? null, homeIntentSuggestion: pendingHomeIntentSuggestion?.suggestion ?? null,
homeIntentDecisionPending, homeIntentDecisionPending,
homeIntentLabels: { homeIntentLabels: {
...@@ -1380,9 +1379,6 @@ export default function App() { ...@@ -1380,9 +1379,6 @@ export default function App() {
continue: ui.suggestionContinue, continue: ui.suggestionContinue,
switchAction: ui.suggestionSwitchAction switchAction: ui.suggestionSwitchAction
}, },
renderIntentIcon: getIntentSuggestionIcon,
onContinueHomeIntent: continuePendingHomePromptInHome,
onSwitchHomeIntent: switchExpertAndContinuePendingHomePrompt,
showBindEntry, showBindEntry,
bindEntry: { bindEntry: {
lobsterKeyDraft, lobsterKeyDraft,
...@@ -1396,8 +1392,10 @@ export default function App() { ...@@ -1396,8 +1392,10 @@ export default function App() {
noExpertsLabel: expertsPageCopy.noExperts, noExpertsLabel: expertsPageCopy.noExperts,
starterQuestionsHint: ui.starterQuestionsHint, starterQuestionsHint: ui.starterQuestionsHint,
homeEmptyTitle: homeChatCopy.emptyTitle, homeEmptyTitle: homeChatCopy.emptyTitle,
homePrompts: homeChatCopy.prompts, homePrompts: homeChatCopy.prompts
onStarterPrompt: applyStarterPrompt, },
messages: {
messageListRef,
messages, messages,
showEmptyState, showEmptyState,
messageTraces, messageTraces,
...@@ -1412,17 +1410,11 @@ export default function App() { ...@@ -1412,17 +1410,11 @@ export default function App() {
copyIcon: <CopyIcon />, copyIcon: <CopyIcon />,
copiedIcon: <CheckIcon />, copiedIcon: <CheckIcon />,
deleteIcon: <TrashIcon />, deleteIcon: <TrashIcon />,
regenerateIcon: <RefreshIcon />, regenerateIcon: <RefreshIcon />
renderThumbIcon: (direction) => <ThumbIcon direction={direction} />, },
renderMarkdownContent, composer: {
buildDouyinVideoStatusCard, attachmentInputRef,
formatMessageTimestamp, skillMenuRef,
onMessageListScroll: handleMessageListScroll,
onCopyText: handleCopyText,
onDeleteMessage: deleteMessage,
onTraceExpandedChange: setMessageTraceExpanded,
onRegenerateAssistantMessage: regenerateAssistantMessage,
onToggleMessageReaction: toggleMessageReaction,
prompt, prompt,
isBound, isBound,
canSend, canSend,
...@@ -1441,7 +1433,24 @@ export default function App() { ...@@ -1441,7 +1433,24 @@ export default function App() {
skills: effectiveSkills, skills: effectiveSkills,
skillMenuOpen, skillMenuOpen,
attachmentIcon: <AttachmentIcon />, attachmentIcon: <AttachmentIcon />,
submitIcon: sendPhase !== "idle" ? <StopIcon /> : <ArrowUpIcon />, submitIcon: sendPhase !== "idle" ? <StopIcon /> : <ArrowUpIcon />
},
actions: {
renderExpertIcon,
renderIntentIcon: getIntentSuggestionIcon,
onContinueHomeIntent: continuePendingHomePromptInHome,
onSwitchHomeIntent: switchExpertAndContinuePendingHomePrompt,
onStarterPrompt: applyStarterPrompt,
renderThumbIcon: (direction) => <ThumbIcon direction={direction} />,
renderMarkdownContent,
buildDouyinVideoStatusCard,
formatMessageTimestamp,
onMessageListScroll: handleMessageListScroll,
onCopyText: handleCopyText,
onDeleteMessage: deleteMessage,
onTraceExpandedChange: setMessageTraceExpanded,
onRegenerateAssistantMessage: regenerateAssistantMessage,
onToggleMessageReaction: toggleMessageReaction,
onSubmit: sendPrompt, onSubmit: sendPrompt,
onCancel: cancelActiveStream, onCancel: cancelActiveStream,
onPromptChange: setPrompt, onPromptChange: setPrompt,
...@@ -1459,6 +1468,7 @@ export default function App() { ...@@ -1459,6 +1468,7 @@ export default function App() {
onResizePointerDown: handleComposerResizePointerDown, onResizePointerDown: handleComposerResizePointerDown,
onResizePointerMove: handleComposerResizePointerMove, onResizePointerMove: handleComposerResizePointerMove,
onResizePointerEnd: handleComposerResizePointerEnd onResizePointerEnd: handleComposerResizePointerEnd
}
} satisfies ComponentProps<typeof ConversationWorkspaceView>; } satisfies ComponentProps<typeof ConversationWorkspaceView>;
const settingsStatusHint = showSettingsStatusHint const settingsStatusHint = showSettingsStatusHint
? <div className={"inline-hint settings-runtime-hint" + (chatLaunchState === "error" ? " error" : "")}>{startupMessage}</div> ? <div className={"inline-hint settings-runtime-hint" + (chatLaunchState === "error" ? " error" : "")}>{startupMessage}</div>
......
...@@ -258,7 +258,7 @@ ...@@ -258,7 +258,7 @@
- Modify: `apps/ui/src/features/settings/SettingsPanels.tsx` - Modify: `apps/ui/src/features/settings/SettingsPanels.tsx`
- Create or modify focused hooks only under existing `apps/ui/src/features/*` - Create or modify focused hooks only under existing `apps/ui/src/features/*`
- [ ] **Step 1: 拆出纯 props 组装** - [x] **Step 1: 拆出纯 props 组装**
Move only pure prop-building logic from `App.tsx` into focused helpers or hooks when all inputs are already available. Move only pure prop-building logic from `App.tsx` into focused helpers or hooks when all inputs are already available.
...@@ -274,7 +274,12 @@ ...@@ -274,7 +274,12 @@
- No IPC calls move across ownership boundaries in this step. - No IPC calls move across ownership boundaries in this step.
- `App.tsx` line count decreases, but line count is not the success metric; clearer ownership is. - `App.tsx` line count decreases, but line count is not the success metric; clearer ownership is.
- [ ] **Step 2: Keep high-risk flows in place** Progress note:
- Completed on 2026-05-25 by grouping `ConversationWorkspaceView` props into focused `status`, `emptyState`, `messages`, `composer`, and `actions` objects.
- IPC calls, stream lifecycle, composer submit/cancel, session actions, startup overlay actions, and smoke hooks remain in `App.tsx`.
- [x] **Step 2: Keep high-risk flows in place**
Do not move these during this phase: Do not move these during this phase:
...@@ -289,7 +294,11 @@ ...@@ -289,7 +294,11 @@
- Existing smoke tests do not need selector or action rewrites. - Existing smoke tests do not need selector or action rewrites.
- [ ] **Step 3: Reduce oversized component props** Progress note:
- Confirmed during the prop grouping pass; no smoke contract or high-risk flow was moved.
- [x] **Step 3: Reduce oversized component props**
For `ConversationWorkspaceView`, group related props into typed objects only when ownership is obvious: For `ConversationWorkspaceView`, group related props into typed objects only when ownership is obvious:
...@@ -304,7 +313,11 @@ ...@@ -304,7 +313,11 @@
- Component call site becomes easier to read. - Component call site becomes easier to read.
- Existing child component props stay unchanged unless required. - Existing child component props stay unchanged unless required.
- [ ] **Step 4: Validate App.tsx encoding and tests** Progress note:
- `ConversationWorkspaceView` now receives typed grouped props; child components still receive their existing prop shapes.
- [x] **Step 4: Validate App.tsx encoding and tests**
Run: Run:
...@@ -320,6 +333,12 @@ ...@@ -320,6 +333,12 @@
- Diff contains no mojibake and no unrelated Chinese copy changes. - Diff contains no mojibake and no unrelated Chinese copy changes.
- UI typecheck passes. - UI typecheck passes.
Progress note:
- Passed on 2026-05-25: BOM check printed `b'imp'`.
- Inspected `git diff -- apps/ui/src/App.tsx apps/ui/src/features/chat/ConversationWorkspaceView.tsx`; no mojibake or unrelated Chinese copy changes.
- Passed on 2026-05-25: `corepack pnpm --filter @qjclaw/ui typecheck`; `corepack pnpm build`.
## 6. Phase 4 - 修正核心工作流 UI/UX ## 6. Phase 4 - 修正核心工作流 UI/UX
**目标:** 优先改善用户每天会反复使用的界面:聊天、任务、自动化、设置。 **目标:** 优先改善用户每天会反复使用的界面:聊天、任务、自动化、设置。
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment