Skip to content

feat(ai): Warp Block 风格统一聊天界面 (Issue #69)#70

Merged
hrygo merged 28 commits into
mainfrom
feat/69-warp-block-ui
Feb 4, 2026
Merged

feat(ai): Warp Block 风格统一聊天界面 (Issue #69)#70
hrygo merged 28 commits into
mainfrom
feat/69-warp-block-ui

Conversation

@hrygo

@hrygo hrygo commented Feb 4, 2026

Copy link
Copy Markdown
Owner

概述

实现 Issue #69: Warp Block 风格统一聊天界面,将用户输入 + AI 回复封装为一个统一的可折叠 Block。

变更内容

  • ✅ 新建 UnifiedMessageBlock 组件
  • ✅ 支持五种 Parrot 主题适配 (MEMO/SCHEDULE/AMAZING/GEEK/EVOLUTION)
  • ✅ 新 Block 默认展开,历史 Block 默认折叠
  • ✅ 保留所有现有交互功能 (复制/重新生成/删除)
  • ✅ 更新 docs/dev-guides/FRONTEND.md

组件结构

┌─────────────────────────────────────────────────────────┐
│  Block Header (用户消息 + 时间戳 + 状态)                │
├─────────────────────────────────────────────────────────┤
│  Block Body (可折叠)                                    │
│  ├── Thinking Section (思考过程)                        │
│  ├── ToolCalls Section (工具调用)                        │
│  ├── Answer Section (最终回答)                          │
│  └── Summary Section (会话统计)                          │
├─────────────────────────────────────────────────────────┤
│  Block Footer (操作栏)                                  │
└─────────────────────────────────────────────────────────┘

关联 Issue

Resolves #69

测试计划

  • ✅ 本地测试通过
  • ✅ 单元测试新增/更新
  • make check-all 通过
  • ✅ pnpm lint + pnpm build 通过

检查清单

  • 代码遵循项目规范
  • 自我审查代码
  • 注释说明了复杂逻辑
  • 文档已更新

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

hotplex-ai and others added 28 commits February 4, 2026 09:57
Implement Issue #69: Warp Block 风格统一聊天界面

- Add UnifiedMessageBlock.tsx with Warp Block design pattern
  - Block Header: user message preview + timestamp + status badge
  - Block Body: collapsible content (thinking/tools/results/answer/summary)
  - Block Footer: actions (copy/regenerate/delete)
- Support 5 Parrot themes (MEMO/SCHEDULE/AMAZING/GEEK/EVOLUTION)
- Implement collapse strategy: new/latest blocks expanded, historical collapsed
- Add i18n keys: ai.events.tools, ai.events.results
- Add research report with architecture design

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add UnifiedMessageBlock component index.ts for clean exports
- Update FRONTEND.md with UnifiedMessageBlock usage documentation
- Document Block structure, theme support, and collapse strategy

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix MEMO ringColor from blue to slate for consistency with PARROT_THEMES
- Replace inline styles with Tailwind classes for collapse animation
- Remove unnecessary useMemo for userInitial (simple regex is fast enough)
- Fix useEffect dependency stability using messageIds for comparison
- Add trailing comma for Biome formatter

Fixes the following issues:
1. MEMO theme ringColor was blue instead of slate
2. BlockBody used inline styles instead of Tailwind
3. Unnecessary useMemo optimization
4. useEffect could trigger on every messages reference change

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This is a major refactor to adopt the Warp Block design pattern.

## Changes

### UnifiedMessageBlock.tsx
- Restructured with clear Header/Body/Footer sections
- Footer now always visible (previously hidden when collapsed)
- Collapse/Expand button moved from Header to Footer
- Added proper border separators between sections

### ChatMessages.tsx
- **Critical**: UnifiedMessageBlock was never being used before
- Added `groupMessagesIntoBlocks()` to pair user+assistant messages
- Replaced MessageBubble rendering with UnifiedMessageBlock
- Removed 600+ lines of obsolete MessageBubble code
- SessionSummary now renders as a UnifiedMessageBlock

## Architecture

Before: Flat message list → MessageBubble (WeChat-style bubbles)
After:  Paired blocks → UnifiedMessageBlock (Warp Block style)

Each Block contains:
- Header: User input + timestamp + status badge
- Body: Thinking + ToolCalls + ToolResults + Answer (collapsible)
- Footer: Collapse/Expand + Copy + Regenerate + Delete buttons

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add thinkingSteps array with round tracking to ConversationMessage
- Deep merge metadata in updateMessage to preserve existing fields
- Render multi-round thinking with "Round N" labels
- Fix onThinking callback to save to metadata.thinking
- Add round field to toolCalls and toolResults for grouping

This enables the AI to have multiple thinking cycles within a single
response, with each cycle properly tracked and displayed in the timeline.

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add visual feedback to timeline nodes during AI streaming:
- AI Thinking node shows spinning brain when active
- Tools node shows spinning wrench when executing
- Answer node shows spinning bolt when generating
- Removes redundant "处理中..." text indicators
- Adds streamingPhase calculation (thinking/tools/answer)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract magic numbers to constants (ROUND_TIMESTAMP_MULTIPLIER, TOOL_CALL_OFFSET_MS)
- Centralize isContextSeparator type guard in @/types/aichat.ts
- Optimize useMemo dependencies to avoid unnecessary recalculations
- Add AIMode type annotation for block mode detection
- Rename animate-pulse-border to animate-block-pulse to avoid conflicts
- Add aria-label and aria-expanded for better accessibility
- Add explanatory comment for syncMessages useEffect dependency
- Clean up unused imports (AIMode, ContextSeparator)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add common.copied to i18n (en/zh-Hans)
- Add ai.session_stats.* keys for Geek/Evolution summary panel
- Add ai.typing_indicator, ai.aichat.amazing-insight.auto_generated
- Add schedule.time_filter and schedule.error.* keys
- Replace hardcoded strings with i18n calls across components
- Fix token display: "k tok" → "k token", "tokens" → "token"
- Add footerBg theme property for Header/Footer visual distinction
- Import i18next for ScheduleErrorBoundary class component

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive spec document for the Unified Block Model design,
which aims to unify the data structures between Normal Mode and
CC Mode (Geek/Evolution) while supporting complete persistence
of the Warp Block UI.

Key features:
- Block as first-class conversation turn unit
- Mode-independent storage (normal/geek/evolution per block)
- Support for appending user inputs (Issue #57)
- Complete event stream persistence (thinking/tool_use/answer)
- CC session mapping with UUID v5 deterministic algorithm
- Backward compatibility with migration strategy

Includes:
- Database schema (ai_block table)
- Store interface definitions (Go)
- Proto definitions
- Frontend type definitions
- Component adaptation strategy
- 7-phase implementation plan (16-22 days)

Refs #71

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add 6 detailed phase specs for implementing the Unified Block Model:

- Phase 1 (5人天): Database & Backend Store
  - ai_block table with JSONB fields
  - BlockStore interface and PostgreSQL implementation
  - Compatibility view v_ai_message

- Phase 2 (3人天): Proto & API
  - Protobuf message definitions
  - BlockService RPC methods

- Phase 3 (2人天): Frontend Types
  - TypeScript interfaces for AIBlock, BlockEvent, UserInput
  - Block API hooks

- Phase 4 (4人天): Frontend Components
  - ChatMessages refactoring to use Block data
  - AIChatContext extensions

- Phase 5 (4人天): Chat Handler Integration
  - Block lifecycle management
  - EventWriter implementation

- Phase 6 (3人天): Integration Testing
  - Unit, integration, and E2E tests

Also updated:
- docs/specs/INDEX.md: Added phase spec links
- docs/specs/unified-block-model.md: Updated implementation plan
- docs/specs/unified-block-model-index.md: Clean index for navigation

Refs #71

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add comprehensive animation library (scanline, dataFlow, dnaHelix, etc.)
- Geek Mode: terminal scanlines, data flow borders, cursor blink effects
- Evolution Mode: DNA double helix, organic breathing, particle effects
- DivineEye: isActive prop for dynamic state feedback
- ChatInput: larger touch targets (40px mobile, 32px desktop) for better UX
- Text size optimization: replace 9px/10px with 11px for readability
- Footer color distinction: header (50 scale) vs footer (200/80 scale)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- P0-1: Remove inline SVG filter (drop-shadow) causing CPU rendering
- P0-2: Simplify glitchFlicker animation (5→2 keyframes)
- P0-3: Add prefers-reduced-motion support for accessibility
- P1-3: Remove will-change滥用 from theme CSS files
- P1-4: Replace box-shadow animation with transform/opacity (GPU-accelerated)
- P2-1: Add focus-visible rings to UnifiedMessageBlock buttons
- P2-2: Add ARIA labels to DivineEye component

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix user input display and timeline alignment issue:

**Block Header (标题栏)**:
- Change from single-line truncate to line-clamp-2 (最多2行)
- Add hover tooltip for full content preview
- Add appended input count badge (蓝色圆点显示总数)
- Smart preview text for multiple inputs

**UserInputsSection (新增用户输入区域)**:
- New dedicated section in Block Body for displaying user inputs
- Support multiple appended inputs with numbered badges (①②③)
- Long content collapse (超过300字默认折叠)
- Click-to-expand with preview
- Each input shows timestamp
- Proper timeline alignment with pl-8 padding

**Fix Timeline Alignment**:
- Move UserInputsSection inside timeline container
- Add pl-8 padding to content for timeline node
- Ensure consistent spacing with other timeline events

**i18n**:
- Add keys: user_inputs, more_input, more_inputs, expand_to_read_all

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- P1-1: Include additionalUserInputs in contentForCopy
- P1-2: Add focus-visible ring to expand/collapse button
- P2-1: Change collapsed preview to <button> for a11y
- P2-2: Fix counter badge overflow with min-w-[16px] px-0.5
- P3-1: Extract magic number 300 to USER_INPUTS_EXPAND_THRESHOLD

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
**Block Header**:
- Change to fixed char truncate (20 chars max)
- Single line only, no wrap, no expand on hover
- Simplified preview format: "content..." or "content...+N"

**UserInputsSection**:
- Remove internal mb-6 (use parent space-y-6)
- Add transition-colors to timeline node
- Add group-hover effect for consistency
- Align with other timeline event styles

**Error Section**:
- Add transition-colors to timeline node
- Add group-hover effect for consistency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement visual width-aware truncation to handle Chinese/English differences:

**Visual Width Calculation**:
- ASCII characters (English, numbers, half-width symbols) = 1
- CJK characters (Chinese, full-width symbols, Emoji) = 2

**Header Preview**:
- Max visual width: 24 (≈12 Chinese chars or 24 English chars)
- Reserve space for "+N" suffix when multiple inputs exist

This ensures consistent display width across different languages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove the `pl-8` wrapper from UserInputsSection to match the
structure of other timeline events (ThinkingSection, ToolCallsSection,
etc.). All sections now follow the same pattern:

- `relative group` container
- `absolute -left-8` timeline node
- Direct content (no extra padding wrapper)

This ensures consistent left alignment across all block sections.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
**Block Header**:
- Remove `hidden sm:` from timestamp - now visible on all screen sizes
- Remove `hidden sm:` from parrot badge - now visible on all screen sizes

**Block Footer**:
- Remove `hidden sm:` from "Forget" button - now visible on all screen sizes
- Keep text label with `hidden lg:inline` for mobile optimization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove the "用户输入" (User Inputs) label and MessageSquare icon
from the section header for a cleaner UI. The expand/collapse
button is still shown when needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove redundant elements for a cleaner design:

**Removed**:
- "(展开)/(收起)" status text - redundant with chevron icon
- Collapsed preview text - created double clickable area confusion

**Improved**:
- Chevron icon now ml-auto for right alignment
- Increased icon size (w-4 h-4) and visibility (no opacity-50)
- Single clickable area (title button) for clarity

**Result**: Cleaner, more intuitive collapsible section.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix useState closure trap with refs for latest isLatest/isStreaming values
- Improve visual width calculation with better Unicode handling (surrogate pairs, zero-width chars, CJK ranges)
- Add mobile-friendly Geek Summary display (simplified cost indicator)
- Add will-change hints to CSS animations for GPU acceleration
- Replace console.debug with conditional debugLog (DEV-only)
- Extract magic numbers to centralized constants.ts file
- Remove hardcoded Chinese fallback strings

Fixes code review issues from P1-P3 priorities.

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add hadThinkingPhase state to preserve thinking UI when
streaming completes, maintaining visual continuity.

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show Loader2 spinner during active thinking phase
- Show Brain icon when thinking is completed
- Improve visual feedback for streaming state

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The thinking phase tracking state was added but not utilized
in the rendering logic. Removed to reduce unnecessary state.

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement clear state distinction for Thinking Section:

**States**:
- `streamingPhase === "thinking"` → 🔄 思考中... (spinner + blue)
- `streamingPhase !== "thinking"` → 🧠 思考过程 (static + muted)

**Visual Changes**:
- Add Loader2 spinner icon in title during thinking phase
- Color-coded states: blue (active) vs muted (completed)
- Icon and text color match the state

This solves the UX issue where users couldn't tell if thinking
was "in progress" or "already completed".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Mobile: Show simplified header only, no expand button
- Desktop (lg+): Keep expand/collapse functionality
- Add lg: prefix to expand button and expanded content
- Header remains clickable on desktop only

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Simplify UserInputsSection by removing the timestamp display
below each input. The block header already shows the main
message time, so individual input times are redundant.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hrygo hrygo merged commit e5496c0 into main Feb 4, 2026
5 checks passed
@hrygo hrygo deleted the feat/69-warp-block-ui branch February 4, 2026 12:47
hrygo added a commit that referenced this pull request Feb 5, 2026
* feat(ai): add UnifiedMessageBlock component for Warp-style chat UI

Implement Issue #69: Warp Block 风格统一聊天界面

- Add UnifiedMessageBlock.tsx with Warp Block design pattern
  - Block Header: user message preview + timestamp + status badge
  - Block Body: collapsible content (thinking/tools/results/answer/summary)
  - Block Footer: actions (copy/regenerate/delete)
- Support 5 Parrot themes (MEMO/SCHEDULE/AMAZING/GEEK/EVOLUTION)
- Implement collapse strategy: new/latest blocks expanded, historical collapsed
- Add i18n keys: ai.events.tools, ai.events.results
- Add research report with architecture design

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs(ai): add UnifiedMessageBlock documentation and index export

- Add UnifiedMessageBlock component index.ts for clean exports
- Update FRONTEND.md with UnifiedMessageBlock usage documentation
- Document Block structure, theme support, and collapse strategy

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): fix code review issues in UnifiedMessageBlock

- Fix MEMO ringColor from blue to slate for consistency with PARROT_THEMES
- Replace inline styles with Tailwind classes for collapse animation
- Remove unnecessary useMemo for userInitial (simple regex is fast enough)
- Fix useEffect dependency stability using messageIds for comparison
- Add trailing comma for Biome formatter

Fixes the following issues:
1. MEMO theme ringColor was blue instead of slate
2. BlockBody used inline styles instead of Tailwind
3. Unnecessary useMemo optimization
4. useEffect could trigger on every messages reference change

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): integrate UnifiedMessageBlock into ChatMessages

This is a major refactor to adopt the Warp Block design pattern.

## Changes

### UnifiedMessageBlock.tsx
- Restructured with clear Header/Body/Footer sections
- Footer now always visible (previously hidden when collapsed)
- Collapse/Expand button moved from Header to Footer
- Added proper border separators between sections

### ChatMessages.tsx
- **Critical**: UnifiedMessageBlock was never being used before
- Added `groupMessagesIntoBlocks()` to pair user+assistant messages
- Replaced MessageBubble rendering with UnifiedMessageBlock
- Removed 600+ lines of obsolete MessageBubble code
- SessionSummary now renders as a UnifiedMessageBlock

## Architecture

Before: Flat message list → MessageBubble (WeChat-style bubbles)
After:  Paired blocks → UnifiedMessageBlock (Warp Block style)

Each Block contains:
- Header: User input + timestamp + status badge
- Body: Thinking + ToolCalls + ToolResults + Answer (collapsible)
- Footer: Collapse/Expand + Copy + Regenerate + Delete buttons

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): support multi-round thinking in UnifiedMessageBlock

- Add thinkingSteps array with round tracking to ConversationMessage
- Deep merge metadata in updateMessage to preserve existing fields
- Render multi-round thinking with "Round N" labels
- Fix onThinking callback to save to metadata.thinking
- Add round field to toolCalls and toolResults for grouping

This enables the AI to have multiple thinking cycles within a single
response, with each cycle properly tracked and displayed in the timeline.

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): add animated timeline indicators for streaming phases

Add visual feedback to timeline nodes during AI streaming:
- AI Thinking node shows spinning brain when active
- Tools node shows spinning wrench when executing
- Answer node shows spinning bolt when generating
- Removes redundant "处理中..." text indicators
- Adds streamingPhase calculation (thinking/tools/answer)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ai): fix code review issues in Warp Block UI

- Extract magic numbers to constants (ROUND_TIMESTAMP_MULTIPLIER, TOOL_CALL_OFFSET_MS)
- Centralize isContextSeparator type guard in @/types/aichat.ts
- Optimize useMemo dependencies to avoid unnecessary recalculations
- Add AIMode type annotation for block mode detection
- Rename animate-pulse-border to animate-block-pulse to avoid conflicts
- Add aria-label and aria-expanded for better accessibility
- Add explanatory comment for syncMessages useEffect dependency
- Clean up unused imports (AIMode, ContextSeparator)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ai): i18n improvements and UI polish for Warp Block

- Add common.copied to i18n (en/zh-Hans)
- Add ai.session_stats.* keys for Geek/Evolution summary panel
- Add ai.typing_indicator, ai.aichat.amazing-insight.auto_generated
- Add schedule.time_filter and schedule.error.* keys
- Replace hardcoded strings with i18n calls across components
- Fix token display: "k tok" → "k token", "tokens" → "token"
- Add footerBg theme property for Header/Footer visual distinction
- Import i18next for ScheduleErrorBoundary class component

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(specs): add unified block model specification

Add comprehensive spec document for the Unified Block Model design,
which aims to unify the data structures between Normal Mode and
CC Mode (Geek/Evolution) while supporting complete persistence
of the Warp Block UI.

Key features:
- Block as first-class conversation turn unit
- Mode-independent storage (normal/geek/evolution per block)
- Support for appending user inputs (Issue #57)
- Complete event stream persistence (thinking/tool_use/answer)
- CC session mapping with UUID v5 deterministic algorithm
- Backward compatibility with migration strategy

Includes:
- Database schema (ai_block table)
- Store interface definitions (Go)
- Proto definitions
- Frontend type definitions
- Component adaptation strategy
- 7-phase implementation plan (16-22 days)

Refs #71

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* specs(ai): add unified block model phase specifications (21人天)

Add 6 detailed phase specs for implementing the Unified Block Model:

- Phase 1 (5人天): Database & Backend Store
  - ai_block table with JSONB fields
  - BlockStore interface and PostgreSQL implementation
  - Compatibility view v_ai_message

- Phase 2 (3人天): Proto & API
  - Protobuf message definitions
  - BlockService RPC methods

- Phase 3 (2人天): Frontend Types
  - TypeScript interfaces for AIBlock, BlockEvent, UserInput
  - Block API hooks

- Phase 4 (4人天): Frontend Components
  - ChatMessages refactoring to use Block data
  - AIChatContext extensions

- Phase 5 (4人天): Chat Handler Integration
  - Block lifecycle management
  - EventWriter implementation

- Phase 6 (3人天): Integration Testing
  - Unit, integration, and E2E tests

Also updated:
- docs/specs/INDEX.md: Added phase spec links
- docs/specs/unified-block-model.md: Updated implementation plan
- docs/specs/unified-block-model-index.md: Clean index for navigation

Refs #71

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): enhance Geek/Evolution mode UX/UI with AI Native effects

- Add comprehensive animation library (scanline, dataFlow, dnaHelix, etc.)
- Geek Mode: terminal scanlines, data flow borders, cursor blink effects
- Evolution Mode: DNA double helix, organic breathing, particle effects
- DivineEye: isActive prop for dynamic state feedback
- ChatInput: larger touch targets (40px mobile, 32px desktop) for better UX
- Text size optimization: replace 9px/10px with 11px for readability
- Footer color distinction: header (50 scale) vs footer (200/80 scale)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): optimize performance and accessibility in animations

- P0-1: Remove inline SVG filter (drop-shadow) causing CPU rendering
- P0-2: Simplify glitchFlicker animation (5→2 keyframes)
- P0-3: Add prefers-reduced-motion support for accessibility
- P1-3: Remove will-change滥用 from theme CSS files
- P1-4: Replace box-shadow animation with transform/opacity (GPU-accelerated)
- P2-1: Add focus-visible rings to UnifiedMessageBlock buttons
- P2-2: Add ARIA labels to DivineEye component

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): handle long user input in UnifiedBlock UI

Fix user input display and timeline alignment issue:

**Block Header (标题栏)**:
- Change from single-line truncate to line-clamp-2 (最多2行)
- Add hover tooltip for full content preview
- Add appended input count badge (蓝色圆点显示总数)
- Smart preview text for multiple inputs

**UserInputsSection (新增用户输入区域)**:
- New dedicated section in Block Body for displaying user inputs
- Support multiple appended inputs with numbered badges (①②③)
- Long content collapse (超过300字默认折叠)
- Click-to-expand with preview
- Each input shows timestamp
- Proper timeline alignment with pl-8 padding

**Fix Timeline Alignment**:
- Move UserInputsSection inside timeline container
- Add pl-8 padding to content for timeline node
- Ensure consistent spacing with other timeline events

**i18n**:
- Add keys: user_inputs, more_input, more_inputs, expand_to_read_all

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): improve UserInputsSection a11y and content copy

- P1-1: Include additionalUserInputs in contentForCopy
- P1-2: Add focus-visible ring to expand/collapse button
- P2-1: Change collapsed preview to <button> for a11y
- P2-2: Fix counter badge overflow with min-w-[16px] px-0.5
- P3-1: Extract magic number 300 to USER_INPUTS_EXPAND_THRESHOLD

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): unify Block Header and timeline event styles

**Block Header**:
- Change to fixed char truncate (20 chars max)
- Single line only, no wrap, no expand on hover
- Simplified preview format: "content..." or "content...+N"

**UserInputsSection**:
- Remove internal mb-6 (use parent space-y-6)
- Add transition-colors to timeline node
- Add group-hover effect for consistency
- Align with other timeline event styles

**Error Section**:
- Add transition-colors to timeline node
- Add group-hover effect for consistency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): reduce header max chars to 12

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): use visual width for header text truncation

Implement visual width-aware truncation to handle Chinese/English differences:

**Visual Width Calculation**:
- ASCII characters (English, numbers, half-width symbols) = 1
- CJK characters (Chinese, full-width symbols, Emoji) = 2

**Header Preview**:
- Max visual width: 24 (≈12 Chinese chars or 24 English chars)
- Reserve space for "+N" suffix when multiple inputs exist

This ensures consistent display width across different languages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): remove extra padding in UserInputsSection for alignment

Remove the `pl-8` wrapper from UserInputsSection to match the
structure of other timeline events (ThinkingSection, ToolCallsSection,
etc.). All sections now follow the same pattern:

- `relative group` container
- `absolute -left-8` timeline node
- Direct content (no extra padding wrapper)

This ensures consistent left alignment across all block sections.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): show block header time and footer buttons on mobile

**Block Header**:
- Remove `hidden sm:` from timestamp - now visible on all screen sizes
- Remove `hidden sm:` from parrot badge - now visible on all screen sizes

**Block Footer**:
- Remove `hidden sm:` from "Forget" button - now visible on all screen sizes
- Keep text label with `hidden lg:inline` for mobile optimization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ai): remove UserInputsSection title and icon

Remove the "用户输入" (User Inputs) label and MessageSquare icon
from the section header for a cleaner UI. The expand/collapse
button is still shown when needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ai): simplify Thinking Section UI

Remove redundant elements for a cleaner design:

**Removed**:
- "(展开)/(收起)" status text - redundant with chevron icon
- Collapsed preview text - created double clickable area confusion

**Improved**:
- Chevron icon now ml-auto for right alignment
- Increased icon size (w-4 h-4) and visibility (no opacity-50)
- Single clickable area (title button) for clarity

**Result**: Cleaner, more intuitive collapsible section.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ai): optimize Warp Block UI performance and maintainability

- Fix useState closure trap with refs for latest isLatest/isStreaming values
- Improve visual width calculation with better Unicode handling (surrogate pairs, zero-width chars, CJK ranges)
- Add mobile-friendly Geek Summary display (simplified cost indicator)
- Add will-change hints to CSS animations for GPU acceleration
- Replace console.debug with conditional debugLog (DEV-only)
- Extract magic numbers to centralized constants.ts file
- Remove hardcoded Chinese fallback strings

Fixes code review issues from P1-P3 priorities.

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): track thinking phase for completed state display

Add hadThinkingPhase state to preserve thinking UI when
streaming completes, maintaining visual continuity.

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): add animated icons to thinking section header

- Show Loader2 spinner during active thinking phase
- Show Brain icon when thinking is completed
- Improve visual feedback for streaming state

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ai): remove unused hadThinkingPhase state

The thinking phase tracking state was added but not utilized
in the rendering logic. Removed to reduce unnecessary state.

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): add state-aware Thinking Section titles

Implement clear state distinction for Thinking Section:

**States**:
- `streamingPhase === "thinking"` → 🔄 思考中... (spinner + blue)
- `streamingPhase !== "thinking"` → 🧠 思考过程 (static + muted)

**Visual Changes**:
- Add Loader2 spinner icon in title during thinking phase
- Color-coded states: blue (active) vs muted (completed)
- Icon and text color match the state

This solves the UX issue where users couldn't tell if thinking
was "in progress" or "already completed".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ai): hide Session Summary expand on mobile

- Mobile: Show simplified header only, no expand button
- Desktop (lg+): Keep expand/collapse functionality
- Add lg: prefix to expand button and expanded content
- Header remains clickable on desktop only

Refs #69

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ai): remove timestamp from user inputs in block

Simplify UserInputsSection by removing the timestamp display
below each input. The block header already shows the main
message time, so individual input times are redundant.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: 黄飞虹 <aaronwong1989@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature-web] Warp Block 风格统一聊天界面

2 participants