Skip to content

fix(chat): polish new chat entry UX#1467

Merged
zerob13 merged 2 commits intodevfrom
feat/layout-optimize
Apr 13, 2026
Merged

fix(chat): polish new chat entry UX#1467
zerob13 merged 2 commits intodevfrom
feat/layout-optimize

Conversation

@zerob13
Copy link
Copy Markdown
Collaborator

@zerob13 zerob13 commented Apr 13, 2026

fix #1456
fix #1457

Summary by CodeRabbit

  • New Features

    • Visible collapsed "new chat" button in the chat workspace and reduced chat input minimum height for a more compact editor.
  • Refactor

    • Unified "start new conversation" flow so UI actions delegate to the session conversation-start logic.
  • Documentation

    • Added UI specification detailing collapsed new-chat behavior, placement, page availability, and input size constraint.
  • Tests

    • Added and updated tests for collapsed new-chat button and conversation-start scenarios.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97bb1b18-4196-45fe-8d29-018f0a92b38a

📥 Commits

Reviewing files that changed from the base of the PR and between 77aead3 and 6f74606.

📒 Files selected for processing (2)
  • src/renderer/src/stores/ui/session.ts
  • test/renderer/stores/sessionStore.test.ts
👮 Files not reviewed due to content moderation or server errors (2)
  • src/renderer/src/stores/ui/session.ts
  • test/renderer/stores/sessionStore.test.ts

📝 Walkthrough

Walkthrough

Centralizes "new conversation" initiation into the session store, adds a collapsed "new chat" button when the sidebar is hidden, reduces the chat editor minimum height from 80px to 60px, and updates related components, views, and tests to use the new session API and render the collapsed button conditionally.

Changes

Cohort / File(s) Summary
Specification
docs/specs/chat-sidebar-input-polish/spec.md
Adds UI/product spec for collapsed + button behavior, placement, availability across pages, and editor min-height reduction to 60px plus non-goals.
Session store
src/renderer/src/stores/ui/session.ts
Introduces startNewConversation(options?), CloseSessionOptions/StartNewConversationOptions types, and newConversationTargetAgentId computed; changes closeSession signature to accept options and centralizes new-conversation flow (agent selection, optional close, navigation).
Component updates
src/renderer/src/App.vue, src/renderer/src/components/WindowSideBar.vue, src/renderer/src/stores/ui/spotlight.ts
Replaces local/new-chat control flow with calls to sessionStore.startNewConversation({ refresh: true }), removing direct pageRouter.goToNewThread usage from these components/actions.
Collapsed button & layout
src/renderer/src/components/chat/ChatTopBar.vue, src/renderer/src/views/ChatTabView.vue
Adds conditional left padding spacer and animated, accessible collapsed "new chat" icon button rendered when sidebar is collapsed and newConversationTargetAgentId is present; button invokes startNewConversation.
Editor sizing
src/renderer/src/components/chat/ChatInputBox.vue
Reduced TipTap editor min-height from min-h-[80px] to min-h-[60px] in template and editor props.
Tests
test/renderer/components/..., test/renderer/stores/...
Updated and added tests to mock startNewConversation, assert IPC shortcut and UI behaviors call the session API, adapt editor height expectations, and cover startNewConversation control-flow permutations. (Multiple test files updated/added.)

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as "UI Component"
    participant Session as "Session Store"
    participant Agent as "Agent Store"
    participant Router as "Page Router"

    User->>UI: Click collapsed "New Chat" button
    UI->>Session: startNewConversation({ refresh: true })
    Session->>Session: determine targetAgentId
    alt target differs from selected
        Session->>Agent: setSelectedAgent(targetAgentId)
    end
    alt active session exists
        Session->>Session: closeSession({ refresh: true })
    end
    Session->>Router: goToNewThread({ refresh: true })
    Router->>UI: Navigate to New Thread / render new conversation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • deepinfect

Poem

🐰🌿 A tiny plus peeks where the sidebar sleeps,
I nudge the chat box down a bit — not too deep.
Click, and agents shuffle, a fresh thread begins,
Padding slides, a button glows, the new-chat wins.
Hopping on, I chant: shorter box, grander grins!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(chat): polish new chat entry UX' directly matches the PR's main objective of improving the new chat entry experience by addressing editor height and adding a new conversation button when sidebar is hidden.
Linked Issues check ✅ Passed The PR successfully addresses both linked issues: #1456 (reduced editor min-height from 80px to 60px) and #1457 (added new chat button in chat view when sidebar is collapsed).
Out of Scope Changes check ✅ Passed All changes are scoped to the stated objectives. Session store refactoring supports the new conversation flow, and component updates implement the required UI improvements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/layout-optimize

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
test/renderer/components/ChatTabView.test.ts (1)

1-178: Move this suite under test/renderer/views.

This file tests src/renderer/src/views/ChatTabView.vue, but the new suite lives under test/renderer/components/. Please mirror the source layout here so view tests stay discoverable and consistent with the repo convention.

As per coding guidelines, "Vitest test suites should mirror the source structure under test/main/** and test/renderer/**".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/renderer/components/ChatTabView.test.ts` around lines 1 - 178, The test
suite file ChatTabView.test.ts is placed under test/renderer/components but
should mirror the source layout for the view under src/renderer/src/views; move
ChatTabView.test.ts into test/renderer/views (creating the directory if needed)
so its path mirrors ChatTabView.vue, and update any test-runner config or
imports if necessary to reflect the new location (the test content, mocks
referencing ChatTabView.vue and the setup function names can remain unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/renderer/src/components/WindowSideBar.vue`:
- Around line 675-676: handleNewChat currently fire-and-forgets
sessionStore.startNewConversation which can produce unhandled rejections; update
handleNewChat to await the promise (or return it) and add proper error handling
(try/catch or .catch) mirroring the error handling used for the App.vue shortcut
path so any failure in sessionStore.startNewConversation is caught and
logged/handled instead of discarded.

In `@src/renderer/src/stores/ui/session.ts`:
- Around line 332-349: startNewConversation currently ignores the
options.refresh flag when there is an active session because it calls await
closeSession() which internally routes via pageRouter.goToNewThread() without
the refresh key; update either closeSession or startNewConversation so the
refresh intent is preserved: when startNewConversation is called with
options.refresh (e.g., true) and hasActiveSession.value is true, pass the
refresh through to the routing call (for example by calling closeSession with a
parameter or by invoking pageRouter.goToNewThread({ refresh: options.refresh ??
true }) after closeSession resolves) so that newThreadRefreshKey is bumped
consistently; modify the signatures/uses of closeSession and any calls to
pageRouter.goToNewThread() accordingly and ensure newThreadRefreshKey logic
remains unchanged.

---

Nitpick comments:
In `@test/renderer/components/ChatTabView.test.ts`:
- Around line 1-178: The test suite file ChatTabView.test.ts is placed under
test/renderer/components but should mirror the source layout for the view under
src/renderer/src/views; move ChatTabView.test.ts into test/renderer/views
(creating the directory if needed) so its path mirrors ChatTabView.vue, and
update any test-runner config or imports if necessary to reflect the new
location (the test content, mocks referencing ChatTabView.vue and the setup
function names can remain unchanged).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 410d173b-385c-479a-8f72-7a93f78847df

📥 Commits

Reviewing files that changed from the base of the PR and between 9414461 and 77aead3.

📒 Files selected for processing (14)
  • docs/specs/chat-sidebar-input-polish/spec.md
  • src/renderer/src/App.vue
  • src/renderer/src/components/WindowSideBar.vue
  • src/renderer/src/components/chat/ChatInputBox.vue
  • src/renderer/src/components/chat/ChatTopBar.vue
  • src/renderer/src/stores/ui/session.ts
  • src/renderer/src/stores/ui/spotlight.ts
  • src/renderer/src/views/ChatTabView.vue
  • test/renderer/components/App.startup.test.ts
  • test/renderer/components/ChatInputBox.test.ts
  • test/renderer/components/ChatTabView.test.ts
  • test/renderer/components/WindowSideBar.test.ts
  • test/renderer/stores/sessionStore.test.ts
  • test/renderer/stores/spotlight.test.ts

Comment on lines 675 to +676
const handleNewChat = () => {
if (sessionStore.hasActiveSession) {
void sessionStore.closeSession()
return
}

pageRouterStore.goToNewThread({ refresh: true })
void sessionStore.startNewConversation({ refresh: true })
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't fire-and-forget startNewConversation() from the sidebar.

Line 676 discards the promise. If the store action fails, this click path turns into an unhandled rejection, unlike the App.vue shortcut path which catches the error.

Suggested fix
-const handleNewChat = () => {
-  void sessionStore.startNewConversation({ refresh: true })
-}
+const handleNewChat = async () => {
+  try {
+    await sessionStore.startNewConversation({ refresh: true })
+  } catch (error) {
+    console.error('Failed to start new conversation:', error)
+  }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleNewChat = () => {
if (sessionStore.hasActiveSession) {
void sessionStore.closeSession()
return
}
pageRouterStore.goToNewThread({ refresh: true })
void sessionStore.startNewConversation({ refresh: true })
const handleNewChat = async () => {
try {
await sessionStore.startNewConversation({ refresh: true })
} catch (error) {
console.error('Failed to start new conversation:', error)
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/src/components/WindowSideBar.vue` around lines 675 - 676,
handleNewChat currently fire-and-forgets sessionStore.startNewConversation which
can produce unhandled rejections; update handleNewChat to await the promise (or
return it) and add proper error handling (try/catch or .catch) mirroring the
error handling used for the App.vue shortcut path so any failure in
sessionStore.startNewConversation is caught and logged/handled instead of
discarded.

@zerob13 zerob13 merged commit 404295e into dev Apr 13, 2026
3 checks passed
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.

[反馈] 侧边栏隐藏时,编辑框工具栏缺少直接开启新对话的按钮 [反馈] 编辑框的固定高度在笔记本界面占比太大了

1 participant